diff --git a/src/ng/http.js b/src/ng/http.js index e79284163443..f26ee0d37f82 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -750,6 +750,13 @@ function $HttpProvider() { */ function $http(requestConfig) { + var config = { + method: 'get', + transformRequest: defaults.transformRequest, + transformResponse: defaults.transformResponse, + progress: null + }; + var headers = mergeHeaders(requestConfig); if (!angular.isObject(requestConfig)) { throw minErr('$http')('badreq', 'Http request configuration must be an object. Received: {0}', requestConfig); @@ -1067,7 +1074,7 @@ function $HttpProvider() { } $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout, - config.withCredentials, config.responseType); + config.withCredentials, config.responseType, config.progress); } return promise; diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js index 5ba78b749932..94cb3e480cc6 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -28,7 +28,7 @@ function $HttpBackendProvider() { function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) { // TODO(vojta): fix the signature - return function(method, url, post, callback, headers, timeout, withCredentials, responseType) { + return function(method, url, post, callback, headers, timeout, withCredentials, responseType, progressCallback) { $browser.$$incOutstandingRequestCount(); url = url || $browser.url(); @@ -109,6 +109,13 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc } } + if (typeof progressCallback === "function") { + xhr.onprogress = progressCallback; + if ("upload" in xhr) { + xhr.upload.onprogress = progressCallback; + } + } + xhr.send(post || null); } diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 977d129629de..e48e3b01ee50 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -1147,7 +1147,8 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { } // TODO(vojta): change params to: method, url, data, headers, callback - function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) { + function $httpBackend(method, url, data, callback, headers, timeout, withCredentials, + progressCallback) { var xhr = new MockXhr(), expectation = expectations[0], wasExpected = false; @@ -1209,7 +1210,8 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) { // if $browser specified, we do auto flush all requests ($browser ? $browser.defer : responsesPush)(wrapResponse(definition)); } else if (definition.passThrough) { - $delegate(method, url, data, callback, headers, timeout, withCredentials); + $delegate(method, url, data, callback, headers, timeout, withCredentials, + progressCallback); } else throw new Error('No response defined !'); return; } diff --git a/test/ng/httpBackendSpec.js b/test/ng/httpBackendSpec.js index 12ceed5beb01..d20e6d9a090f 100644 --- a/test/ng/httpBackendSpec.js +++ b/test/ng/httpBackendSpec.js @@ -214,6 +214,25 @@ describe('$httpBackend', function() { expect(MockXhr.$$lastInstance.withCredentials).toBe(true); }); + describe('upload and download events', function() { + + it('should call progress callback on POST requests', function() { + $backend('POST', '/whatever', null, noop, {}, null, null, 'blob', callback); + + MockXhr.$$lastInstance.onprogress(); + + expect(callback).toHaveBeenCalled(); + }); + + it('should call progress callback on GET requests', function() { + $backend('GET', '/whatever', null, noop, {}, null, null, 'blob', callback); + + MockXhr.$$lastInstance.onprogress(); + + expect(callback).toHaveBeenCalled(); + }); + }); + describe('responseType', function() { diff --git a/test/ngMock/angular-mocksSpec.js b/test/ngMock/angular-mocksSpec.js index 54ea6f340d0f..16a3e795abde 100644 --- a/test/ngMock/angular-mocksSpec.js +++ b/test/ngMock/angular-mocksSpec.js @@ -1741,10 +1741,10 @@ describe('ngMockE2E', function() { describe('passThrough()', function() { it('should delegate requests to the real backend when passThrough is invoked', function() { hb.when('GET', /\/passThrough\/.*/).passThrough(); - hb('GET', '/passThrough/23', null, callback, {}, null, true); + hb('GET', '/passThrough/23', null, callback, {}, null, true, null); expect(realHttpBackend).toHaveBeenCalledOnceWith( - 'GET', '/passThrough/23', null, callback, {}, null, true); + 'GET', '/passThrough/23', null, callback, {}, null, true, null); }); it('should be able to override a respond definition with passThrough', function() {