diff --git a/lib/mock-ajax.js b/lib/mock-ajax.js index 2b453e2..3b628f4 100644 --- a/lib/mock-ajax.js +++ b/lib/mock-ajax.js @@ -233,15 +233,20 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. }, getResponseHeader: function(name) { - return this.responseHeaders[name]; + var values = []; + for (var i = 0; i < this.responseHeaders.length; i++) { + if (this.responseHeaders[i].name === name) { + values.push(this.responseHeaders[i].value); + } + } + return values.join(', '); }, getAllResponseHeaders: function() { var responseHeaders = []; - for (var i in this.responseHeaders) { - if (this.responseHeaders.hasOwnProperty(i)) { - responseHeaders.push(i + ': ' + this.responseHeaders[i]); - } + for (var i = 0; i < this.responseHeaders.length; i++) { + responseHeaders.push(this.responseHeaders[i].name + ': ' + + this.responseHeaders[i].value); } return responseHeaders.join('\r\n'); }, @@ -256,8 +261,30 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. this.statusText = response.statusText || ""; this.responseText = response.responseText || ""; this.readyState = 4; - this.responseHeaders = response.responseHeaders || - {"Content-Type": response.contentType || "application/json" }; + this.responseHeaders = []; + + var i; + if (response.responseHeaders) { + if (response.responseHeaders instanceof Array) { + this.responseHeaders = response.responseHeaders; + } else { + for (i in response.responseHeaders) { + if (response.responseHeaders.hasOwnProperty(i)) { + this.responseHeaders.push({ name: i, value: response.responseHeaders[i] }); + } + } + } + } else { + this.responseHeaders.push({ name: "Content-Type", value: response.contentType || "application/json" }); + } + + for (i = 0; i < this.responseHeaders.length; i++) { + if (typeof(this.responseHeaders[this.responseHeaders[i].name]) === 'undefined') { + this.responseHeaders[this.responseHeaders[i].name] = this.responseHeaders[i].value; + } else { + this.responseHeaders[this.responseHeaders[i].name] += ', ' + this.responseHeaders[i].value; + } + } this.onload(); this.onreadystatechange(); diff --git a/spec/javascripts/mock-ajax-toplevel-spec.js b/spec/javascripts/mock-ajax-toplevel-spec.js index 90d3f21..0a86cad 100644 --- a/spec/javascripts/mock-ajax-toplevel-spec.js +++ b/spec/javascripts/mock-ajax-toplevel-spec.js @@ -252,6 +252,83 @@ describe("Jasmine Mock Ajax (for toplevel)", function() { sharedAjaxResponseBehaviorForZepto_Success(sharedContext); }); + describe("response with unique header names using an object", function () { + var value1, value2, value3; + beforeEach(function () { + client = new fakeGlobal.XMLHttpRequest(); + client.onreadystatechange = onreadystatechange; + client.open("GET", "example.com"); + client.send(); + + value1 = Math.random().toString(); + value2 = Math.random().toString(); + value3 = Math.random().toString(); + + request = mockAjax.requests.mostRecent(); + var responseObject = {status: 200, statusText: "OK", responseText: '["foo"]', responseHeaders: { + 'X-Header1': value1, + 'X-Header2': value2, + 'X-Header3': value3 + }}; + request.response(responseObject); + response = success.calls.mostRecent().args[2]; + }); + + it("getResponseHeader should return the each value", function () { + expect(response.getResponseHeader('X-Header1')).toBe(value1); + expect(response.getResponseHeader('X-Header2')).toBe(value2); + expect(response.getResponseHeader('X-Header3')).toBe(value3); + expect(response.responseHeaders['X-Header1']).toBe(value1); + expect(response.responseHeaders['X-Header2']).toBe(value2); + expect(response.responseHeaders['X-Header3']).toBe(value3); + }); + + it("getAllResponseHeaders should return all values", function () { + expect(response.getAllResponseHeaders()).toBe([ + "X-Header1: " + value1, + "X-Header2: " + value2, + "X-Header3: " + value3 + ].join("\r\n")); + }); + }); + + describe("response with multiple headers of the same name using an array of objects", function () { + var value1, value2, value3; + beforeEach(function () { + client = new fakeGlobal.XMLHttpRequest(); + client.onreadystatechange = onreadystatechange; + client.open("GET", "example.com"); + client.send(); + + value1 = Math.random().toString(); + value2 = Math.random().toString(); + value3 = Math.random().toString(); + + request = mockAjax.requests.mostRecent(); + var responseObject = {status: 200, statusText: "OK", responseText: '["foo"]', responseHeaders: [ + { name: 'X-Header', value: value1 }, + { name: 'X-Header', value: value2 }, + { name: 'X-Header', value: value3 } + ]}; + request.response(responseObject); + response = success.calls.mostRecent().args[2]; + }); + + it("getResponseHeader should return all values comma separated", function () { + var values = [value1, value2, value3].join(', '); // see http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method + expect(response.getResponseHeader('X-Header')).toBe(values); + expect(response.responseHeaders['X-Header']).toBe(values); + }); + + it("getAllResponseHeaders should return all values", function () { + expect(response.getAllResponseHeaders()).toBe([ + "X-Header: " + value1, + "X-Header: " + value2, + "X-Header: " + value3 + ].join("\r\n")); + }); + }); + describe("the content type defaults to application/json", function () { beforeEach(function() { client = new fakeGlobal.XMLHttpRequest();