Files
initiative/packages/domain/src/__tests__/edit-player-character.test.ts
Lukas 36768d3aa1 Upgrade Biome to 2.4.7 and enable 54 additional lint rules
Add rules covering bug prevention (noLeakedRender, noFloatingPromises,
noImportCycles, noReactForwardRef), security (noScriptUrl, noAlert),
performance (noAwaitInLoops, useTopLevelRegex), and code style
(noNestedTernary, useGlobalThis, useNullishCoalescing, useSortedClasses,
plus ~40 more). Fix all violations: extract top-level regex constants,
guard React && renders with boolean coercion, refactor nested ternaries,
replace window with globalThis, sort Tailwind classes, and introduce
expectDomainError test helper to eliminate conditional expects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 14:25:09 +01:00

114 lines
3.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { editPlayerCharacter } from "../edit-player-character.js";
import type { PlayerCharacter } from "../player-character-types.js";
import { playerCharacterId } from "../player-character-types.js";
import { isDomainError } from "../types.js";
import { expectDomainError } from "./test-helpers.js";
const id = playerCharacterId("pc-1");
function makePC(overrides?: Partial<PlayerCharacter>): PlayerCharacter {
return {
id,
name: "Aragorn",
ac: 16,
maxHp: 120,
color: "green",
icon: "sword",
...overrides,
};
}
describe("editPlayerCharacter", () => {
it("edits name successfully", () => {
const result = editPlayerCharacter([makePC()], id, { name: "Strider" });
if (isDomainError(result)) throw new Error(result.message);
expect(result.characters[0].name).toBe("Strider");
expect(result.events[0].type).toBe("PlayerCharacterUpdated");
});
it("edits multiple fields", () => {
const result = editPlayerCharacter([makePC()], id, {
name: "Strider",
ac: 18,
});
if (isDomainError(result)) throw new Error(result.message);
expect(result.characters[0].name).toBe("Strider");
expect(result.characters[0].ac).toBe(18);
});
it("returns error for not-found id", () => {
const result = editPlayerCharacter(
[makePC()],
playerCharacterId("pc-999"),
{ name: "Nope" },
);
expectDomainError(result, "player-character-not-found");
});
it("rejects empty name", () => {
const result = editPlayerCharacter([makePC()], id, { name: "" });
expectDomainError(result, "invalid-name");
});
it("rejects invalid AC", () => {
const result = editPlayerCharacter([makePC()], id, { ac: -1 });
expectDomainError(result, "invalid-ac");
});
it("rejects invalid maxHp", () => {
const result = editPlayerCharacter([makePC()], id, { maxHp: 0 });
expectDomainError(result, "invalid-max-hp");
});
it("rejects invalid color", () => {
const result = editPlayerCharacter([makePC()], id, { color: "neon" });
expectDomainError(result, "invalid-color");
});
it("rejects invalid icon", () => {
const result = editPlayerCharacter([makePC()], id, { icon: "banana" });
expectDomainError(result, "invalid-icon");
});
it("returns error when no fields changed", () => {
const pc = makePC();
const result = editPlayerCharacter([pc], id, {
name: pc.name,
ac: pc.ac,
});
expectDomainError(result, "no-changes");
});
it("emits exactly one event on success", () => {
const result = editPlayerCharacter([makePC()], id, { name: "Strider" });
if (isDomainError(result)) throw new Error(result.message);
expect(result.events).toHaveLength(1);
});
it("clears color when set to null", () => {
const result = editPlayerCharacter([makePC({ color: "green" })], id, {
color: null,
});
if (isDomainError(result)) throw new Error(result.message);
expect(result.characters[0].color).toBeUndefined();
});
it("clears icon when set to null", () => {
const result = editPlayerCharacter([makePC({ icon: "sword" })], id, {
icon: null,
});
if (isDomainError(result)) throw new Error(result.message);
expect(result.characters[0].icon).toBeUndefined();
});
it("event includes old and new name", () => {
const result = editPlayerCharacter([makePC()], id, { name: "Strider" });
if (isDomainError(result)) throw new Error(result.message);
const event = result.events[0];
if (event.type !== "PlayerCharacterUpdated") throw new Error("wrong event");
expect(event.oldName).toBe("Aragorn");
expect(event.newName).toBe("Strider");
});
});