Files
HiveGrid-Wireframes/03 Quellen und Referenzen/hivegrid-cloud/apps/web/app/components/screens/api/ApiKeyEditDialog.test.tsx
T

73 lines
2.9 KiB
TypeScript

// Guards the contract the edit route relies on after "Bearbeiten" moved from the
// boilerplate ApiKeyForm onto the shared FormDialog: saving reports the trimmed
// fields, and rotate and delete both ask before they run — the old FormGroup
// wired its delete straight to a submit.
import { fireEvent, render, screen } from "@testing-library/react";
import "@testing-library/jest-dom/vitest";
import { describe, expect, it, vi } from "vitest";
import { ApiKeyEditDialog, type ApiKeyEditData } from "./ApiKeyEditDialog";
vi.mock("react-i18next", () => ({
useTranslation: () => ({ t: (s: string) => s, i18n: { language: "de" } }),
}));
const DATA: ApiKeyEditData = {
redactedKey: "hgd_demo…••••auth",
alias: "Website Lead Intake",
expires: "",
active: true,
canUpdate: true,
canDelete: true,
canRotate: true,
};
function renderDialog(overrides: Partial<ApiKeyEditData> = {}) {
const handlers = { onSave: vi.fn(), onRotate: vi.fn(), onDelete: vi.fn(), onClose: vi.fn() };
render(<ApiKeyEditDialog data={{ ...DATA, ...overrides }} submitting={false} errorMessage={null} {...handlers} />);
return handlers;
}
const byId = (id: string) => document.querySelector(`[data-ui-id='${id}']`) as HTMLButtonElement;
describe("ApiKeyEditDialog", () => {
it("prefills the key and reports the trimmed save", () => {
const { onSave } = renderDialog({ expires: "2027-01-31" });
expect(screen.getByLabelText("models.apiKey.alias")).toHaveValue("Website Lead Intake");
fireEvent.change(screen.getByLabelText("models.apiKey.alias"), { target: { value: " Intake " } });
fireEvent.click(byId("ui.settings.apiKeys.editDialog.submit"));
expect(onSave).toHaveBeenCalledWith({ alias: "Intake", expires: "2027-01-31", active: true });
});
it("asks before rotating and only then reports it", () => {
const { onRotate } = renderDialog();
fireEvent.click(byId("ui.settings.apiKeys.editDialog.rotate"));
expect(onRotate).not.toHaveBeenCalled();
expect(screen.getByText("models.apiKey.rotateBody")).toBeInTheDocument();
fireEvent.click(byId("ui.settings.apiKeys.editDialog.rotateSubmit"));
expect(onRotate).toHaveBeenCalledTimes(1);
});
it("asks before deleting and only then reports it", () => {
const { onDelete } = renderDialog();
fireEvent.click(byId("ui.settings.apiKeys.editDialog.delete"));
expect(onDelete).not.toHaveBeenCalled();
fireEvent.click(byId("ui.settings.apiKeys.editDialog.deleteSubmit"));
expect(onDelete).toHaveBeenCalledTimes(1);
});
it("hides the actions a viewer is not allowed to run", () => {
renderDialog({ canDelete: false, canRotate: false, canUpdate: false });
expect(byId("ui.settings.apiKeys.editDialog.delete")).toBeNull();
expect(byId("ui.settings.apiKeys.editDialog.rotate")).toBeNull();
expect(byId("ui.settings.apiKeys.editDialog.submit")).toBeDisabled();
expect(screen.getByLabelText("models.apiKey.alias")).toBeDisabled();
});
});