/** * L1 — the DI provider resolves real vs mock gateways from `VITE_USE_MOCK`, * and `useGateways` exposes the injected set (and guards against misuse). */ import { describe, it, expect, afterEach, vi } from "vitest"; import { render, screen, renderHook } from "@testing-library/react"; import { MockSystemGateway } from "@/adapters/mock"; import { HttpSystemGateway } from "@/adapters/http/streamGateways"; import { TauriSystemGateway } from "@/adapters"; import { DIProvider, useGateways, resolveGateways, resolveTransport, shouldUseMock, shouldUseHttp, } from "./di"; import { transportFromEnv } from "./transport"; afterEach(() => { vi.unstubAllEnvs(); }); describe("shouldUseMock / resolveGateways", () => { it("returns mock gateways when VITE_USE_MOCK=1", () => { vi.stubEnv("VITE_USE_MOCK", "1"); expect(shouldUseMock()).toBe(true); expect(resolveGateways().system).toBeInstanceOf(MockSystemGateway); }); it("returns mock gateways when VITE_USE_MOCK=true", () => { vi.stubEnv("VITE_USE_MOCK", "true"); expect(shouldUseMock()).toBe(true); }); it("returns real (non-mock) gateways otherwise", () => { vi.stubEnv("VITE_USE_MOCK", ""); vi.stubEnv("VITE_TRANSPORT", ""); expect(shouldUseMock()).toBe(false); // Real adapter is not the mock implementation. expect(resolveGateways().system).not.toBeInstanceOf(MockSystemGateway); }); }); describe("resolveTransport / web (HTTP+WS) selection (ticket #13, F1)", () => { it("selects the HTTP transport when VITE_TRANSPORT=http", () => { vi.stubEnv("VITE_USE_MOCK", ""); vi.stubEnv("VITE_TRANSPORT", "http"); expect(shouldUseHttp()).toBe(true); expect(resolveTransport()).toBe("http"); expect(resolveGateways().system).toBeInstanceOf(HttpSystemGateway); }); it("keeps Tauri as the default when no transport env is set", () => { vi.stubEnv("VITE_USE_MOCK", ""); vi.stubEnv("VITE_TRANSPORT", ""); expect(resolveTransport()).toBe("tauri"); expect(resolveGateways().system).toBeInstanceOf(TauriSystemGateway); }); it("lets mock win over the web transport", () => { vi.stubEnv("VITE_USE_MOCK", "1"); vi.stubEnv("VITE_TRANSPORT", "http"); expect(resolveTransport()).toBe("mock"); expect(resolveGateways().system).toBeInstanceOf(MockSystemGateway); }); }); describe("transportFromEnv (ticket #74, F1)", () => { // The build config derives `__IDEA_TRANSPORT__` from this same predicate, so // pinning it here pins both the runtime transport and the build constant. it("selects http only for the exact opt-in value", () => { expect(transportFromEnv("http")).toBe("http"); }); it.each([undefined, "", "tauri", "HTTP", "http ", "web"])( "falls back to tauri for %o", (value) => { expect(transportFromEnv(value)).toBe("tauri"); }, ); it("agrees with shouldUseHttp for the value the build reads", () => { vi.stubEnv("VITE_TRANSPORT", "http"); expect(shouldUseHttp()).toBe(transportFromEnv("http") === "http"); vi.stubEnv("VITE_TRANSPORT", ""); expect(shouldUseHttp()).toBe(transportFromEnv("") === "http"); }); }); describe("DIProvider / useGateways", () => { it("provides explicit gateways to consumers", () => { const gateways = resolveGatewaysMock(); const { result } = renderHook(() => useGateways(), { wrapper: ({ children }) => ( {children} ), }); expect(result.current).toBe(gateways); }); it("renders children inside the provider", () => { render( ok , ); expect(screen.getByText("ok")).toBeTruthy(); }); it("throws when useGateways is used outside a provider", () => { expect(() => renderHook(() => useGateways())).toThrow( /must be used within a /, ); }); }); function resolveGatewaysMock() { vi.stubEnv("VITE_USE_MOCK", "1"); const g = resolveGateways(); vi.unstubAllEnvs(); return g; }