aboutsummaryrefslogtreecommitdiffstats
path: root/test/service/httpBackendSpec.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/service/httpBackendSpec.js')
-rw-r--r--test/service/httpBackendSpec.js179
1 files changed, 179 insertions, 0 deletions
diff --git a/test/service/httpBackendSpec.js b/test/service/httpBackendSpec.js
new file mode 100644
index 00000000..e609eea6
--- /dev/null
+++ b/test/service/httpBackendSpec.js
@@ -0,0 +1,179 @@
+describe('$httpBackend', function() {
+
+ var $backend, $browser, $window,
+ xhr, fakeBody, callback;
+
+ // TODO(vojta): should be replaced by $defer mock
+ function fakeTimeout(fn, delay) {
+ fakeTimeout.fns.push(fn);
+ fakeTimeout.delays.push(delay);
+ }
+
+ fakeTimeout.fns = [];
+ fakeTimeout.delays = [];
+ fakeTimeout.flush = function() {
+ var len = fakeTimeout.fns.length;
+ fakeTimeout.delays = [];
+ while (len--) fakeTimeout.fns.shift()();
+ };
+
+
+ beforeEach(inject(function($injector) {
+ $window = {};
+ $browser = $injector.get('$browser');
+ fakeBody = {removeChild: jasmine.createSpy('body.removeChild')};
+ $backend = createHttpBackend($browser, MockXhr, fakeTimeout, $window, fakeBody);
+ callback = jasmine.createSpy('done');
+ }));
+
+
+ it('should do basics - open async xhr and send data', function() {
+ $backend('GET', '/some-url', 'some-data', noop);
+ xhr = MockXhr.$$lastInstance;
+
+ expect(xhr.$$method).toBe('GET');
+ expect(xhr.$$url).toBe('/some-url');
+ expect(xhr.$$data).toBe('some-data');
+ expect(xhr.$$async).toBe(true);
+ });
+
+
+ it('should normalize IE\'s 1223 status code into 204', function() {
+ callback.andCallFake(function(status) {
+ expect(status).toBe(204);
+ });
+
+ $backend('GET', 'URL', null, callback);
+ xhr = MockXhr.$$lastInstance;
+
+ xhr.status = 1223;
+ xhr.readyState = 4;
+ xhr.onreadystatechange();
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should set only the requested headers', function() {
+ $backend('POST', 'URL', null, noop, {'X-header1': 'value1', 'X-header2': 'value2'});
+ xhr = MockXhr.$$lastInstance;
+
+ expect(xhr.$$headers).toEqual({
+ 'X-header1': 'value1',
+ 'X-header2': 'value2'
+ });
+ });
+
+
+ it('should return raw xhr object', function() {
+ expect($backend('GET', '/url', null, noop)).toBe(MockXhr.$$lastInstance);
+ });
+
+
+ it('should abort request on timeout', function() {
+ callback.andCallFake(function(status, response) {
+ expect(status).toBe(-1);
+ });
+
+ $backend('GET', '/url', null, callback, {}, 2000);
+ xhr = MockXhr.$$lastInstance;
+ spyOn(xhr, 'abort');
+
+ expect(fakeTimeout.delays[0]).toBe(2000);
+
+ fakeTimeout.flush();
+ expect(xhr.abort).toHaveBeenCalledOnce();
+
+ xhr.status = 0;
+ xhr.readyState = 4;
+ xhr.onreadystatechange();
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should be async even if xhr.send() is sync', function() {
+ // IE6, IE7 is sync when serving from cache
+ function SyncXhr() {
+ xhr = this;
+ this.open = this.setRequestHeader = noop;
+ this.send = function() {
+ this.status = 200;
+ this.responseText = 'response';
+ this.readyState = 4;
+ };
+ }
+
+ callback.andCallFake(function(status, response) {
+ expect(status).toBe(200);
+ expect(response).toBe('response');
+ });
+
+ $backend = createHttpBackend($browser, SyncXhr, fakeTimeout);
+ $backend('GET', '/url', null, callback);
+ expect(callback).not.toHaveBeenCalled();
+
+ fakeTimeout.flush();
+ expect(callback).toHaveBeenCalledOnce();
+
+ (xhr.onreadystatechange || noop)();
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ describe('JSONP', function() {
+
+ it('should add script tag for JSONP request', function() {
+ callback.andCallFake(function(status, response) {
+ expect(status).toBe(200);
+ expect(response).toBe('some-data');
+ });
+
+ $backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, callback);
+ expect($browser.$$scripts.length).toBe(1);
+
+ var script = $browser.$$scripts.shift(),
+ url = script.url.split('?cb=');
+
+ expect(url[0]).toBe('http://example.org/path');
+ $window[url[1]]('some-data');
+ script.done();
+
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ it('should clean up the callback and remove the script', function() {
+ $backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, callback);
+ expect($browser.$$scripts.length).toBe(1);
+
+ var script = $browser.$$scripts.shift(),
+ callbackId = script.url.split('?cb=')[1];
+
+ $window[callbackId]('some-data');
+ script.done();
+
+ expect($window[callbackId]).toBeUndefined();
+ expect(fakeBody.removeChild).toHaveBeenCalledOnce();
+ expect(fakeBody.removeChild).toHaveBeenCalledWith(script);
+ });
+
+
+ it('should call callback with status -2 when script fails to load', function() {
+ callback.andCallFake(function(status, response) {
+ expect(status).toBe(-2);
+ expect(response).toBeUndefined();
+ });
+
+ $backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, callback);
+ expect($browser.$$scripts.length).toBe(1);
+
+ $browser.$$scripts.shift().done();
+ expect(callback).toHaveBeenCalledOnce();
+ });
+
+
+ // TODO(vojta): test whether it fires "async-start"
+ // TODO(vojta): test whether it fires "async-end" on both success and error
+ });
+});
+