import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { fetchTenantBySlug, type Tenant } from "./tenant-registry"; const SAMPLE: Tenant = { id: "00000000-0000-0000-0000-000000000001", slug: "acme", name: "Acme Inc.", status: "active", plan: "professional", products: ["certifai", "compliance"], created_at: "2026-05-18T22:00:00Z", }; const originalFetch = globalThis.fetch; const originalRegistryUrl = process.env.TENANT_REGISTRY_URL; afterEach(() => { globalThis.fetch = originalFetch; process.env.TENANT_REGISTRY_URL = originalRegistryUrl; vi.restoreAllMocks(); }); describe("fetchTenantBySlug", () => { beforeEach(() => { process.env.TENANT_REGISTRY_URL = "http://test:1234"; }); test("200 → parsed tenant", async () => { globalThis.fetch = vi.fn(async () => new Response(JSON.stringify(SAMPLE), { status: 200 })); const t = await fetchTenantBySlug("acme"); expect(t).toEqual(SAMPLE); }); test("404 → null", async () => { globalThis.fetch = vi.fn(async () => new Response("", { status: 404 })); const t = await fetchTenantBySlug("nope"); expect(t).toBeNull(); }); test("500 → throws", async () => { globalThis.fetch = vi.fn(async () => new Response("", { status: 500, statusText: "boom" })); await expect(fetchTenantBySlug("acme")).rejects.toThrow(/tenant-registry: 500/); }); test("falls back to default base URL when env unset", async () => { delete process.env.TENANT_REGISTRY_URL; const fetchSpy = vi.fn(async () => new Response(JSON.stringify(SAMPLE), { status: 200 })); globalThis.fetch = fetchSpy; await fetchTenantBySlug("acme"); expect(fetchSpy).toHaveBeenCalledWith( "http://localhost:8080/v1/tenants/by-slug/acme", expect.any(Object), ); }); test("encodes slug to defend against weird input", async () => { const fetchSpy = vi.fn(async () => new Response("", { status: 404 })); globalThis.fetch = fetchSpy; await fetchTenantBySlug("a/b c"); const firstCall = fetchSpy.mock.calls[0]; expect(firstCall).toBeDefined(); expect(firstCall![0]).toBe("http://test:1234/v1/tenants/by-slug/a%2Fb%20c"); }); });