Adds tests for DifficultyIndicator, Toast, RollModeMenu, OverflowMenu, useTheme, and useRulesEdition. Covers rendering, user interactions, auto-dismiss timers, external store sync, and localStorage persistence. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { cleanup, render, screen } from "@testing-library/react";
|
|
import { userEvent } from "@testing-library/user-event";
|
|
import { Circle } from "lucide-react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { OverflowMenu } from "../ui/overflow-menu.js";
|
|
|
|
afterEach(cleanup);
|
|
|
|
const items = [
|
|
{ icon: <Circle />, label: "Action A", onClick: vi.fn() },
|
|
{ icon: <Circle />, label: "Action B", onClick: vi.fn() },
|
|
];
|
|
|
|
describe("OverflowMenu", () => {
|
|
it("renders toggle button", () => {
|
|
render(<OverflowMenu items={items} />);
|
|
expect(screen.getByRole("button", { name: "More actions" })).toBeDefined();
|
|
});
|
|
|
|
it("does not show menu items when closed", () => {
|
|
render(<OverflowMenu items={items} />);
|
|
expect(screen.queryByText("Action A")).toBeNull();
|
|
});
|
|
|
|
it("shows menu items when toggled open", async () => {
|
|
render(<OverflowMenu items={items} />);
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: "More actions" }));
|
|
|
|
expect(screen.getByText("Action A")).toBeDefined();
|
|
expect(screen.getByText("Action B")).toBeDefined();
|
|
});
|
|
|
|
it("closes menu after clicking an item", async () => {
|
|
const onClick = vi.fn();
|
|
render(
|
|
<OverflowMenu items={[{ icon: <Circle />, label: "Do it", onClick }]} />,
|
|
);
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: "More actions" }));
|
|
await userEvent.click(screen.getByText("Do it"));
|
|
|
|
expect(onClick).toHaveBeenCalledOnce();
|
|
expect(screen.queryByText("Do it")).toBeNull();
|
|
});
|
|
|
|
it("keeps menu open when keepOpen is true", async () => {
|
|
const onClick = vi.fn();
|
|
render(
|
|
<OverflowMenu
|
|
items={[
|
|
{
|
|
icon: <Circle />,
|
|
label: "Stay",
|
|
onClick,
|
|
keepOpen: true,
|
|
},
|
|
]}
|
|
/>,
|
|
);
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: "More actions" }));
|
|
await userEvent.click(screen.getByText("Stay"));
|
|
|
|
expect(onClick).toHaveBeenCalledOnce();
|
|
expect(screen.getByText("Stay")).toBeDefined();
|
|
});
|
|
|
|
it("disables items when disabled is true", async () => {
|
|
const onClick = vi.fn();
|
|
render(
|
|
<OverflowMenu
|
|
items={[
|
|
{
|
|
icon: <Circle />,
|
|
label: "Nope",
|
|
onClick,
|
|
disabled: true,
|
|
},
|
|
]}
|
|
/>,
|
|
);
|
|
|
|
await userEvent.click(screen.getByRole("button", { name: "More actions" }));
|
|
const item = screen.getByText("Nope");
|
|
expect(item.closest("button")?.hasAttribute("disabled")).toBe(true);
|
|
});
|
|
});
|