mirror of
https://github.com/tenrok/axios.git
synced 2026-06-17 19:21:29 +03:00
847d89b436
* fix(buildURL): support URL object as input Fixes #6546 When passing a URL object (e.g., new URL(...)) to axios methods like axios.get(url, { params: {...} }), the buildURL function would crash with 'url.indexOf is not a function' because it assumed url was always a string. This fix converts URL objects to strings before processing. * fix: support URL object as config.url input - Move URL object coercion from buildURL to Axios._request so that all downstream consumers (buildFullPath, combineURLs, adapters) see a string. This fixes the crash when using URL object with baseURL (combineURLs calls .replace() on the URL object). - Remove the broken buildURL unit test that tested buildURL(url, null) without actually exercising URL coercion (buildURL early-returns when !params). - Add e2e tests via the HTTP adapter for URL object with params and URL object without params (no crash). * feat: note + example added under axios(url[, config]) documenting URL support * feat: url widened to string | URL * feat: oercion now uses config.url instanceof url * chore: add additional test cases to improve coverage * fix: apply suggestions from cubic review --------- Co-authored-by: liuwei53 <liuwei53@baidu.com> Co-authored-by: Jason Saayman <jasonsaayman@gmail.com>
203 lines
6.0 KiB
JavaScript
203 lines
6.0 KiB
JavaScript
import { describe, it } from 'vitest';
|
|
import assert from 'assert';
|
|
import axios, { create } from '../../index.js';
|
|
|
|
describe('static api', () => {
|
|
it('should have request method helpers', () => {
|
|
assert.strictEqual(typeof axios.request, 'function');
|
|
assert.strictEqual(typeof axios.get, 'function');
|
|
assert.strictEqual(typeof axios.head, 'function');
|
|
assert.strictEqual(typeof axios.options, 'function');
|
|
assert.strictEqual(typeof axios.delete, 'function');
|
|
assert.strictEqual(typeof axios.post, 'function');
|
|
assert.strictEqual(typeof axios.put, 'function');
|
|
assert.strictEqual(typeof axios.patch, 'function');
|
|
assert.strictEqual(typeof axios.query, 'function');
|
|
});
|
|
|
|
it('should have promise method helpers', async () => {
|
|
const promise = axios.request({
|
|
url: '/test',
|
|
adapter: (config) =>
|
|
Promise.resolve({
|
|
data: null,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
headers: {},
|
|
config,
|
|
request: {},
|
|
}),
|
|
});
|
|
|
|
assert.strictEqual(typeof promise.then, 'function');
|
|
assert.strictEqual(typeof promise.catch, 'function');
|
|
|
|
await promise;
|
|
});
|
|
|
|
it('should support URL object shorthand with config', async () => {
|
|
const url = new URL('http://example.com/test?a=1');
|
|
|
|
const response = await axios(url, {
|
|
params: {
|
|
b: 2,
|
|
},
|
|
adapter: (config) =>
|
|
Promise.resolve({
|
|
data: null,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
headers: {},
|
|
config,
|
|
request: {},
|
|
}),
|
|
});
|
|
|
|
assert.strictEqual(response.config.url, url.toString());
|
|
assert.deepStrictEqual(response.config.params, { b: 2 });
|
|
});
|
|
|
|
it('should not require global URL to be a constructor for string requests', async () => {
|
|
const descriptor = Object.getOwnPropertyDescriptor(globalThis, 'URL');
|
|
|
|
Object.defineProperty(globalThis, 'URL', {
|
|
configurable: true,
|
|
writable: true,
|
|
value: {},
|
|
});
|
|
|
|
try {
|
|
const response = await axios('/test', {
|
|
adapter: (config) =>
|
|
Promise.resolve({
|
|
data: null,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
headers: {},
|
|
config,
|
|
request: {},
|
|
}),
|
|
});
|
|
|
|
assert.strictEqual(response.config.url, '/test');
|
|
} finally {
|
|
if (descriptor) {
|
|
Object.defineProperty(globalThis, 'URL', descriptor);
|
|
} else {
|
|
delete globalThis.URL;
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should normalize URL object set by a request interceptor before dispatch', async () => {
|
|
const url = new URL('http://example.com/interceptor');
|
|
let transformUrl;
|
|
const interceptorId = axios.interceptors.request.use((config) => {
|
|
config.url = url;
|
|
return config;
|
|
});
|
|
|
|
try {
|
|
const response = await axios('/test', {
|
|
transformRequest: [
|
|
function (data) {
|
|
transformUrl = this.url;
|
|
return data;
|
|
},
|
|
],
|
|
adapter: (config) =>
|
|
Promise.resolve({
|
|
data: null,
|
|
status: 200,
|
|
statusText: 'OK',
|
|
headers: {},
|
|
config,
|
|
request: {},
|
|
}),
|
|
});
|
|
|
|
assert.strictEqual(transformUrl, url.toString());
|
|
assert.strictEqual(response.config.url, url.toString());
|
|
} finally {
|
|
axios.interceptors.request.eject(interceptorId);
|
|
}
|
|
});
|
|
|
|
it('should have defaults', () => {
|
|
assert.strictEqual(typeof axios.defaults, 'object');
|
|
assert.strictEqual(typeof axios.defaults.headers, 'object');
|
|
});
|
|
|
|
it('should have interceptors', () => {
|
|
assert.strictEqual(typeof axios.interceptors.request, 'object');
|
|
assert.strictEqual(typeof axios.interceptors.response, 'object');
|
|
});
|
|
|
|
it('should have all/spread helpers', () => {
|
|
assert.strictEqual(typeof axios.all, 'function');
|
|
assert.strictEqual(typeof axios.spread, 'function');
|
|
});
|
|
|
|
it('should have factory method', () => {
|
|
assert.strictEqual(typeof axios.create, 'function');
|
|
});
|
|
|
|
it('should expose create as a named export', () => {
|
|
assert.strictEqual(typeof create, 'function');
|
|
assert.strictEqual(create, axios.create);
|
|
});
|
|
|
|
it('should have CanceledError, CancelToken, and isCancel properties', () => {
|
|
assert.strictEqual(typeof axios.Cancel, 'function');
|
|
assert.strictEqual(typeof axios.CancelToken, 'function');
|
|
assert.strictEqual(typeof axios.isCancel, 'function');
|
|
});
|
|
|
|
it('should have getUri method', () => {
|
|
assert.strictEqual(typeof axios.getUri, 'function');
|
|
});
|
|
|
|
it('should support URL object config in getUri', () => {
|
|
const url = new URL('https://api.example.com/foo');
|
|
|
|
assert.strictEqual(axios.getUri({ url }), url.toString());
|
|
assert.strictEqual(
|
|
axios.getUri({ baseURL: 'https://example.com/base', url }),
|
|
url.toString()
|
|
);
|
|
});
|
|
|
|
it('should have isAxiosError properties', () => {
|
|
assert.strictEqual(typeof axios.isAxiosError, 'function');
|
|
});
|
|
|
|
it('should have mergeConfig properties', () => {
|
|
assert.strictEqual(typeof axios.mergeConfig, 'function');
|
|
});
|
|
|
|
it('should have getAdapter properties', () => {
|
|
assert.strictEqual(typeof axios.getAdapter, 'function');
|
|
});
|
|
});
|
|
|
|
describe('instance api', () => {
|
|
const instance = axios.create();
|
|
|
|
it('should have request methods', () => {
|
|
assert.strictEqual(typeof instance.request, 'function');
|
|
assert.strictEqual(typeof instance.get, 'function');
|
|
assert.strictEqual(typeof instance.options, 'function');
|
|
assert.strictEqual(typeof instance.head, 'function');
|
|
assert.strictEqual(typeof instance.delete, 'function');
|
|
assert.strictEqual(typeof instance.post, 'function');
|
|
assert.strictEqual(typeof instance.put, 'function');
|
|
assert.strictEqual(typeof instance.patch, 'function');
|
|
assert.strictEqual(typeof instance.query, 'function');
|
|
});
|
|
|
|
it('should have interceptors', () => {
|
|
assert.strictEqual(typeof instance.interceptors.request, 'object');
|
|
assert.strictEqual(typeof instance.interceptors.response, 'object');
|
|
});
|
|
});
|