import { describe, it, expect, beforeAll } from 'vitest' import { ACT_BOSSES, type BossPreset } from '../src/boss.ts' import { getEmbeddedDropTables } from '../src/game/embedded-drop-tables.ts' import { executeDropPipeline, createDroppedItem, type DropTables } from '../src/game/drop-pipeline.ts' import { formatItemTooltip } from '../src/game/item-tooltip.ts' import type { Item } from '../src/game/items.ts' describe('Act Boss Loot Simulator (boss.html)', () => { let dropTables: DropTables beforeAll(() => { dropTables = getEmbeddedDropTables() }) it('1. ACT_BOSSES catalog includes all 5 canonical Act Bosses', () => { expect(ACT_BOSSES).toHaveLength(5) const bossIds = ACT_BOSSES.map(b => b.id) expect(bossIds).toEqual(['andariel', 'duriel', 'mephisto', 'diablo', 'baal']) }) it('2. All standard TCs and Quest TCs resolve to valid nodes in TreasureClassEx', () => { const difficulties: Array<'normal' | 'nightmare' | 'hell'> = ['normal', 'nightmare', 'hell'] for (const boss of ACT_BOSSES) { for (const diff of difficulties) { const stdTc = boss.tc[diff] const questTc = boss.questTc[diff] const stdNode = dropTables.tcTable.get(stdTc) const questNode = dropTables.tcTable.get(questTc) expect(stdNode, `Boss ${boss.id} [${diff}] std TC ${stdTc} should exist`).toBeDefined() expect(questNode, `Boss ${boss.id} [${diff}] quest TC ${questTc} should exist`).toBeDefined() expect(stdNode?.picks).toBeGreaterThan(0) expect(questNode?.picks).toBeGreaterThan(0) } } }) it('3. Simulates single Hell Mephisto kill and generates realistic dropped items with attributes', () => { const drops: Item[] = executeDropPipeline({ tcName: 'Mephistoq (H)', nLevel: 87, dropTables, difficulty: 'hell', playerMf: 300, gamePlayers: 1, partyPlayers: 1, monsterRng: 42, }) expect(drops.length).toBeGreaterThan(0) for (const item of drops) { expect(item.name.length).toBeGreaterThan(0) expect(item.code).toBeDefined() expect(item.code!.length).toBeGreaterThan(0) expect(item.base).toBeDefined() const tooltip = formatItemTooltip(item) expect(tooltip.title.length).toBeGreaterThan(0) expect(tooltip.quality.length).toBeGreaterThan(0) expect(tooltip.ilvl).toBe(87) // If equipment, verify stats formatting if (item.base.kind === 'weapon' || item.base.kind === 'armor') { expect(tooltip.baseType).toMatch(/Weapon|Armor/) } } }) it('4. Simulates Hell Baal kill with 7 Players (low NoDrop) and rolls multi-tier affixes', () => { const drops: Item[] = executeDropPipeline({ tcName: 'Baal (H)', nLevel: 99, dropTables, difficulty: 'hell', playerMf: 250, gamePlayers: 7, partyPlayers: 1, monsterRng: 99999, }) expect(drops.length).toBeGreaterThan(0) const qualities = drops.map(d => d.rarity) expect(qualities.length).toBe(drops.length) }) it('5. Verifies formatItemTooltip generates correct properties for Unique, Rare, and Magic items', () => { // 5.1 Unique Item Tooltip Test const dummyUniqueBase = dropTables.getBase('uap')! // Shako const dummyUniqueDef = dropTables.uniques.getEnabledByCode('uap')[0]! const uniqueItem: Item = { base: dummyUniqueBase, prefix: null, suffix: null, level: 87, ilvl: 87, name: dummyUniqueDef.index, stats: { defense: 141, allskills: 2, mag: 50 }, invWidth: dummyUniqueBase.invWidth, invHeight: dummyUniqueBase.invHeight, stack: 1, value: 10000, rarity: 'unique', uniqueItemDef: dummyUniqueDef, } const uniqueTooltip = formatItemTooltip(uniqueItem) expect(uniqueTooltip.title).toBe(dummyUniqueDef.index) expect(uniqueTooltip.quality.toLowerCase()).toBe('unique') expect(uniqueTooltip.lines.length).toBeGreaterThan(0) // 5.2 Rune Tooltip Test const dummyRuneBase = dropTables.getBase('r30')! // Ber Rune const runeItem: Item = { base: dummyRuneBase, prefix: null, suffix: null, level: 63, ilvl: 63, name: 'Ber Rune', code: 'r30 ', stats: {}, invWidth: 1, invHeight: 1, stack: 1, value: 100, rarity: 'normal', } const runeTooltip = formatItemTooltip(runeItem) expect(runeTooltip.title).toBe('Ber Rune') expect(runeTooltip.quality).toBe('Rune') expect(runeTooltip.lines.some(l => l.text.includes('Crushing Blow'))).toBe(true) }) it('6. Verifies concrete rolled values for variable modifiers (e.g. +X to Mana, not range)', () => { const ringBase = dropTables.getBase('rin')! // Roll an item with mana stat const rolledItem = createDroppedItem(ringBase, 'magic', { magicAffixes: { name: "Bahamut's Ring", prefix: { name: "Bahamut's", affix: dropTables.magicAffixes.prefixes.getByName("Bahamut's")[0]!, level: 37, mods: [{ code: 'mana', min: 80, max: 120, value: 105 }], }, } as any, ilvl: 50, dwInitSeed: 12345, }) const tooltip = formatItemTooltip(rolledItem) expect(tooltip.lines.some(l => l.text === '+105 to Mana')).toBe(true) expect(tooltip.lines.some(l => l.text.includes('80-120'))).toBe(false) }) })