60 lines
2.6 KiB
TypeScript
60 lines
2.6 KiB
TypeScript
// @vitest-environment jsdom
|
|
|
|
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
import { renderToStaticMarkup } from "react-dom/server";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import { AdminModalForm } from "./admin-modal-form";
|
|
|
|
beforeEach(() => {
|
|
HTMLDialogElement.prototype.showModal = function showModal() { this.open = true; };
|
|
HTMLDialogElement.prototype.close = function close() {
|
|
this.open = false;
|
|
this.dispatchEvent(new Event("close"));
|
|
};
|
|
});
|
|
|
|
describe("AdminModalForm", () => {
|
|
it("renders an accessible trigger, labelled dialog, cancellation, and pending-capable submit control", () => {
|
|
const markup = renderToStaticMarkup(
|
|
<AdminModalForm
|
|
action={async () => undefined}
|
|
description="Review this policy change before applying it."
|
|
submitLabel="Apply policy"
|
|
title="Change access policy"
|
|
triggerLabel="Change"
|
|
>
|
|
<input name="groupId" type="hidden" value="group-one" />
|
|
</AdminModalForm>,
|
|
);
|
|
expect(markup).toContain("Change access policy");
|
|
expect(markup).toContain("Review this policy change before applying it.");
|
|
expect(markup).toContain("<dialog");
|
|
expect(markup).toContain("aria-haspopup=\"dialog\"");
|
|
expect(markup).toContain("Cancel");
|
|
expect(markup).toContain("Apply policy");
|
|
});
|
|
|
|
it("opens, cancels, and prevents dismissal while the action is pending", async () => {
|
|
let finishAction!: () => void;
|
|
const action = vi.fn(() => new Promise<void>((resolve) => { finishAction = resolve; }));
|
|
render(<AdminModalForm action={action} description="Confirm it." submitLabel="Apply policy" title="Change access policy" triggerLabel="Change" />);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "Change" }));
|
|
const dialog = screen.getByRole("dialog") as HTMLDialogElement;
|
|
expect(dialog.open).toBe(true);
|
|
fireEvent.click(screen.getByRole("button", { name: "Apply policy" }));
|
|
await waitFor(() => expect(action).toHaveBeenCalledOnce());
|
|
expect((screen.getByRole("button", { name: "Change" }) as HTMLButtonElement).disabled).toBe(true);
|
|
|
|
const cancelEvent = new Event("cancel", { bubbles: false, cancelable: true });
|
|
dialog.dispatchEvent(cancelEvent);
|
|
expect(cancelEvent.defaultPrevented).toBe(true);
|
|
expect(dialog.open).toBe(true);
|
|
|
|
finishAction();
|
|
await waitFor(() => expect((screen.getByRole("button", { name: "Change" }) as HTMLButtonElement).disabled).toBe(false));
|
|
fireEvent.click(screen.getByRole("button", { name: "Cancel" }));
|
|
expect(dialog.open).toBe(false);
|
|
});
|
|
});
|