| import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
|
|
| const mocks = vi.hoisted(() => ({ |
| loadConfig: vi.fn(() => ({ |
| gateway: { |
| auth: { |
| token: "loopback-token", |
| }, |
| }, |
| })), |
| })); |
|
|
| vi.mock("../config/config.js", async (importOriginal) => { |
| const actual = await importOriginal<typeof import("../config/config.js")>(); |
| return { |
| ...actual, |
| loadConfig: mocks.loadConfig, |
| }; |
| }); |
|
|
| vi.mock("./control-service.js", () => ({ |
| createBrowserControlContext: vi.fn(() => ({})), |
| startBrowserControlServiceFromConfig: vi.fn(async () => ({ ok: true })), |
| })); |
|
|
| vi.mock("./routes/dispatcher.js", () => ({ |
| createBrowserRouteDispatcher: vi.fn(() => ({ |
| dispatch: vi.fn(async () => ({ status: 200, body: { ok: true } })), |
| })), |
| })); |
|
|
| import { fetchBrowserJson } from "./client-fetch.js"; |
|
|
| describe("fetchBrowserJson loopback auth", () => { |
| beforeEach(() => { |
| vi.restoreAllMocks(); |
| mocks.loadConfig.mockReset(); |
| mocks.loadConfig.mockReturnValue({ |
| gateway: { |
| auth: { |
| token: "loopback-token", |
| }, |
| }, |
| }); |
| }); |
|
|
| afterEach(() => { |
| vi.unstubAllGlobals(); |
| }); |
|
|
| it("adds bearer auth for loopback absolute HTTP URLs", async () => { |
| const fetchMock = vi.fn( |
| async () => |
| new Response(JSON.stringify({ ok: true }), { |
| status: 200, |
| headers: { "Content-Type": "application/json" }, |
| }), |
| ); |
| vi.stubGlobal("fetch", fetchMock); |
|
|
| const res = await fetchBrowserJson<{ ok: boolean }>("http://127.0.0.1:18888/"); |
| expect(res.ok).toBe(true); |
|
|
| const init = fetchMock.mock.calls[0]?.[1] as RequestInit; |
| const headers = new Headers(init?.headers); |
| expect(headers.get("authorization")).toBe("Bearer loopback-token"); |
| }); |
|
|
| it("does not inject auth for non-loopback absolute URLs", async () => { |
| const fetchMock = vi.fn( |
| async () => |
| new Response(JSON.stringify({ ok: true }), { |
| status: 200, |
| headers: { "Content-Type": "application/json" }, |
| }), |
| ); |
| vi.stubGlobal("fetch", fetchMock); |
|
|
| await fetchBrowserJson<{ ok: boolean }>("http://example.com/"); |
|
|
| const init = fetchMock.mock.calls[0]?.[1] as RequestInit; |
| const headers = new Headers(init?.headers); |
| expect(headers.get("authorization")).toBeNull(); |
| }); |
|
|
| it("keeps caller-supplied auth header", async () => { |
| const fetchMock = vi.fn( |
| async () => |
| new Response(JSON.stringify({ ok: true }), { |
| status: 200, |
| headers: { "Content-Type": "application/json" }, |
| }), |
| ); |
| vi.stubGlobal("fetch", fetchMock); |
|
|
| await fetchBrowserJson<{ ok: boolean }>("http://localhost:18888/", { |
| headers: { |
| Authorization: "Bearer caller-token", |
| }, |
| }); |
|
|
| const init = fetchMock.mock.calls[0]?.[1] as RequestInit; |
| const headers = new Headers(init?.headers); |
| expect(headers.get("authorization")).toBe("Bearer caller-token"); |
| }); |
| }); |
|
|