// @vitest-environment jsdom import { playerCharacterId } from "@initiative/domain"; import { act, renderHook } from "@testing-library/react"; import type { ReactNode } from "react"; import { beforeAll, describe, expect, it, vi } from "vitest"; import { createTestAdapters } from "../../__tests__/adapters/in-memory-adapters.js"; import { AllProviders } from "../../__tests__/test-providers.js"; import { usePlayerCharacters } from "../use-player-characters.js"; beforeAll(() => { Object.defineProperty(globalThis, "matchMedia", { writable: true, value: vi.fn().mockImplementation((query: string) => ({ matches: false, media: query, onchange: null, addListener: vi.fn(), removeListener: vi.fn(), addEventListener: vi.fn(), removeEventListener: vi.fn(), dispatchEvent: vi.fn(), })), }); }); function wrapper({ children }: { children: ReactNode }) { return {children}; } describe("usePlayerCharacters", () => { it("initializes with characters from persistence", () => { const stored = [ { id: playerCharacterId("pc-1"), name: "Aria", ac: 16, maxHp: 30, color: undefined, icon: undefined, }, ]; const adapters = createTestAdapters({ playerCharacters: stored }); const { result } = renderHook(() => usePlayerCharacters(), { wrapper: ({ children }: { children: ReactNode }) => ( {children} ), }); expect(result.current.characters).toEqual(stored); }); it("createCharacter adds a character and persists", () => { const { result } = renderHook(() => usePlayerCharacters(), { wrapper }); act(() => { result.current.createCharacter( "Vex", 15, 28, undefined, undefined, undefined, ); }); expect(result.current.characters).toHaveLength(1); expect(result.current.characters[0].name).toBe("Vex"); expect(result.current.characters[0].ac).toBe(15); expect(result.current.characters[0].maxHp).toBe(28); }); it("createCharacter returns domain error for empty name", () => { const { result } = renderHook(() => usePlayerCharacters(), { wrapper }); let error: unknown; act(() => { error = result.current.createCharacter( "", 15, 28, undefined, undefined, undefined, ); }); expect(error).toMatchObject({ kind: "domain-error" }); expect(result.current.characters).toHaveLength(0); }); it("editCharacter updates character and persists", () => { const { result } = renderHook(() => usePlayerCharacters(), { wrapper }); act(() => { result.current.createCharacter( "Vex", 15, 28, undefined, undefined, undefined, ); }); const id = result.current.characters[0].id; act(() => { result.current.editCharacter(id, { name: "Vex'ahlia" }); }); expect(result.current.characters[0].name).toBe("Vex'ahlia"); }); it("deleteCharacter removes character and persists", () => { const { result } = renderHook(() => usePlayerCharacters(), { wrapper }); act(() => { result.current.createCharacter( "Vex", 15, 28, undefined, undefined, undefined, ); }); const id = result.current.characters[0].id; act(() => { result.current.deleteCharacter(id); }); expect(result.current.characters).toHaveLength(0); }); });