File size: 2,415 Bytes
37211b8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { installApiAuthResponseMonitor, onApiUnauthorized } from "./apiAuthEvents";
const FETCH_PATCH_FLAG = "__mastersToolkitAuthFetchPatched";
async function flushAsync(): Promise<void> {
await new Promise<void>((resolve) => window.setTimeout(resolve, 0));
}
describe("apiAuthEvents", () => {
let originalFetch: typeof window.fetch;
beforeEach(() => {
originalFetch = window.fetch.bind(window);
delete (window as Window & { [FETCH_PATCH_FLAG]?: boolean })[FETCH_PATCH_FLAG];
});
afterEach(() => {
window.fetch = originalFetch;
delete (window as Window & { [FETCH_PATCH_FLAG]?: boolean })[FETCH_PATCH_FLAG];
});
it("ignores 401 responses without Authorization header", async () => {
const events: Array<{ status: number; message: string }> = [];
const dispose = onApiUnauthorized((detail) => {
events.push({ status: detail.status, message: detail.message });
});
window.fetch = vi.fn(async () => {
return new Response(JSON.stringify({ detail: "Missing Authorization header." }), {
status: 401,
headers: {
"content-type": "application/json",
"x-masters-auth-error": "1",
},
});
}) as unknown as typeof window.fetch;
installApiAuthResponseMonitor();
await window.fetch("/api/ui/tabs");
await flushAsync();
dispose();
expect(events).toHaveLength(0);
});
it("emits unauthorized event for protected 401 responses with Authorization header", async () => {
const events: Array<{ status: number; message: string }> = [];
const dispose = onApiUnauthorized((detail) => {
events.push({ status: detail.status, message: detail.message });
});
window.fetch = vi.fn(async () => {
return new Response(JSON.stringify({ detail: "Invalid or expired token." }), {
status: 401,
headers: {
"content-type": "application/json",
"x-masters-auth-error": "1",
},
});
}) as unknown as typeof window.fetch;
installApiAuthResponseMonitor();
await window.fetch("/api/health", {
headers: { Authorization: "Bearer token" },
});
await flushAsync();
dispose();
expect(events).toHaveLength(1);
expect(events[0]?.status).toBe(401);
expect(events[0]?.message).toContain("Invalid or expired token");
});
});
|