import test from "node:test"; import assert from "node:assert/strict"; import { EventBus } from "../src/core/EventBus.js"; import { StateStore } from "../src/core/StateStore.js"; import { Inventory } from "../src/gameplay/Inventory.js"; import { QuestManager } from "../src/gameplay/QuestManager.js"; import { CommandRouter } from "../src/gameplay/CommandRouter.js"; function createHarness() { const bus = new EventBus(); let tick = 0; const store = new StateStore({ bus, clock: () => `2026-07-23T00:00:${String(tick++).padStart(2, "0")}.000Z`, }); const inventory = new Inventory(store); const quests = new QuestManager(store, bus); const commands = new CommandRouter({ store, bus, inventory }); store.setMode("PLAYING"); return { bus, store, inventory, quests, commands }; } test("vertical slice advances only from authoritative state conditions", async () => { const { store, commands } = createHarness(); assert.equal(commands.execute("ACTIVATE_TERMINAL"), false); assert.equal(store.state.quest.stage, 0); commands.execute("INSPECT_ARTWORK"); assert.equal(store.state.quest.stage, 1); commands.execute("COLLECT_DOCUMENT"); assert.equal(store.state.quest.stage, 2); assert.deepEqual(store.state.inventory.order, ["covenant-fragment-01"]); store.setMode("DOCUMENT"); commands.execute("VERIFY_DOCUMENT", { itemId: "covenant-fragment-01" }); assert.equal(store.state.quest.stage, 3); store.setMode("PLAYING"); commands.execute("ACTIVATE_TERMINAL"); assert.equal(store.state.quest.stage, 4); assert.equal(store.state.world.entities["door.exit"].locked, false); assert.equal(store.state.world.entities["door.exit"].open, true); const receipts = await store.whenSealed(); assert.deepEqual(receipts.map(receipt => receipt.eventType), [ "ARTWORK_INSPECTED", "OBJECTIVE_ADVANCED", "DOCUMENT_COLLECTED", "OBJECTIVE_ADVANCED", "DOCUMENT_VERIFIED", "OBJECTIVE_ADVANCED", "TERMINAL_UNLOCKED", "OBJECTIVE_ADVANCED", "DOOR_OPENED", ]); receipts.forEach((receipt, index) => { assert.equal(receipt.sequence, index + 1); assert.equal(receipt.previousHash, index ? receipts[index - 1].currentHash : "GENESIS"); }); }); test("lamp and couch actions are modeled independently from meshes", async () => { const { store, commands, bus } = createHarness(); let sitRequest = null; bus.on("PLAYER_SIT_REQUESTED", request => { sitRequest = request; }); commands.execute("TOGGLE_LAMP"); assert.equal(store.state.world.entities["lamp.floor"].on, false); commands.execute("TOGGLE_LAMP"); assert.equal(store.state.world.entities["lamp.floor"].on, true); const anchor = { position: [-2.2, 0.79, -3.12], yaw: Math.PI, pitch: 0 }; commands.execute("USE_COUCH", { anchor }); assert.equal(store.state.world.entities["couch.main"].used, true); assert.deepEqual(sitRequest.anchor, anchor); const receipts = await store.whenSealed(); assert.deepEqual(receipts.map(receipt => receipt.eventType), [ "LAMP_DEACTIVATED", "LAMP_ACTIVATED", "COUCH_USED", ]); }); test("world commands are rejected outside PLAYING mode", () => { const { store, commands } = createHarness(); store.setMode("PAUSED"); assert.equal(commands.execute("TOGGLE_LAMP"), false); assert.equal(commands.execute("COLLECT_DOCUMENT"), false); assert.equal(store.state.world.entities["lamp.floor"].on, true); assert.equal(store.state.world.entities["document.covenant"].present, true); });