Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit bd63b22

Browse files
fix(ngMockE2E): ensure that mocked $httpBackend uses correct $browser
The fix from #13124 enabled ngMock and ngMockE2E to work together but did it in a way that meant that the "real" `$httpBackend` service that was used in pass-through depended upon a different `$browser` service to the rest of the app. This broke Protractor since it watches the `$browser` for outstanding requests and the pass through requests were being tracked by the wrong `$browser` instance. Closes #15593
1 parent f418ffd commit bd63b22

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

src/ngMock/angular-mocks.js

+10-7
Original file line numberDiff line numberDiff line change
@@ -1313,9 +1313,8 @@ angular.mock.dump = function(object) {
13131313
});
13141314
```
13151315
*/
1316-
angular.mock.$HttpBackendProvider = function() {
1317-
this.$get = ['$rootScope', '$timeout', createHttpBackendMock];
1318-
};
1316+
angular.mock.$httpBackendDecorator =
1317+
['$rootScope', '$timeout', '$delegate', createHttpBackendMock];
13191318

13201319
/**
13211320
* General factory function for $httpBackend mock.
@@ -1336,7 +1335,10 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
13361335
expectations = [],
13371336
responses = [],
13381337
responsesPush = angular.bind(responses, responses.push),
1339-
copy = angular.copy;
1338+
copy = angular.copy,
1339+
// We cache the original backend so that if both ngMock and ngMockE2E override the
1340+
// service the ngMockE2E version can pass through to the real backend
1341+
originalHttpBackend = $delegate.$$originalHttpBackend || $delegate;
13401342

13411343
function createResponse(status, data, headers, statusText) {
13421344
if (angular.isFunction(status)) return status;
@@ -1421,7 +1423,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
14211423
// if $browser specified, we do auto flush all requests
14221424
($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
14231425
} else if (definition.passThrough) {
1424-
$delegate(method, url, data, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers);
1426+
originalHttpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers);
14251427
} else throw new Error('No response defined !');
14261428
return;
14271429
}
@@ -1897,6 +1899,8 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
18971899
responses.length = 0;
18981900
};
18991901

1902+
$httpBackend.$$originalHttpBackend = originalHttpBackend;
1903+
19001904
return $httpBackend;
19011905

19021906

@@ -2394,14 +2398,14 @@ angular.module('ngMock', ['ng']).provider({
23942398
$exceptionHandler: angular.mock.$ExceptionHandlerProvider,
23952399
$log: angular.mock.$LogProvider,
23962400
$interval: angular.mock.$IntervalProvider,
2397-
$httpBackend: angular.mock.$HttpBackendProvider,
23982401
$rootElement: angular.mock.$RootElementProvider,
23992402
$componentController: angular.mock.$ComponentControllerProvider
24002403
}).config(['$provide', '$compileProvider', function($provide, $compileProvider) {
24012404
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
24022405
$provide.decorator('$$rAF', angular.mock.$RAFDecorator);
24032406
$provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
24042407
$provide.decorator('$controller', createControllerDecorator($compileProvider));
2408+
$provide.decorator('$httpBackend', angular.mock.$httpBackendDecorator);
24052409
}]);
24062410

24072411
/**
@@ -2416,7 +2420,6 @@ angular.module('ngMock', ['ng']).provider({
24162420
* the {@link ngMockE2E.$httpBackend e2e $httpBackend} mock.
24172421
*/
24182422
angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {
2419-
$provide.value('$httpBackend', angular.injector(['ng']).get('$httpBackend'));
24202423
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
24212424
}]);
24222425

test/ngMock/angular-mocksSpec.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -2432,13 +2432,15 @@ describe('ngMock', function() {
24322432

24332433
describe('ngMockE2E', function() {
24342434
describe('$httpBackend', function() {
2435-
var hb, realHttpBackend, callback;
2435+
var hb, realHttpBackend, realHttpBackendBrowser, callback;
24362436

24372437
beforeEach(function() {
24382438
callback = jasmine.createSpy('callback');
24392439
angular.module('ng').config(function($provide) {
24402440
realHttpBackend = jasmine.createSpy('real $httpBackend');
2441-
$provide.value('$httpBackend', realHttpBackend);
2441+
$provide.factory('$httpBackend', ['$browser', function($browser) {
2442+
return realHttpBackend.and.callFake(function() { realHttpBackendBrowser = $browser; });
2443+
}]);
24422444
});
24432445
module('ngMockE2E');
24442446
inject(function($injector) {
@@ -2477,6 +2479,14 @@ describe('ngMockE2E', function() {
24772479
expect(realHttpBackend).not.toHaveBeenCalled();
24782480
expect(callback).toHaveBeenCalledOnceWith(200, 'passThrough override', '', '');
24792481
}));
2482+
2483+
it('should pass through to an httpBackend that uses the same $browser service', inject(function($browser) {
2484+
hb.when('GET', /\/passThrough\/.*/).passThrough();
2485+
hb('GET', '/passThrough/23');
2486+
2487+
expect(realHttpBackend).toHaveBeenCalledOnce();
2488+
expect(realHttpBackendBrowser).toBe($browser);
2489+
}));
24802490
});
24812491

24822492

0 commit comments

Comments
 (0)