- Introduce `installAxiosRequestQueue` to manage and queue requests globally. - Update `main.js` to install the interceptor at app initialization. - Add `__skipRequestQueue` configuration in `authenticatedRequest` for bypassing the queue. - Create unit tests to validate queue behavior and ensure request sequencing.
99 lines
2.5 KiB
JavaScript
99 lines
2.5 KiB
JavaScript
import axios from "axios";
|
|
import { beforeEach, afterEach, describe, expect, it } from "vitest";
|
|
import {
|
|
__configureRequestQueueForTests,
|
|
__resetRequestQueueForTests,
|
|
requestQueueState
|
|
} from "@/services/requestQueue.js";
|
|
import {
|
|
__resetAxiosRequestQueueInstallerForTests,
|
|
installAxiosRequestQueue
|
|
} from "@/services/installAxiosRequestQueue.js";
|
|
|
|
const flushMicrotasks = async () => {
|
|
await Promise.resolve();
|
|
await Promise.resolve();
|
|
};
|
|
|
|
const flushManyMicrotasks = async (rounds = 10) => {
|
|
for (let index = 0; index < rounds; index += 1) {
|
|
await Promise.resolve();
|
|
}
|
|
};
|
|
|
|
const createDeferred = () => {
|
|
let resolve;
|
|
let reject;
|
|
const promise = new Promise((res, rej) => {
|
|
resolve = res;
|
|
reject = rej;
|
|
});
|
|
|
|
return { promise, resolve, reject };
|
|
};
|
|
|
|
const createResponse = (data) => ({
|
|
status: 200,
|
|
statusText: "OK",
|
|
headers: {},
|
|
config: {},
|
|
data
|
|
});
|
|
|
|
describe("axios request queue interceptor", () => {
|
|
beforeEach(() => {
|
|
__resetAxiosRequestQueueInstallerForTests();
|
|
__resetRequestQueueForTests();
|
|
__configureRequestQueueForTests({ maxConcurrent: 1, spacingMs: 0 });
|
|
installAxiosRequestQueue();
|
|
});
|
|
|
|
afterEach(() => {
|
|
__resetAxiosRequestQueueInstallerForTests();
|
|
__resetRequestQueueForTests();
|
|
});
|
|
|
|
it("queues plain axios requests system-wide", async () => {
|
|
const first = createDeferred();
|
|
const second = createDeferred();
|
|
const adapters = [first, second];
|
|
|
|
const requestOne = axios({
|
|
url: "/queue-test-1",
|
|
method: "GET",
|
|
adapter: () => adapters.shift()?.promise
|
|
});
|
|
|
|
const requestTwo = axios({
|
|
url: "/queue-test-2",
|
|
method: "GET",
|
|
adapter: () => adapters.shift()?.promise
|
|
});
|
|
|
|
await flushMicrotasks();
|
|
|
|
expect(requestQueueState.active).toBe(1);
|
|
expect(requestQueueState.pending).toBe(1);
|
|
expect(requestQueueState.batchTotal).toBe(2);
|
|
|
|
first.resolve(createResponse({ id: 1 }));
|
|
await flushManyMicrotasks();
|
|
|
|
expect(requestQueueState.active).toBe(1);
|
|
expect(requestQueueState.pending).toBe(0);
|
|
|
|
second.resolve(createResponse({ id: 2 }));
|
|
const [responseOne, responseTwo] = await Promise.all([requestOne, requestTwo]);
|
|
|
|
expect(responseOne.data).toEqual({ id: 1 });
|
|
expect(responseTwo.data).toEqual({ id: 2 });
|
|
|
|
await flushMicrotasks();
|
|
|
|
expect(requestQueueState.active).toBe(0);
|
|
expect(requestQueueState.pending).toBe(0);
|
|
expect(requestQueueState.batchCompleted).toBe(2);
|
|
expect(requestQueueState.batchFailed).toBe(0);
|
|
});
|
|
});
|