From 512d69643ff08dda38fddd43a33f8e1faa9fc8c4 Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Wed, 18 Nov 2015 11:46:18 +0000 Subject: [PATCH] - Add `readystatechange` to xhr events regardless of the browser supporting `onload`, for ajax implementations that still rely on readystatechange - Move `evts` into function closure so multiple calls to `createPassthrough` don't result in duplicate entries in `evts`. --- pretender.js | 22 +++++++++++----------- test/passthrough_test.js | 24 +++++++++++++++++++++--- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/pretender.js b/pretender.js index 63d36e4..a1a9838 100644 --- a/pretender.js +++ b/pretender.js @@ -133,23 +133,22 @@ function interceptor(pretender) { } }; - // event types to handle on the xhr - var evts = ['error', 'timeout', 'abort']; - // event types to handle on the xhr.upload - var uploadEvents = ['progress']; + function createPassthrough(fakeXHR) { + // event types to handle on the xhr + var evts = ['error', 'timeout', 'abort', 'readystatechange']; - // properties to copy from the native xhr to fake xhr - var lifecycleProps = ['readyState', 'responseText', 'responseXML', 'status', 'statusText']; + // event types to handle on the xhr.upload + var uploadEvents = ['progress']; + + // properties to copy from the native xhr to fake xhr + var lifecycleProps = ['readyState', 'responseText', 'responseXML', 'status', 'statusText']; - function createPassthrough(fakeXHR) { var xhr = fakeXHR._passthroughRequest = new pretender._nativeXMLHttpRequest(); - // Use onload instead of onreadystatechange if the browser supports it + // Use onload if the browser supports it if ('onload' in xhr) { evts.push('load'); - } else { - evts.push('readystatechange'); } // add progress event for async calls @@ -183,6 +182,8 @@ function interceptor(pretender) { }; } + xhr.open(fakeXHR.method, fakeXHR.url, fakeXHR.async, fakeXHR.username, fakeXHR.password); + // set the on- handler on the native xhr's `upload` property for // the given eventType function createUploadHandler(eventType) { @@ -201,7 +202,6 @@ function interceptor(pretender) { createUploadHandler(uploadEvents[i]); } - xhr.open(fakeXHR.method, fakeXHR.url, fakeXHR.async, fakeXHR.username, fakeXHR.password); if (fakeXHR.async) { xhr.timeout = fakeXHR.timeout; xhr.withCredentials = fakeXHR.withCredentials; diff --git a/test/passthrough_test.js b/test/passthrough_test.js index 9f862e8..6269704 100644 --- a/test/passthrough_test.js +++ b/test/passthrough_test.js @@ -98,17 +98,19 @@ asyncTest('synchronous request does not have timeout, withCredentials and onprog test('asynchronous request fires events', function(assert) { var done = assert.async(); - assert.expect(4); + assert.expect(6); pretender.post('/some/:route', pretender.passthrough); var onEvents = { load: false, - progress: false + progress: false, + readystatechange: false }; var listenerEvents = { load: false, - progress: false + progress: false, + readystatechange: false }; var xhr = new window.XMLHttpRequest(); @@ -132,6 +134,20 @@ test('asynchronous request fires events', function(assert) { finishNext(); }; + xhr.addEventListener('readystatechange', function _load() { + if (xhr.readyState == 4) { + listenerEvents.readystatechange = true; + finishNext(); + } + }); + + xhr.onreadystatechange = function _onload() { + if (xhr.readyState == 4) { + onEvents.readystatechange = true; + finishNext(); + } + }; + xhr.send(); // call `finish` in next tick to ensure both load event handlers @@ -147,9 +163,11 @@ test('asynchronous request fires events', function(assert) { assert.ok(onEvents.load, 'onload called'); assert.ok(onEvents.progress, 'onprogress called'); + assert.ok(onEvents.readystatechange, 'onpreadystate called'); assert.ok(listenerEvents.load, 'load listener called'); assert.ok(listenerEvents.progress, 'progress listener called'); + assert.ok(listenerEvents.readystatechange, 'readystate listener called'); done(); }