/** * Tests for SpokeConfigurationForm Component */ import { describe, it, expect, vi } from "vitest"; import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import { SpokeConfigurationForm } from "./SpokeConfigurationForm"; import type { PublicInstanceIdentity } from "@/lib/api/federation"; describe("SpokeConfigurationForm", () => { const mockInstance: PublicInstanceIdentity = { id: "instance-123", instanceId: "test-instance-001", name: "Test Instance", url: "https://test.example.com", publicKey: "-----BEGIN PUBLIC KEY-----\nMOCKPUBLICKEY\n-----END PUBLIC KEY-----", capabilities: { supportsQuery: true, supportsCommand: true, supportsEvent: true, supportsAgentSpawn: false, protocolVersion: "1.0", }, metadata: { description: "Test instance description", }, createdAt: "2026-02-01T00:00:00Z", updatedAt: "2026-02-01T00:00:00Z", }; it("should render instance identity information", () => { const onSave = vi.fn(); render(); expect(screen.getByDisplayValue("Test Instance")).toBeInTheDocument(); expect(screen.getByText("test-instance-001")).toBeInTheDocument(); expect(screen.getByText("https://test.example.com")).toBeInTheDocument(); }); it("should render capability toggles with correct initial state", () => { const onSave = vi.fn(); render(); const queryToggle = screen.getByLabelText(/Query Support/i); const commandToggle = screen.getByLabelText(/Command Support/i); const eventToggle = screen.getByLabelText(/Event Support/i); const agentToggle = screen.getByLabelText(/Agent Spawn Support/i); expect(queryToggle).toBeChecked(); expect(commandToggle).toBeChecked(); expect(eventToggle).toBeChecked(); expect(agentToggle).not.toBeChecked(); }); it("should allow editing instance name", async () => { const onSave = vi.fn(); render(); const nameInput = screen.getByDisplayValue("Test Instance"); fireEvent.change(nameInput, { target: { value: "Updated Instance" } }); await waitFor(() => { expect(screen.getByDisplayValue("Updated Instance")).toBeInTheDocument(); }); }); it("should toggle capabilities", async () => { const onSave = vi.fn(); render(); const agentToggle = screen.getByLabelText(/Agent Spawn Support/i); expect(agentToggle).not.toBeChecked(); fireEvent.click(agentToggle); await waitFor(() => { expect(agentToggle).toBeChecked(); }); }); it("should call onSave with updated configuration", async () => { const onSave = vi.fn(); render(); // Change name const nameInput = screen.getByDisplayValue("Test Instance"); fireEvent.change(nameInput, { target: { value: "Updated Instance" } }); // Toggle agent spawn const agentToggle = screen.getByLabelText(/Agent Spawn Support/i); fireEvent.click(agentToggle); // Click save const saveButton = screen.getByText("Save Configuration"); fireEvent.click(saveButton); await waitFor(() => { expect(onSave).toHaveBeenCalledWith({ name: "Updated Instance", capabilities: { supportsQuery: true, supportsCommand: true, supportsEvent: true, supportsAgentSpawn: true, protocolVersion: "1.0", }, metadata: { description: "Test instance description", }, }); }); }); it("should display loading state when saving", () => { const onSave = vi.fn(); render(); const saveButton = screen.getByText("Saving..."); expect(saveButton).toBeDisabled(); }); it("should display error message when provided", () => { const onSave = vi.fn(); render( ); expect(screen.getByText("Unable to save configuration")).toBeInTheDocument(); }); it("should use PDA-friendly language in help text", () => { const onSave = vi.fn(); render(); // Should NOT use demanding language expect(screen.queryByText(/must/i)).not.toBeInTheDocument(); expect(screen.queryByText(/required/i)).not.toBeInTheDocument(); expect(screen.queryByText(/critical/i)).not.toBeInTheDocument(); // Should use friendly language (multiple instances expected) const friendlyText = screen.getAllByText(/Allows connected instances/i); expect(friendlyText.length).toBeGreaterThan(0); }); it("should truncate public key and show copy button", () => { const onSave = vi.fn(); render(); // Public key should be truncated expect(screen.getByText(/-----BEGIN PUBLIC KEY-----/)).toBeInTheDocument(); expect(screen.getByText(/Copy/i)).toBeInTheDocument(); }); it("should handle cancel action", async () => { const onSave = vi.fn(); const onCancel = vi.fn(); render(); const cancelButton = screen.getByText("Cancel"); fireEvent.click(cancelButton); await waitFor(() => { expect(onCancel).toHaveBeenCalled(); }); }); });