mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
issue#2609 | Sasha | predictable axios requests (#2702)
* issue#2609 | Sasha | predictable axios requests
- axios requests are not delayed by pre-emptive promise creation by default
- add options to interceptors api ("synchronous" and "runWhen")
- add documentation and unit tests
* issue#2609 | Sasha | pull request feedback changes
* issue#2609 | Sasha | additional feedback changes
* issue#2609 | Sasha | put back try/catch
* issue#2609 | Sasha | add 2 adapter unit tests
- remove check for requestCancelled
Co-authored-by: ak71845 <alexandre.korotkov@kroger.com>
Co-authored-by: Xianming Zhong <chinesedfan@qq.com>
Co-authored-by: Jay <jasonsaayman@gmail.com>
This commit is contained in:
@@ -1,19 +1,98 @@
|
||||
var axios = require('../../index');
|
||||
|
||||
describe('adapter', function () {
|
||||
it('should support custom adapter', function (done) {
|
||||
var called = false;
|
||||
beforeEach(function () {
|
||||
jasmine.Ajax.install();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
jasmine.Ajax.uninstall();
|
||||
});
|
||||
|
||||
it('should support custom adapter', function (done) {
|
||||
axios('/foo', {
|
||||
adapter: function (config) {
|
||||
called = true;
|
||||
adapter: function barAdapter(config) {
|
||||
return new Promise(function dispatchXhrRequest(resolve) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', '/bar');
|
||||
|
||||
request.onreadystatechange = function () {
|
||||
resolve({
|
||||
config: config,
|
||||
request: request
|
||||
});
|
||||
};
|
||||
|
||||
request.send(null);
|
||||
});
|
||||
}
|
||||
}).catch(console.log);
|
||||
|
||||
getAjaxRequest().then(function(request) {
|
||||
expect(request.url).toBe('/bar');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should execute adapter code synchronously', function (done) {
|
||||
var asyncFlag = false;
|
||||
axios('/foo', {
|
||||
adapter: function barAdapter(config) {
|
||||
return new Promise(function dispatchXhrRequest(resolve) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', '/bar');
|
||||
|
||||
request.onreadystatechange = function () {
|
||||
resolve({
|
||||
config: config,
|
||||
request: request
|
||||
});
|
||||
};
|
||||
|
||||
expect(asyncFlag).toBe(false);
|
||||
request.send(null);
|
||||
});
|
||||
}
|
||||
}).catch(console.log);
|
||||
|
||||
asyncFlag = true;
|
||||
|
||||
getAjaxRequest().then(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should execute adapter code asynchronously when interceptor is present', function (done) {
|
||||
var asyncFlag = false;
|
||||
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.async = 'async it!';
|
||||
return config;
|
||||
});
|
||||
|
||||
setTimeout(function () {
|
||||
expect(called).toBe(true);
|
||||
axios('/foo', {
|
||||
adapter: function barAdapter(config) {
|
||||
return new Promise(function dispatchXhrRequest(resolve) {
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('GET', '/bar');
|
||||
|
||||
request.onreadystatechange = function () {
|
||||
resolve({
|
||||
config: config,
|
||||
request: request
|
||||
});
|
||||
};
|
||||
|
||||
expect(asyncFlag).toBe(true);
|
||||
request.send(null);
|
||||
});
|
||||
}
|
||||
}).catch(console.log);
|
||||
|
||||
asyncFlag = true;
|
||||
|
||||
getAjaxRequest().then(function() {
|
||||
done();
|
||||
}, 100);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -9,25 +9,164 @@ describe('interceptors', function () {
|
||||
axios.interceptors.response.handlers = [];
|
||||
});
|
||||
|
||||
it('should add a request interceptor', function (done) {
|
||||
it('should add a request interceptor (asynchronous by default)', function (done) {
|
||||
var asyncFlag = false;
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'added by interceptor';
|
||||
expect(asyncFlag).toBe(true);
|
||||
return config;
|
||||
});
|
||||
|
||||
axios('/foo');
|
||||
asyncFlag = true;
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
request.respondWith({
|
||||
status: 200,
|
||||
responseText: 'OK'
|
||||
});
|
||||
|
||||
expect(request.requestHeaders.test).toBe('added by interceptor');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a request interceptor (explicitly flagged as asynchronous)', function (done) {
|
||||
var asyncFlag = false;
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'added by interceptor';
|
||||
expect(asyncFlag).toBe(true);
|
||||
return config;
|
||||
}, null, { synchronous: false });
|
||||
|
||||
axios('/foo');
|
||||
asyncFlag = true;
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
expect(request.requestHeaders.test).toBe('added by interceptor');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a request interceptor that is executed synchronously when flag is provided', function (done) {
|
||||
var asyncFlag = false;
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'added by synchronous interceptor';
|
||||
expect(asyncFlag).toBe(false);
|
||||
return config;
|
||||
}, null, { synchronous: true });
|
||||
|
||||
axios('/foo');
|
||||
asyncFlag = true;
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
expect(request.requestHeaders.test).toBe('added by synchronous interceptor');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should execute asynchronously when not all interceptors are explicitly flagged as synchronous', function (done) {
|
||||
var asyncFlag = false;
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.foo = 'uh oh, async';
|
||||
expect(asyncFlag).toBe(true);
|
||||
return config;
|
||||
});
|
||||
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'added by synchronous interceptor';
|
||||
expect(asyncFlag).toBe(true);
|
||||
return config;
|
||||
}, null, { synchronous: true });
|
||||
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'added by the async interceptor';
|
||||
expect(asyncFlag).toBe(true);
|
||||
return config;
|
||||
});
|
||||
|
||||
axios('/foo');
|
||||
asyncFlag = true;
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
expect(request.requestHeaders.foo).toBe('uh oh, async');
|
||||
/* request interceptors have a reversed execution order */
|
||||
expect(request.requestHeaders.test).toBe('added by synchronous interceptor');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('runs the interceptor if runWhen function is provided and resolves to true', function (done) {
|
||||
function onGetCall(config) {
|
||||
return config.method === 'get';
|
||||
}
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'special get headers';
|
||||
return config;
|
||||
}, null, { runWhen: onGetCall });
|
||||
|
||||
axios('/foo');
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
expect(request.requestHeaders.test).toBe('special get headers');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not run the interceptor if runWhen function is provided and resolves to false', function (done) {
|
||||
function onPostCall(config) {
|
||||
return config.method === 'post';
|
||||
}
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'special get headers';
|
||||
return config;
|
||||
}, null, { runWhen: onPostCall });
|
||||
|
||||
axios('/foo');
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
expect(request.requestHeaders.test).toBeUndefined()
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not run async interceptor if runWhen function is provided and resolves to false (and run synchronously)', function (done) {
|
||||
var asyncFlag = false;
|
||||
|
||||
function onPostCall(config) {
|
||||
return config.method === 'post';
|
||||
}
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.test = 'special get headers';
|
||||
return config;
|
||||
}, null, { synchronous: false, runWhen: onPostCall });
|
||||
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.headers.sync = 'hello world';
|
||||
expect(asyncFlag).toBe(false);
|
||||
return config;
|
||||
}, null, { synchronous: true });
|
||||
|
||||
axios('/foo');
|
||||
asyncFlag = true
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
expect(request.requestHeaders.test).toBeUndefined()
|
||||
expect(request.requestHeaders.sync).toBe('hello world')
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a request interceptor with an onRejected block that is called if interceptor code fails', function (done) {
|
||||
var rejectedSpy = jasmine.createSpy('rejectedSpy');
|
||||
var error = new Error('deadly error');
|
||||
axios.interceptors.request.use(function () {
|
||||
throw error;
|
||||
}, rejectedSpy, { synchronous: true });
|
||||
|
||||
axios('/foo');
|
||||
|
||||
getAjaxRequest().then(function () {
|
||||
expect(rejectedSpy).toHaveBeenCalledWith(error);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a request interceptor that returns a new config object', function (done) {
|
||||
axios.interceptors.request.use(function () {
|
||||
return {
|
||||
@@ -237,6 +376,32 @@ describe('interceptors', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should remove async interceptor before making request and execute synchronously', function (done) {
|
||||
var asyncFlag = false;
|
||||
var asyncIntercept = axios.interceptors.request.use(function (config) {
|
||||
config.headers.async = 'async it!';
|
||||
return config;
|
||||
}, null, { synchronous: false });
|
||||
|
||||
var syncIntercept = axios.interceptors.request.use(function (config) {
|
||||
config.headers.sync = 'hello world';
|
||||
expect(asyncFlag).toBe(false);
|
||||
return config;
|
||||
}, null, { synchronous: true });
|
||||
|
||||
|
||||
axios.interceptors.request.eject(asyncIntercept);
|
||||
|
||||
axios('/foo')
|
||||
asyncFlag = true
|
||||
|
||||
getAjaxRequest().then(function (request) {
|
||||
expect(request.requestHeaders.async).toBeUndefined();
|
||||
expect(request.requestHeaders.sync).toBe('hello world');
|
||||
done()
|
||||
});
|
||||
});
|
||||
|
||||
it('should execute interceptors before transformers', function (done) {
|
||||
axios.interceptors.request.use(function (config) {
|
||||
config.data.baz = 'qux';
|
||||
|
||||
Reference in New Issue
Block a user