// @vitest-environment jsdom import "@testing-library/jest-dom/vitest"; import { type ConditionEntry, type ConditionId, getConditionsForEdition, } from "@initiative/domain"; import { cleanup, render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { createRef, type RefObject } from "react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { RulesEditionProvider } from "../../contexts/index.js"; import { ConditionPicker } from "../condition-picker"; afterEach(cleanup); function renderPicker( overrides: Partial<{ activeConditions: readonly ConditionEntry[]; onToggle: (conditionId: ConditionId) => void; onSetValue: (conditionId: ConditionId, value: number) => void; onClose: () => void; }> = {}, ) { const onToggle = overrides.onToggle ?? vi.fn(); const onSetValue = overrides.onSetValue ?? vi.fn(); const onClose = overrides.onClose ?? vi.fn(); const anchorRef = createRef() as RefObject; const anchor = document.createElement("div"); document.body.appendChild(anchor); (anchorRef as { current: HTMLElement }).current = anchor; const result = render( , ); return { ...result, onToggle, onSetValue, onClose }; } describe("ConditionPicker", () => { it("renders edition-specific conditions from domain", () => { renderPicker(); const editionConditions = getConditionsForEdition("5.5e"); for (const def of editionConditions) { expect(screen.getByText(def.label)).toBeInTheDocument(); } }); it("active conditions are visually distinguished", () => { renderPicker({ activeConditions: [{ id: "blinded" }] }); const row = screen.getByText("Blinded").closest("div[class]"); expect(row?.className).toContain("bg-card/50"); }); it("clicking a condition calls onToggle with that condition's ID", async () => { const user = userEvent.setup(); const { onToggle } = renderPicker(); await user.click(screen.getByText("Poisoned")); expect(onToggle).toHaveBeenCalledWith("poisoned"); }); it("non-active conditions render with muted styling", () => { renderPicker({ activeConditions: [] }); const label = screen.getByText("Charmed"); expect(label.className).toContain("text-muted-foreground"); }); it("active condition labels use foreground color", () => { renderPicker({ activeConditions: [{ id: "charmed" }] }); const label = screen.getByText("Charmed"); expect(label.className).toContain("text-foreground"); }); });