import { expect } from "@esm-bundle/chai"; import sinon from "sinon"; import { gameStateManager, GameStateManager, } from "../../../src/core/GameStateManager.js"; describe("Core: GameStateManager - Inventory Integration", () => { let mockPersistence; let mockGameLoop; let mockInventoryManager; let mockRunStash; beforeEach(() => { // Reset Singleton State gameStateManager.reset(); // Mock InventoryManager mockRunStash = { id: "RUN_LOOT", getAllItems: sinon.stub().returns([ { uid: "ITEM_001", defId: "ITEM_RUSTY_BLADE", isNew: false, quantity: 1, }, { uid: "ITEM_002", defId: "ITEM_SCRAP_PLATE", isNew: true, quantity: 1, }, ]), currency: { aetherShards: 150, ancientCores: 2, }, }; mockInventoryManager = { runStash: mockRunStash, hubStash: { id: "HUB_VAULT", getAllItems: sinon.stub().returns([]), currency: { aetherShards: 0, ancientCores: 0, }, }, }; // Mock Persistence mockPersistence = { init: sinon.stub().resolves(), saveRun: sinon.stub().resolves(), loadRun: sinon.stub().resolves(null), loadRoster: sinon.stub().resolves(null), saveRoster: sinon.stub().resolves(), loadHubStash: sinon.stub().resolves(null), saveHubStash: sinon.stub().resolves(), loadUnlocks: sinon.stub().resolves([]), saveUnlocks: sinon.stub().resolves(), }; gameStateManager.persistence = mockPersistence; // Mock GameLoop with inventoryManager mockGameLoop = { init: sinon.spy(), startLevel: sinon.stub().resolves(), stop: sinon.spy(), inventoryManager: mockInventoryManager, }; gameStateManager.gameLoop = mockGameLoop; // Mock MissionManager gameStateManager.missionManager = { setupActiveMission: sinon.stub(), getActiveMission: sinon.stub().returns({ id: "MISSION_TUTORIAL_01", config: { title: "Test Mission" }, biome: { generator_config: { seed_type: "RANDOM", seed: 12345, }, }, objectives: [], }), playIntro: sinon.stub().resolves(), }; // Set gameLoop so gameLoopInitialized promise can resolve gameStateManager.gameLoop = mockGameLoop; // Call the internal method that resolves the promise (simulating init completion) // We need to trigger the resolution - check if there's a method or we need to call init }); it("CoA 1: _initializeRun should include inventory data in runData", async () => { // Initialize gameStateManager first await gameStateManager.init(); // Use setGameLoop to properly resolve the promise gameStateManager.setGameLoop(mockGameLoop); const squadManifest = [ { id: "UNIT_001", classId: "CLASS_VANGUARD", name: "Test Vanguard", }, ]; await gameStateManager._initializeRun(squadManifest); // Verify saveRun was called expect(mockPersistence.saveRun.calledOnce).to.be.true; // Get the saved run data const savedData = mockPersistence.saveRun.firstCall.args[0]; // Verify inventory data is included expect(savedData.inventory).to.exist; expect(savedData.inventory.runStash).to.exist; expect(savedData.inventory.runStash.id).to.equal("RUN_LOOT"); expect(savedData.inventory.runStash.items).to.be.an("array"); expect(savedData.inventory.runStash.items.length).to.equal(2); expect(savedData.inventory.runStash.currency).to.exist; expect(savedData.inventory.runStash.currency.aetherShards).to.equal(150); expect(savedData.inventory.runStash.currency.ancientCores).to.equal(2); }); it("CoA 2: _initializeRun should handle missing inventoryManager gracefully", async () => { await gameStateManager.init(); // Remove inventoryManager mockGameLoop.inventoryManager = null; gameStateManager.setGameLoop(mockGameLoop); const squadManifest = [ { id: "UNIT_001", classId: "CLASS_VANGUARD", name: "Test Vanguard", }, ]; await gameStateManager._initializeRun(squadManifest); // Should still save without error expect(mockPersistence.saveRun.calledOnce).to.be.true; const savedData = mockPersistence.saveRun.firstCall.args[0]; // Inventory should be undefined if manager doesn't exist expect(savedData.inventory).to.be.undefined; }); it("CoA 3: saved inventory should include item instances with uid", async () => { await gameStateManager.init(); gameStateManager.setGameLoop(mockGameLoop); const squadManifest = [ { id: "UNIT_001", classId: "CLASS_VANGUARD", name: "Test Vanguard", }, ]; await gameStateManager._initializeRun(squadManifest); const savedData = mockPersistence.saveRun.firstCall.args[0]; // Verify items have uid (not just defId) expect(savedData.inventory.runStash.items[0].uid).to.equal("ITEM_001"); expect(savedData.inventory.runStash.items[0].defId).to.equal("ITEM_RUSTY_BLADE"); expect(savedData.inventory.runStash.items[0].quantity).to.equal(1); }); it("CoA 4: saved inventory should preserve currency values", async () => { await gameStateManager.init(); gameStateManager.setGameLoop(mockGameLoop); const squadManifest = [ { id: "UNIT_001", classId: "CLASS_VANGUARD", name: "Test Vanguard", }, ]; await gameStateManager._initializeRun(squadManifest); const savedData = mockPersistence.saveRun.firstCall.args[0]; // Verify currency is saved correctly expect(savedData.inventory.runStash.currency.aetherShards).to.equal(150); expect(savedData.inventory.runStash.currency.ancientCores).to.equal(2); }); });