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 }); }); });