// @vitest-environment jsdom import { playerCharacterId } from "@initiative/domain"; import { act, renderHook } from "@testing-library/react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { usePlayerCharacters } from "../use-player-characters.js"; vi.mock("../../persistence/player-character-storage.js", () => ({ loadPlayerCharacters: vi.fn().mockReturnValue([]), savePlayerCharacters: vi.fn(), })); const { loadPlayerCharacters: mockLoad, savePlayerCharacters: mockSave } = await vi.importMock< typeof import("../../persistence/player-character-storage.js") >("../../persistence/player-character-storage.js"); describe("usePlayerCharacters", () => { beforeEach(() => { vi.clearAllMocks(); mockLoad.mockReturnValue([]); }); it("initializes with characters from persistence", () => { const stored = [ { id: playerCharacterId("pc-1"), name: "Aria", ac: 16, maxHp: 30, color: undefined, icon: undefined, }, ]; mockLoad.mockReturnValue(stored); const { result } = renderHook(() => usePlayerCharacters()); expect(result.current.characters).toEqual(stored); }); it("createCharacter adds a character and persists", () => { const { result } = renderHook(() => usePlayerCharacters()); act(() => { result.current.createCharacter("Vex", 15, 28, 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); expect(mockSave).toHaveBeenCalled(); }); it("createCharacter returns domain error for empty name", () => { const { result } = renderHook(() => usePlayerCharacters()); let error: unknown; act(() => { error = result.current.createCharacter("", 15, 28, undefined, undefined); }); expect(error).toMatchObject({ kind: "domain-error" }); expect(result.current.characters).toHaveLength(0); }); it("editCharacter updates character and persists", () => { const { result } = renderHook(() => usePlayerCharacters()); act(() => { result.current.createCharacter("Vex", 15, 28, 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"); expect(mockSave).toHaveBeenCalled(); }); it("deleteCharacter removes character and persists", () => { const { result } = renderHook(() => usePlayerCharacters()); act(() => { result.current.createCharacter("Vex", 15, 28, undefined, undefined); }); const id = result.current.characters[0].id; act(() => { result.current.deleteCharacter(id); }); expect(result.current.characters).toHaveLength(0); expect(mockSave).toHaveBeenCalled(); }); });