Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Add tests to) document how multiple inceptors work #3564

Merged
merged 19 commits into from
Dec 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
7dc8984
Add a group for the multiple-interceptors tests.
wolframkriesing Jan 16, 2021
8ba3198
Fix indentation.
wolframkriesing Jan 16, 2021
6bd87c1
Make explicit that the test only tests the interception of the fulfil…
wolframkriesing Jan 16, 2021
5f31559
Indent.
wolframkriesing Jan 16, 2021
37c061a
Make the test just test a tiny bit, as described.
wolframkriesing Jan 17, 2021
287296f
Add a test that explicitly shows that the order of interceptors is as…
wolframkriesing Jan 17, 2021
abdd29d
Pull out reusable code, to make the tests more explicitly stating the…
wolframkriesing Jan 17, 2021
3c9388d
Write a test showing that the responses are not merged or anything,
wolframkriesing Jan 17, 2021
f5910e9
Make visible that the interceptors are a chain, one receives its pred…
wolframkriesing Jan 17, 2021
4649677
Test what happens when the interceptor throws.
wolframkriesing Jan 17, 2021
2299a9d
Refactor, add another group of tests and pull helper function there.
wolframkriesing Jan 17, 2021
9d1b7ee
Documenting that the following reject-interceptor gets called.
wolframkriesing Jan 17, 2021
b492b3d
Documenting how the interceptor chain handles caught rejections.
wolframkriesing Jan 17, 2021
56e877f
Document "multiple interceptors".
wolframkriesing Jan 17, 2021
4983c05
Transfer the better readable descriptions as I changed them in the RE…
wolframkriesing Jan 17, 2021
34ff58d
Be a bit more explicit, it was not clear when reading, imho.
wolframkriesing Jan 17, 2021
cc1bfdd
Add new lines to be kinda consistent with the rest of the file.
wolframkriesing Jan 17, 2021
8290f21
Merge branch 'master' into document-multiple-inceptors
wolframkriesing Feb 1, 2021
d188ea5
Merge branch 'master' into document-multiple-inceptors
jasonsaayman Dec 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Promise based HTTP client for the browser and node.js
- [Custom instance defaults](#custom-instance-defaults)
- [Config order of precedence](#config-order-of-precedence)
- [Interceptors](#interceptors)
- [Multiple Interceptors](#multiple-interceptors)
- [Handling Errors](#handling-errors)
- [Cancellation](#cancellation)
- [Using application/x-www-form-urlencoded format](#using-applicationx-www-form-urlencoded-format)
Expand Down Expand Up @@ -645,6 +646,21 @@ axios.interceptors.request.use(function (config) {
}, null, { runWhen: onGetCall });
```

### Multiple Interceptors

Given you add multiple response interceptors
and when the response was fulfilled
- then each interceptor is executed
- then they are executed in the order they were added
- then only the last interceptor's result is returned
- then every interceptor receives the result of it's predecessor
- and when the fulfillment-interceptor throws
- then the following fulfillment-interceptor is not called
- then the following rejection-interceptor is called
- once caught, another following fulfill-interceptor is called again (just like in a promise chain).

Read [the interceptor tests](./test/specs/interceptors.spec.js) for seeing all this in code.

## Handling Errors

```js
Expand Down
157 changes: 132 additions & 25 deletions test/specs/interceptors.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,36 +337,143 @@ describe('interceptors', function () {
});
});

it('should add multiple response interceptors', function (done) {
var response;
describe('given you add multiple response interceptors', function () {

describe('and when the response was fulfilled', function () {

function fireRequestAndExpect(expectation) {
var response;
axios('/foo').then(function(data) {
response = data;
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK'
});

setTimeout(function() {
expectation(response)
}, 100);
});
}

it('then each interceptor is executed', function (done) {
var interceptor1 = jasmine.createSpy('interceptor1');
var interceptor2 = jasmine.createSpy('interceptor2');
axios.interceptors.response.use(interceptor1);
axios.interceptors.response.use(interceptor2);

fireRequestAndExpect(function () {
expect(interceptor1).toHaveBeenCalled();
expect(interceptor2).toHaveBeenCalled();
done();
});
});

axios.interceptors.response.use(function (data) {
data.data = data.data + '1';
return data;
});
axios.interceptors.response.use(function (data) {
data.data = data.data + '2';
return data;
});
axios.interceptors.response.use(function (data) {
data.data = data.data + '3';
return data;
});
it('then they are executed in the order they were added', function (done) {
var interceptor1 = jasmine.createSpy('interceptor1');
var interceptor2 = jasmine.createSpy('interceptor2');
axios.interceptors.response.use(interceptor1);
axios.interceptors.response.use(interceptor2);

axios('/foo').then(function (data) {
response = data;
});
fireRequestAndExpect(function () {
expect(interceptor1).toHaveBeenCalledBefore(interceptor2);
done();
});
});

getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK'
it('then only the last interceptor\'s result is returned', function (done) {
axios.interceptors.response.use(function() {
return 'response 1';
});
axios.interceptors.response.use(function() {
return 'response 2';
});

fireRequestAndExpect(function (response) {
expect(response).toBe('response 2');
done();
});
});

setTimeout(function () {
expect(response.data).toBe('OK123');
done();
}, 100);
it('then every interceptor receives the result of it\'s predecessor', function (done) {
axios.interceptors.response.use(function() {
return 'response 1';
});
axios.interceptors.response.use(function(response) {
return [response, 'response 2'];
});

fireRequestAndExpect(function (response) {
expect(response).toEqual(['response 1', 'response 2']);
done();
});
});

describe('and when the fulfillment-interceptor throws', function () {

function fireRequestCatchAndExpect(expectation) {
axios('/foo').catch(function(data) {
// dont handle result
});
getAjaxRequest().then(function (request) {
request.respondWith({
status: 200,
responseText: 'OK'
});

setTimeout(function() {
expectation()
}, 100);
});
}

it('then the following fulfillment-interceptor is not called', function (done) {
axios.interceptors.response.use(function() {
throw Error('throwing interceptor');
});
var interceptor2 = jasmine.createSpy('interceptor2');
axios.interceptors.response.use(interceptor2);

fireRequestCatchAndExpect(function () {
expect(interceptor2).not.toHaveBeenCalled();
done();
});
});

it('then the following rejection-interceptor is called', function (done) {
axios.interceptors.response.use(function() {
throw Error('throwing interceptor');
});
var unusedFulfillInterceptor = function() {};
var rejectIntercept = jasmine.createSpy('rejectIntercept');
axios.interceptors.response.use(unusedFulfillInterceptor, rejectIntercept);

fireRequestCatchAndExpect(function () {
expect(rejectIntercept).toHaveBeenCalled();
done();
});
});

it('once caught, another following fulfill-interceptor is called again (just like in a promise chain)', function (done) {
axios.interceptors.response.use(function() {
throw Error('throwing interceptor');
});

var unusedFulfillInterceptor = function() {};
var catchingThrowingInterceptor = function() {};
axios.interceptors.response.use(unusedFulfillInterceptor, catchingThrowingInterceptor);

var interceptor3 = jasmine.createSpy('interceptor3');
axios.interceptors.response.use(interceptor3);

fireRequestCatchAndExpect(function () {
expect(interceptor3).toHaveBeenCalled();
done();
});
});
});
});
});

Expand Down