From 5d96ce960953b667d65c1b0d538a9c4f06c68cd2 Mon Sep 17 00:00:00 2001 From: Mickael Jeanroy Date: Thu, 9 Apr 2015 22:27:02 +0200 Subject: [PATCH] Event readystatechange is triggered when headers are available According to the specification, readyState value must be equal to 2 and readystatechange event should be triggered once status and headers are available. Close #97 --- spec/fakeRequestSpec.js | 46 +++++++++++++++++++++++++++++++++++++---- src/fakeRequest.js | 8 ++++--- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/spec/fakeRequestSpec.js b/spec/fakeRequestSpec.js index 486c2ff..c8a6b3d 100644 --- a/spec/fakeRequestSpec.js +++ b/spec/fakeRequestSpec.js @@ -125,14 +125,15 @@ describe('FakeRequest', function() { expect(this.fakeEventBus.trigger).toHaveBeenCalledWith('readystatechange'); }); - it('has a ready state of 2 (sent) when sent', function() { + it('has a ready state of 1 (sent) when sent', function() { this.request.open(); this.fakeEventBus.trigger.calls.reset(); this.request.send(); - expect(this.request.readyState).toBe(2); - expect(this.fakeEventBus.trigger).toHaveBeenCalledWith('readystatechange'); + expect(this.request.readyState).toBe(1); + expect(this.fakeEventBus.trigger).toHaveBeenCalledWith('loadstart'); + expect(this.fakeEventBus.trigger).not.toHaveBeenCalledWith('readystatechange'); }); it('has a ready state of 4 (loaded) when timed out', function() { @@ -170,6 +171,43 @@ describe('FakeRequest', function() { expect(this.fakeEventBus.trigger).toHaveBeenCalledWith('readystatechange'); }); + it('has a ready state of 2, then 4 (loaded) when responding', function() { + this.request.open(); + this.request.send(); + this.fakeEventBus.trigger.calls.reset(); + + var request = this.request; + var events = []; + var headers = [ + { name: 'X-Header', value: 'foo' } + ]; + + this.fakeEventBus.trigger.and.callFake(function(event) { + if (event === 'readystatechange') { + events.push({ + readyState: request.readyState, + status: request.status, + statusText: request.statusText, + responseHeaders: request.responseHeaders + }); + } + }); + + this.request.respondWith({ + status: 200, + statusText: 'OK', + responseHeaders: headers + }); + + expect(this.request.readyState).toBe(4); + expect(this.fakeEventBus.trigger).toHaveBeenCalledWith('readystatechange'); + expect(events.length).toBe(2); + expect(events).toEqual([ + { readyState: 2, status: 200, statusText: 'OK', responseHeaders: headers }, + { readyState: 4, status: 200, statusText: 'OK', responseHeaders: headers } + ]); + }); + it('throws an error when timing out a request that has completed', function() { this.request.open(); this.request.send(); @@ -270,7 +308,7 @@ describe('FakeRequest', function() { this.request.send(); expect(this.fakeEventBus.trigger).toHaveBeenCalledWith('loadstart'); - expect(this.fakeEventBus.trigger).toHaveBeenCalledWith('readystatechange'); + expect(this.fakeEventBus.trigger).not.toHaveBeenCalledWith('readystatechange'); expect(this.fakeEventBus.trigger).not.toHaveBeenCalledWith('progress'); expect(this.fakeEventBus.trigger).not.toHaveBeenCalledWith('abort'); expect(this.fakeEventBus.trigger).not.toHaveBeenCalledWith('error'); diff --git a/src/fakeRequest.js b/src/fakeRequest.js index a0c3951..a9421ca 100644 --- a/src/fakeRequest.js +++ b/src/fakeRequest.js @@ -164,9 +164,7 @@ getJasmineRequireObj().AjaxFakeRequest = function(eventBusFactory) { send: function(data) { this.params = data; - this.readyState = 2; this.eventBus.trigger('loadstart'); - this.eventBus.trigger('readystatechange'); var stub = stubTracker.findStub(this.url, data, this.method); if (stub) { @@ -237,12 +235,16 @@ getJasmineRequireObj().AjaxFakeRequest = function(eventBusFactory) { if (this.readyState === 4) { throw new Error("FakeXMLHttpRequest already completed"); } + this.status = response.status; this.statusText = response.statusText || ""; + this.responseHeaders = normalizeHeaders(response.responseHeaders, response.contentType); + this.readyState = 2; + this.eventBus.trigger('readystatechange'); + this.responseText = response.responseText || ""; this.responseType = response.responseType || ""; this.readyState = 4; - this.responseHeaders = normalizeHeaders(response.responseHeaders, response.contentType); this.responseXML = getResponseXml(response.responseText, this.getResponseHeader('content-type') || ''); if (this.responseXML) { this.responseType = 'document';