/** * ConnectionCard Component Tests * Following TDD - write tests first! */ import { describe, it, expect, vi } from "vitest"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { ConnectionCard } from "./ConnectionCard"; import { FederationConnectionStatus, type ConnectionDetails } from "@/lib/api/federation"; describe("ConnectionCard", (): void => { const mockActiveConnection: ConnectionDetails = { id: "conn-1", workspaceId: "workspace-1", remoteInstanceId: "instance-work-001", remoteUrl: "https://mosaic.work.example.com", remotePublicKey: "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----", remoteCapabilities: { supportsQuery: true, supportsCommand: true, supportsEvent: true, supportsAgentSpawn: true, protocolVersion: "1.0", }, status: FederationConnectionStatus.ACTIVE, metadata: { name: "Work Instance", description: "Corporate Mosaic instance", }, createdAt: new Date("2026-02-01").toISOString(), updatedAt: new Date("2026-02-01").toISOString(), connectedAt: new Date("2026-02-01").toISOString(), disconnectedAt: null, }; const mockPendingConnection: ConnectionDetails = { ...mockActiveConnection, id: "conn-2", status: FederationConnectionStatus.PENDING, metadata: { name: "Partner Instance", description: "Awaiting acceptance", }, connectedAt: null, }; const mockOnAccept = vi.fn(); const mockOnReject = vi.fn(); const mockOnDisconnect = vi.fn(); it("should render connection name from metadata", (): void => { render(); expect(screen.getByText("Work Instance")).toBeInTheDocument(); }); it("should render connection URL", (): void => { render(); expect(screen.getByText("https://mosaic.work.example.com")).toBeInTheDocument(); }); it("should render connection description from metadata", (): void => { render(); expect(screen.getByText("Corporate Mosaic instance")).toBeInTheDocument(); }); it("should show Active status with green indicator for active connections", (): void => { render(); expect(screen.getByText("Active")).toBeInTheDocument(); }); it("should show Pending status with blue indicator for pending connections", (): void => { render(); expect(screen.getByText("Pending")).toBeInTheDocument(); }); it("should show Disconnected status for disconnected connections", (): void => { const disconnectedConnection = { ...mockActiveConnection, status: FederationConnectionStatus.DISCONNECTED, disconnectedAt: new Date("2026-02-02").toISOString(), }; render(); expect(screen.getByText("Disconnected")).toBeInTheDocument(); }); it("should show Rejected status for rejected connections", (): void => { const rejectedConnection = { ...mockActiveConnection, status: FederationConnectionStatus.REJECTED, }; render(); expect(screen.getByText("Rejected")).toBeInTheDocument(); }); it("should show Disconnect button for active connections", (): void => { render(); expect(screen.getByRole("button", { name: /disconnect/i })).toBeInTheDocument(); }); it("should show Accept and Reject buttons for pending connections", (): void => { render( ); expect(screen.getByRole("button", { name: /accept/i })).toBeInTheDocument(); expect(screen.getByRole("button", { name: /reject/i })).toBeInTheDocument(); }); it("should not show action buttons for disconnected connections", (): void => { const disconnectedConnection = { ...mockActiveConnection, status: FederationConnectionStatus.DISCONNECTED, }; render(); expect(screen.queryByRole("button")).not.toBeInTheDocument(); }); it("should call onAccept when accept button clicked", async (): Promise => { const user = userEvent.setup(); render( ); const acceptButton = screen.getByRole("button", { name: /accept/i }); await user.click(acceptButton); expect(mockOnAccept).toHaveBeenCalledWith(mockPendingConnection.id); }); it("should call onReject when reject button clicked", async (): Promise => { const user = userEvent.setup(); render( ); const rejectButton = screen.getByRole("button", { name: /reject/i }); await user.click(rejectButton); expect(mockOnReject).toHaveBeenCalledWith(mockPendingConnection.id); }); it("should call onDisconnect when disconnect button clicked", async (): Promise => { const user = userEvent.setup(); render(); const disconnectButton = screen.getByRole("button", { name: /disconnect/i }); await user.click(disconnectButton); expect(mockOnDisconnect).toHaveBeenCalledWith(mockActiveConnection.id); }); it("should display capabilities when showDetails is true", (): void => { render(); expect(screen.getByText(/Query/i)).toBeInTheDocument(); expect(screen.getByText(/Command/i)).toBeInTheDocument(); expect(screen.getByText(/Events/i)).toBeInTheDocument(); expect(screen.getByText(/Agent Spawn/i)).toBeInTheDocument(); }); it("should not display capabilities by default", (): void => { render(); // Capabilities should not be visible without showDetails=true const card = screen.getByText("Work Instance").closest("div"); expect(card?.textContent).not.toMatch(/Query.*Command.*Events/); }); it("should use fallback name if metadata name is missing", (): void => { const connectionWithoutName = { ...mockActiveConnection, metadata: {}, }; render(); expect(screen.getByText("Remote Instance")).toBeInTheDocument(); }); it("should render with compact layout when compact prop is true", (): void => { const { container } = render( ); // Verify compact class is applied expect(container.querySelector(".p-3")).toBeInTheDocument(); }); it("should render with full layout by default", (): void => { const { container } = render(); // Verify full padding is applied expect(container.querySelector(".p-4")).toBeInTheDocument(); }); });