import { beforeEach, describe, expect, it, vi } from "vitest"; const { axiosMock } = vi.hoisted(() => ({ axiosMock: vi.fn(), })); vi.mock("axios", () => ({ default: axiosMock, })); import { authenticatedRequest } from "@/components/session/authenticatedRequest.vue"; import { __configureRequestQueueForTests, __resetRequestQueueForTests, requestQueueState, } from "@/services/requestQueue.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 }; }; describe("authenticatedRequest", () => { beforeEach(() => { axiosMock.mockReset(); __resetRequestQueueForTests(); __configureRequestQueueForTests({ maxConcurrentGet: 1, maxConcurrentOther: 1, spacingMs: 0, retryByStatusCode: {}, }); localStorage.clear(); localStorage.setItem("token", "token"); }); it("suppresses known scanner lpr extraction failures and resolves with response", async () => { const response = { status: 500, data: { success: false, data: { message: "Internal server error: License plate extraction failed.", }, meta: [], includes: [], }, }; axiosMock.mockRejectedValueOnce({ response }); const catchCallable = vi.fn(); const result = await authenticatedRequest("/modules/scanner/lpr", "POST", { base64_image: "x" }, catchCallable); expect(result).toBe(response); expect(catchCallable).not.toHaveBeenCalled(); }); it("continues to reject non-suppressed scanner errors", async () => { const error = { response: { status: 500, data: { success: false, data: { message: "Internal server error: Different scanner problem.", }, }, }, }; axiosMock.mockRejectedValueOnce(error); const catchCallable = vi.fn(); await expect( authenticatedRequest("/modules/scanner/lpr", "POST", { base64_image: "x" }, catchCallable) ).rejects.toBe(error); expect(catchCallable).toHaveBeenCalledWith(error); }); it("continues to reject non-lpr errors", async () => { const error = { response: { status: 500, data: { success: false, data: { message: "Internal server error: License plate extraction failed.", }, }, }, }; axiosMock.mockRejectedValueOnce(error); await expect(authenticatedRequest("/auth/session", "GET")).rejects.toBe(error); }); it("queues requests and executes them sequentially", async () => { const first = createDeferred(); const second = createDeferred(); const third = createDeferred(); const deferredCalls = [first, second, third]; axiosMock.mockImplementation(() => deferredCalls.shift()?.promise); const request1 = authenticatedRequest("/one", "GET"); const request2 = authenticatedRequest("/two", "GET"); const request3 = authenticatedRequest("/three", "GET"); await flushMicrotasks(); expect(axiosMock).toHaveBeenCalledTimes(1); expect(requestQueueState.active).toBe(1); expect(requestQueueState.pending).toBe(2); expect(requestQueueState.batchTotal).toBe(3); first.resolve({ status: 200, data: { id: 1 } }); await flushManyMicrotasks(); expect(axiosMock).toHaveBeenCalledTimes(2); expect(requestQueueState.active).toBe(1); expect(requestQueueState.pending).toBe(1); second.resolve({ status: 200, data: { id: 2 } }); await flushManyMicrotasks(); expect(axiosMock).toHaveBeenCalledTimes(3); expect(requestQueueState.active).toBe(1); expect(requestQueueState.pending).toBe(0); third.resolve({ status: 200, data: { id: 3 } }); await expect(Promise.all([request1, request2, request3])).resolves.toEqual([ { status: 200, data: { id: 1 } }, { status: 200, data: { id: 2 } }, { status: 200, data: { id: 3 } }, ]); await flushMicrotasks(); expect(requestQueueState.active).toBe(0); expect(requestQueueState.pending).toBe(0); expect(requestQueueState.batchCompleted).toBe(3); expect(requestQueueState.batchFailed).toBe(0); }); });