|
1 | 1 | describe('$httpBackend', function() {
|
2 | 2 |
|
3 | 3 | var $backend, $browser, callbacks,
|
4 |
| - xhr, fakeDocument, callback; |
| 4 | + xhr, fakeDocument, callback, |
| 5 | + fakeTimeoutId = 0; |
5 | 6 |
|
6 | 7 | // TODO(vojta): should be replaced by $defer mock
|
7 | 8 | function fakeTimeout(fn, delay) {
|
8 | 9 | fakeTimeout.fns.push(fn);
|
9 | 10 | fakeTimeout.delays.push(delay);
|
| 11 | + fakeTimeout.ids.push(++fakeTimeoutId); |
| 12 | + return fakeTimeoutId; |
10 | 13 | }
|
11 | 14 |
|
12 | 15 | fakeTimeout.fns = [];
|
13 | 16 | fakeTimeout.delays = [];
|
| 17 | + fakeTimeout.ids = []; |
14 | 18 | fakeTimeout.flush = function() {
|
15 | 19 | var len = fakeTimeout.fns.length;
|
16 | 20 | fakeTimeout.delays = [];
|
| 21 | + fakeTimeout.ids = []; |
17 | 22 | while (len--) fakeTimeout.fns.shift()();
|
18 | 23 | };
|
| 24 | + fakeTimeout.cancel = function(id) { |
| 25 | + var i = indexOf(fakeTimeout.ids, id); |
| 26 | + if (i >= 0) { |
| 27 | + fakeTimeout.fns.splice(i, 1); |
| 28 | + fakeTimeout.delays.splice(i, 1); |
| 29 | + fakeTimeout.ids.splice(i, 1); |
| 30 | + return true; |
| 31 | + } |
| 32 | + return false; |
| 33 | + }; |
19 | 34 |
|
20 | 35 |
|
21 | 36 | beforeEach(inject(function($injector) {
|
@@ -102,6 +117,27 @@ describe('$httpBackend', function() {
|
102 | 117 | });
|
103 | 118 |
|
104 | 119 |
|
| 120 | + it('should cancel timeout on completion', function() { |
| 121 | + callback.andCallFake(function(status, response) { |
| 122 | + expect(status).toBe(200); |
| 123 | + }); |
| 124 | + |
| 125 | + $backend('GET', '/url', null, callback, {}, 2000); |
| 126 | + xhr = MockXhr.$$lastInstance; |
| 127 | + spyOn(xhr, 'abort'); |
| 128 | + |
| 129 | + expect(fakeTimeout.delays[0]).toBe(2000); |
| 130 | + |
| 131 | + xhr.status = 200; |
| 132 | + xhr.readyState = 4; |
| 133 | + xhr.onreadystatechange(); |
| 134 | + expect(callback).toHaveBeenCalledOnce(); |
| 135 | + |
| 136 | + expect(fakeTimeout.delays.length).toBe(0); |
| 137 | + expect(xhr.abort).not.toHaveBeenCalled(); |
| 138 | + }); |
| 139 | + |
| 140 | + |
105 | 141 | it('should register onreadystatechange callback before sending', function() {
|
106 | 142 | // send() in IE6, IE7 is sync when serving from cache
|
107 | 143 | function SyncXhr() {
|
@@ -239,6 +275,21 @@ describe('$httpBackend', function() {
|
239 | 275 | });
|
240 | 276 |
|
241 | 277 |
|
| 278 | + it('should abort request on timeout', function() { |
| 279 | + callback.andCallFake(function(status, response) { |
| 280 | + expect(status).toBe(-1); |
| 281 | + }); |
| 282 | + |
| 283 | + $backend('JSONP', 'http://example.org/path?cb=JSON_CALLBACK', null, callback, null, 2000); |
| 284 | + expect(fakeDocument.$$scripts.length).toBe(1); |
| 285 | + expect(fakeTimeout.delays[0]).toBe(2000); |
| 286 | + |
| 287 | + fakeTimeout.flush(); |
| 288 | + expect(fakeDocument.$$scripts.length).toBe(0); |
| 289 | + expect(callback).toHaveBeenCalledOnce(); |
| 290 | + }); |
| 291 | + |
| 292 | + |
242 | 293 | // TODO(vojta): test whether it fires "async-start"
|
243 | 294 | // TODO(vojta): test whether it fires "async-end" on both success and error
|
244 | 295 | });
|
|
0 commit comments