aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/ResourceSpec.js2
-rw-r--r--test/directivesSpec.js8
-rw-r--r--test/service/browserSpecs.js2
-rw-r--r--test/service/httpSpec.js983
-rw-r--r--test/service/xhr.bulkSpec.js81
-rw-r--r--test/service/xhr.cacheSpec.js175
-rw-r--r--test/service/xhr.errorSpec.js29
-rw-r--r--test/service/xhrSpec.js271
-rw-r--r--test/widgetsSpec.js103
9 files changed, 1078 insertions, 576 deletions
diff --git a/test/ResourceSpec.js b/test/ResourceSpec.js
index 57aaffe0..46616799 100644
--- a/test/ResourceSpec.js
+++ b/test/ResourceSpec.js
@@ -1,6 +1,6 @@
'use strict';
-describe("resource", function() {
+xdescribe("resource", function() {
var resource, CreditCard, callback;
function nakedExpect(obj) {
diff --git a/test/directivesSpec.js b/test/directivesSpec.js
index 5f9fa0a8..ffb6d57c 100644
--- a/test/directivesSpec.js
+++ b/test/directivesSpec.js
@@ -502,12 +502,12 @@ describe("directive", function() {
expect(element.text()).toEqual('hey dude!');
}));
- it('should infer injection arguments', inject(function($rootScope, $compile, $xhr) {
- temp.MyController = function($xhr){
- this.$root.someService = $xhr;
+ it('should infer injection arguments', inject(function($rootScope, $compile, $http) {
+ temp.MyController = function($http) {
+ this.$root.someService = $http;
};
var element = $compile('<div ng:controller="temp.MyController"></div>')($rootScope);
- expect($rootScope.someService).toBe($xhr);
+ expect($rootScope.someService).toBe($http);
}));
});
diff --git a/test/service/browserSpecs.js b/test/service/browserSpecs.js
index 566ffb09..2ec000f4 100644
--- a/test/service/browserSpecs.js
+++ b/test/service/browserSpecs.js
@@ -124,7 +124,7 @@ describe('browser', function() {
// We don't have unit tests for IE because script.readyState is readOnly.
- // Instead we run e2e tests on all browsers - see e2e for $xhr.
+ // Instead we run e2e tests on all browsers - see e2e for $http.
if (!msie) {
it('should add script tag for JSONP request', function() {
diff --git a/test/service/httpSpec.js b/test/service/httpSpec.js
new file mode 100644
index 00000000..196a57ed
--- /dev/null
+++ b/test/service/httpSpec.js
@@ -0,0 +1,983 @@
+'use strict';
+
+// TODO(vojta): refactor these tests to use new inject() syntax
+describe('$http', function() {
+
+ var $http, $browser, $exceptionHandler, // services
+ method, url, data, headers, timeout, // passed arguments
+ onSuccess, onError, // callback spies
+ scope, errorLogs, respond, rawXhrObject, future;
+
+ beforeEach(inject(function($injector) {
+ $injector.get('$exceptionHandlerProvider').mode('log');
+ scope = $injector.get('$rootScope');
+ $http = $injector.get('$http');
+ $browser = $injector.get('$browser');
+ $exceptionHandler = $injector.get('$exceptionHandler');
+
+ // TODO(vojta): move this into mock browser ?
+ respond = method = url = data = headers = null;
+ rawXhrObject = {
+ abort: jasmine.createSpy('request.abort'),
+ getResponseHeader: function(h) {return h + '-val';},
+ getAllResponseHeaders: function() {
+ return 'content-encoding: gzip\nserver: Apache\n';
+ }
+ };
+
+ spyOn(scope, '$apply');
+ spyOn($browser, 'xhr').andCallFake(function(m, u, d, c, h, t) {
+ method = m;
+ url = u;
+ data = d;
+ respond = c;
+ headers = h;
+ timeout = t;
+ return rawXhrObject;
+ });
+ }));
+
+ afterEach(function() {
+ // expect($exceptionHandler.errors.length).toBe(0);
+ });
+
+ function doCommonXhr(method, url) {
+ future = $http({method: method || 'GET', url: url || '/url'});
+
+ onSuccess = jasmine.createSpy('on200');
+ onError = jasmine.createSpy('on400');
+ future.on('200', onSuccess);
+ future.on('400', onError);
+
+ return future;
+ }
+
+
+ it('should do basic request', function() {
+ $http({url: '/url', method: 'GET'});
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ expect(url).toBe('/url');
+ expect(method).toBe('GET');
+ });
+
+
+ it('should pass data if specified', function() {
+ $http({url: '/url', method: 'POST', data: 'some-data'});
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ expect(data).toBe('some-data');
+ });
+
+
+ it('should pass timeout if specified', function() {
+ $http({url: '/url', method: 'POST', timeout: 5000});
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ expect(timeout).toBe(5000);
+ });
+
+
+ describe('callbacks', function() {
+
+ beforeEach(doCommonXhr);
+
+ it('should log exceptions', function() {
+ onSuccess.andThrow('exception in success callback');
+ onError.andThrow('exception in error callback');
+
+ respond(200, 'content');
+ expect($exceptionHandler.errors.pop()).toContain('exception in success callback');
+
+ respond(400, '');
+ expect($exceptionHandler.errors.pop()).toContain('exception in error callback');
+ });
+
+
+ it('should log more exceptions', function() {
+ onError.andThrow('exception in error callback');
+ future.on('500', onError).on('50x', onError);
+ respond(500, '');
+
+ expect($exceptionHandler.errors.length).toBe(2);
+ $exceptionHandler.errors = [];
+ });
+
+
+ it('should get response as first param', function() {
+ respond(200, 'response');
+ expect(onSuccess).toHaveBeenCalledOnce();
+ expect(onSuccess.mostRecentCall.args[0]).toBe('response');
+
+ respond(400, 'empty');
+ expect(onError).toHaveBeenCalledOnce();
+ expect(onError.mostRecentCall.args[0]).toBe('empty');
+ });
+
+
+ it('should get status code as second param', function() {
+ respond(200, 'response');
+ expect(onSuccess).toHaveBeenCalledOnce();
+ expect(onSuccess.mostRecentCall.args[1]).toBe(200);
+
+ respond(400, 'empty');
+ expect(onError).toHaveBeenCalledOnce();
+ expect(onError.mostRecentCall.args[1]).toBe(400);
+ });
+ });
+
+
+ describe('response headers', function() {
+
+ var callback;
+
+ beforeEach(function() {
+ callback = jasmine.createSpy('callback');
+ });
+
+ it('should return single header', function() {
+ callback.andCallFake(function(r, s, header) {
+ expect(header('date')).toBe('date-val');
+ });
+
+ $http({url: '/url', method: 'GET'}).on('200', callback);
+ respond(200, '');
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should return null when single header does not exist', function() {
+ callback.andCallFake(function(r, s, header) {
+ header(); // we need that to get headers parsed first
+ expect(header('nothing')).toBe(null);
+ });
+
+ $http({url: '/url', method: 'GET'}).on('200', callback);
+ respond(200, '');
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should return all headers as object', function() {
+ callback.andCallFake(function(r, s, header) {
+ expect(header()).toEqual({'content-encoding': 'gzip', 'server': 'Apache'});
+ });
+
+ $http({url: '/url', method: 'GET'}).on('200', callback);
+ respond(200, '');
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should return empty object for jsonp request', function() {
+ // jsonp doesn't return raw object
+ rawXhrObject = undefined;
+ callback.andCallFake(function(r, s, headers) {
+ expect(headers()).toEqual({});
+ });
+
+ $http({url: '/some', method: 'JSONP'}).on('200', callback);
+ respond(200, '');
+ expect(callback).toHaveBeenCalledOnce();
+ });
+ });
+
+
+ describe('response headers parser', function() {
+
+ it('should parse basic', function() {
+ var parsed = parseHeaders(
+ 'date: Thu, 04 Aug 2011 20:23:08 GMT\n' +
+ 'content-encoding: gzip\n' +
+ 'transfer-encoding: chunked\n' +
+ 'x-cache-info: not cacheable; response has already expired, not cacheable; response has already expired\n' +
+ 'connection: Keep-Alive\n' +
+ 'x-backend-server: pm-dekiwiki03\n' +
+ 'pragma: no-cache\n' +
+ 'server: Apache\n' +
+ 'x-frame-options: DENY\n' +
+ 'content-type: text/html; charset=utf-8\n' +
+ 'vary: Cookie, Accept-Encoding\n' +
+ 'keep-alive: timeout=5, max=1000\n' +
+ 'expires: Thu: , 19 Nov 1981 08:52:00 GMT\n');
+
+ expect(parsed['date']).toBe('Thu, 04 Aug 2011 20:23:08 GMT');
+ expect(parsed['content-encoding']).toBe('gzip');
+ expect(parsed['transfer-encoding']).toBe('chunked');
+ expect(parsed['keep-alive']).toBe('timeout=5, max=1000');
+ });
+
+
+ it('should parse lines without space after colon', function() {
+ expect(parseHeaders('key:value').key).toBe('value');
+ });
+
+
+ it('should trim the values', function() {
+ expect(parseHeaders('key: value ').key).toBe('value');
+ });
+
+
+ it('should allow headers without value', function() {
+ expect(parseHeaders('key:').key).toBe('');
+ });
+
+
+ it('should merge headers with same key', function() {
+ expect(parseHeaders('key: a\nkey:b\n').key).toBe('a, b');
+ });
+
+
+ it('should normalize keys to lower case', function() {
+ expect(parseHeaders('KeY: value').key).toBe('value');
+ });
+
+
+ it('should parse CRLF as delimiter', function() {
+ // IE does use CRLF
+ expect(parseHeaders('a: b\r\nc: d\r\n')).toEqual({a: 'b', c: 'd'});
+ expect(parseHeaders('a: b\r\nc: d\r\n').a).toBe('b');
+ });
+
+
+ it('should parse tab after semi-colon', function() {
+ expect(parseHeaders('a:\tbb').a).toBe('bb');
+ expect(parseHeaders('a: \tbb').a).toBe('bb');
+ });
+ });
+
+
+ describe('request headers', function() {
+
+ it('should send custom headers', function() {
+ $http({url: '/url', method: 'GET', headers: {
+ 'Custom': 'header',
+ 'Content-Type': 'application/json'
+ }});
+
+ expect(headers['Custom']).toEqual('header');
+ expect(headers['Content-Type']).toEqual('application/json');
+ });
+
+
+ it('should set default headers for GET request', function() {
+ $http({url: '/url', method: 'GET', headers: {}});
+
+ expect(headers['Accept']).toBe('application/json, text/plain, */*');
+ expect(headers['X-Requested-With']).toBe('XMLHttpRequest');
+ });
+
+
+ it('should set default headers for POST request', function() {
+ $http({url: '/url', method: 'POST', headers: {}});
+
+ expect(headers['Accept']).toBe('application/json, text/plain, */*');
+ expect(headers['X-Requested-With']).toBe('XMLHttpRequest');
+ expect(headers['Content-Type']).toBe('application/json');
+ });
+
+
+ it('should set default headers for PUT request', function() {
+ $http({url: '/url', method: 'PUT', headers: {}});
+
+ expect(headers['Accept']).toBe('application/json, text/plain, */*');
+ expect(headers['X-Requested-With']).toBe('XMLHttpRequest');
+ expect(headers['Content-Type']).toBe('application/json');
+ });
+
+
+ it('should set default headers for custom HTTP method', function() {
+ $http({url: '/url', method: 'FOO', headers: {}});
+
+ expect(headers['Accept']).toBe('application/json, text/plain, */*');
+ expect(headers['X-Requested-With']).toBe('XMLHttpRequest');
+ });
+
+
+ it('should override default headers with custom', function() {
+ $http({url: '/url', method: 'POST', headers: {
+ 'Accept': 'Rewritten',
+ 'Content-Type': 'Rewritten'
+ }});
+
+ expect(headers['Accept']).toBe('Rewritten');
+ expect(headers['X-Requested-With']).toBe('XMLHttpRequest');
+ expect(headers['Content-Type']).toBe('Rewritten');
+ });
+
+
+ it('should set the XSRF cookie into a XSRF header', function() {
+ $browser.cookies('XSRF-TOKEN', 'secret');
+
+ $http({url: '/url', method: 'GET'});
+ expect(headers['X-XSRF-TOKEN']).toBe('secret');
+
+ $http({url: '/url', method: 'POST', headers: {'S-ome': 'Header'}});
+ expect(headers['X-XSRF-TOKEN']).toBe('secret');
+
+ $http({url: '/url', method: 'PUT', headers: {'Another': 'Header'}});
+ expect(headers['X-XSRF-TOKEN']).toBe('secret');
+
+ $http({url: '/url', method: 'DELETE', headers: {}});
+ expect(headers['X-XSRF-TOKEN']).toBe('secret');
+ });
+ });
+
+
+ describe('short methods', function() {
+
+ it('should have .get()', function() {
+ $http.get('/url');
+
+ expect(method).toBe('GET');
+ expect(url).toBe('/url');
+ });
+
+
+ it('.get() should allow config param', function() {
+ $http.get('/url', {headers: {'Custom': 'Header'}});
+
+ expect(method).toBe('GET');
+ expect(url).toBe('/url');
+ expect(headers['Custom']).toBe('Header');
+ });
+
+
+ it('should have .delete()', function() {
+ $http['delete']('/url');
+
+ expect(method).toBe('DELETE');
+ expect(url).toBe('/url');
+ });
+
+
+ it('.delete() should allow config param', function() {
+ $http['delete']('/url', {headers: {'Custom': 'Header'}});
+
+ expect(method).toBe('DELETE');
+ expect(url).toBe('/url');
+ expect(headers['Custom']).toBe('Header');
+ });
+
+
+ it('should have .head()', function() {
+ $http.head('/url');
+
+ expect(method).toBe('HEAD');
+ expect(url).toBe('/url');
+ });
+
+
+ it('.head() should allow config param', function() {
+ $http.head('/url', {headers: {'Custom': 'Header'}});
+
+ expect(method).toBe('HEAD');
+ expect(url).toBe('/url');
+ expect(headers['Custom']).toBe('Header');
+ });
+
+
+ it('should have .patch()', function() {
+ $http.patch('/url');
+
+ expect(method).toBe('PATCH');
+ expect(url).toBe('/url');
+ });
+
+
+ it('.patch() should allow config param', function() {
+ $http.patch('/url', {headers: {'Custom': 'Header'}});
+
+ expect(method).toBe('PATCH');
+ expect(url).toBe('/url');
+ expect(headers['Custom']).toBe('Header');
+ });
+
+
+ it('should have .post()', function() {
+ $http.post('/url', 'some-data');
+
+ expect(method).toBe('POST');
+ expect(url).toBe('/url');
+ expect(data).toBe('some-data');
+ });
+
+
+ it('.post() should allow config param', function() {
+ $http.post('/url', 'some-data', {headers: {'Custom': 'Header'}});
+
+ expect(method).toBe('POST');
+ expect(url).toBe('/url');
+ expect(data).toBe('some-data');
+ expect(headers['Custom']).toBe('Header');
+ });
+
+
+ it('should have .put()', function() {
+ $http.put('/url', 'some-data');
+
+ expect(method).toBe('PUT');
+ expect(url).toBe('/url');
+ expect(data).toBe('some-data');
+ });
+
+
+ it('.put() should allow config param', function() {
+ $http.put('/url', 'some-data', {headers: {'Custom': 'Header'}});
+
+ expect(method).toBe('PUT');
+ expect(url).toBe('/url');
+ expect(data).toBe('some-data');
+ expect(headers['Custom']).toBe('Header');
+ });
+
+
+ it('should have .jsonp()', function() {
+ $http.jsonp('/url');
+
+ expect(method).toBe('JSONP');
+ expect(url).toBe('/url');
+ });
+
+
+ it('.jsonp() should allow config param', function() {
+ $http.jsonp('/url', {headers: {'Custom': 'Header'}});
+
+ expect(method).toBe('JSONP');
+ expect(url).toBe('/url');
+ expect(headers['Custom']).toBe('Header');
+ });
+ });
+
+
+ describe('future', function() {
+
+ describe('abort', function() {
+
+ beforeEach(doCommonXhr);
+
+ 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() {
+ respond(200, 'content');
+
+ future.abort();
+ expect(rawXhrObject.abort).not.toHaveBeenCalled();
+ });
+ });
+
+
+ describe('retry', function() {
+
+ it('should retry last request with same callbacks', function() {
+ doCommonXhr('HEAD', '/url-x');
+ respond(200, '');
+ $browser.xhr.reset();
+ onSuccess.reset();
+
+ future.retry();
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ expect(method).toBe('HEAD');
+ expect(url).toBe('/url-x');
+
+ respond(200, 'body');
+ expect(onSuccess).toHaveBeenCalledOnce();
+ });
+
+
+ it('should return itself to allow chaining', function() {
+ doCommonXhr();
+ respond(200, '');
+ expect(future.retry()).toBe(future);
+ });
+
+
+ it('should throw error when pending request', function() {
+ doCommonXhr();
+ expect(future.retry).toThrow('Can not retry request. Abort pending request first.');
+ });
+ });
+
+
+ describe('on', function() {
+
+ var callback;
+
+ beforeEach(function() {
+ future = $http({method: 'GET', url: '/url'});
+ callback = jasmine.createSpy('callback');
+ });
+
+ it('should return itself to allow chaining', function() {
+ expect(future.on('200', noop)).toBe(future);
+ });
+
+
+ it('should call exact status code callback', function() {
+ future.on('205', callback);
+ respond(205, '');
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should match 2xx', function() {
+ future.on('2xx', callback);
+
+ respond(200, '');
+ respond(201, '');
+ respond(266, '');
+
+ respond(400, '');
+ respond(300, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(3);
+ });
+
+
+ it('should match 20x', function() {
+ future.on('20x', callback);
+
+ respond(200, '');
+ respond(201, '');
+ respond(205, '');
+
+ respond(400, '');
+ respond(300, '');
+ respond(210, '');
+ respond(255, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(3);
+ });
+
+
+ it('should match 2x1', function() {
+ future.on('2x1', callback);
+
+ respond(201, '');
+ respond(211, '');
+ respond(251, '');
+
+ respond(400, '');
+ respond(300, '');
+ respond(210, '');
+ respond(255, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(3);
+ });
+
+
+ it('should match xxx', function() {
+ future.on('xxx', callback);
+
+ respond(201, '');
+ respond(211, '');
+ respond(251, '');
+ respond(404, '');
+ respond(501, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(5);
+ });
+
+
+ it('should call all matched callbacks', function() {
+ var no = jasmine.createSpy('wrong');
+ future.on('xxx', callback);
+ future.on('2xx', callback);
+ future.on('205', callback);
+ future.on('3xx', no);
+ future.on('2x1', no);
+ future.on('4xx', no);
+ respond(205, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(3);
+ expect(no).not.toHaveBeenCalled();
+ });
+
+
+ it('should allow list of status patterns', function() {
+ future.on('2xx,3xx', callback);
+
+ respond(405, '');
+ expect(callback).not.toHaveBeenCalled();
+
+ respond(201);
+ expect(callback).toHaveBeenCalledOnce();
+
+ respond(301);
+ expect(callback.callCount).toBe(2);
+ });
+
+
+ it('should preserve the order of listeners', function() {
+ var log = '';
+ future.on('2xx', function() {log += '1';});
+ future.on('201', function() {log += '2';});
+ future.on('2xx', function() {log += '3';});
+
+ respond(201);
+ expect(log).toBe('123');
+ });
+
+
+ it('should know "success" alias', function() {
+ future.on('success', callback);
+ respond(200, '');
+ expect(callback).toHaveBeenCalledOnce();
+
+ callback.reset();
+ respond(201, '');
+ expect(callback).toHaveBeenCalledOnce();
+
+ callback.reset();
+ respond(250, '');
+ expect(callback).toHaveBeenCalledOnce();
+
+ callback.reset();
+ respond(404, '');
+ respond(501, '');
+ expect(callback).not.toHaveBeenCalled();
+ });
+
+
+ it('should know "error" alias', function() {
+ future.on('error', callback);
+ respond(401, '');
+ expect(callback).toHaveBeenCalledOnce();
+
+ callback.reset();
+ respond(500, '');
+ expect(callback).toHaveBeenCalledOnce();
+
+ callback.reset();
+ respond(0, '');
+ expect(callback).toHaveBeenCalledOnce();
+
+ callback.reset();
+ respond(201, '');
+ respond(200, '');
+ respond(300, '');
+ expect(callback).not.toHaveBeenCalled();
+ });
+
+
+ it('should know "always" alias', function() {
+ future.on('always', callback);
+ respond(201, '');
+ respond(200, '');
+ respond(300, '');
+ respond(401, '');
+ respond(502, '');
+ respond(0, '');
+ respond(-1, '');
+ respond(-2, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(8);
+ });
+
+
+ it('should call "xxx" when 0 status code', function() {
+ future.on('xxx', callback);
+ respond(0, '');
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should not call "2xx" when 0 status code', function() {
+ future.on('2xx', callback);
+ respond(0, '');
+ expect(callback).not.toHaveBeenCalled();
+ });
+
+ it('should normalize internal statuses -1, -2 to 0', function() {
+ callback.andCallFake(function(response, status) {
+ expect(status).toBe(0);
+ });
+
+ future.on('xxx', callback);
+ respond(-1, '');
+ respond(-2, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(2);
+ });
+
+ it('should match "timeout" when -1 internal status', function() {
+ future.on('timeout', callback);
+ respond(-1, '');
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+ it('should match "abort" when 0 status', function() {
+ future.on('abort', callback);
+ respond(0, '');
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+ it('should match "error" when 0, -1, or -2', function() {
+ future.on('error', callback);
+ respond(0, '');
+ respond(-1, '');
+ respond(-2, '');
+
+ expect(callback).toHaveBeenCalled();
+ expect(callback.callCount).toBe(3);
+ });
+ });
+ });
+
+
+ describe('scope.$apply', function() {
+
+ beforeEach(doCommonXhr);
+
+ it('should $apply after success callback', function() {
+ respond(200, '');
+ expect(scope.$apply).toHaveBeenCalledOnce();
+ });
+
+
+ it('should $apply after error callback', function() {
+ respond(404, '');
+ expect(scope.$apply).toHaveBeenCalledOnce();
+ });
+
+
+ it('should $apply even if exception thrown during callback', function() {
+ onSuccess.andThrow('error in callback');
+ onError.andThrow('error in callback');
+
+ respond(200, '');
+ expect(scope.$apply).toHaveBeenCalledOnce();
+
+ scope.$apply.reset();
+ respond(400, '');
+ expect(scope.$apply).toHaveBeenCalledOnce();
+
+ $exceptionHandler.errors = [];
+ });
+ });
+
+
+ describe('transform', function() {
+
+ describe('request', function() {
+
+ describe('default', function() {
+
+ it('should transform object into json', function() {
+ $http({method: 'POST', url: '/url', data: {one: 'two'}});
+ expect(data).toBe('{"one":"two"}');
+ });
+
+
+ it('should ignore strings', function() {
+ $http({method: 'POST', url: '/url', data: 'string-data'});
+ expect(data).toBe('string-data');
+ });
+ });
+ });
+
+
+ describe('response', function() {
+
+ describe('default', function() {
+
+ it('should deserialize json objects', function() {
+ doCommonXhr();
+ respond(200, '{"foo":"bar","baz":23}');
+
+ expect(onSuccess.mostRecentCall.args[0]).toEqual({foo: 'bar', baz: 23});
+ });
+
+
+ it('should deserialize json arrays', function() {
+ doCommonXhr();
+ respond(200, '[1, "abc", {"foo":"bar"}]');
+
+ expect(onSuccess.mostRecentCall.args[0]).toEqual([1, 'abc', {foo: 'bar'}]);
+ });
+
+
+ it('should deserialize json with security prefix', function() {
+ doCommonXhr();
+ respond(200, ')]}\',\n[1, "abc", {"foo":"bar"}]');
+
+ expect(onSuccess.mostRecentCall.args[0]).toEqual([1, 'abc', {foo:'bar'}]);
+ });
+ });
+
+ it('should pipeline more functions', function() {
+ function first(d) {return d + '1';}
+ function second(d) {return d + '2';}
+ onSuccess = jasmine.createSpy('onSuccess');
+
+ $http({method: 'POST', url: '/url', data: '0', transformResponse: [first, second]})
+ .on('200', onSuccess);
+
+ respond(200, '0');
+ expect(onSuccess).toHaveBeenCalledOnce();
+ expect(onSuccess.mostRecentCall.args[0]).toBe('012');
+ });
+ });
+ });
+
+
+ describe('cache', function() {
+
+ function doFirstCacheRequest(method, responseStatus) {
+ onSuccess = jasmine.createSpy('on200');
+ $http({method: method || 'get', url: '/url', cache: true});
+ respond(responseStatus || 200, 'content');
+ $browser.xhr.reset();
+ }
+
+ it('should cache GET request', function() {
+ doFirstCacheRequest();
+
+ $http({method: 'get', url: '/url', cache: true}).on('200', onSuccess);
+ $browser.defer.flush();
+
+ expect(onSuccess).toHaveBeenCalledOnce();
+ expect(onSuccess.mostRecentCall.args[0]).toBe('content');
+ expect($browser.xhr).not.toHaveBeenCalled();
+ });
+
+
+ it('should always call callback asynchronously', function() {
+ doFirstCacheRequest();
+
+ $http({method: 'get', url: '/url', cache: true}).on('200', onSuccess);
+ expect(onSuccess).not.toHaveBeenCalled();
+ });
+
+
+ it('should not cache POST request', function() {
+ doFirstCacheRequest('post');
+
+ $http({method: 'post', url: '/url', cache: true}).on('200', onSuccess);
+ $browser.defer.flush();
+ expect(onSuccess).not.toHaveBeenCalled();
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ });
+
+
+ it('should not cache PUT request', function() {
+ doFirstCacheRequest('put');
+
+ $http({method: 'put', url: '/url', cache: true}).on('200', onSuccess);
+ $browser.defer.flush();
+ expect(onSuccess).not.toHaveBeenCalled();
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ });
+
+
+ it('should not cache DELETE request', function() {
+ doFirstCacheRequest('delete');
+
+ $http({method: 'delete', url: '/url', cache: true}).on('200', onSuccess);
+ $browser.defer.flush();
+ expect(onSuccess).not.toHaveBeenCalled();
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ });
+
+
+ it('should not cache non 2xx responses', function() {
+ doFirstCacheRequest('get', 404);
+
+ $http({method: 'get', url: '/url', cache: true}).on('200', onSuccess);
+ $browser.defer.flush();
+ expect(onSuccess).not.toHaveBeenCalled();
+ expect($browser.xhr).toHaveBeenCalledOnce();
+ });
+
+
+ it('should cache the headers as well', function() {
+ doFirstCacheRequest();
+ onSuccess.andCallFake(function(r, s, headers) {
+ expect(headers()).toEqual({'content-encoding': 'gzip', 'server': 'Apache'});
+ expect(headers('server')).toBe('Apache');
+ });
+
+ $http({method: 'get', url: '/url', cache: true}).on('200', onSuccess);
+ $browser.defer.flush();
+ expect(onSuccess).toHaveBeenCalledOnce();
+ });
+
+
+ it('should cache status code as well', function() {
+ doFirstCacheRequest('get', 201);
+ onSuccess.andCallFake(function(r, status, h) {
+ expect(status).toBe(201);
+ });
+
+ $http({method: 'get', url: '/url', cache: true}).on('2xx', onSuccess);
+ $browser.defer.flush();
+ expect(onSuccess).toHaveBeenCalledOnce();
+ });
+ });
+
+
+ describe('pendingCount', function() {
+
+ it('should return number of pending requests', function() {
+ expect($http.pendingCount()).toBe(0);
+
+ $http({method: 'get', url: '/some'});
+ expect($http.pendingCount()).toBe(1);
+
+ respond(200, '');
+ expect($http.pendingCount()).toBe(0);
+ });
+
+
+ it('should decrement the counter when request aborted', function() {
+ future = $http({method: 'get', url: '/x'});
+ expect($http.pendingCount()).toBe(1);
+ future.abort();
+ respond(0, '');
+
+ expect($http.pendingCount()).toBe(0);
+ });
+
+
+ it('should decrement the counter when served from cache', function() {
+ $http({method: 'get', url: '/cached', cache: true});
+ respond(200, 'content');
+ expect($http.pendingCount()).toBe(0);
+
+ $http({method: 'get', url: '/cached', cache: true});
+ expect($http.pendingCount()).toBe(1);
+
+ $browser.defer.flush();
+ expect($http.pendingCount()).toBe(0);
+ });
+
+
+ it('should decrement the counter before firing callbacks', function() {
+ $http({method: 'get', url: '/cached'}).on('xxx', function() {
+ expect($http.pendingCount()).toBe(0);
+ });
+
+ expect($http.pendingCount()).toBe(1);
+ respond(200, 'content');
+ });
+ });
+});
diff --git a/test/service/xhr.bulkSpec.js b/test/service/xhr.bulkSpec.js
deleted file mode 100644
index 6e55b387..00000000
--- a/test/service/xhr.bulkSpec.js
+++ /dev/null
@@ -1,81 +0,0 @@
-'use strict';
-
-describe('$xhr.bulk', function() {
- var log;
-
- beforeEach(inject(function($provide) {
- $provide.value('$xhr.error', jasmine.createSpy('$xhr.error'));
- $provide.factory('$xhrError', ['$xhr.error', identity]);
- $provide.factory('$xhrBulk', ['$xhr.bulk', identity]);
- log = '';
- }));
-
-
- function callback(code, response) {
- expect(code).toEqual(200);
- log = log + toJson(response) + ';';
- }
-
-
- it('should collect requests', inject(function($browser, $xhrBulk) {
- $xhrBulk.urls["/"] = {match:/.*/};
- $xhrBulk('GET', '/req1', null, callback);
- $xhrBulk('POST', '/req2', {post:'data'}, callback);
-
- $browser.xhr.expectPOST('/', {
- requests:[{method:'GET', url:'/req1', data: null},
- {method:'POST', url:'/req2', data:{post:'data'} }]
- }).respond([
- {status:200, response:'first'},
- {status:200, response:'second'}
- ]);
- $xhrBulk.flush(function() { log += 'DONE';});
- $browser.xhr.flush();
- expect(log).toEqual('"first";"second";DONE');
- }));
-
-
- it('should handle non 200 status code by forwarding to error handler',
- inject(function($browser, $xhrBulk, $xhrError) {
- $xhrBulk.urls['/'] = {match:/.*/};
- $xhrBulk('GET', '/req1', null, callback);
- $xhrBulk('POST', '/req2', {post:'data'}, callback);
-
- $browser.xhr.expectPOST('/', {
- requests:[{method:'GET', url:'/req1', data: null},
- {method:'POST', url:'/req2', data:{post:'data'} }]
- }).respond([
- {status:404, response:'NotFound'},
- {status:200, response:'second'}
- ]);
- $xhrBulk.flush(function() { log += 'DONE';});
- $browser.xhr.flush();
-
- expect($xhrError).toHaveBeenCalled();
- var cb = $xhrError.mostRecentCall.args[0].success;
- expect(typeof cb).toEqual('function');
- expect($xhrError).toHaveBeenCalledWith(
- {url: '/req1', method: 'GET', data: null, success: cb},
- {status: 404, response: 'NotFound'});
-
- expect(log).toEqual('"second";DONE');
- }));
-
- it('should handle non 200 status code by calling error callback if provided',
- inject(function($browser, $xhrBulk, $xhrError) {
- var callback = jasmine.createSpy('error');
-
- $xhrBulk.urls['/'] = {match: /.*/};
- $xhrBulk('GET', '/req1', null, noop, callback);
-
- $browser.xhr.expectPOST('/', {
- requests:[{method: 'GET', url: '/req1', data: null}]
- }).respond([{status: 404, response: 'NotFound'}]);
-
- $xhrBulk.flush();
- $browser.xhr.flush();
-
- expect($xhrError).not.toHaveBeenCalled();
- expect(callback).toHaveBeenCalledWith(404, 'NotFound');
- }));
-});
diff --git a/test/service/xhr.cacheSpec.js b/test/service/xhr.cacheSpec.js
deleted file mode 100644
index b6eeb6aa..00000000
--- a/test/service/xhr.cacheSpec.js
+++ /dev/null
@@ -1,175 +0,0 @@
-'use strict';
-
-describe('$xhr.cache', function() {
- var log;
-
- beforeEach(inject(function($provide) {
- $provide.value('$xhr.error', jasmine.createSpy('$xhr.error'));
- $provide.factory('$xhrError', ['$xhr.error', identity]);
- $provide.factory('$xhrBulk', ['$xhr.bulk', identity]);
- $provide.factory('$xhrCache', ['$xhr.cache', identity]);
- log = '';
- }));
-
-
- function callback(code, response) {
- expect(code).toEqual(200);
- log = log + toJson(response) + ';';
- }
-
-
- it('should cache requests', inject(function($browser, $xhrCache) {
- $browser.xhr.expectGET('/url').respond('first');
- $xhrCache('GET', '/url', null, callback);
- $browser.xhr.flush();
-
- $browser.xhr.expectGET('/url').respond('ERROR');
- $xhrCache('GET', '/url', null, callback);
- $browser.defer.flush();
- expect(log).toEqual('"first";"first";');
-
- $xhrCache('GET', '/url', null, callback, false);
- $browser.defer.flush();
- expect(log).toEqual('"first";"first";"first";');
- }));
-
-
- it('should first return cache request, then return server request', inject(function($browser, $xhrCache) {
- $browser.xhr.expectGET('/url').respond('first');
- $xhrCache('GET', '/url', null, callback, true);
- $browser.xhr.flush();
-
- $browser.xhr.expectGET('/url').respond('ERROR');
- $xhrCache('GET', '/url', null, callback, true);
- $browser.defer.flush();
- expect(log).toEqual('"first";"first";');
-
- $browser.xhr.flush();
- expect(log).toEqual('"first";"first";"ERROR";');
- }));
-
-
- it('should serve requests from cache', inject(function($browser, $xhrCache) {
- $xhrCache.data.url = {value:'123'};
- $xhrCache('GET', 'url', null, callback);
- $browser.defer.flush();
- expect(log).toEqual('"123";');
-
- $xhrCache('GET', 'url', null, callback, false);
- $browser.defer.flush();
- expect(log).toEqual('"123";"123";');
- }));
-
-
- it('should keep track of in flight requests and request only once', inject(function($browser, $xhrCache, $xhrBulk) {
- $xhrBulk.urls['/bulk'] = {
- match:function(url){
- return url == '/url';
- }
- };
- $browser.xhr.expectPOST('/bulk', {
- requests:[{method:'GET', url:'/url', data: null}]
- }).respond([
- {status:200, response:'123'}
- ]);
- $xhrCache('GET', '/url', null, callback);
- $xhrCache('GET', '/url', null, callback);
- $xhrCache.delegate.flush();
- $browser.xhr.flush();
- expect(log).toEqual('"123";"123";');
- }));
-
-
- it('should clear cache on non GET', inject(function($browser, $xhrCache) {
- $browser.xhr.expectPOST('abc', {}).respond({});
- $xhrCache.data.url = {value:123};
- $xhrCache('POST', 'abc', {});
- expect($xhrCache.data.url).toBeUndefined();
- }));
-
-
- it('should call callback asynchronously for both cache hit and cache miss', inject(function($browser, $xhrCache) {
- $browser.xhr.expectGET('/url').respond('+');
- $xhrCache('GET', '/url', null, callback);
- expect(log).toEqual(''); //callback hasn't executed
-
- $browser.xhr.flush();
- expect(log).toEqual('"+";'); //callback has executed
-
- $xhrCache('GET', '/url', null, callback);
- expect(log).toEqual('"+";'); //callback hasn't executed
-
- $browser.defer.flush();
- expect(log).toEqual('"+";"+";'); //callback has executed
- }));
-
-
- it('should call callback synchronously when sync flag is on', inject(function($browser, $xhrCache) {
- $browser.xhr.expectGET('/url').respond('+');
- $xhrCache('GET', '/url', null, callback, false, true);
- expect(log).toEqual(''); //callback hasn't executed
-
- $browser.xhr.flush();
- expect(log).toEqual('"+";'); //callback has executed
-
- $xhrCache('GET', '/url', null, callback, false, true);
- expect(log).toEqual('"+";"+";'); //callback has executed
-
- $browser.defer.flush();
- expect(log).toEqual('"+";"+";'); //callback was not called again any more
- }));
-
-
- it('should call eval after callbacks for both cache hit and cache miss execute',
- inject(function($browser, $xhrCache, $rootScope) {
- var flushSpy = this.spyOn($rootScope, '$digest').andCallThrough();
-
- $browser.xhr.expectGET('/url').respond('+');
- $xhrCache('GET', '/url', null, callback);
- expect(flushSpy).not.toHaveBeenCalled();
-
- $browser.xhr.flush();
- expect(flushSpy).toHaveBeenCalled();
-
- flushSpy.reset(); //reset the spy
-
- $xhrCache('GET', '/url', null, callback);
- expect(flushSpy).not.toHaveBeenCalled();
-
- $browser.defer.flush();
- expect(flushSpy).toHaveBeenCalled();
- }));
-
- it('should call the error callback on error if provided', inject(function($browser, $xhrCache) {
- var errorSpy = jasmine.createSpy('error'),
- successSpy = jasmine.createSpy('success');
-
- $browser.xhr.expectGET('/url').respond(500, 'error');
-
- $xhrCache('GET', '/url', null, successSpy, errorSpy, false, true);
- $browser.xhr.flush();
- expect(errorSpy).toHaveBeenCalledWith(500, 'error');
- expect(successSpy).not.toHaveBeenCalled();
-
- errorSpy.reset();
- $xhrCache('GET', '/url', successSpy, errorSpy, false, true);
- $browser.xhr.flush();
- expect(errorSpy).toHaveBeenCalledWith(500, 'error');
- expect(successSpy).not.toHaveBeenCalled();
- }));
-
- it('should call the $xhr.error on error if error callback not provided',
- inject(function($browser, $xhrCache, $xhrError) {
- var errorSpy = jasmine.createSpy('error'),
- successSpy = jasmine.createSpy('success');
-
- $browser.xhr.expectGET('/url').respond(500, 'error');
- $xhrCache('GET', '/url', null, successSpy, false, true);
- $browser.xhr.flush();
-
- expect(successSpy).not.toHaveBeenCalled();
- expect($xhrError).toHaveBeenCalledWith(
- {method: 'GET', url: '/url', data: null, success: successSpy},
- {status: 500, body: 'error'});
- }));
-});
diff --git a/test/service/xhr.errorSpec.js b/test/service/xhr.errorSpec.js
deleted file mode 100644
index f9ce2b72..00000000
--- a/test/service/xhr.errorSpec.js
+++ /dev/null
@@ -1,29 +0,0 @@
-'use strict';
-
-describe('$xhr.error', function() {
- var log;
-
- beforeEach(inject(function($provide) {
- $provide.value('$xhr.error', jasmine.createSpy('$xhr.error'));
- $provide.factory('$xhrError', ['$xhr.error', identity]);
- log = '';
- }));
-
-
- function callback(code, response) {
- expect(code).toEqual(200);
- log = log + toJson(response) + ';';
- }
-
-
- it('should handle non 200 status codes by forwarding to error handler', inject(function($browser, $xhr, $xhrError) {
- $browser.xhr.expectPOST('/req', 'MyData').respond(500, 'MyError');
- $xhr('POST', '/req', 'MyData', callback);
- $browser.xhr.flush();
- var cb = $xhrError.mostRecentCall.args[0].success;
- expect(typeof cb).toEqual('function');
- expect($xhrError).toHaveBeenCalledWith(
- {url: '/req', method: 'POST', data: 'MyData', success: cb},
- {status: 500, body: 'MyError'});
- }));
-});
diff --git a/test/service/xhrSpec.js b/test/service/xhrSpec.js
deleted file mode 100644
index 83c5f93f..00000000
--- a/test/service/xhrSpec.js
+++ /dev/null
@@ -1,271 +0,0 @@
-'use strict';
-
-describe('$xhr', function() {
-
- var log;
-
- beforeEach(inject(function($provide) {
- log = '';
- $provide.value('$xhr.error', jasmine.createSpy('xhr.error'));
- $provide.factory('$xhrError', ['$xhr.error', identity]);
- }));
-
-
- function callback(code, response) {
- log = log + '{code=' + code + '; response=' + toJson(response) + '}';
- }
-
-
- it('should forward the request to $browser and decode JSON', inject(function($browser, $xhr) {
- $browser.xhr.expectGET('/reqGET').respond('first');
- $browser.xhr.expectGET('/reqGETjson').respond('["second"]');
- $browser.xhr.expectPOST('/reqPOST', {post:'data'}).respond('third');
-
- $xhr('GET', '/reqGET', null, callback);
- $xhr('GET', '/reqGETjson', null, callback);
- $xhr('POST', '/reqPOST', {post:'data'}, callback);
-
- $browser.xhr.flush();
-
- expect(log).toEqual(
- '{code=200; response="third"}' +
- '{code=200; response=["second"]}' +
- '{code=200; response="first"}');
- }));
-
- it('should allow all 2xx requests', inject(function($browser, $xhr) {
- $browser.xhr.expectGET('/req1').respond(200, '1');
- $xhr('GET', '/req1', null, callback);
- $browser.xhr.flush();
-
- $browser.xhr.expectGET('/req2').respond(299, '2');
- $xhr('GET', '/req2', null, callback);
- $browser.xhr.flush();
-
- expect(log).toEqual(
- '{code=200; response="1"}' +
- '{code=299; response="2"}');
- }));
-
-
- it('should handle exceptions in callback', inject(function($browser, $xhr, $log) {
- $browser.xhr.expectGET('/reqGET').respond('first');
- $xhr('GET', '/reqGET', null, function() { throw "MyException"; });
- $browser.xhr.flush();
-
- expect($log.error.logs.shift()).toContain('MyException');
- }));
-
-
- it('should automatically deserialize json objects', inject(function($browser, $xhr) {
- var response;
-
- $browser.xhr.expectGET('/foo').respond('{"foo":"bar","baz":23}');
- $xhr('GET', '/foo', function(code, resp) {
- response = resp;
- });
- $browser.xhr.flush();
-
- expect(response).toEqual({foo:'bar', baz:23});
- }));
-
-
- it('should automatically deserialize json arrays', inject(function($browser, $xhr) {
- var response;
-
- $browser.xhr.expectGET('/foo').respond('[1, "abc", {"foo":"bar"}]');
- $xhr('GET', '/foo', function(code, resp) {
- response = resp;
- });
- $browser.xhr.flush();
-
- expect(response).toEqual([1, 'abc', {foo:'bar'}]);
- }));
-
-
- it('should automatically deserialize json with security prefix', inject(function($browser, $xhr) {
- var response;
-
- $browser.xhr.expectGET('/foo').respond(')]}\',\n[1, "abc", {"foo":"bar"}]');
- $xhr('GET', '/foo', function(code, resp) {
- response = resp;
- });
- $browser.xhr.flush();
-
- expect(response).toEqual([1, 'abc', {foo:'bar'}]);
- }));
-
- it('should call $xhr.error on error if no error callback provided', inject(function($browser, $xhr, $xhrError) {
- var successSpy = jasmine.createSpy('success');
-
- $browser.xhr.expectGET('/url').respond(500, 'error');
- $xhr('GET', '/url', null, successSpy);
- $browser.xhr.flush();
-
- expect(successSpy).not.toHaveBeenCalled();
- expect($xhrError).toHaveBeenCalledWith(
- {method: 'GET', url: '/url', data: null, success: successSpy},
- {status: 500, body: 'error'}
- );
- }));
-
- it('should call the error callback on error if provided', inject(function($browser, $xhr) {
- var errorSpy = jasmine.createSpy('error'),
- successSpy = jasmine.createSpy('success');
-
- $browser.xhr.expectGET('/url').respond(500, 'error');
- $xhr('GET', '/url', null, successSpy, errorSpy);
- $browser.xhr.flush();
-
- expect(errorSpy).toHaveBeenCalledWith(500, 'error');
- expect(successSpy).not.toHaveBeenCalled();
-
- errorSpy.reset();
- $xhr('GET', '/url', successSpy, errorSpy);
- $browser.xhr.flush();
-
- expect(errorSpy).toHaveBeenCalledWith(500, 'error');
- expect(successSpy).not.toHaveBeenCalled();
- }));
-
- describe('http headers', function() {
-
- describe('default headers', function() {
-
- it('should set default headers for GET request', inject(function($browser, $xhr) {
- var callback = jasmine.createSpy('callback');
-
- $browser.xhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*',
- 'X-Requested-With': 'XMLHttpRequest'}).
- respond(234, 'OK');
-
- $xhr('GET', 'URL', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- }));
-
-
- it('should set default headers for POST request', inject(function($browser, $xhr) {
- var callback = jasmine.createSpy('callback');
-
- $browser.xhr.expectPOST('URL', 'xx', {'Accept': 'application/json, text/plain, */*',
- 'X-Requested-With': 'XMLHttpRequest',
- 'Content-Type': 'application/x-www-form-urlencoded'}).
- respond(200, 'OK');
-
- $xhr('POST', 'URL', 'xx', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- }));
-
-
- it('should set default headers for custom HTTP method', inject(function($browser, $xhr) {
- var callback = jasmine.createSpy('callback');
-
- $browser.xhr.expect('FOO', 'URL', '', {'Accept': 'application/json, text/plain, */*',
- 'X-Requested-With': 'XMLHttpRequest'}).
- respond(200, 'OK');
-
- $xhr('FOO', 'URL', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- }));
-
-
- describe('custom headers', function() {
-
- it('should allow appending a new header to the common defaults', inject(function($browser, $xhr) {
- var callback = jasmine.createSpy('callback');
-
- $browser.xhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*',
- 'X-Requested-With': 'XMLHttpRequest',
- 'Custom-Header': 'value'}).
- respond(200, 'OK');
-
- $xhr.defaults.headers.common['Custom-Header'] = 'value';
- $xhr('GET', 'URL', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- callback.reset();
-
- $browser.xhr.expectPOST('URL', 'xx', {'Accept': 'application/json, text/plain, */*',
- 'X-Requested-With': 'XMLHttpRequest',
- 'Content-Type': 'application/x-www-form-urlencoded',
- 'Custom-Header': 'value'}).
- respond(200, 'OK');
-
- $xhr('POST', 'URL', 'xx', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- }));
-
-
- it('should allow appending a new header to a method specific defaults', inject(function($browser, $xhr) {
- var callback = jasmine.createSpy('callback');
-
- $browser.xhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*',
- 'X-Requested-With': 'XMLHttpRequest',
- 'Content-Type': 'application/json'}).
- respond(200, 'OK');
-
- $xhr.defaults.headers.get['Content-Type'] = 'application/json';
- $xhr('GET', 'URL', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- callback.reset();
-
- $browser.xhr.expectPOST('URL', 'x', {'Accept': 'application/json, text/plain, */*',
- 'X-Requested-With': 'XMLHttpRequest',
- 'Content-Type': 'application/x-www-form-urlencoded'}).
- respond(200, 'OK');
-
- $xhr('POST', 'URL', 'x', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- }));
-
-
- it('should support overwriting and deleting default headers', inject(function($browser, $xhr) {
- var callback = jasmine.createSpy('callback');
-
- $browser.xhr.expectGET('URL', '', {'Accept': 'application/json, text/plain, */*'}).
- respond(200, 'OK');
-
- //delete a default header
- delete $xhr.defaults.headers.common['X-Requested-With'];
- $xhr('GET', 'URL', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- callback.reset();
-
- $browser.xhr.expectPOST('URL', 'xx', {'Accept': 'application/json, text/plain, */*',
- 'Content-Type': 'application/json'}).
- respond(200, 'OK');
-
- //overwrite a default header
- $xhr.defaults.headers.post['Content-Type'] = 'application/json';
- $xhr('POST', 'URL', 'xx', callback);
- $browser.xhr.flush();
- expect(callback).toHaveBeenCalled();
- }));
- });
- });
- });
-
- describe('xsrf', function() {
- it('should copy the XSRF cookie into a XSRF Header', inject(function($browser, $xhr) {
- var code, response;
- $browser.xhr
- .expectPOST('URL', 'DATA', {'X-XSRF-TOKEN': 'secret'})
- .respond(234, 'OK');
- $browser.cookies('XSRF-TOKEN', 'secret');
- $xhr('POST', 'URL', 'DATA', function(c, r){
- code = c;
- response = r;
- });
- $browser.xhr.flush();
- expect(code).toEqual(234);
- expect(response).toEqual('OK');
- }));
- });
-});
diff --git a/test/widgetsSpec.js b/test/widgetsSpec.js
index 82aa4956..2ddb26e1 100644
--- a/test/widgetsSpec.js
+++ b/test/widgetsSpec.js
@@ -1,10 +1,6 @@
'use strict';
describe("widget", function() {
- beforeEach(inject(function($provide){
- $provide.factory('$xhrCache', ['$xhr.cache', identity]);
- }));
-
describe('ng:switch', inject(function($rootScope, $compile) {
it('should switch on value change', inject(function($rootScope, $compile) {
var element = $compile(
@@ -60,26 +56,26 @@ describe("widget", function() {
describe('ng:include', inject(function($rootScope, $compile) {
- it('should include on external file', inject(function($rootScope, $compile, $xhrCache) {
+ it('should include on external file', inject(function($rootScope, $compile, $cacheFactory) {
var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
var element = $compile(element)($rootScope);
$rootScope.childScope = $rootScope.$new();
$rootScope.childScope.name = 'misko';
$rootScope.url = 'myUrl';
- $xhrCache.data.myUrl = {value:'{{name}}'};
+ $cacheFactory.get('templates').put('myUrl', '{{name}}');
$rootScope.$digest();
expect(element.text()).toEqual('misko');
}));
it('should remove previously included text if a falsy value is bound to src',
- inject(function($rootScope, $compile, $xhrCache) {
+ inject(function($rootScope, $compile, $cacheFactory) {
var element = jqLite('<ng:include src="url" scope="childScope"></ng:include>');
var element = $compile(element)($rootScope);
$rootScope.childScope = $rootScope.$new();
$rootScope.childScope.name = 'igor';
$rootScope.url = 'myUrl';
- $xhrCache.data.myUrl = {value:'{{name}}'};
+ $cacheFactory.get('templates').put('myUrl', '{{name}}');
$rootScope.$digest();
expect(element.text()).toEqual('igor');
@@ -91,11 +87,11 @@ describe("widget", function() {
}));
- it('should allow this for scope', inject(function($rootScope, $compile, $xhrCache) {
+ it('should allow this for scope', inject(function($rootScope, $compile, $cacheFactory) {
var element = jqLite('<ng:include src="url" scope="this"></ng:include>');
var element = $compile(element)($rootScope);
$rootScope.url = 'myUrl';
- $xhrCache.data.myUrl = {value:'{{"abc"}}'};
+ $cacheFactory.get('templates').put('myUrl', '{{"abc"}}');
$rootScope.$digest();
// TODO(misko): because we are using scope==this, the eval gets registered
// during the flush phase and hence does not get called.
@@ -108,28 +104,28 @@ describe("widget", function() {
it('should evaluate onload expression when a partial is loaded',
- inject(function($rootScope, $compile, $xhrCache) {
+ inject(function($rootScope, $compile, $cacheFactory) {
var element = jqLite('<ng:include src="url" onload="loaded = true"></ng:include>');
var element = $compile(element)($rootScope);
expect($rootScope.loaded).not.toBeDefined();
$rootScope.url = 'myUrl';
- $xhrCache.data.myUrl = {value:'my partial'};
+ $cacheFactory.get('templates').put('myUrl', 'my partial');
$rootScope.$digest();
expect(element.text()).toEqual('my partial');
expect($rootScope.loaded).toBe(true);
}));
- it('should destroy old scope', inject(function($rootScope, $compile, $xhrCache) {
+ it('should destroy old scope', inject(function($rootScope, $compile, $cacheFactory) {
var element = jqLite('<ng:include src="url"></ng:include>');
var element = $compile(element)($rootScope);
expect($rootScope.$$childHead).toBeFalsy();
$rootScope.url = 'myUrl';
- $xhrCache.data.myUrl = {value:'my partial'};
+ $cacheFactory.get('templates').put('myUrl', 'my partial');
$rootScope.$digest();
expect($rootScope.$$childHead).toBeTruthy();
@@ -137,6 +133,55 @@ describe("widget", function() {
$rootScope.$digest();
expect($rootScope.$$childHead).toBeFalsy();
}));
+
+ it('should do xhr request and cache it', inject(function($rootScope, $browser, $compile) {
+ var element = $compile('<ng:include src="url"></ng:include>')($rootScope);
+ var $browserXhr = $browser.xhr;
+ $browserXhr.expectGET('myUrl').respond('my partial');
+
+ $rootScope.url = 'myUrl';
+ $rootScope.$digest();
+ $browserXhr.flush();
+ expect(element.text()).toEqual('my partial');
+
+ $rootScope.url = null;
+ $rootScope.$digest();
+ expect(element.text()).toEqual('');
+
+ $rootScope.url = 'myUrl';
+ $rootScope.$digest();
+ expect(element.text()).toEqual('my partial');
+ dealoc($rootScope);
+ }));
+
+ it('should clear content when error during xhr request',
+ inject(function($browser, $compile, $rootScope) {
+ var element = $compile('<ng:include src="url">content</ng:include>')($rootScope);
+ var $browserXhr = $browser.xhr;
+ $browserXhr.expectGET('myUrl').respond(404, '');
+
+ $rootScope.url = 'myUrl';
+ $rootScope.$digest();
+ $browserXhr.flush();
+
+ expect(element.text()).toBe('');
+ }));
+
+ it('should be async even if served from cache', inject(function($rootScope, $compile, $cacheFactory) {
+ var element = $compile('<ng:include src="url"></ng:include>')($rootScope);
+
+ $rootScope.url = 'myUrl';
+ $cacheFactory.get('templates').put('myUrl', 'my partial');
+
+ var called = 0;
+ // we want to assert only during first watch
+ $rootScope.$watch(function() {
+ if (!called++) expect(element.text()).toBe('');
+ });
+
+ $rootScope.$digest();
+ expect(element.text()).toBe('my partial');
+ }));
}));
@@ -587,6 +632,36 @@ describe("widget", function() {
expect($rootScope.$element.text()).toEqual('2');
}));
+
+ it('should clear the content when error during xhr request',
+ inject(function($route, $location, $rootScope, $browser) {
+ $route.when('/foo', {controller: noop, template: 'myUrl1'});
+
+ $location.path('/foo');
+ $browser.xhr.expectGET('myUrl1').respond(404, '');
+ $rootScope.$element.text('content');
+
+ $rootScope.$digest();
+ $browser.xhr.flush();
+
+ expect($rootScope.$element.text()).toBe('');
+ }));
+
+ it('should be async even if served from cache',
+ inject(function($route, $rootScope, $location, $cacheFactory) {
+ $route.when('/foo', {controller: noop, template: 'myUrl1'});
+ $cacheFactory.get('templates').put('myUrl1', 'my partial');
+ $location.path('/foo');
+
+ var called = 0;
+ // we want to assert only during first watch
+ $rootScope.$watch(function() {
+ if (!called++) expect(element.text()).toBe('');
+ });
+
+ $rootScope.$digest();
+ expect(element.text()).toBe('my partial');
+ }));
});