118 lines
4.1 KiB
TypeScript
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 });
|
|
});
|
|
});
|