-
Notifications
You must be signed in to change notification settings - Fork 27.4k
Add request and requestError interception in ngResource #13273
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
describe("resource", function() { | ||
|
||
describe("basic usage", function() { | ||
var $resource, CreditCard, callback, $httpBackend, resourceProvider; | ||
var $resource, CreditCard, callback, $httpBackend, resourceProvider, $q; | ||
|
||
beforeEach(module('ngResource')); | ||
|
||
|
@@ -14,6 +14,7 @@ describe("basic usage", function() { | |
beforeEach(inject(function($injector) { | ||
$httpBackend = $injector.get('$httpBackend'); | ||
$resource = $injector.get('$resource'); | ||
$q = $injector.get('$q'); | ||
CreditCard = $resource('/CreditCard/:id:verb', {id:'@id.key'}, { | ||
charge:{ | ||
method:'post', | ||
|
@@ -978,6 +979,188 @@ describe("basic usage", function() { | |
}); | ||
}); | ||
|
||
|
||
describe('requestInterceptor', function() { | ||
var rejectReason = {'lol':'cat'}; | ||
var successSpy, failureSpy; | ||
|
||
beforeEach(function() { | ||
successSpy = jasmine.createSpy('successSpy'); | ||
failureSpy = jasmine.createSpy('failureSpy'); | ||
}); | ||
|
||
it('should allow per action request interceptor that gets full configuration', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function(httpConfig) { | ||
callback(httpConfig); | ||
return httpConfig; | ||
} | ||
} | ||
} | ||
}); | ||
|
||
$httpBackend.expect('GET', '/CreditCard').respond([{id: 1}]); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
|
||
$httpBackend.flush(); | ||
expect(callback).toHaveBeenCalledOnce(); | ||
expect(successSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).not.toHaveBeenCalled(); | ||
|
||
expect(callback).toHaveBeenCalledWith({ | ||
'method': 'get', | ||
'url': '/CreditCard' | ||
}); | ||
}); | ||
|
||
it('should call $http with the value returned from requestInterceptor', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function(httpConfig) { | ||
httpConfig.url = '/DebitCard'; | ||
return httpConfig; | ||
} | ||
} | ||
} | ||
}); | ||
|
||
$httpBackend.expect('GET', '/DebitCard').respond([{id: 1}]); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
|
||
$httpBackend.flush(); | ||
expect(successSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).not.toHaveBeenCalled(); | ||
}); | ||
|
||
it('should abort the operation if the requestInterceptor rejects the operation', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function() { | ||
return $q.reject(rejectReason); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
|
||
// Make sure all promises resolve. | ||
$rootScope.$apply(); | ||
|
||
// Ensure the resource promise was rejected | ||
expect(resource.$resolved).toBeTruthy(); | ||
expect(successSpy).not.toHaveBeenCalled(); | ||
expect(failureSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).toHaveBeenCalledWith(rejectReason); | ||
|
||
// Ensure that no requests were made. | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
|
||
it('should call requestErrorInterceptor if requestInterceptor rejects the operation', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function() { | ||
return $q.reject(rejectReason); | ||
}, | ||
requestError: function(rejection) { | ||
callback(rejection); | ||
return $q.reject(rejection); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
$rootScope.$digest(); | ||
|
||
expect(callback).toHaveBeenCalledOnce(); | ||
expect(callback).toHaveBeenCalledWith(rejectReason); | ||
expect(successSpy).not.toHaveBeenCalled(); | ||
expect(failureSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).toHaveBeenCalledWith(rejectReason); | ||
|
||
// Ensure that no requests were made. | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
|
||
it('should abort the operation if a requestErrorInterceptor rejects the operation', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function() { | ||
return $q.reject(rejectReason); | ||
}, | ||
requestError: function(rejection) { | ||
return $q.reject(rejection); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
$rootScope.$apply(); | ||
|
||
expect(resource.$resolved).toBeTruthy(); | ||
expect(successSpy).not.toHaveBeenCalled(); | ||
expect(failureSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).toHaveBeenCalledWith(rejectReason); | ||
|
||
// Ensure that no requests were made. | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
|
||
it('should continue the operation if a requestErrorInterceptor rescues it', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function(httpConfig) { | ||
return $q.reject(httpConfig); | ||
}, | ||
requestError: function(httpConfig) { | ||
return $q.resolve(httpConfig); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
$httpBackend.expect('GET', '/CreditCard').respond([{id: 1}]); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
$httpBackend.flush(); | ||
|
||
expect(resource.$resolved).toBeTruthy(); | ||
expect(successSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).not.toHaveBeenCalled(); | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should verify that |
||
}); | ||
|
||
it('should allow per action response interceptor that gets full response', function() { | ||
CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
|
@@ -1318,7 +1501,7 @@ describe("basic usage", function() { | |
}); | ||
|
||
describe('errors', function() { | ||
var $httpBackend, $resource, $q; | ||
var $httpBackend, $resource, $q, $rootScope; | ||
|
||
beforeEach(module(function($exceptionHandlerProvider) { | ||
$exceptionHandlerProvider.mode('log'); | ||
|
@@ -1330,6 +1513,7 @@ describe('errors', function() { | |
$httpBackend = $injector.get('$httpBackend'); | ||
$resource = $injector.get('$resource'); | ||
$q = $injector.get('$q'); | ||
$rootScope = $injector.get('$rootScope'); | ||
})); | ||
|
||
|
||
|
@@ -1366,6 +1550,78 @@ describe('errors', function() { | |
/^\[\$resource:badcfg\] Error in resource configuration for action `get`\. Expected response to contain an object but got an array \(Request: GET \/Customer\/123\)/ | ||
); | ||
}); | ||
|
||
describe('requestInterceptor', function() { | ||
var rejectReason = {'lol':'cat'}; | ||
var successSpy, failureSpy, callback; | ||
|
||
beforeEach(function() { | ||
successSpy = jasmine.createSpy('successSpy'); | ||
failureSpy = jasmine.createSpy('failureSpy'); | ||
callback = jasmine.createSpy(); | ||
}); | ||
|
||
it('should call requestErrorInterceptor if requestInterceptor throws an error', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function() { | ||
throw rejectReason; | ||
}, | ||
requestError: function(rejection) { | ||
callback(rejection); | ||
return $q.reject(rejection); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
$rootScope.$apply(); | ||
|
||
expect(callback).toHaveBeenCalledOnce(); | ||
expect(callback).toHaveBeenCalledWith(rejectReason); | ||
expect(successSpy).not.toHaveBeenCalled(); | ||
expect(failureSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).toHaveBeenCalledWith(rejectReason); | ||
|
||
// Ensure that no requests were made. | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
|
||
it('should abort the operation if a requestErrorInterceptor throws an exception', function() { | ||
var CreditCard = $resource('/CreditCard', {}, { | ||
query: { | ||
method: 'get', | ||
isArray: true, | ||
interceptor: { | ||
request: function() { | ||
return $q.reject(); | ||
}, | ||
requestError: function() { | ||
throw rejectReason; | ||
} | ||
} | ||
} | ||
}); | ||
|
||
var resource = CreditCard.query(); | ||
resource.$promise.then(successSpy, failureSpy); | ||
$rootScope.$apply(); | ||
|
||
expect(resource.$resolved).toBeTruthy(); | ||
expect(successSpy).not.toHaveBeenCalled(); | ||
expect(failureSpy).toHaveBeenCalledOnce(); | ||
expect(failureSpy).toHaveBeenCalledWith(rejectReason); | ||
|
||
// Ensure that no requests were made. | ||
$httpBackend.verifyNoOutstandingRequest(); | ||
}); | ||
}); | ||
|
||
}); | ||
|
||
describe('cancelling requests', function() { | ||
|
@@ -1430,7 +1686,7 @@ describe('cancelling requests', function() { | |
); | ||
|
||
it('should use `cancellable` value if passed a non-numeric `timeout` in an action', | ||
inject(function($log, $q) { | ||
inject(function($log, $q, $rootScope) { | ||
spyOn($log, 'debug'); | ||
$httpBackend.whenGET('/CreditCard').respond({}); | ||
|
||
|
@@ -1443,6 +1699,7 @@ describe('cancelling requests', function() { | |
}); | ||
|
||
var creditCard = CreditCard.get(); | ||
$rootScope.$apply(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really needed ? That might indicate a BC 😞 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. I believe it's because we're putting a promise between the GET request and the invocation to $http, which has to resolve first. We can wrap creating the requestInterceptor promise into a conditional though, which would remove the need for this line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How come this is the only test that needs this ? 😕 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...perhaps a sign that ngResource needs more coverage ;) |
||
expect(creditCard.$cancelRequest).toBeDefined(); | ||
expect(httpSpy.calls.argsFor(0)[0].timeout).toEqual(jasmine.any($q)); | ||
expect(httpSpy.calls.argsFor(0)[0].timeout.then).toBeDefined(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the callback defined somewhere?