test/unit/angularjs/rails/interceptorsSpec.js in angularjs-rails-resource-1.0.0.pre.3 vs test/unit/angularjs/rails/interceptorsSpec.js in angularjs-rails-resource-1.0.0.pre.4

- old
+ new

@@ -1,57 +1,131 @@ -describe('transformers', function () { +describe('interceptors', function () { 'use strict'; - var $httpBackend, $rootScope, factory, Test, testInterceptor, testAfterInterceptor, + var $q, $http, $httpBackend, $rootScope, factory, Test, testInterceptor, testAfterInterceptor, testRequestTransformer, + deprecatedTestInterceptor, deprecatedTestAfterInterceptor, config = { url: '/test', name: 'test' }; beforeEach(function () { module('rails'); - angular.module('rails').factory('railsTestInterceptor', function () { + angular.module('rails').factory('deprecatedRailsTestInterceptor', function () { return function (promise) { return promise.then(function (response) { response.data.interceptorAdded = 'x'; return response; }); } }); - angular.module('rails').factory('railsTestAfterInterceptor', function () { + angular.module('rails').factory('deprecatedRailsTestAfterInterceptor', function () { return function (promise) { return promise.then(function (resource) { resource.interceptorAdded = 'x'; return resource; }); } }); + + angular.module('rails').factory('railsTestInterceptor', function () { + return { + 'response': function (response) { + response.data.interceptorAdded = 'x'; + return response; + }, + 'responseError': function (rejection) { + rejection.interceptorCalled = true; + return $q.reject(rejection); + } + }; + }); + + angular.module('rails').factory('asyncInterceptor', function () { + return { + 'response': function (response) { + return $http.get('/async').then(function (asyncResponse) { + response.data.async = asyncResponse.data; + return response; + }); + } + }; + }); + + angular.module('rails').factory('saveIndicatorInterceptor', function () { + return { + 'beforeRequest': function (httpConfig, resourceConstructor, context) { + if (context && (httpConfig.method === 'put' || httpConfig.method === 'post')) { + context.$savePending = true; + } + return httpConfig; + }, + 'afterResponse': function (result, resourceConstructor, context) { + if (context) { + context.$savePending = false; + } + return result; + }, + 'afterResponseError': function (rejection, resourceConstructor, context) { + if (context) { + context.$savePending = false; + } + return $q.reject(rejection); + } + }; + }); + + angular.module('rails').factory('railsTestAfterInterceptor', function () { + return { + 'afterResponse': function (response) { + response.interceptorAdded = 'x'; + return response; + } + }; + }); + + angular.module('rails').factory('railsTestRequestTransformer', function () { + return { + 'beforeRequest': function (httpConfig, resource) { + httpConfig.data.transformer_called = true; + return httpConfig; + } + }; + }); + }); - beforeEach(inject(function (_$httpBackend_, _$rootScope_, railsResourceFactory, railsTestInterceptor, railsTestAfterInterceptor) { + beforeEach(inject(function (_$q_, _$http_, _$httpBackend_, _$rootScope_, railsResourceFactory, + railsTestInterceptor, railsTestAfterInterceptor, railsTestRequestTransformer, + deprecatedRailsTestInterceptor, deprecatedRailsTestAfterInterceptor) { + $q = _$q_; + $http = _$http_; $httpBackend = _$httpBackend_; $rootScope = _$rootScope_; factory = railsResourceFactory; Test = railsResourceFactory(config); testInterceptor = railsTestInterceptor; testAfterInterceptor = railsTestAfterInterceptor; + deprecatedTestInterceptor = deprecatedRailsTestInterceptor; + deprecatedTestAfterInterceptor = deprecatedRailsTestAfterInterceptor; + testRequestTransformer = railsTestRequestTransformer; })); afterEach(function () { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); - describe('before response', function () { + describe('deprecated before response', function () { it('should be able to reference interceptor using name', function () { var promise, result, Resource, testConfig = {}; $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); angular.copy(config, testConfig); - testConfig.responseInterceptors = ['railsTestInterceptor']; + testConfig.responseInterceptors = ['deprecatedRailsTestInterceptor']; Resource = factory(testConfig); expect(promise = Resource.get(123)).toBeDefined(); promise.then(function (response) { @@ -69,11 +143,11 @@ $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); angular.copy(config, testConfig); - testConfig.responseInterceptors = [testInterceptor]; + testConfig.responseInterceptors = [deprecatedTestInterceptor]; Resource = factory(testConfig); expect(promise = Resource.get(123)).toBeDefined(); promise.then(function (response) { @@ -136,19 +210,19 @@ expect(interceptorCalled).toBeTruthy(); }); }); - describe('after response', function () { + describe('response', function () { it('should be able to reference interceptor using name', function () { var promise, result, Resource, testConfig = {}; $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); angular.copy(config, testConfig); - testConfig.afterResponseInterceptors = ['railsTestAfterInterceptor']; Resource = factory(testConfig); + Resource.addInterceptor('railsTestInterceptor'); expect(promise = Resource.get(123)).toBeDefined(); promise.then(function (response) { result = response; @@ -163,27 +237,148 @@ it('should be able to add interceptor using reference', function () { var promise, result, Resource, testConfig = {}; $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + angular.copy(config, testConfig); + Resource = factory(testConfig); + Resource.addInterceptor(testInterceptor); + expect(promise = Resource.get(123)).toBeDefined(); + + promise.then(function (response) { + result = response; + }); + + $httpBackend.flush(); + + expect(result).toBeInstanceOf(Resource); + expect(result).toEqualData({interceptorAdded: 'x', id: 123, abcDef: 'xyz'}); + }); + + it('should execute error interceptors on HTTP error', function () { + var promise, result, rejection, Resource, testConfig = {}; + + $httpBackend.expectGET('/test/123').respond(500); + angular.copy(config, testConfig); - testConfig.afterResponseInterceptors = [testAfterInterceptor]; Resource = factory(testConfig); + Resource.addInterceptor(testInterceptor); expect(promise = Resource.get(123)).toBeDefined(); promise.then(function (response) { result = response; + }, function (error) { + rejection = error; }); $httpBackend.flush(); + expect(result).not.toBeDefined(); + expect(rejection).toBeDefined(); + expect(rejection.interceptorCalled).toBeTruthy(); + }); + + it('should be able to add interceptor using interceptResponse', function () { + var promise, result, Resource, interceptorCalled = false; + + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + + Resource = factory(config); + + Resource.interceptResponse(function (response, constructor, context) { + expect(response.data).toEqualData({id: 123, abcDef: 'xyz'}); + expect(constructor).toEqual(Resource); + expect(context).toBeUndefined(); + interceptorCalled = true; + return response; + }); + + expect(promise = Resource.get(123)).toBeDefined(); + + promise.then(function (response) { + result = response; + }); + + $httpBackend.flush(); + expect(result).toBeInstanceOf(Resource); + expect(result).toEqualData({id: 123, abcDef: 'xyz'}); + expect(interceptorCalled).toBeTruthy(); + }); + + it('should set context to resource instance', function () { + var instance, Resource, interceptorCalled = false; + + $httpBackend.expectPOST('/test').respond(200, {id: 123, abc_def: 'xyz'}); + + Resource = factory(config); + + instance = new Resource({abcDef: 'xyz'}); + + Resource.interceptResponse(function (response, constructor, context) { + expect(response.data).toEqualData({id: 123, abcDef: 'xyz'}); + expect(constructor).toEqual(Resource); + expect(context).toBeInstanceOf(Resource); + expect(context).toEqualData(instance); + interceptorCalled = true; + return response; + }); + + instance.save(); + + $httpBackend.flush(); + + expect(interceptorCalled).toBeTruthy(); + }); + }); + + describe('deprecated after response', function () { + it('should be able to reference interceptor using name', function () { + var promise, result, Resource, testConfig = {}; + + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + + angular.copy(config, testConfig); + testConfig.afterResponseInterceptors = ['deprecatedRailsTestAfterInterceptor']; + Resource = factory(testConfig); + + expect(promise = Resource.get(123)).toBeDefined(); + + promise.then(function (response) { + result = response; + }); + + $httpBackend.flush(); + + expect(result).toBeInstanceOf(Resource); expect(result).toEqualData({interceptorAdded: 'x', id: 123, abcDef: 'xyz'}); }); + it('should be able to add interceptor using reference', function () { + var promise, result, Resource, testConfig = {}; + + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + + + angular.copy(config, testConfig); + testConfig.afterResponseInterceptors = [deprecatedTestAfterInterceptor]; + Resource = factory(testConfig); + + expect(promise = Resource.get(123)).toBeDefined(); + + promise.then(function (response) { + result = response; + }); + + $httpBackend.flush(); + + expect(result).toBeInstanceOf(Resource); + expect(result).toEqualData({interceptorAdded: 'x', id: 123, abcDef: 'xyz'}); + }); + it('should be able to add interceptor using afterResponse', function () { var promise, result, Resource, interceptorCalled = false; $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); @@ -229,7 +424,214 @@ expect(interceptorCalled).toBeTruthy(); }); }); + describe('after response', function () { + it('should be able to reference interceptor using name', function () { + var promise, result, Resource, testConfig = {}; + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + + angular.copy(config, testConfig); + testConfig.interceptors = ['railsTestAfterInterceptor']; + Resource = factory(testConfig); + + expect(promise = Resource.get(123)).toBeDefined(); + + promise.then(function (response) { + result = response; + }); + + $httpBackend.flush(); + + expect(result).toBeInstanceOf(Resource); + expect(result).toEqualData({interceptorAdded: 'x', id: 123, abcDef: 'xyz'}); + }); + + it('should be able to add interceptor using reference', function () { + var promise, result, Resource, testConfig = {}; + + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + + angular.copy(config, testConfig); + testConfig.interceptors = [testAfterInterceptor]; + Resource = factory(testConfig); + + expect(promise = Resource.get(123)).toBeDefined(); + + promise.then(function (response) { + result = response; + }); + + $httpBackend.flush(); + + expect(result).toBeInstanceOf(Resource); + expect(result).toEqualData({interceptorAdded: 'x', id: 123, abcDef: 'xyz'}); + }); + + it('should be able to add interceptor using afterResponse', function () { + var promise, result, Resource, interceptorCalled = false; + + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + + Resource = factory(config); + + Resource.interceptAfterResponse(function (resource, constructor, context) { + expect(resource).toEqualData({id: 123, abcDef: 'xyz'}); + expect(constructor).toEqual(Resource); + interceptorCalled = true; + }); + + expect(promise = Resource.get(123)).toBeDefined(); + + promise.then(function (response) { + result = response; + }); + + $httpBackend.flush(); + + expect(result).toBeInstanceOf(Resource); + expect(result).toEqualData({id: 123, abcDef: 'xyz'}); + expect(interceptorCalled).toBeTruthy(); + }); + + it('should set context to resource instance', function () { + var instance, Resource, interceptorCalled = false; + + $httpBackend.expectPOST('/test').respond(200, {id: 123, abc_def: 'xyz'}); + + Resource = factory(config); + + instance = new Resource({abcDef: 'xyz'}); + + Resource.interceptAfterResponse(function (resource, constructor, context) { + expect(resource).toEqualData({id: 123, abcDef: 'xyz'}); + expect(constructor).toEqual(Resource); + interceptorCalled = true; + }); + + instance.save(); + + $httpBackend.flush(); + + expect(interceptorCalled).toBeTruthy(); + }); + }); + + describe('before request wrapping', function () { + it('should be able to add transformer using name', function() { + var Resource, testConfig = {}; + + $httpBackend.expectPOST('/test/123', {test: {id: 123, transformer_called: true}}).respond(200, {id: 123, abc_def: 'xyz'}); + + angular.copy(config, testConfig); + testConfig.interceptors = ['railsTestRequestTransformer']; + Resource = factory(testConfig); + new Resource({id: 123}).create(); + + $httpBackend.flush(); + }); + + it('should be able to add transformer using reference', function() { + var Resource, testConfig = {}; + + $httpBackend.expectPOST('/test/123', {test: {id: 123, transformer_called: true}}).respond(200, {id: 123, abc_def: 'xyz'}); + + angular.copy(config, testConfig); + testConfig.interceptors = [testRequestTransformer]; + Resource = factory(testConfig); + new Resource({id: 123}).create(); + + $httpBackend.flush(); + }); + + it('should call transformer function with beforeRequest', function () { + var Resource, transformerCalled = false; + + $httpBackend.expectPOST('/test/123', {test: {id: 123}}).respond(200, {id: 123, abc_def: 'xyz'}); + + Resource = factory(config); + Resource.interceptBeforeRequest(function (httpConfig, constructor) { + expect(httpConfig.data).toEqualData({id: 123}); + expect(constructor).toEqual(Resource); + transformerCalled = true; + return httpConfig; + }); + + new Resource({id: 123}).create(); + + $httpBackend.flush(); + expect(transformerCalled).toBeTruthy(); + }); + + it('should be able to return new data from beforeRequest function', function () { + var Resource, transformerCalled = false; + + $httpBackend.expectPOST('/test/123', {test: {id: 1}}).respond(200, {id: 123, abc_def: 'xyz'}); + + Resource = factory(config); + Resource.interceptBeforeRequest(function (httpConfig, resource) { + expect(httpConfig.data).toEqualData({id: 123}); + expect(resource).toEqual(Resource); + transformerCalled = true; + httpConfig.data = {id: 1}; + return httpConfig; + }); + + new Resource({id: 123}).create(); + + $httpBackend.flush(); + expect(transformerCalled).toBeTruthy(); + }); + }); + + describe('async interceptor', function () { + it('should execute both requests', function () { + var testResult; + + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + $httpBackend.expectGET('/async').respond(200, {id: 1, value: true}); + + Test.addInterceptor('asyncInterceptor'); + Test.get(123).then(function (result) { + testResult = result; + }); + + $httpBackend.flush(); + expect(testResult).toEqualData({id: 123, abcDef: 'xyz', async: {id: 1, value: true}}); + }); + + it('should fail if async operation fails', function () { + var testResult, testError; + + $httpBackend.expectGET('/test/123').respond(200, {id: 123, abc_def: 'xyz'}); + $httpBackend.expectGET('/async').respond(500); + + Test.addInterceptor('asyncInterceptor'); + Test.get(123).then(function (result) { + testResult = result; + }, function (error) { + testError = error; + }); + + $httpBackend.flush(); + expect(testResult).not.toBeDefined(); + expect(testError).toBeDefined(); + }); + }); + + describe('multi-phase interceptor', function () { + it('should execute multiple success phases', function () { + var test = new Test({abcDef: 'xyz'}); + + Test.addInterceptor('saveIndicatorInterceptor'); + $httpBackend.expectPOST('/test', {test: {abc_def: 'xyz'}}).respond(200, {id: 123, abc_def: 'xyz'}); + $rootScope.$apply(function () { + test.save(); + }); + expect(test.$savePending).toEqual(true); + $httpBackend.flush(); + expect(test.$savePending).toEqual(false); + }); + }); });