Files
healer-man/src/app/gmManastormRuntime.test.ts
T
2026-09-01 14:35:56 -04:00

118 lines
4.1 KiB
TypeScript

import { beforeEach, describe, expect, it } from "vitest";
import { createDefaultAppearance } from "./characterCatalog";
import { enterRandomGmReview } from "./gmManastormRuntime";
import { useShellStore } from "./shellStore";
import { DUNGEON_CATALOG } from "../game/dungeonCatalog";
import {
DEFAULT_MANASTORM_ADMIN_CONFIG,
resolvedBossAdminCatalog,
type ManastormAdminConfig,
} from "../game/manastormAdminConfig";
import { useManastormAdminStore } from "../game/manastormAdminStore";
import { useManastormStore } from "../game/manastormStore";
import { useGameStore } from "../game/store";
const character = {
id: "gm-character",
ownerId: "gm-account",
name: "Verifier",
raceId: "human" as const,
classId: "priest" as const,
gender: "female" as const,
appearance: createDefaultAppearance(),
level: 20,
experience: 0,
talentRanks: {},
actionBindings: {},
inventory: [],
equipment: {},
location: "GM Tools",
createdAt: 1,
lastPlayedAt: 1,
};
function prepareGm(config: ManastormAdminConfig): void {
useShellStore.setState({
phase: "gm-admin",
session: {
kind: "account",
ownerId: "gm-account",
displayName: "Game Master",
accessToken: "gm-token",
roles: ["gm"],
},
characters: [character],
selectedCharacterId: character.id,
activeCharacter: null,
notice: "",
});
useManastormAdminStore.setState({ config, draft: config, dirty: false, saving: false, error: null });
}
describe("GM random review runtime", () => {
beforeEach(() => {
useGameStore.getState().resetAtEntrance();
useManastormStore.getState().resetRun();
useGameStore.setState({ activeGmReviewTarget: null, gmTestMode: false });
});
it("launches the exact remaining dungeon in GM test mode", () => {
const available = DUNGEON_CATALOG.filter((dungeon) => dungeon.available);
const selected = available[0];
const config: ManastormAdminConfig = {
...DEFAULT_MANASTORM_ADMIN_CONFIG,
dungeons: Object.fromEntries(available.map((dungeon) => [
dungeon.id,
{ status: dungeon.id === selected.id ? "needs-tested" : "ready" },
])),
};
prepareGm(config);
expect(enterRandomGmReview("dungeon")).toBe(true);
expect(useShellStore.getState()).toMatchObject({ phase: "game", activeDungeonId: selected.id });
expect(useGameStore.getState()).toMatchObject({
gmTestMode: true,
activeGmReviewTarget: { kind: "dungeon", dungeonId: selected.id },
});
});
it("allows a runnable Not ready Manastorm in an isolated GM review", () => {
const catalog = resolvedBossAdminCatalog(DEFAULT_MANASTORM_ADMIN_CONFIG);
const selected = catalog.find((entry) => entry.runnable && entry.source.includes("installed-manastorm"));
expect(selected).toBeTruthy();
const config: ManastormAdminConfig = {
...DEFAULT_MANASTORM_ADMIN_CONFIG,
bosses: Object.fromEntries(catalog.map((entry) => [
entry.key,
{ status: entry.key === selected!.key ? "not-ready" : "ready" },
])),
};
prepareGm(config);
expect(enterRandomGmReview("manastorm")).toBe(true);
expect(useGameStore.getState()).toMatchObject({
gameMode: "manastorm",
gmTestMode: true,
activeGmReviewTarget: { kind: "manastorm", bossKey: selected!.key },
});
expect(useManastormStore.getState().currentEncounter?.bossName).toBe(selected!.name);
});
it("rejects non-GM sessions and clears review context when leaving", () => {
prepareGm(DEFAULT_MANASTORM_ADMIN_CONFIG);
useShellStore.setState({
session: { kind: "offline", ownerId: "gm-account", displayName: "Offline", roles: ["gm"] },
});
expect(enterRandomGmReview("dungeon")).toBe(false);
expect(useGameStore.getState().activeGmReviewTarget).toBeNull();
prepareGm(DEFAULT_MANASTORM_ADMIN_CONFIG);
useGameStore.setState({
gmTestMode: true,
activeGmReviewTarget: { kind: "dungeon", dungeonId: DUNGEON_CATALOG[0].id },
});
useShellStore.getState().returnToMainMenu();
expect(useGameStore.getState()).toMatchObject({ activeGmReviewTarget: null, gmTestMode: false });
});
});