import { HttpResponse, http } from "msw"; import { afterEach, describe, expect, it, vi } from "vitest"; import { server } from "@/test/server"; import { apiClient, configureAuthClient } from "./client"; describe("apiClient authentication", () => { afterEach(() => configureAuthClient(null)); it("refreshes once and retries an unauthorized protected request", async () => { let token = "expired"; const refresh = vi.fn(async () => { token = "fresh"; return true; }); const authorization: string[] = []; server.use( http.get("*/api/v1/brokerage-accounts", ({ request }) => { authorization.push(request.headers.get("Authorization") ?? ""); return authorization.length === 1 ? HttpResponse.json({ code: "UNAUTHORIZED" }, { status: 401 }) : HttpResponse.json([]); }), ); configureAuthClient({ accessToken: () => token, refresh, clear: vi.fn() }); const { data } = await apiClient.GET("/api/v1/brokerage-accounts"); expect(data).toEqual([]); expect(refresh).toHaveBeenCalledOnce(); expect(authorization).toEqual(["Bearer expired", "Bearer fresh"]); }); it("clears the session when refresh cannot restore it", async () => { const clear = vi.fn(); server.use( http.get("*/api/v1/brokerage-accounts", () => HttpResponse.json({ code: "UNAUTHORIZED" }, { status: 401 }), ), ); configureAuthClient({ accessToken: () => "expired", refresh: async () => false, clear, }); await apiClient.GET("/api/v1/brokerage-accounts"); expect(clear).toHaveBeenCalledOnce(); }); it("does not attach Bearer auth to authentication endpoints", async () => { let authorization: string | null = null; server.use( http.post("*/api/v1/auth/refresh", ({ request }) => { authorization = request.headers.get("Authorization"); return HttpResponse.json({ code: "UNAUTHORIZED" }, { status: 401 }); }), ); configureAuthClient({ accessToken: () => "token", refresh: vi.fn(), clear: vi.fn(), }); await apiClient.POST("/api/v1/auth/refresh"); expect(authorization).toBeNull(); }); });