- Update `requestQueue` to differentiate between GET and other request types with configurable limits. - Refactor `enqueueRequest` and queue draining logic for type-based concurrent handling. - Add unit tests to validate GET-specific concurrency and proper queue functionality.
134 lines
3.6 KiB
JavaScript
134 lines
3.6 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({ maxConcurrentGet: 1, maxConcurrentOther: 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);
|
|
});
|
|
|
|
it("allows 5 concurrent GET requests", async () => {
|
|
__configureRequestQueueForTests({ maxConcurrentGet: 5, maxConcurrentOther: 1, spacingMs: 0 });
|
|
|
|
const allDeferred = Array.from({ length: 6 }, () => createDeferred());
|
|
const pendingAdapters = [...allDeferred];
|
|
const adapter = () => pendingAdapters.shift()?.promise;
|
|
|
|
const requests = Array.from({ length: 6 }, (_, index) =>
|
|
axios({
|
|
url: `/queue-get-${index + 1}`,
|
|
method: "GET",
|
|
adapter
|
|
})
|
|
);
|
|
|
|
await flushMicrotasks();
|
|
|
|
expect(requestQueueState.active).toBe(5);
|
|
expect(requestQueueState.pending).toBe(1);
|
|
|
|
for (let index = 0; index < 5; index += 1) {
|
|
allDeferred[index].resolve(createResponse({ id: index + 1 }));
|
|
}
|
|
|
|
await flushManyMicrotasks();
|
|
|
|
expect(requestQueueState.active).toBe(1);
|
|
expect(requestQueueState.pending).toBe(0);
|
|
|
|
allDeferred[5].resolve(createResponse({ id: 6 }));
|
|
const responses = await Promise.all(requests);
|
|
|
|
expect(responses.map((item) => item.data.id)).toEqual([1, 2, 3, 4, 5, 6]);
|
|
});
|
|
});
|