aether-shards/test/managers/InventoryManager.test.js
Matthew Mone ac0f3cc396 Enhance testing and integration of inventory and character management systems
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.
2025-12-27 16:54:03 -08:00

298 lines
8.2 KiB
JavaScript

import { expect } from "@esm-bundle/chai";
import { InventoryManager } from "../../src/managers/InventoryManager.js";
import { InventoryContainer } from "../../src/models/InventoryContainer.js";
import { Item } from "../../src/items/Item.js";
describe("Manager: InventoryManager", () => {
let manager;
let mockItemRegistry;
let mockUnit;
let runStash;
let hubStash;
beforeEach(() => {
// Mock Item Registry
mockItemRegistry = {
get: (defId) => {
const items = {
"ITEM_RUSTY_BLADE": new Item({
id: "ITEM_RUSTY_BLADE",
name: "Rusty Blade",
type: "WEAPON",
stats: { attack: 3 },
requirements: {},
}),
"ITEM_SCRAP_PLATE": new Item({
id: "ITEM_SCRAP_PLATE",
name: "Scrap Plate",
type: "ARMOR",
stats: { defense: 3 },
requirements: {},
}),
"ITEM_TINKER_GUN": new Item({
id: "ITEM_TINKER_GUN",
name: "Tinker Gun",
type: "WEAPON",
stats: { attack: 5 },
requirements: { class_lock: ["CLASS_TINKER"] },
}),
"ITEM_TWO_HANDED_SWORD": new Item({
id: "ITEM_TWO_HANDED_SWORD",
name: "Greatsword",
type: "WEAPON",
stats: { attack: 10 },
requirements: {},
tags: ["TWO_HANDED"],
}),
"ITEM_SHIELD": new Item({
id: "ITEM_SHIELD",
name: "Shield",
type: "UTILITY",
stats: { defense: 2 },
requirements: {},
}),
"ITEM_HEALTH_POTION": new Item({
id: "ITEM_HEALTH_POTION",
name: "Health Potion",
type: "CONSUMABLE",
stats: {},
requirements: {},
}),
};
return items[defId] || null;
},
};
// Mock Unit (Explorer)
mockUnit = {
id: "UNIT_001",
activeClassId: "CLASS_VANGUARD",
baseStats: {
health: 100,
attack: 10,
defense: 5,
magic: 0,
speed: 10,
willpower: 5,
movement: 4,
tech: 0,
},
loadout: {
mainHand: null,
offHand: null,
body: null,
accessory: null,
belt: [null, null],
},
recalculateStats: () => {
// Mock stat recalculation
},
};
runStash = new InventoryContainer("RUN_LOOT");
hubStash = new InventoryContainer("HUB_VAULT");
manager = new InventoryManager(mockItemRegistry, runStash, hubStash);
});
describe("canEquip", () => {
it("should return true if unit meets requirements", () => {
const itemInstance = {
uid: "ITEM_001",
defId: "ITEM_RUSTY_BLADE",
isNew: false,
quantity: 1,
};
const canEquip = manager.canEquip(mockUnit, itemInstance);
expect(canEquip).to.be.true;
});
it("should return false if unit does not meet class requirements", () => {
const itemInstance = {
uid: "ITEM_002",
defId: "ITEM_TINKER_GUN",
isNew: false,
quantity: 1,
};
const canEquip = manager.canEquip(mockUnit, itemInstance);
expect(canEquip).to.be.false;
});
it("should return false if item definition not found", () => {
const itemInstance = {
uid: "ITEM_003",
defId: "ITEM_NONEXISTENT",
isNew: false,
quantity: 1,
};
const canEquip = manager.canEquip(mockUnit, itemInstance);
expect(canEquip).to.be.false;
});
});
describe("equipItem", () => {
it("should equip item to mainHand slot", () => {
const itemInstance = {
uid: "ITEM_001",
defId: "ITEM_RUSTY_BLADE",
isNew: false,
quantity: 1,
};
hubStash.addItem(itemInstance);
const result = manager.equipItem(mockUnit, itemInstance, "MAIN_HAND");
expect(result).to.be.true;
expect(mockUnit.loadout.mainHand).to.deep.equal(itemInstance);
expect(hubStash.findItem("ITEM_001")).to.be.null; // Removed from stash
});
it("should swap item if slot is occupied", () => {
const existingItem = {
uid: "ITEM_002",
defId: "ITEM_SCRAP_PLATE",
isNew: false,
quantity: 1,
};
const newItem = {
uid: "ITEM_001",
defId: "ITEM_RUSTY_BLADE",
isNew: false,
quantity: 1,
};
mockUnit.loadout.mainHand = existingItem;
hubStash.addItem(newItem);
const result = manager.equipItem(mockUnit, newItem, "MAIN_HAND");
expect(result).to.be.true;
expect(mockUnit.loadout.mainHand).to.deep.equal(newItem);
expect(hubStash.findItem("ITEM_002")).to.deep.equal(existingItem); // Old item in stash
});
it("should automatically unequip offHand when equipping two-handed weapon", () => {
const twoHandedItem = {
uid: "ITEM_003",
defId: "ITEM_TWO_HANDED_SWORD",
isNew: false,
quantity: 1,
};
const shieldItem = {
uid: "ITEM_004",
defId: "ITEM_SHIELD",
isNew: false,
quantity: 1,
};
mockUnit.loadout.offHand = shieldItem;
hubStash.addItem(twoHandedItem);
const result = manager.equipItem(mockUnit, twoHandedItem, "MAIN_HAND");
expect(result).to.be.true;
expect(mockUnit.loadout.mainHand).to.deep.equal(twoHandedItem);
expect(mockUnit.loadout.offHand).to.be.null; // Off-hand unequipped
expect(hubStash.findItem("ITEM_004")).to.deep.equal(shieldItem); // Shield in stash
});
it("should return false if item cannot be equipped", () => {
const itemInstance = {
uid: "ITEM_002",
defId: "ITEM_TINKER_GUN",
isNew: false,
quantity: 1,
};
hubStash.addItem(itemInstance);
const result = manager.equipItem(mockUnit, itemInstance, "MAIN_HAND");
expect(result).to.be.false;
expect(mockUnit.loadout.mainHand).to.be.null;
expect(hubStash.findItem("ITEM_002")).to.exist; // Still in stash
});
it("should equip item to belt slot", () => {
const potion = {
uid: "ITEM_005",
defId: "ITEM_HEALTH_POTION",
isNew: false,
quantity: 1,
};
hubStash.addItem(potion);
const result = manager.equipItem(mockUnit, potion, "BELT", 0);
expect(result).to.be.true;
expect(mockUnit.loadout.belt[0]).to.deep.equal(potion);
});
});
describe("unequipItem", () => {
it("should unequip item from slot and move to stash", () => {
const itemInstance = {
uid: "ITEM_001",
defId: "ITEM_RUSTY_BLADE",
isNew: false,
quantity: 1,
};
mockUnit.loadout.mainHand = itemInstance;
const result = manager.unequipItem(mockUnit, "MAIN_HAND");
expect(result).to.be.true;
expect(mockUnit.loadout.mainHand).to.be.null;
expect(hubStash.findItem("ITEM_001")).to.deep.equal(itemInstance);
});
it("should return false if slot is empty", () => {
const result = manager.unequipItem(mockUnit, "MAIN_HAND");
expect(result).to.be.false;
});
it("should unequip from belt slot", () => {
const potion = {
uid: "ITEM_005",
defId: "ITEM_HEALTH_POTION",
isNew: false,
quantity: 1,
};
mockUnit.loadout.belt[0] = potion;
const result = manager.unequipItem(mockUnit, "BELT", 0);
expect(result).to.be.true;
expect(mockUnit.loadout.belt[0]).to.be.null;
expect(hubStash.findItem("ITEM_005")).to.deep.equal(potion);
});
});
describe("transferToStash", () => {
it("should move item from unit loadout to stash", () => {
const itemInstance = {
uid: "ITEM_001",
defId: "ITEM_RUSTY_BLADE",
isNew: false,
quantity: 1,
};
mockUnit.loadout.mainHand = itemInstance;
const result = manager.transferToStash(mockUnit, "MAIN_HAND");
expect(result).to.be.true;
expect(mockUnit.loadout.mainHand).to.be.null;
expect(hubStash.findItem("ITEM_001")).to.deep.equal(itemInstance);
});
it("should return false if slot is empty", () => {
const result = manager.transferToStash(mockUnit, "MAIN_HAND");
expect(result).to.be.false;
});
});
});