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.
228 lines
7.6 KiB
JavaScript
228 lines
7.6 KiB
JavaScript
import { expect } from "@esm-bundle/chai";
|
|
import sinon from "sinon";
|
|
import { MissionManager } from "../../src/managers/MissionManager.js";
|
|
import { narrativeManager } from "../../src/managers/NarrativeManager.js";
|
|
|
|
describe("Manager: MissionManager", () => {
|
|
let manager;
|
|
let mockNarrativeManager;
|
|
|
|
beforeEach(() => {
|
|
manager = new MissionManager();
|
|
|
|
// Mock narrativeManager
|
|
mockNarrativeManager = {
|
|
startSequence: sinon.stub(),
|
|
addEventListener: sinon.stub(),
|
|
removeEventListener: sinon.stub(),
|
|
};
|
|
|
|
// Replace the singleton reference in the manager if possible
|
|
// Since it's imported, we'll need to stub the methods we use
|
|
sinon.stub(narrativeManager, "startSequence");
|
|
sinon.stub(narrativeManager, "addEventListener");
|
|
sinon.stub(narrativeManager, "removeEventListener");
|
|
});
|
|
|
|
afterEach(() => {
|
|
sinon.restore();
|
|
});
|
|
|
|
it("CoA 1: Should initialize with tutorial mission registered", () => {
|
|
expect(manager.missionRegistry.has("MISSION_TUTORIAL_01")).to.be.true;
|
|
expect(manager.activeMissionId).to.be.null;
|
|
expect(manager.completedMissions).to.be.instanceof(Set);
|
|
});
|
|
|
|
it("CoA 2: registerMission should add mission to registry", () => {
|
|
const newMission = {
|
|
id: "MISSION_TEST_01",
|
|
config: { title: "Test Mission" },
|
|
objectives: { primary: [] },
|
|
};
|
|
|
|
manager.registerMission(newMission);
|
|
|
|
expect(manager.missionRegistry.has("MISSION_TEST_01")).to.be.true;
|
|
expect(manager.missionRegistry.get("MISSION_TEST_01")).to.equal(newMission);
|
|
});
|
|
|
|
it("CoA 3: getActiveMission should return tutorial if no active mission", () => {
|
|
const mission = manager.getActiveMission();
|
|
|
|
expect(mission).to.exist;
|
|
expect(mission.id).to.equal("MISSION_TUTORIAL_01");
|
|
});
|
|
|
|
it("CoA 4: getActiveMission should return active mission if set", () => {
|
|
const testMission = {
|
|
id: "MISSION_TEST_01",
|
|
config: { title: "Test" },
|
|
objectives: { primary: [] },
|
|
};
|
|
manager.registerMission(testMission);
|
|
manager.activeMissionId = "MISSION_TEST_01";
|
|
|
|
const mission = manager.getActiveMission();
|
|
|
|
expect(mission.id).to.equal("MISSION_TEST_01");
|
|
});
|
|
|
|
it("CoA 5: setupActiveMission should initialize objectives", () => {
|
|
const mission = manager.getActiveMission();
|
|
mission.objectives = {
|
|
primary: [
|
|
{ type: "ELIMINATE_ALL", target_count: 5 },
|
|
{ type: "ELIMINATE_UNIT", target_def_id: "ENEMY_GOBLIN", target_count: 3 },
|
|
],
|
|
};
|
|
|
|
manager.setupActiveMission();
|
|
|
|
expect(manager.currentObjectives).to.have.length(2);
|
|
expect(manager.currentObjectives[0].current).to.equal(0);
|
|
expect(manager.currentObjectives[0].complete).to.be.false;
|
|
expect(manager.currentObjectives[1].target_count).to.equal(3);
|
|
});
|
|
|
|
it("CoA 6: onGameEvent should update ELIMINATE_ALL objectives", () => {
|
|
manager.setupActiveMission();
|
|
manager.currentObjectives = [
|
|
{ type: "ELIMINATE_ALL", target_count: 3, current: 0, complete: false },
|
|
];
|
|
|
|
manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_1" });
|
|
manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_2" });
|
|
manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_3" });
|
|
|
|
expect(manager.currentObjectives[0].current).to.equal(3);
|
|
expect(manager.currentObjectives[0].complete).to.be.true;
|
|
});
|
|
|
|
it("CoA 7: onGameEvent should update ELIMINATE_UNIT objectives for specific unit", () => {
|
|
manager.setupActiveMission();
|
|
manager.currentObjectives = [
|
|
{
|
|
type: "ELIMINATE_UNIT",
|
|
target_def_id: "ENEMY_GOBLIN",
|
|
target_count: 2,
|
|
current: 0,
|
|
complete: false,
|
|
},
|
|
];
|
|
|
|
manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_GOBLIN" });
|
|
manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_OTHER" }); // Should not count
|
|
manager.onGameEvent("ENEMY_DEATH", { unitId: "ENEMY_GOBLIN" });
|
|
|
|
expect(manager.currentObjectives[0].current).to.equal(2);
|
|
expect(manager.currentObjectives[0].complete).to.be.true;
|
|
});
|
|
|
|
it("CoA 8: checkVictory should dispatch mission-victory event when all objectives complete", () => {
|
|
const victorySpy = sinon.spy();
|
|
window.addEventListener("mission-victory", victorySpy);
|
|
|
|
manager.setupActiveMission();
|
|
manager.currentObjectives = [
|
|
{ type: "ELIMINATE_ALL", target_count: 2, current: 2, complete: true },
|
|
];
|
|
manager.activeMissionId = "MISSION_TUTORIAL_01";
|
|
|
|
manager.checkVictory();
|
|
|
|
expect(victorySpy.called).to.be.true;
|
|
expect(manager.completedMissions.has("MISSION_TUTORIAL_01")).to.be.true;
|
|
|
|
window.removeEventListener("mission-victory", victorySpy);
|
|
});
|
|
|
|
it("CoA 9: completeActiveMission should add mission to completed set", () => {
|
|
manager.activeMissionId = "MISSION_TUTORIAL_01";
|
|
|
|
manager.completeActiveMission();
|
|
|
|
expect(manager.completedMissions.has("MISSION_TUTORIAL_01")).to.be.true;
|
|
});
|
|
|
|
it("CoA 10: load should restore completed missions", () => {
|
|
const saveData = {
|
|
completedMissions: ["MISSION_TUTORIAL_01", "MISSION_TEST_01"],
|
|
};
|
|
|
|
manager.load(saveData);
|
|
|
|
expect(manager.completedMissions.has("MISSION_TUTORIAL_01")).to.be.true;
|
|
expect(manager.completedMissions.has("MISSION_TEST_01")).to.be.true;
|
|
});
|
|
|
|
it("CoA 11: save should serialize completed missions", () => {
|
|
manager.completedMissions.add("MISSION_TUTORIAL_01");
|
|
manager.completedMissions.add("MISSION_TEST_01");
|
|
|
|
const saved = manager.save();
|
|
|
|
expect(saved.completedMissions).to.be.an("array");
|
|
expect(saved.completedMissions).to.include("MISSION_TUTORIAL_01");
|
|
expect(saved.completedMissions).to.include("MISSION_TEST_01");
|
|
});
|
|
|
|
it("CoA 12: _mapNarrativeIdToFileName should convert narrative IDs to filenames", () => {
|
|
expect(manager._mapNarrativeIdToFileName("NARRATIVE_TUTORIAL_INTRO")).to.equal(
|
|
"tutorial_intro"
|
|
);
|
|
expect(manager._mapNarrativeIdToFileName("NARRATIVE_TUTORIAL_SUCCESS")).to.equal(
|
|
"tutorial_success"
|
|
);
|
|
// The implementation converts NARRATIVE_UNKNOWN to narrative_unknown (lowercase with NARRATIVE_ prefix removed)
|
|
expect(manager._mapNarrativeIdToFileName("NARRATIVE_UNKNOWN")).to.equal("narrative_unknown");
|
|
});
|
|
|
|
it("CoA 13: getActiveMission should expose enemy_spawns from mission definition", () => {
|
|
const missionWithEnemies = {
|
|
id: "MISSION_TEST",
|
|
config: { title: "Test Mission" },
|
|
enemy_spawns: [
|
|
{ enemy_def_id: "ENEMY_SHARDBORN_SENTINEL", count: 2 },
|
|
],
|
|
objectives: { primary: [] },
|
|
};
|
|
|
|
manager.registerMission(missionWithEnemies);
|
|
manager.activeMissionId = "MISSION_TEST";
|
|
|
|
const mission = manager.getActiveMission();
|
|
|
|
expect(mission.enemy_spawns).to.exist;
|
|
expect(mission.enemy_spawns).to.have.length(1);
|
|
expect(mission.enemy_spawns[0].enemy_def_id).to.equal("ENEMY_SHARDBORN_SENTINEL");
|
|
expect(mission.enemy_spawns[0].count).to.equal(2);
|
|
});
|
|
|
|
it("CoA 14: getActiveMission should expose deployment constraints with tutorial hints", () => {
|
|
const missionWithDeployment = {
|
|
id: "MISSION_TEST",
|
|
config: { title: "Test Mission" },
|
|
deployment: {
|
|
suggested_units: ["CLASS_VANGUARD", "CLASS_AETHER_WEAVER"],
|
|
tutorial_hint: "Drag units from the bench to the Green Zone.",
|
|
},
|
|
objectives: { primary: [] },
|
|
};
|
|
|
|
manager.registerMission(missionWithDeployment);
|
|
manager.activeMissionId = "MISSION_TEST";
|
|
|
|
const mission = manager.getActiveMission();
|
|
|
|
expect(mission.deployment).to.exist;
|
|
expect(mission.deployment.suggested_units).to.deep.equal([
|
|
"CLASS_VANGUARD",
|
|
"CLASS_AETHER_WEAVER",
|
|
]);
|
|
expect(mission.deployment.tutorial_hint).to.equal(
|
|
"Drag units from the bench to the Green Zone."
|
|
);
|
|
});
|
|
});
|
|
|