diff options
| author | Karl Seamon | 2011-07-29 18:32:30 -0400 |
|---|---|---|
| committer | Igor Minar | 2011-08-19 01:20:45 -0700 |
| commit | 4ec1d8ee86e3138fb91543ca0dca28463895c090 (patch) | |
| tree | 9f7fff13f177317ff15f8804789a44576a151908 | |
| parent | c37bfde9eb31556ee1eb146795b0c1f1504a4a26 (diff) | |
| download | angular.js-4ec1d8ee86e3138fb91543ca0dca28463895c090.tar.bz2 | |
feat($xhr,$resource): expose response headers in callbacks
all $xhr*, $resource and related mocks now have access to headers from
their callbacks
| -rw-r--r-- | src/Browser.js | 35 | ||||
| -rw-r--r-- | src/Resource.js | 4 | ||||
| -rw-r--r-- | src/angular-mocks.js | 35 | ||||
| -rw-r--r-- | src/service/resource.js | 10 | ||||
| -rw-r--r-- | src/service/xhr.bulk.js | 11 | ||||
| -rw-r--r-- | src/service/xhr.cache.js | 18 | ||||
| -rw-r--r-- | src/service/xhr.js | 11 | ||||
| -rw-r--r-- | test/BrowserSpecs.js | 42 | ||||
| -rw-r--r-- | test/ResourceSpec.js | 42 | ||||
| -rw-r--r-- | test/service/xhr.bulkSpec.js | 7 | ||||
| -rw-r--r-- | test/service/xhr.cacheSpec.js | 35 | ||||
| -rw-r--r-- | test/service/xhrSpec.js | 37 |
12 files changed, 215 insertions, 72 deletions
diff --git a/src/Browser.js b/src/Browser.js index 2b2170e2..65d27448 100644 --- a/src/Browser.js +++ b/src/Browser.js @@ -84,7 +84,9 @@ function Browser(window, document, body, XHR, $log) { * @param {string} method Requested method (get|post|put|delete|head|json) * @param {string} url Requested url * @param {?string} post Post data to send (null if nothing to post) - * @param {function(number, string)} callback Function that will be called on response + * @param {function(number, string, function([string]))} callback Function that will be called on + * response. The third argument is a function that can be called to return a specified response + * header or an Object containing all headers (when called with no arguments). * @param {object=} header additional HTTP headers to send with XHR. * Standard headers are: * <ul> @@ -97,6 +99,8 @@ function Browser(window, document, body, XHR, $log) { * Send ajax request */ self.xhr = function(method, url, post, callback, headers) { + var parsedHeaders; + outstandingRequestCount ++; if (lowercase(method) == 'json') { var callbackId = ("angular_" + Math.random() + '_' + (idCounter++)).replace(/\d\./, ''); @@ -123,7 +127,34 @@ function Browser(window, document, body, XHR, $log) { if (xhr.readyState == 4) { // normalize IE bug (http://bugs.jquery.com/ticket/1450) var status = xhr.status == 1223 ? 204 : xhr.status || 200; - completeOutstandingRequest(callback, status, xhr.responseText); + completeOutstandingRequest(callback, status, xhr.responseText, function(header) { + header = lowercase(header); + + if (header) { + return parsedHeaders + ? parsedHeaders[header] || null + : xhr.getResponseHeader(header); + } else { + // Return an object containing each response header + parsedHeaders = {}; + + forEach(xhr.getAllResponseHeaders().split('\n'), function(line) { + var i = line.indexOf(':'), + key = lowercase(trim(line.substr(0, i))), + value = trim(line.substr(i + 1)); + + if (parsedHeaders[key]) { + // Combine repeated headers + // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 + parsedHeaders[key] += ', ' + value; + } else { + parsedHeaders[key] = value; + } + }); + + return parsedHeaders; + } + }); } }; xhr.send(post || ''); diff --git a/src/Resource.js b/src/Resource.js index 74d952ed..4bf5cf65 100644 --- a/src/Resource.js +++ b/src/Resource.js @@ -111,7 +111,7 @@ ResourceFactory.prototype = { action.method, route.url(extend({}, action.params || {}, extractParams(data), params)), data, - function(status, response) { + function(status, response, responseHeaders) { if (response) { if (action.isArray) { value.length = 0; @@ -122,7 +122,7 @@ ResourceFactory.prototype = { copy(response, value); } } - (success||noop)(value); + (success||noop)(value, responseHeaders); }, error || action.verifyCache, action.verifyCache); diff --git a/src/angular-mocks.js b/src/angular-mocks.js index 5d56ae27..d793f511 100644 --- a/src/angular-mocks.js +++ b/src/angular-mocks.js @@ -152,7 +152,14 @@ function MockBrowser() { throw new Error("Missing HTTP request header: " + key + ": " + value); } }); - callback(expectation.code, expectation.response); + callback(expectation.code, expectation.response, function(header) { + if (header) { + header = header.toLowerCase(); + return expectation.responseHeaders && expectation.responseHeaders[header] || null; + } else { + return expectation.responseHeaders || {}; + } + }); }); }; self.xhr.expectations = expectations; @@ -162,12 +169,22 @@ function MockBrowser() { if (data && angular.isString(data)) url += "|" + data; var expect = expectations[method] || (expectations[method] = {}); return { - respond: function(code, response) { + respond: function(code, response, responseHeaders) { if (!angular.isNumber(code)) { + responseHeaders = response; response = code; code = 200; } - expect[url] = {code:code, response:response, headers: headers || {}}; + angular.forEach(responseHeaders, function(value, key) { + delete responseHeaders[key]; + responseHeaders[key.toLowerCase()] = value; + }); + expect[url] = { + code: code, + response: response, + headers: headers || {}, + responseHeaders: responseHeaders || {} + }; } }; }; @@ -268,7 +285,7 @@ function MockBrowser() { self.defer = function(fn, delay) { delay = delay || 0; self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId}); - self.deferredFns.sort(function(a,b){ return a.time - b.time;}); + self.deferredFns.sort(function(a,b){return a.time - b.time;}); return self.deferredNextId++; }; @@ -374,7 +391,7 @@ angular.service('$browser', function(){ * See {@link angular.mock} for more info on angular mocks. */ angular.service('$exceptionHandler', function() { - return function(e) { throw e;}; + return function(e) {throw e;}; }); @@ -394,10 +411,10 @@ angular.service('$log', MockLogFactory); function MockLogFactory() { var $log = { - log: function(){ $log.log.logs.push(arguments); }, - warn: function(){ $log.warn.logs.push(arguments); }, - info: function(){ $log.info.logs.push(arguments); }, - error: function(){ $log.error.logs.push(arguments); } + log: function(){$log.log.logs.push(arguments);}, + warn: function(){$log.warn.logs.push(arguments);}, + info: function(){$log.info.logs.push(arguments);}, + error: function(){$log.error.logs.push(arguments);} }; $log.log.logs = []; diff --git a/src/service/resource.js b/src/service/resource.js index f6e0be18..47b57645 100644 --- a/src/service/resource.js +++ b/src/service/resource.js @@ -147,9 +147,15 @@ * <pre> var User = $resource('/user/:userId', {userId:'@id'}); - User.get({userId:123}, function(u){ + User.get({userId:123}, function(u, responseHeaders){ u.abc = true; - u.$save(); + u.$save(function(u, responseHeaders) { + // Get an Object containing all response headers + var allHeaders = responseHeaders(); + + // Get a specific response header + u.newId = responseHeaders('Location'); + }); }); </pre> diff --git a/src/service/xhr.bulk.js b/src/service/xhr.bulk.js index d7fc7990..8d9e7a72 100644 --- a/src/service/xhr.bulk.js +++ b/src/service/xhr.bulk.js @@ -48,13 +48,14 @@ angularServiceInject('$xhr.bulk', function($xhr, $error, $log){ queue.requests = []; queue.callbacks = []; $xhr('POST', url, {requests: currentRequests}, - function(code, response) { + function(code, response, responseHeaders) { forEach(response, function(response, i) { try { if (response.status == 200) { - (currentRequests[i].success || noop)(response.status, response.response); + (currentRequests[i].success || noop) + (response.status, response.response, responseHeaders); } else if (isFunction(currentRequests[i].error)) { - currentRequests[i].error(response.status, response.response); + currentRequests[i].error(response.status, response.response, responseHeaders); } else { $error(currentRequests[i], response); } @@ -64,11 +65,11 @@ angularServiceInject('$xhr.bulk', function($xhr, $error, $log){ }); (success || noop)(); }, - function(code, response) { + function(code, response, responseHeaders) { forEach(currentRequests, function(request, i) { try { if (isFunction(request.error)) { - request.error(code, response); + request.error(code, response, responseHeaders); } else { $error(request, response); } diff --git a/src/service/xhr.cache.js b/src/service/xhr.cache.js index 256b936e..b3280101 100644 --- a/src/service/xhr.cache.js +++ b/src/service/xhr.cache.js @@ -22,8 +22,8 @@ * @param {string} method HTTP method. * @param {string} url Destination URL. * @param {(string|Object)=} post Request body. - * @param {function(number, (string|Object))} success Response success callback. - * @param {function(number, (string|Object))=} error Response error callback. + * @param {function(number, (string|Object), Function)} success Response success callback. + * @param {function(number, (string|Object), Function)} error Response error callback. * @param {boolean=} [verifyCache=false] If `true` then a result is immediately returned from cache * (if present) while a request is sent to the server for a fresh response that will update the * cached entry. The `success` function will be called when the response is received. @@ -55,9 +55,9 @@ angularServiceInject('$xhr.cache', function($xhr, $defer, $error, $log) { if (dataCached = cache.data[url]) { if (sync) { - success(200, copy(dataCached.value)); + success(200, copy(dataCached.value), copy(dataCached.headers)); } else { - $defer(function() { success(200, copy(dataCached.value)); }); + $defer(function() { success(200, copy(dataCached.value), copy(dataCached.headers)); }); } if (!verifyCache) @@ -70,20 +70,20 @@ angularServiceInject('$xhr.cache', function($xhr, $defer, $error, $log) { } else { inflight[url] = {successes: [success], errors: [error]}; cache.delegate(method, url, post, - function(status, response) { + function(status, response, responseHeaders) { if (status == 200) - cache.data[url] = {value: response}; + cache.data[url] = {value: response, headers: responseHeaders}; var successes = inflight[url].successes; delete inflight[url]; forEach(successes, function(success) { try { - (success||noop)(status, copy(response)); + (success||noop)(status, copy(response), responseHeaders); } catch(e) { $log.error(e); } }); }, - function(status, response) { + function(status, response, responseHeaders) { var errors = inflight[url].errors, successes = inflight[url].successes; delete inflight[url]; @@ -91,7 +91,7 @@ angularServiceInject('$xhr.cache', function($xhr, $defer, $error, $log) { forEach(errors, function(error, i) { try { if (isFunction(error)) { - error(status, copy(response)); + error(status, copy(response), copy(responseHeaders)); } else { $error( {method: method, url: url, data: post, success: successes[i]}, diff --git a/src/service/xhr.js b/src/service/xhr.js index 70fcd067..6bff6f04 100644 --- a/src/service/xhr.js +++ b/src/service/xhr.js @@ -96,7 +96,7 @@ * angular generated callback function. * @param {(string|Object)=} post Request content as either a string or an object to be stringified * as JSON before sent to the server. - * @param {function(number, (string|Object))} success A function to be called when the response is + * @param {function(number, (string|Object), Function)} success A function to be called when the response is * received. The success function will be called with: * * - {number} code [HTTP status code](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes) of @@ -104,6 +104,9 @@ * {@link angular.service.$xhr.error} service (or custom error callback). * - {string|Object} response Response object as string or an Object if the response was in JSON * format. + * - {function(string=)} responseHeaders A function that when called with a {string} header name, + * returns the value of that header or null if it does not exist; when called without + * arguments, returns an object containing every response header * @param {function(number, (string|Object))} error A function to be called if the response code is * not 2xx.. Accepts the same arguments as success, above. * @@ -198,7 +201,7 @@ angularServiceInject('$xhr', function($browser, $error, $log, $updateView){ post = toJson(post); } - $browser.xhr(method, url, post, function(code, response){ + $browser.xhr(method, url, post, function(code, response, responseHeaders){ try { if (isString(response)) { if (response.match(/^\)\]\}',\n/)) response=response.substr(6); @@ -207,9 +210,9 @@ angularServiceInject('$xhr', function($browser, $error, $log, $updateView){ } } if (200 <= code && code < 300) { - success(code, response); + success(code, response, responseHeaders); } else if (isFunction(error)) { - error(code, response); + error(code, response, responseHeaders); } else { $error( {method: method, url: url, data: post, success: success}, diff --git a/test/BrowserSpecs.js b/test/BrowserSpecs.js index 92e4e501..93882c1a 100644 --- a/test/BrowserSpecs.js +++ b/test/BrowserSpecs.js @@ -49,6 +49,13 @@ describe('browser', function(){ this.send = function(post){ xhr.post = post; }; + this.getResponseHeader = function(header) { + return header; + }; + this.getAllResponseHeaders = function() { + return 'Content-Type: application/json\n\rContent-Encoding: gzip\n\rContent-Type: text/json'; + } + }; logs = {log:[], warn:[], info:[], error:[]}; @@ -198,6 +205,41 @@ describe('browser', function(){ expect(code).toEqual(202); expect(response).toEqual('RESPONSE'); }); + + describe('response headers', function() { + it('should return a single response header', function() { + var headerA; + + browser.xhr('GET', 'URL', null, function(code, resp, headers) { + headerA = headers('A-Header'); + }); + + xhr.status = 200; + xhr.responseText = 'RESPONSE'; + xhr.readyState = 4; + xhr.onreadystatechange(); + + expect(headerA).toEqual('a-header'); + }); + + it('should return an object containing all response headers', function() { + var allHeaders; + + browser.xhr('GET', 'URL', null, function(code, resp, headers) { + allHeaders = headers(); + }); + + xhr.status = 200; + xhr.responseText = 'RESPONSE'; + xhr.readyState = 4; + xhr.onreadystatechange(); + + expect(allHeaders).toEqual({ + 'content-type': 'application/json, text/json', + 'content-encoding': 'gzip' + }); + }); + }); }); describe('defer', function() { diff --git a/test/ResourceSpec.js b/test/ResourceSpec.js index 7bba9357..a143fc0e 100644 --- a/test/ResourceSpec.js +++ b/test/ResourceSpec.js @@ -83,7 +83,8 @@ describe("resource", function() { expect(callback).not.toHaveBeenCalled(); xhr.flush(); nakedExpect(cc).toEqual({id:123, name:'misko'}); - expect(callback).toHaveBeenCalledWith(cc); + expect(callback.mostRecentCall.args[0]).toEqual(cc); + expect(callback.mostRecentCall.args[1]()).toEqual({}); }); it("should read resource", function(){ @@ -94,7 +95,8 @@ describe("resource", function() { expect(callback).not.toHaveBeenCalled(); xhr.flush(); nakedExpect(cc).toEqual({id:123, number:'9876'}); - expect(callback).toHaveBeenCalledWith(cc); + expect(callback.mostRecentCall.args[0]).toEqual(cc); + expect(callback.mostRecentCall.args[1]()).toEqual({}); }); it("should read partial resource", function(){ @@ -108,7 +110,8 @@ describe("resource", function() { expect(cc.number).not.toBeDefined(); cc.$get(callback); xhr.flush(); - expect(callback).toHaveBeenCalledWith(cc); + expect(callback.mostRecentCall.args[0]).toEqual(cc); + expect(callback.mostRecentCall.args[1]()).toEqual({}); expect(cc.number).toEqual('9876'); }); @@ -129,7 +132,8 @@ describe("resource", function() { expect(callback).not.toHaveBeenCalled(); xhr.flush(); nakedExpect(ccs).toEqual([{id:1}, {id:2}]); - expect(callback).toHaveBeenCalledWith(ccs); + expect(callback.mostRecentCall.args[0]).toEqual(ccs); + expect(callback.mostRecentCall.args[1]()).toEqual({}); }); it("should have all arguments optional", function(){ @@ -147,14 +151,16 @@ describe("resource", function() { CreditCard.remove({id:123}, callback); expect(callback).not.toHaveBeenCalled(); xhr.flush(); - nakedExpect(callback.mostRecentCall.args).toEqual([{}]); + nakedExpect(callback.mostRecentCall.args[0]).toEqual({}); + nakedExpect(callback.mostRecentCall.args[1]()).toEqual({}); callback.reset(); xhr.expectDELETE("/CreditCard/333").respond(204, null); CreditCard.remove({id:333}, callback); expect(callback).not.toHaveBeenCalled(); xhr.flush(); - nakedExpect(callback.mostRecentCall.args).toEqual([{}]); + nakedExpect(callback.mostRecentCall.args[0]).toEqual({}); + nakedExpect(callback.mostRecentCall.args[1]()).toEqual({}); }); it('should post charge verb', function(){ @@ -171,7 +177,7 @@ describe("resource", function() { }); it('should create on save', function(){ - xhr.expectPOST('/CreditCard', {name:'misko'}).respond({id:123}); + xhr.expectPOST('/CreditCard', {name:'misko'}).respond({id: 123}, {foo: 'bar'}); var cc = new CreditCard(); expect(cc.$get).toBeDefined(); expect(cc.$query).toBeDefined(); @@ -183,7 +189,9 @@ describe("resource", function() { nakedExpect(cc).toEqual({name:'misko'}); xhr.flush(); nakedExpect(cc).toEqual({id:123}); - expect(callback).toHaveBeenCalledWith(cc); + expect(callback.mostRecentCall.args[0]).toEqual(cc); + expect(callback.mostRecentCall.args[1]('foo')).toEqual('bar'); + expect(callback.mostRecentCall.args[1]()).toEqual({foo: 'bar'}); }); it('should not mutate the resource object if response contains no body', function(){ @@ -245,10 +253,15 @@ describe("resource", function() { describe('failure mode', function() { var ERROR_CODE = 500, ERROR_RESPONSE = 'Server Error', - errorCB; + errorCB, + headersFn; beforeEach(function() { - errorCB = jasmine.createSpy(); + errorCB = jasmine.createSpy().andCallFake(function(code, response, headers) { + headersFn = headers; + }); + + xhr.expectGET('/CreditCard/123').respond(ERROR_CODE, ERROR_RESPONSE, {foo: 'bar'}); }); it('should report error when non 2xx if error callback is not provided', function() { @@ -262,16 +275,19 @@ describe("resource", function() { xhr.expectGET('/CreditCard/123').respond(ERROR_CODE, ERROR_RESPONSE); CreditCard.get({id:123}, callback, errorCB); xhr.flush(); - expect(errorCB).toHaveBeenCalledWith(500, ERROR_RESPONSE); + expect(errorCB).toHaveBeenCalledWith(500, ERROR_RESPONSE, headersFn); expect(callback).not.toHaveBeenCalled(); expect($xhrErr).not.toHaveBeenCalled(); }); it('should call the error callback if provided on non 2xx response', function() { - xhr.expectGET('/CreditCard').respond(ERROR_CODE, ERROR_RESPONSE); + xhr.expectGET('/CreditCard').respond(ERROR_CODE, ERROR_RESPONSE, {foo: 'bar'}); CreditCard.get(callback, errorCB); xhr.flush(); - expect(errorCB).toHaveBeenCalledWith(500, ERROR_RESPONSE); + expect(errorCB).toHaveBeenCalledWith(500, ERROR_RESPONSE, headersFn); + expect(headersFn('foo')).toBe('bar'); + expect(headersFn()).toEqual({'foo': 'bar'}); + expect(callback).not.toHaveBeenCalled(); expect($xhrErr).not.toHaveBeenCalled(); }); diff --git a/test/service/xhr.bulkSpec.js b/test/service/xhr.bulkSpec.js index adcb61fa..c278fa50 100644 --- a/test/service/xhr.bulkSpec.js +++ b/test/service/xhr.bulkSpec.js @@ -18,8 +18,9 @@ describe('$xhr.bulk', function() { }); - function callback(code, response) { + function callback(code, response, responseHeaders) { expect(code).toEqual(200); + expect(responseHeaders()).toEqual({}); log = log + toJson(response) + ';'; } @@ -81,6 +82,8 @@ describe('$xhr.bulk', function() { $browserXhr.flush(); expect($xhrError).not.toHaveBeenCalled(); - expect(callback).toHaveBeenCalledWith(404, 'NotFound'); + expect(callback.mostRecentCall.args[0]).toEqual(404); + expect(callback.mostRecentCall.args[1]).toEqual('NotFound'); + expect(callback.mostRecentCall.args[2]()).toEqual({}); }); }); diff --git a/test/service/xhr.cacheSpec.js b/test/service/xhr.cacheSpec.js index f4654cd4..cd42153f 100644 --- a/test/service/xhr.cacheSpec.js +++ b/test/service/xhr.cacheSpec.js @@ -1,7 +1,7 @@ 'use strict'; describe('$xhr.cache', function() { - var scope, $browser, $browserXhr, $xhrErr, cache, log; + var scope, $browser, $browserXhr, $xhrErr, cache, log, rHeaders; beforeEach(function() { scope = angular.scope({}, null, {'$xhr.error': $xhrErr = jasmine.createSpy('$xhr.error')}); @@ -9,6 +9,7 @@ describe('$xhr.cache', function() { $browserXhr = $browser.xhr; cache = scope.$service('$xhr.cache'); log = ''; + rHeaders = {}; }); @@ -17,18 +18,21 @@ describe('$xhr.cache', function() { }); - function callback(code, response) { + function callback(code, response, responseHeaders) { expect(code).toEqual(200); + expect(responseHeaders()).toEqual(rHeaders); log = log + toJson(response) + ';'; } it('should cache requests', function(){ - $browserXhr.expectGET('/url').respond('first'); + rHeaders = {foo: 'bar'}; + + $browserXhr.expectGET('/url').respond('first', rHeaders); cache('GET', '/url', null, callback); $browserXhr.flush(); - $browserXhr.expectGET('/url').respond('ERROR'); + $browserXhr.expectGET('/url').respond('ERROR', rHeaders); cache('GET', '/url', null, callback); $browser.defer.flush(); expect(log).toEqual('"first";"first";'); @@ -40,11 +44,13 @@ describe('$xhr.cache', function() { it('should first return cache request, then return server request', function(){ - $browserXhr.expectGET('/url').respond('first'); + rHeaders = {foo: 'bar'}; + + $browserXhr.expectGET('/url').respond('first', rHeaders); cache('GET', '/url', null, callback, true); $browserXhr.flush(); - $browserXhr.expectGET('/url').respond('ERROR'); + $browserXhr.expectGET('/url').respond('ERROR', rHeaders); cache('GET', '/url', null, callback, true); $browser.defer.flush(); expect(log).toEqual('"first";"first";'); @@ -55,7 +61,14 @@ describe('$xhr.cache', function() { it('should serve requests from cache', function(){ - cache.data.url = {value:'123'}; + rHeaders = {foo: 'bar'}; + + cache.data.url = { + value: '123', + headers: function() { + return rHeaders; + } + }; cache('GET', 'url', null, callback); $browser.defer.flush(); expect(log).toEqual('"123";'); @@ -152,13 +165,17 @@ describe('$xhr.cache', function() { cache('GET', '/url', null, successSpy, errorSpy, false, true); $browserXhr.flush(); - expect(errorSpy).toHaveBeenCalledWith(500, 'error'); + expect(errorSpy.mostRecentCall.args[0]).toEqual(500); + expect(errorSpy.mostRecentCall.args[1]).toEqual('error'); + expect(errorSpy.mostRecentCall.args[2]()).toEqual({}); expect(successSpy).not.toHaveBeenCalled(); errorSpy.reset(); cache('GET', '/url', successSpy, errorSpy, false, true); $browserXhr.flush(); - expect(errorSpy).toHaveBeenCalledWith(500, 'error'); + expect(errorSpy.mostRecentCall.args[0]).toEqual(500); + expect(errorSpy.mostRecentCall.args[1]).toEqual('error'); + expect(errorSpy.mostRecentCall.args[2]()).toEqual({}); expect(successSpy).not.toHaveBeenCalled(); }); diff --git a/test/service/xhrSpec.js b/test/service/xhrSpec.js index 9f496535..12ee614d 100644 --- a/test/service/xhrSpec.js +++ b/test/service/xhrSpec.js @@ -18,15 +18,16 @@ describe('$xhr', function() { }); - function callback(code, response) { - log = log + '{code=' + code + '; response=' + toJson(response) + '}'; + function callback(code, response, responseHeader) { + log = log + '{code=' + code + '; response=' + toJson(response) + '; responseHeaders=' + + toJson(responseHeader()) + '}'; } it('should forward the request to $browser and decode JSON', function(){ - $browserXhr.expectGET('/reqGET').respond('first'); - $browserXhr.expectGET('/reqGETjson').respond('["second"]'); - $browserXhr.expectPOST('/reqPOST', {post:'data'}).respond('third'); + $browserXhr.expectGET('/reqGET').respond('first', {h: 'first'}); + $browserXhr.expectGET('/reqGETjson').respond('["second"]', {h: 'second'}); + $browserXhr.expectPOST('/reqPOST', {post:'data'}).respond('third', {h: 'third'}); $xhr('GET', '/reqGET', null, callback); $xhr('GET', '/reqGETjson', null, callback); @@ -35,23 +36,23 @@ describe('$xhr', function() { $browserXhr.flush(); expect(log).toEqual( - '{code=200; response="third"}' + - '{code=200; response=["second"]}' + - '{code=200; response="first"}'); + '{code=200; response="third"; responseHeaders={"h":"third"}}' + + '{code=200; response=["second"]; responseHeaders={"h":"second"}}' + + '{code=200; response="first"; responseHeaders={"h":"first"}}'); }); it('should allow all 2xx requests', function(){ - $browserXhr.expectGET('/req1').respond(200, '1'); + $browserXhr.expectGET('/req1').respond(200, '1', {h: '1'}); $xhr('GET', '/req1', null, callback); $browserXhr.flush(); - $browserXhr.expectGET('/req2').respond(299, '2'); + $browserXhr.expectGET('/req2').respond(299, '2', {h: '2'}); $xhr('GET', '/req2', null, callback); $browserXhr.flush(); expect(log).toEqual( - '{code=200; response="1"}' + - '{code=299; response="2"}'); + '{code=200; response="1"; responseHeaders={"h":"1"}}' + + '{code=299; response="2"; responseHeaders={"h":"2"}}'); }); @@ -120,18 +121,24 @@ describe('$xhr', function() { var errorSpy = jasmine.createSpy('error'), successSpy = jasmine.createSpy('success'); - $browserXhr.expectGET('/url').respond(500, 'error'); + $browserXhr.expectGET('/url').respond(500, 'error', {foo: 'bar'}); $xhr('GET', '/url', null, successSpy, errorSpy); $browserXhr.flush(); - expect(errorSpy).toHaveBeenCalledWith(500, 'error'); + expect(errorSpy.mostRecentCall.args[0]).toEqual(500); + expect(errorSpy.mostRecentCall.args[1]).toEqual('error'); + expect(errorSpy.mostRecentCall.args[2]('foo')).toEqual('bar'); + expect(errorSpy.mostRecentCall.args[2]()).toEqual({foo: 'bar'}); expect(successSpy).not.toHaveBeenCalled(); errorSpy.reset(); $xhr('GET', '/url', successSpy, errorSpy); $browserXhr.flush(); - expect(errorSpy).toHaveBeenCalledWith(500, 'error'); + expect(errorSpy.mostRecentCall.args[0]).toEqual(500); + expect(errorSpy.mostRecentCall.args[1]).toEqual('error'); + expect(errorSpy.mostRecentCall.args[2]('foo')).toEqual('bar'); + expect(errorSpy.mostRecentCall.args[2]()).toEqual({foo: 'bar'}); expect(successSpy).not.toHaveBeenCalled(); }); |
