diff --git a/lib/fake-xhr/index.js b/lib/fake-xhr/index.js index 47a8de7..287f3b4 100644 --- a/lib/fake-xhr/index.js +++ b/lib/fake-xhr/index.js @@ -513,8 +513,6 @@ function fakeXMLHttpRequestFor(globalScope) { false, this ); - var event, progress; - if (typeof this.onreadystatechange === "function") { try { this.onreadystatechange(readyStateChangeEvent); @@ -523,7 +521,11 @@ function fakeXMLHttpRequestFor(globalScope) { } } - if (this.readyState === FakeXMLHttpRequest.DONE) { + if (this.readyState !== FakeXMLHttpRequest.DONE) { + this.dispatchEvent(readyStateChangeEvent); + } else { + var event, progress; + if (this.timedOut || this.aborted || this.status === 0) { progress = { loaded: 0, total: 0 }; event = @@ -553,12 +555,11 @@ function fakeXMLHttpRequestFor(globalScope) { this.dispatchEvent( new sinonEvent.ProgressEvent(event, progress, this) ); + this.dispatchEvent(readyStateChangeEvent); this.dispatchEvent( new sinonEvent.ProgressEvent("loadend", progress, this) ); } - - this.dispatchEvent(readyStateChangeEvent); }, // Ref https://xhr.spec.whatwg.org/#the-setrequestheader()-method diff --git a/lib/fake-xhr/index.test.js b/lib/fake-xhr/index.test.js index 6228693..4d689ef 100644 --- a/lib/fake-xhr/index.test.js +++ b/lib/fake-xhr/index.test.js @@ -1186,6 +1186,29 @@ describe("FakeXMLHttpRequest", function() { assert.equals(status, 204); assert.equals(statusText, "No Content"); }); + + it("only performs readystatechange events prior to loadend event during xhr response", function() { + var eventLog = []; + this.xhr.addEventListener("readystatechange", function() { + eventLog.push({ + event: "readystatechange", + timestamp: Date.now() + }); + }); + this.xhr.addEventListener("loadend", function() { + eventLog.push({ event: "loadend", timestamp: Date.now() }); + }); + this.xhr.respond(200); + + // Loadend is last event + assert.equals(eventLog[eventLog.length - 1].event, "loadend"); + // Only 1 loadend event occurs + assert.equals( + eventLog.filter(item => item.event !== "readystatechange") + .length, + 1 + ); + }); }); describe(".getResponseHeader", function() {