import { screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { SystemSecretRow } from "@/components/ui/system-secret-row"; import type { SystemSecretStatus } from "@/lib/types"; import { renderWithQueryClient } from "./test-utils"; const unconfiguredSecret: SystemSecretStatus = { key: "turnstile_secret", label: "Turnstile Secret Key", configured: false, value: null, }; const configuredSecret: SystemSecretStatus = { key: "turnstile_site_key", label: "Turnstile Site Key", configured: true, value: "0x-my-site-key", }; beforeEach(() => { vi.stubGlobal("fetch", vi.fn()); }); describe("SystemSecretRow", () => { it("shows the label and a masked input for a configured secret", () => { renderWithQueryClient(); expect(screen.getByText("Turnstile Site Key")).toBeInTheDocument(); const textbox = screen.getByDisplayValue("0x-my-site-key") as HTMLInputElement; expect(textbox.type).toBe("password"); }); it("toggles the input between masked and revealed", async () => { const user = userEvent.setup(); renderWithQueryClient(); const textbox = screen.getByDisplayValue("0x-my-site-key") as HTMLInputElement; expect(textbox.type).toBe("password"); await user.click(screen.getByTitle(/show key/i)); expect(textbox.type).toBe("text"); await user.click(screen.getByTitle(/hide key/i)); expect(textbox.type).toBe("password"); }); it("disables Update until the value actually changes", async () => { const user = userEvent.setup(); renderWithQueryClient(); const updateButton = screen.getByRole("button", { name: /update/i }); expect(updateButton).toBeDisabled(); const textbox = screen.getByPlaceholderText(/not set/i); await user.type(textbox, "sk-new-secret"); expect(updateButton).toBeEnabled(); }); it("submits the new value via PUT to the keyed endpoint and reflects the saved value", async () => { const fetchMock = vi.fn().mockResolvedValue({ ok: true, status: 200, json: async () => ({ ...unconfiguredSecret, configured: true, value: "sk-new-secret" }), }); vi.stubGlobal("fetch", fetchMock); const user = userEvent.setup(); renderWithQueryClient(); const textbox = screen.getByPlaceholderText(/not set/i); await user.type(textbox, "sk-new-secret"); await user.click(screen.getByRole("button", { name: /update/i })); await waitFor(() => { expect(fetchMock).toHaveBeenCalledWith( expect.stringContaining("/api/v1/system/secrets/turnstile_secret"), expect.objectContaining({ method: "PUT", body: JSON.stringify({ value: "sk-new-secret" }), }), ); }); await waitFor(() => { expect(screen.getByDisplayValue("sk-new-secret")).toBeInTheDocument(); }); }); });