import { afterEach, describe, expect, it, vi } from "vitest"; import { AUDIT_USER_AGENT, buildAuditHeaders, fetchForAudit, } from "./crawl-request"; afterEach(() => { vi.unstubAllGlobals(); vi.useRealTimers(); }); describe("buildAuditHeaders", () => { it("sends a browser navigation header set", () => { const headers = buildAuditHeaders(); expect(headers["User-Agent"]).toBe(AUDIT_USER_AGENT); expect(AUDIT_USER_AGENT).toMatch(/Chrome\/\d+\.0\.0\.0 Safari/); expect(headers["Accept-Language"]).toContain("en"); expect(headers["Sec-Fetch-Mode"]).toBe("navigate"); expect(headers["Upgrade-Insecure-Requests"]).toBe("1"); }); it("lets callers override individual entries", () => { expect(buildAuditHeaders({ Accept: "text/plain" }).Accept).toBe( "text/plain", ); }); }); describe("fetchForAudit", () => { it("returns the first response when it is not a transient block", async () => { const fetchMock = vi .fn() .mockResolvedValue(new Response("ok", { status: 200 })); vi.stubGlobal("fetch", fetchMock); const res = await fetchForAudit("https://example.com"); expect(res.status).toBe(200); expect(fetchMock).toHaveBeenCalledTimes(1); }); it("applies the browser headers", async () => { let seen: HeadersInit | undefined; vi.stubGlobal( "fetch", vi.fn((_url: string, init?: RequestInit) => { seen = init?.headers; return Promise.resolve(new Response("ok", { status: 200 })); }), ); await fetchForAudit("https://example.com"); expect(seen).toMatchObject({ "User-Agent": AUDIT_USER_AGENT }); }); it("retries once on 503 and returns the retry response", async () => { const fetchMock = vi .fn() .mockResolvedValueOnce(new Response("busy", { status: 503 })) .mockResolvedValueOnce(new Response("ok", { status: 200 })); vi.stubGlobal("fetch", fetchMock); vi.useFakeTimers(); const promise = fetchForAudit("https://example.com"); await vi.runAllTimersAsync(); const res = await promise; expect(res.status).toBe(200); expect(fetchMock).toHaveBeenCalledTimes(2); }); it("does not retry a hard 403", async () => { const fetchMock = vi .fn() .mockResolvedValue(new Response("no", { status: 403 })); vi.stubGlobal("fetch", fetchMock); const res = await fetchForAudit("https://example.com"); expect(res.status).toBe(403); expect(fetchMock).toHaveBeenCalledTimes(1); }); });