73 lines
2.9 KiB
TypeScript
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();
|
|
});
|
|
});
|