diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 3186c3eb0739..e69789897ba8 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -1001,13 +1001,14 @@ angular.mock.dump = function(object) { ```js // testing controller describe('MyController', function() { - var $httpBackend, $rootScope, createController; + var $httpBackend, $rootScope, createController, authRequestHandler; beforeEach(inject(function($injector) { // Set up the mock http service responses $httpBackend = $injector.get('$httpBackend'); // backend definition common for all tests - $httpBackend.when('GET', '/auth.py').respond({userId: 'userX'}, {'A-Token': 'xxx'}); + authRequestHandler = $httpBackend.when('GET', '/auth.py') + .respond({userId: 'userX'}, {'A-Token': 'xxx'}); // Get hold of a scope (i.e. the root scope) $rootScope = $injector.get('$rootScope'); @@ -1033,6 +1034,18 @@ angular.mock.dump = function(object) { }); + it('should fail authentication', function() { + + // Notice how you can change the response even after it was set + authRequestHandler.respond(401, ''); + + $httpBackend.expectGET('/auth.py'); + var controller = createController(); + $httpBackend.flush(); + expect($rootScope.status).toBe('Failed...'); + }); + + it('should send msg to server', function() { var controller = createController(); $httpBackend.flush(); @@ -1187,26 +1200,32 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header * object and returns true if the headers match the current definition. * @returns {requestHandler} Returns an object with `respond` method that controls how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. * * - respond – * `{function([status,] data[, headers, statusText]) * | function(function(method, url, data, headers)}` * – The respond method takes a set of static data to be returned or a function that can * return an array containing response status (number), response data (string), response - * headers (Object), and the text for the status (string). + * headers (Object), and the text for the status (string). The respond method returns the + * `requestHandler` object for possible overrides. */ $httpBackend.when = function(method, url, data, headers) { var definition = new MockHttpExpectation(method, url, data, headers), chain = { respond: function(status, data, headers, statusText) { + definition.passThrough = undefined; definition.response = createResponse(status, data, headers, statusText); + return chain; } }; if ($browser) { chain.passThrough = function() { + definition.response = undefined; definition.passThrough = true; + return chain; }; } @@ -1224,7 +1243,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1237,7 +1257,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1250,7 +1271,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1265,7 +1287,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * data string and returns true if the data is as expected. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1280,7 +1303,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * data string and returns true if the data is as expected. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1292,7 +1316,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ createShortMethods('when'); @@ -1312,23 +1337,28 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header * object and returns true if the headers match the current expectation. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. * * - respond – * `{function([status,] data[, headers, statusText]) * | function(function(method, url, data, headers)}` * – The respond method takes a set of static data to be returned or a function that can * return an array containing response status (number), response data (string), response - * headers (Object), and the text for the status (string). + * headers (Object), and the text for the status (string). The respond method returns the + * `requestHandler` object for possible overrides. */ $httpBackend.expect = function(method, url, data, headers) { - var expectation = new MockHttpExpectation(method, url, data, headers); + var expectation = new MockHttpExpectation(method, url, data, headers), + chain = { + respond: function (status, data, headers, statusText) { + expectation.response = createResponse(status, data, headers, statusText); + return chain; + } + }; + expectations.push(expectation); - return { - respond: function (status, data, headers, statusText) { - expectation.response = createResponse(status, data, headers, statusText); - } - }; + return chain; }; @@ -1342,7 +1372,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * and returns true if the url match the current definition. * @param {Object=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. See #expect for more info. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. See #expect for more info. */ /** @@ -1355,7 +1386,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * and returns true if the url match the current definition. * @param {Object=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1368,7 +1400,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * and returns true if the url match the current definition. * @param {Object=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1384,7 +1417,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * is in JSON format. * @param {Object=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1400,7 +1434,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * is in JSON format. * @param {Object=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1416,7 +1451,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * is in JSON format. * @param {Object=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ /** @@ -1428,7 +1464,8 @@ function createHttpBackendMock($rootScope, $delegate, $browser) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @returns {requestHandler} Returns an object with `respond` method that control how a matched - * request is handled. + * request is handled. You can save this object for later use and invoke `respond` again in + * order to change how a matched request is handled. */ createShortMethods('expect'); @@ -1838,7 +1875,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * @param {(Object|function(Object))=} headers HTTP headers or function that receives http header * object and returns true if the headers match the current definition. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. * * - respond – * `{function([status,] data[, headers, statusText]) @@ -1849,6 +1887,7 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * - passThrough – `{function()}` – Any request matching a backend definition with * `passThrough` handler will be passed through to the real backend (an XHR request will be made * to the server.) + * - Both methods return the `requestHandler` object for possible overrides. */ /** @@ -1862,7 +1901,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. */ /** @@ -1876,7 +1916,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. */ /** @@ -1890,7 +1931,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * and returns true if the url match the current definition. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. */ /** @@ -1905,7 +1947,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * @param {(string|RegExp)=} data HTTP request body. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. */ /** @@ -1920,7 +1963,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * @param {(string|RegExp)=} data HTTP request body. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. */ /** @@ -1935,7 +1979,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * @param {(string|RegExp)=} data HTTP request body. * @param {(Object|function(Object))=} headers HTTP headers. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. */ /** @@ -1948,7 +1993,8 @@ angular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) { * @param {string|RegExp|function(string)} url HTTP url or function that receives the url * and returns true if the url match the current definition. * @returns {requestHandler} Returns an object with `respond` and `passThrough` methods that - * control how a matched request is handled. + * control how a matched request is handled. You can save this object for later use and invoke + * `respond` or `passThrough` again in order to change how a matched request is handled. */ angular.mock.e2e = {}; angular.mock.e2e.$httpBackendDecorator = diff --git a/test/ngMock/angular-mocksSpec.js b/test/ngMock/angular-mocksSpec.js index 9934c37db6a2..fea30188b51f 100644 --- a/test/ngMock/angular-mocksSpec.js +++ b/test/ngMock/angular-mocksSpec.js @@ -1150,6 +1150,44 @@ describe('ngMock', function() { expect(callback.argsForCall[0]).toEqual([200, 'first', '', '']); expect(callback.argsForCall[1]).toEqual([200, 'second', '', '']); }); + + it('should be able to override response of expect definition', function() { + var definition = hb.expect('GET', '/url1'); + definition.respond('first'); + definition.respond('second'); + + hb('GET', '/url1', null, callback); + hb.flush(); + expect(callback).toHaveBeenCalledOnceWith(200, 'second', '', ''); + }); + + it('should be able to override response of when definition', function() { + var definition = hb.when('GET', '/url1'); + definition.respond('first'); + definition.respond('second'); + + hb('GET', '/url1', null, callback); + hb.flush(); + expect(callback).toHaveBeenCalledOnceWith(200, 'second', '', ''); + }); + + it('should be able to override response of expect definition with chaining', function() { + var definition = hb.expect('GET', '/url1').respond('first'); + definition.respond('second'); + + hb('GET', '/url1', null, callback); + hb.flush(); + expect(callback).toHaveBeenCalledOnceWith(200, 'second', '', ''); + }); + + it('should be able to override response of when definition with chaining', function() { + var definition = hb.when('GET', '/url1').respond('first'); + definition.respond('second'); + + hb('GET', '/url1', null, callback); + hb.flush(); + expect(callback).toHaveBeenCalledOnceWith(200, 'second', '', ''); + }); }); @@ -1552,6 +1590,25 @@ describe('ngMockE2E', function() { expect(realHttpBackend).toHaveBeenCalledOnceWith( 'GET', '/passThrough/23', null, callback, {}, null, true); }); + + it('should be able to override a respond definition with passThrough', function() { + var definition = hb.when('GET', /\/passThrough\/.*/).respond('override me'); + definition.passThrough(); + hb('GET', '/passThrough/23', null, callback, {}, null, true); + + expect(realHttpBackend).toHaveBeenCalledOnceWith( + 'GET', '/passThrough/23', null, callback, {}, null, true); + }); + + it('should be able to override a respond definition with passThrough', inject(function($browser) { + var definition = hb.when('GET', /\/passThrough\/.*/).passThrough(); + definition.respond('passThrough override'); + hb('GET', '/passThrough/23', null, callback, {}, null, true); + $browser.defer.flush(); + + expect(realHttpBackend).not.toHaveBeenCalled(); + expect(callback).toHaveBeenCalledOnceWith(200, 'passThrough override', '', ''); + })); });