forked from phenom/healer-man
Release Healer Man 0.1.40
This commit is contained in:
1 parent
ed0d2fea3d
commit
197a64117c
215 files changed
+5131
-181
No files matched your search
@@ -0,0 +1,91 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { collectBossCardDrop, emptyBossCardCollection, normalizeBossCardCollection, rollBossCards, type BossCardDrop } from "./bossCards";
|
||||
import { BOSS_CARD_CATALOG, bossCardForSource, buildBossCardCatalog, groupBossCards } from "./bossCardCatalog";
|
||||
import { DUNGEON_DEFINITIONS } from "./dungeonRegistry";
|
||||
import { useCombatStore } from "./combatStore";
|
||||
import { useGameStore } from "./store";
|
||||
import { allowedLootDrops } from "./lootPolicy";
|
||||
import { EMPTY_ITEM_STATS } from "./itemStats";
|
||||
|
||||
describe("boss card rewards", () => {
|
||||
it("guarantees Normal and rolls each bonus independently at its exact boundary", () => {
|
||||
const random = vi.fn().mockReturnValueOnce(0.099).mockReturnValueOnce(0.02).mockReturnValueOnce(0.009);
|
||||
expect(rollBossCards(random)).toEqual(["normal", "rare", "legendary"]);
|
||||
expect(random).toHaveBeenCalledTimes(3);
|
||||
expect(rollBossCards(() => 0)).toEqual(["normal", "rare", "epic", "legendary"]);
|
||||
expect(rollBossCards(() => 0.1)).toEqual(["normal"]);
|
||||
expect(rollBossCards(() => NaN)).toEqual(["normal"]);
|
||||
});
|
||||
|
||||
it("counts copies and makes repeated world rewards idempotent after save normalization", () => {
|
||||
const drop: BossCardDrop = { bossKey: "wow:lady anacondra", spawnId: "boss-spawn", claimId: "kill:1", rarities: ["normal", "rare"] };
|
||||
const first = collectBossCardDrop(emptyBossCardCollection(), drop);
|
||||
expect(collectBossCardDrop(first, drop)).toBe(first);
|
||||
const restored = normalizeBossCardCollection(JSON.parse(JSON.stringify(first)));
|
||||
expect(collectBossCardDrop(restored, drop)).toBe(restored);
|
||||
expect(collectBossCardDrop(restored, { ...drop, claimId: "kill:2" }).counts[drop.bossKey]).toEqual({ normal: 2, rare: 2 });
|
||||
const later = collectBossCardDrop(restored, { ...drop, claimId: "5000:2:boss-spawn" });
|
||||
expect(collectBossCardDrop(later, { ...drop, claimId: "4000:1:boss-spawn" })).toBe(later);
|
||||
});
|
||||
|
||||
it("migrates old profiles and rejects corrupt counts", () => {
|
||||
expect(normalizeBossCardCollection(undefined)).toEqual(emptyBossCardCollection());
|
||||
expect(normalizeBossCardCollection({ counts: { boss: { normal: 3.9, rare: -1, epic: Infinity, legendary: "5" } } }).counts).toEqual({ boss: { normal: 3 } });
|
||||
});
|
||||
|
||||
it("grants cards from a boss without an equipment loot table exactly once", () => {
|
||||
const dungeon = DUNGEON_DEFINITIONS.find((entry) => entry.id === "ragefire-chasm")!;
|
||||
const boss = Object.values(dungeon.entities).find((entry) => entry.kind === "boss")!;
|
||||
useGameStore.getState().activateDungeon(dungeon.id);
|
||||
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 79 });
|
||||
useCombatStore.getState().registerMob("no-loot-boss", { name: boss.name, boss: true, lootSourceId: boss.id, maxHealth: 1, xpReward: 0 });
|
||||
useCombatStore.getState().damageMob("no-loot-boss", 1, 4000);
|
||||
const key = bossCardForSource(boss.id, dungeon.id)!.key;
|
||||
expect(useCombatStore.getState().bossCards.counts[key]?.normal).toBe(1);
|
||||
expect(useCombatStore.getState().inventory).toEqual([]);
|
||||
expect(useCombatStore.getState().lootMob("no-loot-boss", 4001)).toBe(false);
|
||||
expect(useCombatStore.getState().bossCards.counts[key]?.normal).toBe(1);
|
||||
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 79 });
|
||||
expect(useCombatStore.getState().bossCards).toEqual(emptyBossCardCollection());
|
||||
useGameStore.getState().activateDungeon("wailing-caverns");
|
||||
});
|
||||
|
||||
it.each([1, 40, 79, 80])("preserves non-equipment while allowing equipment only at 80 (level %i)", (level) => {
|
||||
const item = { instanceId: "i", itemId: 1, itemKey: "item", name: "Item", quality: "rare" as const, inventorySlot: "waist", armorType: "cloth", weaponType: null, itemLevel: level, sourceItemLevel: 1, stats: EMPTY_ITEM_STATS, quantity: 1, sourceBossKey: "boss", sourceBossName: "Boss", acquiredAt: 1 };
|
||||
const misc = { ...item, instanceId: "m", inventorySlot: "misc" };
|
||||
expect(allowedLootDrops([item, misc], level)).toEqual(level === 80 ? [item, misc] : [misc]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("boss card catalogue and filters", () => {
|
||||
it("covers every registered boss with its actual model and dungeon", () => {
|
||||
expect(BOSS_CARD_CATALOG.length).toBeGreaterThan(100);
|
||||
for (const dungeon of DUNGEON_DEFINITIONS) for (const boss of Object.values(dungeon.entities)) {
|
||||
if (boss.kind !== "boss") continue;
|
||||
const card = bossCardForSource(boss.id, dungeon.id)!;
|
||||
expect(card, `${dungeon.id}:${boss.id}`).not.toBeNull();
|
||||
expect(card.dungeons).toContainEqual({ id: dungeon.id, title: dungeon.title });
|
||||
if (boss.visual.model) expect(card.model).toBeDefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("merges the same boss across dungeons and groups without changing earned copies", () => {
|
||||
const wc = DUNGEON_DEFINITIONS.find((entry) => entry.id === "wailing-caverns")!;
|
||||
const boss = wc.entities["lady-anacondra"];
|
||||
const catalog = buildBossCardCatalog([
|
||||
{ ...wc, entities: { [boss.id]: boss } },
|
||||
{ ...wc, id: "second-dungeon", title: "Second Dungeon", entities: { [boss.id]: boss } },
|
||||
]);
|
||||
expect(catalog).toHaveLength(1);
|
||||
expect(catalog[0].dungeons).toHaveLength(2);
|
||||
const collection = { counts: { [catalog[0].key]: { normal: 5, legendary: 1 } }, lastClaims: {} };
|
||||
expect(groupBossCards(collection, { earnedOnly: false, grouping: "all" }, catalog)[0].rows).toHaveLength(4);
|
||||
expect(groupBossCards(collection, { earnedOnly: true, grouping: "all" }, catalog)[0].rows.map((row) => row.copies)).toEqual([5, 1]);
|
||||
const dungeons = groupBossCards(collection, { earnedOnly: true, grouping: "dungeon" }, catalog);
|
||||
expect(dungeons).toHaveLength(2);
|
||||
expect(dungeons.every((group) => group.rows[0].copies === 5)).toBe(true);
|
||||
expect(groupBossCards(collection, { earnedOnly: true, grouping: "rarity" }, catalog).map((group) => group.key)).toEqual(["normal", "legendary"]);
|
||||
expect(groupBossCards(collection, { earnedOnly: false, grouping: "all", search: "second dungeon" }, catalog)[0].rows).toHaveLength(4);
|
||||
expect(groupBossCards(collection, { earnedOnly: true, grouping: "all", category: "rom" }, catalog)).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user