diff options
Diffstat (limited to 'test/service/httpSpec.js')
| -rw-r--r-- | test/service/httpSpec.js | 509 |
1 files changed, 137 insertions, 372 deletions
diff --git a/test/service/httpSpec.js b/test/service/httpSpec.js index 210020f4..63c1f529 100644 --- a/test/service/httpSpec.js +++ b/test/service/httpSpec.js @@ -1,26 +1,34 @@ 'use strict'; -// TODO(vojta): refactor these tests to use new inject() syntax describe('$http', function() { + var $rootScope, $http, $httpBackend, callback; - var $http, $browser, $exceptionHandler, $httpBackend, - scope, callback, future, callback; - - beforeEach(inject(function($injector) { - $injector.get('$exceptionHandlerProvider').mode('log'); - scope = $injector.get('$rootScope'); - $http = $injector.get('$http'); - $browser = $injector.get('$browser'); - $httpBackend = $injector.get('$httpBackend'); - $exceptionHandler = $injector.get('$exceptionHandler'); - spyOn(scope, '$apply'); - callback = jasmine.createSpy('callback'); - })); + beforeEach(inject( + function($exceptionHandlerProvider) { + $exceptionHandlerProvider.mode('log'); + }, + ['$rootScope', '$http', '$httpBackend', function($rs, $h, $hb) { + $rootScope = $rs; + $http = $h; + $httpBackend = $hb; + + spyOn($rootScope, '$apply').andCallThrough(); + callback = jasmine.createSpy('done'); + }] + )); + + + afterEach(inject(function($exceptionHandler, $httpBackend) { + forEach($exceptionHandler.errors, function(e) { + dump('Unhandled exception: ', e) + }); + + if ($exceptionHandler.errors.length) { + throw 'Unhandled exceptions trapped in $exceptionHandler!'; + } - afterEach(function() { - if ($exceptionHandler.errors.length) throw $exceptionHandler.errors; $httpBackend.verifyNoOutstandingExpectation(); - }); + })); it('should do basic request', function() { @@ -40,54 +48,81 @@ describe('$http', function() { describe('callbacks', function() { - function throwing(name) { - return function() { - throw name; - }; - } - - it('should log exceptions', function() { - $httpBackend.expect('GET', '/url1').respond(200, 'content'); - $httpBackend.expect('GET', '/url2').respond(400, ''); + it('should pass in the response object when a request is successful', function() { + $httpBackend.expect('GET', '/url').respond(207, 'my content', {'content-encoding': 'smurf'}); + $http({url: '/url', method: 'GET'}).then(function(response) { + expect(response.data).toBe('my content'); + expect(response.status).toBe(207); + expect(response.headers()).toEqual({'content-encoding': 'smurf'}); + expect(response.config.url).toBe('/url'); + callback(); + }); - $http({url: '/url1', method: 'GET'}).on('200', throwing('exception in success callback')); - $http({url: '/url2', method: 'GET'}).on('400', throwing('exception in error callback')); $httpBackend.flush(); - - expect($exceptionHandler.errors.shift()).toContain('exception in success callback'); - expect($exceptionHandler.errors.shift()).toContain('exception in error callback'); + expect(callback).toHaveBeenCalledOnce(); }); - it('should log more exceptions', function() { - $httpBackend.expect('GET', '/url').respond(500, ''); - $http({url: '/url', method: 'GET'}). - on('500', throwing('exception in error callback')). - on('5xx', throwing('exception in error callback')); - $httpBackend.flush(); + it('should pass in the response object when a request failed', function() { + $httpBackend.expect('GET', '/url').respond(543, 'bad error', {'request-id': '123'}); + $http({url: '/url', method: 'GET'}).then(null, function(response) { + expect(response.data).toBe('bad error'); + expect(response.status).toBe(543); + expect(response.headers()).toEqual({'request-id': '123'}); + expect(response.config.url).toBe('/url'); + callback(); + }); - expect($exceptionHandler.errors.length).toBe(2); - $exceptionHandler.errors = []; + $httpBackend.flush(); + expect(callback).toHaveBeenCalledOnce(); }); - it('should get response as first param', function() { - $httpBackend.expect('GET', '/url').respond('some-content'); - $http({url: '/url', method: 'GET'}).on('200', callback); - $httpBackend.flush(); + describe('success', function() { + it('should allow http specific callbacks to be registered via "success"', function() { + $httpBackend.expect('GET', '/url').respond(207, 'my content', {'content-encoding': 'smurf'}); + $http({url: '/url', method: 'GET'}).success(function(data, status, headers, config) { + expect(data).toBe('my content'); + expect(status).toBe(207); + expect(headers()).toEqual({'content-encoding': 'smurf'}); + expect(config.url).toBe('/url'); + callback(); + }); - expect(callback).toHaveBeenCalledOnce(); - expect(callback.mostRecentCall.args[0]).toBe('some-content'); + $httpBackend.flush(); + expect(callback).toHaveBeenCalledOnce(); + }); + + + it('should return the original http promise', function() { + $httpBackend.expect('GET', '/url').respond(207, 'my content', {'content-encoding': 'smurf'}); + var httpPromise = $http({url: '/url', method: 'GET'}); + expect(httpPromise.success(callback)).toBe(httpPromise); + }); }); - it('should get status code as second param', function() { - $httpBackend.expect('GET', '/url').respond(250, 'some-content'); - $http({url: '/url', method: 'GET'}).on('2xx', callback); - $httpBackend.flush(); + describe('error', function() { + it('should allow http specific callbacks to be registered via "error"', function() { + $httpBackend.expect('GET', '/url').respond(543, 'bad error', {'request-id': '123'}); + $http({url: '/url', method: 'GET'}).error(function(data, status, headers, config) { + expect(data).toBe('bad error'); + expect(status).toBe(543); + expect(headers()).toEqual({'request-id': '123'}); + expect(config.url).toBe('/url'); + callback(); + }); - expect(callback).toHaveBeenCalledOnce(); - expect(callback.mostRecentCall.args[1]).toBe(250); + $httpBackend.flush(); + expect(callback).toHaveBeenCalledOnce(); + }); + + + it('should return the original http promise', function() { + $httpBackend.expect('GET', '/url').respond(543, 'bad error', {'request-id': '123'}); + var httpPromise = $http({url: '/url', method: 'GET'}); + expect(httpPromise.error(callback)).toBe(httpPromise); + }); }); }); @@ -96,11 +131,11 @@ describe('$http', function() { it('should return single header', function() { $httpBackend.expect('GET', '/url').respond('', {'date': 'date-val'}); - callback.andCallFake(function(r, s, header) { - expect(header('date')).toBe('date-val'); + callback.andCallFake(function(r) { + expect(r.headers('date')).toBe('date-val'); }); - $http({url: '/url', method: 'GET'}).on('200', callback); + $http({url: '/url', method: 'GET'}).then(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -109,12 +144,12 @@ describe('$http', function() { it('should return null when single header does not exist', function() { $httpBackend.expect('GET', '/url').respond('', {'Some-Header': 'Fake'}); - callback.andCallFake(function(r, s, header) { - header(); // we need that to get headers parsed first - expect(header('nothing')).toBe(null); + callback.andCallFake(function(r) { + r.headers(); // we need that to get headers parsed first + expect(r.headers('nothing')).toBe(null); }); - $http({url: '/url', method: 'GET'}).on('200', callback); + $http({url: '/url', method: 'GET'}).then(callback) $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -122,12 +157,16 @@ describe('$http', function() { it('should return all headers as object', function() { - $httpBackend.expect('GET', '/url').respond('', {'content-encoding': 'gzip', 'server': 'Apache'}); - callback.andCallFake(function(r, s, header) { - expect(header()).toEqual({'content-encoding': 'gzip', 'server': 'Apache'}); + $httpBackend.expect('GET', '/url').respond('', { + 'content-encoding': 'gzip', + 'server': 'Apache' + }); + + callback.andCallFake(function(r) { + expect(r.headers()).toEqual({'content-encoding': 'gzip', 'server': 'Apache'}); }); - $http({url: '/url', method: 'GET'}).on('200', callback); + $http({url: '/url', method: 'GET'}).then(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -135,12 +174,12 @@ describe('$http', function() { it('should return empty object for jsonp request', function() { - callback.andCallFake(function(r, s, headers) { - expect(headers()).toEqual({}); + callback.andCallFake(function(r) { + expect(r.headers()).toEqual({}); }); $httpBackend.expect('JSONP', '/some').respond(200); - $http({url: '/some', method: 'JSONP'}).on('200', callback); + $http({url: '/some', method: 'JSONP'}).then(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); }); @@ -288,7 +327,7 @@ describe('$http', function() { }); - it('should set the XSRF cookie into a XSRF header', function() { + it('should set the XSRF cookie into a XSRF header', inject(function($browser) { function checkXSRF(secret) { return function(headers) { return headers['X-XSRF-TOKEN'] == secret; @@ -307,7 +346,7 @@ describe('$http', function() { $http({url: '/url', method: 'DELETE', headers: {}}); $httpBackend.flush(); - }); + })); }); @@ -404,264 +443,13 @@ describe('$http', function() { }); - describe('future', function() { - - describe('abort', function() { - - var future, rawXhrObject; - - beforeEach(function() { - $httpBackend.when('GET', '/url').respond(''); - future = $http({method: 'GET', url: '/url'}); - rawXhrObject = MockXhr.$$lastInstance; - spyOn(rawXhrObject, 'abort'); - }); - - it('should return itself to allow chaining', function() { - expect(future.abort()).toBe(future); - }); - - it('should allow aborting the request', function() { - future.abort(); - - expect(rawXhrObject.abort).toHaveBeenCalledOnce(); - }); - - - it('should not abort already finished request', function() { - $httpBackend.flush(); - - future.abort(); - expect(rawXhrObject.abort).not.toHaveBeenCalled(); - }); - }); - - - describe('retry', function() { - - var future; - - beforeEach(function() { - $httpBackend.expect('HEAD', '/url-x').respond(''); - future = $http({method: 'HEAD', url: '/url-x'}).on('2xx', callback); - }); - - it('should retry last request with same callbacks', function() { - $httpBackend.flush(); - callback.reset(); - - $httpBackend.expect('HEAD', '/url-x').respond(''); - future.retry(); - $httpBackend.flush(); - expect(callback).toHaveBeenCalledOnce(); - }); - - - it('should return itself to allow chaining', function() { - $httpBackend.flush(); - - $httpBackend.expect('HEAD', '/url-x').respond(''); - expect(future.retry()).toBe(future); - }); - - - it('should throw error when pending request', function() { - expect(future.retry).toThrow('Can not retry request. Abort pending request first.'); - }); - }); - - - describe('on', function() { - - var future; - - function expectToMatch(status, pattern) { - expectToNotMatch(status, pattern, true); - } - - function expectToNotMatch(status, pattern, match) { - callback.reset(); - future = $http({method: 'GET', url: '/' + status}); - future.on(pattern, callback); - $httpBackend.flush(); - - if (match) expect(callback).toHaveBeenCalledOnce(); - else expect(callback).not.toHaveBeenCalled(); - } - - beforeEach(function() { - $httpBackend.when('GET').respond(function(m, url) { - return [parseInt(url.substr(1), 10), '', {}]; - }); - }); - - it('should return itself to allow chaining', function() { - future = $http({method: 'GET', url: '/url'}); - expect(future.on('200', noop)).toBe(future); - }); - - - it('should call exact status code callback', function() { - expectToMatch(205, '205'); - }); - - - it('should match 2xx', function() { - expectToMatch(200, '2xx'); - expectToMatch(201, '2xx'); - expectToMatch(266, '2xx'); - - expectToNotMatch(400, '2xx'); - expectToNotMatch(300, '2xx'); - }); - - - it('should match 20x', function() { - expectToMatch(200, '20x'); - expectToMatch(201, '20x'); - expectToMatch(205, '20x'); - - expectToNotMatch(210, '20x'); - expectToNotMatch(301, '20x'); - expectToNotMatch(404, '20x'); - expectToNotMatch(501, '20x'); - }); - - - it('should match 2x1', function() { - expectToMatch(201, '2x1'); - expectToMatch(211, '2x1'); - expectToMatch(251, '2x1'); - - expectToNotMatch(210, '2x1'); - expectToNotMatch(301, '2x1'); - expectToNotMatch(400, '2x1'); - }); - - - it('should match xxx', function() { - expectToMatch(200, 'xxx'); - expectToMatch(210, 'xxx'); - expectToMatch(301, 'xxx'); - expectToMatch(406, 'xxx'); - expectToMatch(510, 'xxx'); - }); - - - it('should call all matched callbacks', function() { - var no = jasmine.createSpy('wrong'); - $http({method: 'GET', url: '/205'}). - on('xxx', callback). - on('2xx', callback). - on('205', callback). - on('3xx', no). - on('2x1', no). - on('4xx', no); - - $httpBackend.flush(); - - expect(callback).toHaveBeenCalled(); - expect(callback.callCount).toBe(3); - expect(no).not.toHaveBeenCalled(); - }); - - - it('should allow list of status patterns', function() { - expectToMatch(201, '2xx,3xx'); - expectToMatch(301, '2xx,3xx'); - expectToNotMatch(405, '2xx,3xx'); - }); - - - it('should preserve the order of listeners', function() { - var log = ''; - - $http({method: 'GET', url: '/201'}). - on('2xx', function() {log += '1';}). - on('201', function() {log += '2';}). - on('2xx', function() {log += '3';}); - - $httpBackend.flush(); - expect(log).toBe('123'); - }); - - - it('should know "success" alias', function() { - expectToMatch(200, 'success'); - expectToMatch(201, 'success'); - expectToMatch(250, 'success'); - - expectToNotMatch(403, 'success'); - expectToNotMatch(501, 'success'); - }); - - - it('should know "error" alias', function() { - expectToMatch(401, 'error'); - expectToMatch(500, 'error'); - expectToMatch(0, 'error'); - - expectToNotMatch(201, 'error'); - expectToNotMatch(200, 'error'); - }); - - - it('should know "always" alias', function() { - expectToMatch(200, 'always'); - expectToMatch(201, 'always'); - expectToMatch(250, 'always'); - expectToMatch(300, 'always'); - expectToMatch(302, 'always'); - expectToMatch(404, 'always'); - expectToMatch(501, 'always'); - expectToMatch(0, 'always'); - expectToMatch(-1, 'always'); - expectToMatch(-2, 'always'); - }); - - - it('should not call "2xx" when 0 status code', function() { - expectToNotMatch(0, '2xx'); - }); - - it('should normalize internal statuses -1, -2 to 0', function() { - callback.andCallFake(function(response, status) { - expect(status).toBe(0); - }); - - $http({method: 'GET', url: '/0'}).on('always', callback); - $http({method: 'GET', url: '/-1'}).on('always', callback); - $http({method: 'GET', url: '/-2'}).on('always', callback); - - $httpBackend.flush(); - expect(callback).toHaveBeenCalled(); - expect(callback.callCount).toBe(3); - }); - - it('should match "timeout" when -1 internal status', function() { - expectToMatch(-1, 'timeout'); - }); - - it('should match "abort" when 0 status', function() { - expectToMatch(0, 'abort'); - }); - - it('should match "error" when 0, -1, or -2', function() { - expectToMatch(0, 'error'); - expectToMatch(-1, 'error'); - expectToMatch(-2, 'error'); - }); - }); - }); - - describe('scope.$apply', function() { it('should $apply after success callback', function() { $httpBackend.when('GET').respond(200); $http({method: 'GET', url: '/some'}); $httpBackend.flush(); - expect(scope.$apply).toHaveBeenCalledOnce(); + expect($rootScope.$apply).toHaveBeenCalledOnce(); }); @@ -669,30 +457,20 @@ describe('$http', function() { $httpBackend.when('GET').respond(404); $http({method: 'GET', url: '/some'}); $httpBackend.flush(); - expect(scope.$apply).toHaveBeenCalledOnce(); + expect($rootScope.$apply).toHaveBeenCalledOnce(); }); - it('should $apply even if exception thrown during callback', function() { + it('should $apply even if exception thrown during callback', inject(function($exceptionHandler){ $httpBackend.when('GET').respond(200); callback.andThrow('error in callback'); - $http({method: 'GET', url: '/some'}).on('200', callback); + $http({method: 'GET', url: '/some'}).then(callback); $httpBackend.flush(); - expect(scope.$apply).toHaveBeenCalledOnce(); + expect($rootScope.$apply).toHaveBeenCalledOnce(); $exceptionHandler.errors = []; - }); - }); - - - it('should broadcast $http.request', function() { - $httpBackend.when('GET').respond(200); - scope.$on('$http.request', callback); - var xhrFuture = $http({method: 'GET', url: '/whatever'}); - - expect(callback).toHaveBeenCalledOnce(); - expect(callback.mostRecentCall.args[1]).toBe(xhrFuture); + })); }); @@ -722,7 +500,7 @@ describe('$http', function() { it('should deserialize json objects', function() { $httpBackend.expect('GET', '/url').respond('{"foo":"bar","baz":23}'); - $http({method: 'GET', url: '/url'}).on('200', callback); + $http({method: 'GET', url: '/url'}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -732,7 +510,7 @@ describe('$http', function() { it('should deserialize json arrays', function() { $httpBackend.expect('GET', '/url').respond('[1, "abc", {"foo":"bar"}]'); - $http({method: 'GET', url: '/url'}).on('200', callback); + $http({method: 'GET', url: '/url'}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -742,7 +520,7 @@ describe('$http', function() { it('should deserialize json with security prefix', function() { $httpBackend.expect('GET', '/url').respond(')]}\',\n[1, "abc", {"foo":"bar"}]'); - $http({method: 'GET', url: '/url'}).on('200', callback); + $http({method: 'GET', url: '/url'}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -752,7 +530,7 @@ describe('$http', function() { it('should deserialize json with security prefix ")]}\'"', function() { $httpBackend.expect('GET', '/url').respond(')]}\'\n\n[1, "abc", {"foo":"bar"}]'); - $http({method: 'GET', url: '/url'}).on('200', callback); + $http({method: 'GET', url: '/url'}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -762,7 +540,7 @@ describe('$http', function() { it('should not deserialize tpl beginning with ng expression', function() { $httpBackend.expect('GET', '/url').respond('{{some}}'); - $http.get('/url').on('200', callback); + $http.get('/url').success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -776,8 +554,7 @@ describe('$http', function() { function second(d) {return d + '2';} $httpBackend.expect('POST', '/url').respond('0'); - $http({method: 'POST', url: '/url', transformResponse: [first, second]}). - on('200', callback); + $http({method: 'POST', url: '/url', transformResponse: [first, second]}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -801,15 +578,15 @@ describe('$http', function() { $httpBackend.flush(); } - it('should cache GET request when cache is provided', function() { + it('should cache GET request when cache is provided', inject(function($browser) { doFirstCacheRequest(); - $http({method: 'get', url: '/url', cache: cache}).on('200', callback); + $http({method: 'get', url: '/url', cache: cache}).success(callback); $browser.defer.flush(); expect(callback).toHaveBeenCalledOnce(); expect(callback.mostRecentCall.args[0]).toBe('content'); - }); + })); it('should not cache when cache is not provided', function() { @@ -831,7 +608,7 @@ describe('$http', function() { it('should always call callback asynchronously', function() { doFirstCacheRequest(); - $http({method: 'get', url: '/url', cache: cache}).on('200', callback); + $http({method: 'get', url: '/url', cache: cache}).then(callback); expect(callback).not.toHaveBeenCalled(); }); @@ -841,7 +618,7 @@ describe('$http', function() { doFirstCacheRequest('POST'); $httpBackend.expect('POST', '/url').respond('content2'); - $http({method: 'POST', url: '/url', cache: cache}).on('200', callback); + $http({method: 'POST', url: '/url', cache: cache}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -853,7 +630,7 @@ describe('$http', function() { doFirstCacheRequest('PUT'); $httpBackend.expect('PUT', '/url').respond('content2'); - $http({method: 'PUT', url: '/url', cache: cache}).on('200', callback); + $http({method: 'PUT', url: '/url', cache: cache}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -865,7 +642,7 @@ describe('$http', function() { doFirstCacheRequest('DELETE'); $httpBackend.expect('DELETE', '/url').respond(206); - $http({method: 'DELETE', url: '/url', cache: cache}).on('206', callback); + $http({method: 'DELETE', url: '/url', cache: cache}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -876,7 +653,7 @@ describe('$http', function() { doFirstCacheRequest('GET', 404); $httpBackend.expect('GET', '/url').respond('content2'); - $http({method: 'GET', url: '/url', cache: cache}).on('200', callback); + $http({method: 'GET', url: '/url', cache: cache}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalledOnce(); @@ -884,29 +661,29 @@ describe('$http', function() { }); - it('should cache the headers as well', function() { + it('should cache the headers as well', inject(function($browser) { doFirstCacheRequest('GET', 200, {'content-encoding': 'gzip', 'server': 'Apache'}); callback.andCallFake(function(r, s, headers) { expect(headers()).toEqual({'content-encoding': 'gzip', 'server': 'Apache'}); expect(headers('server')).toBe('Apache'); }); - $http({method: 'GET', url: '/url', cache: cache}).on('200', callback); + $http({method: 'GET', url: '/url', cache: cache}).success(callback); $browser.defer.flush(); expect(callback).toHaveBeenCalledOnce(); - }); + })); - it('should cache status code as well', function() { + it('should cache status code as well', inject(function($browser) { doFirstCacheRequest('GET', 201); callback.andCallFake(function(r, status, h) { expect(status).toBe(201); }); - $http({method: 'get', url: '/url', cache: cache}).on('2xx', callback); + $http({method: 'get', url: '/url', cache: cache}).success(callback); $browser.defer.flush(); expect(callback).toHaveBeenCalledOnce(); - }); + })); it('should use cache even if request fired before first response is back', function() { @@ -917,8 +694,8 @@ describe('$http', function() { expect(status).toBe(201); }); - $http({method: 'GET', url: '/url', cache: cache}).on('always', callback); - $http({method: 'GET', url: '/url', cache: cache}).on('always', callback); + $http({method: 'GET', url: '/url', cache: cache}).success(callback); + $http({method: 'GET', url: '/url', cache: cache}).success(callback); $httpBackend.flush(); expect(callback).toHaveBeenCalled(); @@ -941,19 +718,7 @@ describe('$http', function() { }); - it('should remove the request when aborted', function() { - $httpBackend.when('GET').respond(0); - future = $http({method: 'get', url: '/x'}); - expect($http.pendingRequests.length).toBe(1); - - future.abort(); - $httpBackend.flush(); - - expect($http.pendingRequests.length).toBe(0); - }); - - - it('should update pending requests even when served from cache', function() { + it('should update pending requests even when served from cache', inject(function($browser) { $httpBackend.when('GET').respond(200); $http({method: 'get', url: '/cached', cache: true}); @@ -968,12 +733,12 @@ describe('$http', function() { $browser.defer.flush(); expect($http.pendingRequests.length).toBe(0); - }); + })); it('should remove the request before firing callbacks', function() { $httpBackend.when('GET').respond(200); - $http({method: 'get', url: '/url'}).on('xxx', function() { + $http({method: 'get', url: '/url'}).success(function() { expect($http.pendingRequests.length).toBe(0); }); |
