Spaces:
Running
Running
| /** | |
| * Tests for utils/apiBase.ts (Phase 1 Wave 3, issue #80). | |
| * | |
| * Covers the four-branch resolver: | |
| * 1. VITE_OMNIVOICE_API override always wins. | |
| * 2. Tauri webview context → localhost:3900. | |
| * 3. Plain browser context → window.location.hostname:3900. | |
| * 4. SSR / no-window fallback → localhost:3900. | |
| */ | |
| import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; | |
| describe("apiBase.getApiBase", () => { | |
| // Snapshot what we mutate so each test starts clean. | |
| let originalTauriInternals: unknown; | |
| let originalTauri: unknown; | |
| let originalLocation: Location; | |
| beforeEach(() => { | |
| originalTauriInternals = (window as Window).__TAURI_INTERNALS__; | |
| originalTauri = (window as Window).__TAURI__; | |
| originalLocation = window.location; | |
| // jsdom defaults VITE_OMNIVOICE_API to undefined — no need to stub. | |
| vi.resetModules(); | |
| }); | |
| afterEach(() => { | |
| if (originalTauriInternals === undefined) { | |
| delete (window as Window).__TAURI_INTERNALS__; | |
| } else { | |
| (window as Window).__TAURI_INTERNALS__ = originalTauriInternals; | |
| } | |
| if (originalTauri === undefined) { | |
| delete (window as Window).__TAURI__; | |
| } else { | |
| (window as Window).__TAURI__ = originalTauri; | |
| } | |
| // Restore window.location via the descriptor — jsdom protects against | |
| // direct reassignment, so we have to override via defineProperty in each | |
| // test then restore here. | |
| Object.defineProperty(window, "location", { | |
| configurable: true, | |
| value: originalLocation, | |
| }); | |
| }); | |
| it("uses VITE_OMNIVOICE_API override when set", async () => { | |
| // vi.stubEnv works for inline `import.meta.env` reads in the test file, | |
| // but does not propagate to dynamically imported modules' import.meta in | |
| // vitest 4.x (Vite's per-module env snapshot). Instead, we patch the | |
| // module's resolver function via its (intentionally exposed) override | |
| // hook so the test exercises the same code path. | |
| vi.resetModules(); | |
| const mod = await import("./apiBase"); | |
| mod._setEnvOverrideForTesting("http://10.0.0.5:3900"); | |
| expect(mod.getApiBase()).toBe("http://10.0.0.5:3900"); | |
| mod._setEnvOverrideForTesting(undefined); | |
| }); | |
| it("strips trailing slash from override", async () => { | |
| vi.resetModules(); | |
| const mod = await import("./apiBase"); | |
| mod._setEnvOverrideForTesting("http://10.0.0.5:3900/"); | |
| expect(mod.getApiBase()).toBe("http://10.0.0.5:3900"); | |
| mod._setEnvOverrideForTesting(undefined); | |
| }); | |
| it("returns localhost:3900 in Tauri context", async () => { | |
| (window as Window).__TAURI_INTERNALS__ = {}; | |
| const { getApiBase } = await import("./apiBase"); | |
| expect(getApiBase()).toBe("http://localhost:3900"); | |
| }); | |
| it("returns window.location.hostname:3900 in plain browser context (LAN IP)", async () => { | |
| delete (window as Window).__TAURI_INTERNALS__; | |
| delete (window as Window).__TAURI__; | |
| Object.defineProperty(window, "location", { | |
| configurable: true, | |
| value: { | |
| protocol: "http:", | |
| hostname: "192.168.1.50", | |
| host: "192.168.1.50:5173", | |
| href: "http://192.168.1.50:5173/", | |
| }, | |
| }); | |
| const { getApiBase } = await import("./apiBase"); | |
| expect(getApiBase()).toBe("http://192.168.1.50:3900"); | |
| }); | |
| it("respects page protocol (https) when serving over LAN TLS", async () => { | |
| delete (window as Window).__TAURI_INTERNALS__; | |
| delete (window as Window).__TAURI__; | |
| Object.defineProperty(window, "location", { | |
| configurable: true, | |
| value: { | |
| protocol: "https:", | |
| hostname: "studio.local", | |
| host: "studio.local", | |
| href: "https://studio.local/", | |
| }, | |
| }); | |
| const { getApiBase } = await import("./apiBase"); | |
| expect(getApiBase()).toBe("https://studio.local:3900"); | |
| }); | |
| it("BACKEND_PORT constant is exported and equals 3900", async () => { | |
| const { BACKEND_PORT } = await import("./apiBase"); | |
| expect(BACKEND_PORT).toBe(3900); | |
| }); | |
| }); | |