Add comprehensive tests for the InventoryManager and InventoryContainer to validate item management functionalities. Implement integration tests for the CharacterSheet component, ensuring proper interaction with the inventory system. Update the Explorer class to support new inventory features and maintain backward compatibility. Refactor related components for improved clarity and performance.
195 lines
5.6 KiB
JavaScript
195 lines
5.6 KiB
JavaScript
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(),
|
|
};
|
|
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);
|
|
});
|
|
});
|
|
|