diff --git a/frontend/editor/public/locales/en-US/translation.toml b/frontend/editor/public/locales/en-US/translation.toml index af5ed16169..f577b168d5 100644 --- a/frontend/editor/public/locales/en-US/translation.toml +++ b/frontend/editor/public/locales/en-US/translation.toml @@ -7038,8 +7038,6 @@ totalEvents = "Total events · 24h" cancel = "Cancel" createKey = "Create key" done = "Done" -ipAllowlistHelper = "Comma-separated CIDR ranges. Leave blank to allow any IP." -ipAllowlistLabel = "IP allowlist" keyNameLabel = "Key name" keyNamePlaceholder = "e.g. Production · ingest" permissionsLabel = "Permissions" diff --git a/frontend/editor/src/portal/components/infrastructure/CreateKeyModal.test.tsx b/frontend/editor/src/portal/components/infrastructure/CreateKeyModal.test.tsx new file mode 100644 index 0000000000..b5a9c58c0c --- /dev/null +++ b/frontend/editor/src/portal/components/infrastructure/CreateKeyModal.test.tsx @@ -0,0 +1,50 @@ +import type { ComponentProps } from "react"; +import { describe, expect, it, vi } from "vitest"; +import { fireEvent, render, screen } from "@testing-library/react"; +import { MantineProvider } from "@mantine/core"; + +// Deterministic i18n: keys returned verbatim, so assertions are stable. +vi.mock("react-i18next", () => ({ + useTranslation: () => ({ + t: (key: string) => key, + i18n: { changeLanguage: vi.fn() }, + }), +})); + +import { CreateKeyModal } from "@portal/components/infrastructure/CreateKeyModal"; + +const K = "portal.infrastructure.createKey"; + +function renderModal(props: Partial>) { + return render( + + {}} {...props} /> + , + ); +} + +describe("CreateKeyModal", () => { + it("gates the create button on a name and at least one permission", () => { + renderModal({}); + const cta = screen.getByRole("button", { name: `${K}.createKey` }); + expect(cta).toBeDisabled(); + + fireEvent.change(screen.getByPlaceholderText(`${K}.keyNamePlaceholder`), { + target: { value: "Production ingest" }, + }); + expect(cta).toBeEnabled(); + }); + + it("reveals the generated secret with a store-it warning", () => { + renderModal({}); + fireEvent.change(screen.getByPlaceholderText(`${K}.keyNamePlaceholder`), { + target: { value: "Production ingest" }, + }); + fireEvent.click(screen.getByRole("button", { name: `${K}.createKey` })); + + expect(screen.getByText(`${K}.secretWarning`)).toBeInTheDocument(); + expect( + screen.getByText("sk_live_demo_key_rotate_in_prod"), + ).toBeInTheDocument(); + }); +}); diff --git a/frontend/editor/src/portal/components/infrastructure/CreateKeyModal.tsx b/frontend/editor/src/portal/components/infrastructure/CreateKeyModal.tsx index 613eb97377..00a80d6cc1 100644 --- a/frontend/editor/src/portal/components/infrastructure/CreateKeyModal.tsx +++ b/frontend/editor/src/portal/components/infrastructure/CreateKeyModal.tsx @@ -27,13 +27,11 @@ export function CreateKeyModal({ const { t } = useTranslation(); const [name, setName] = useState(""); const [perms, setPerms] = useState(["Read"]); - const [ips, setIps] = useState(""); const [created, setCreated] = useState(false); function reset() { setName(""); setPerms(["Read"]); - setIps(""); setCreated(false); } @@ -50,8 +48,8 @@ export function CreateKeyModal({ } function createKey() { - // TODO(backend): POST /v1/infrastructure/api-keys { name, perms, ips } - // and render the one-time secret from the response instead of the fixture. + // TODO(backend): POST /v1/infrastructure/api-keys { name, perms } and render + // the one-time secret from the response instead of the fixture. setCreated(true); } @@ -133,17 +131,6 @@ export function CreateKeyModal({ ))} - - - setIps(e.target.value)} - placeholder="52.14.0.0/16, 203.0.113.7/32" - /> - )}