/** * Federation API Client Tests * Tests for mock data NODE_ENV gating (SEC-WEB-37) */ import { describe, it, expect, vi, beforeEach } from "vitest"; import * as client from "./client"; import { getMockConnections, fetchConnections, fetchConnection, fetchInstanceIdentity, updateInstanceConfiguration, regenerateInstanceKeys, FederationConnectionStatus, } from "./federation"; // Mock the API client vi.mock("./client", () => ({ apiGet: vi.fn(), apiPost: vi.fn(), apiPatch: vi.fn(), })); describe("Federation API", () => { describe("getMockConnections", () => { it("should return mock connections in development mode", () => { vi.stubEnv("NODE_ENV", "development"); const connections = getMockConnections(); expect(connections).toHaveLength(3); expect(connections[0]?.id).toBe("conn-1"); expect(connections[0]?.remoteUrl).toBe("https://mosaic.work.example.com"); expect(connections[1]?.id).toBe("conn-2"); expect(connections[2]?.id).toBe("conn-3"); }); it("should return empty array in production mode", () => { vi.stubEnv("NODE_ENV", "production"); const connections = getMockConnections(); expect(connections).toEqual([]); expect(connections).toHaveLength(0); }); it("should return empty array in test mode", () => { vi.stubEnv("NODE_ENV", "test"); const connections = getMockConnections(); expect(connections).toEqual([]); expect(connections).toHaveLength(0); }); it("should include expected connection statuses in development", () => { vi.stubEnv("NODE_ENV", "development"); const connections = getMockConnections(); expect(connections[0]?.status).toBe(FederationConnectionStatus.ACTIVE); expect(connections[1]?.status).toBe(FederationConnectionStatus.PENDING); expect(connections[2]?.status).toBe(FederationConnectionStatus.DISCONNECTED); }); it("should include capabilities in development mock data", () => { vi.stubEnv("NODE_ENV", "development"); const connections = getMockConnections(); expect(connections[0]?.remoteCapabilities).toEqual({ supportsQuery: true, supportsCommand: true, supportsEvent: true, supportsAgentSpawn: true, protocolVersion: "1.0", }); }); it("should not expose mock public keys in production", () => { vi.stubEnv("NODE_ENV", "production"); const connections = getMockConnections(); // In production, no connections should be returned at all expect(connections).toHaveLength(0); // Verify no public key data is accessible const hasPublicKeys = connections.some((c) => c.remotePublicKey); expect(hasPublicKeys).toBe(false); }); }); describe("fetchConnections", () => { beforeEach(() => { vi.clearAllMocks(); }); it("should call the connections endpoint without filters", async () => { const mockResponse = [{ id: "conn-1" }]; vi.mocked(client.apiGet).mockResolvedValue(mockResponse); const result = await fetchConnections(); expect(client.apiGet).toHaveBeenCalledWith("/api/v1/federation/connections"); expect(result).toEqual(mockResponse); }); it("should include status filter in query string", async () => { const mockResponse = [{ id: "conn-1" }]; vi.mocked(client.apiGet).mockResolvedValue(mockResponse); const result = await fetchConnections(FederationConnectionStatus.ACTIVE); expect(client.apiGet).toHaveBeenCalledWith("/api/v1/federation/connections?status=ACTIVE"); expect(result).toEqual(mockResponse); }); }); describe("fetchConnection", () => { beforeEach(() => { vi.clearAllMocks(); }); it("should fetch a single connection by ID", async () => { const mockResponse = { id: "conn-1", remoteUrl: "https://example.com" }; vi.mocked(client.apiGet).mockResolvedValue(mockResponse); const result = await fetchConnection("conn-1"); expect(client.apiGet).toHaveBeenCalledWith("/api/v1/federation/connections/conn-1"); expect(result).toEqual(mockResponse); }); }); describe("fetchInstanceIdentity", () => { beforeEach(() => { vi.clearAllMocks(); }); it("should fetch the instance identity", async () => { const mockResponse = { id: "inst-1", name: "Test Instance" }; vi.mocked(client.apiGet).mockResolvedValue(mockResponse); const result = await fetchInstanceIdentity(); expect(client.apiGet).toHaveBeenCalledWith("/api/v1/federation/instance"); expect(result).toEqual(mockResponse); }); }); describe("updateInstanceConfiguration", () => { beforeEach(() => { vi.clearAllMocks(); }); it("should update instance configuration", async () => { const mockResponse = { id: "inst-1", name: "Updated Instance" }; vi.mocked(client.apiPatch).mockResolvedValue(mockResponse); const result = await updateInstanceConfiguration({ name: "Updated Instance" }); expect(client.apiPatch).toHaveBeenCalledWith("/api/v1/federation/instance", { name: "Updated Instance", }); expect(result).toEqual(mockResponse); }); }); describe("regenerateInstanceKeys", () => { beforeEach(() => { vi.clearAllMocks(); }); it("should regenerate instance keys", async () => { const mockResponse = { id: "inst-1", publicKey: "new-key" }; vi.mocked(client.apiPost).mockResolvedValue(mockResponse); const result = await regenerateInstanceKeys(); expect(client.apiPost).toHaveBeenCalledWith( "/api/v1/federation/instance/regenerate-keys", {} ); expect(result).toEqual(mockResponse); }); }); });