All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Replace exported const mockConnections with getMockConnections() function that returns mock data only when NODE_ENV === "development". In production and test environments, returns an empty array as defense-in-depth alongside the existing ComingSoon page gate (SEC-WEB-4). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
195 lines
5.7 KiB
TypeScript
195 lines
5.7 KiB
TypeScript
/**
|
|
* 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);
|
|
});
|
|
});
|
|
});
|