import { describe, expect, it } from "vitest"; import { BASE_CLASS_IDS, COA_CLASS_IDS } from "../app/characterCatalog"; import { ASCENSION_CLASSIC_PROGRESSION_CHAINS, COA_LIVE_CLASSES, COA_LIVE_COUNTS, COA_LIVE_SOURCE, COA_PROGRESSION_CHAINS, COA_TREE_ENTRIES, ascensionProgressionForClass, coaEntriesForClass, coaProgressionForClass, coaSpellById, } from "./coaLiveCatalog"; describe("live Ascension Conquest catalog", () => { it("contains the pinned August Vol'Jin trees with separately preserved classic data", () => { expect(COA_LIVE_SOURCE).toMatchObject({ realmId: 40, realmSlug: "voljin", maximumLevel: 60, schemaVersion: { talents: 2 }, }); expect(COA_LIVE_COUNTS).toMatchObject({ classes: 21, tabs: 91, entries: 3618, abilityEntries: 701, talentEntries: 2917, rankedNodeSpells: 3933, classSpellRows: 12374, classicClassSpellRows: 6930, coaClassSpellRows: 5444, progressionChains: 1822, classicProgressionChains: 1266, classicBaseProgressionChains: 612, coaProgressionChains: 556, progressionRanks: 8405, }); expect(COA_LIVE_SOURCE.coaSpellDbcPath).toContain("client-current/patch-T"); expect(COA_LIVE_SOURCE.classicSpellDbcPath).toContain("client-current/area-52/patch-D"); expect(COA_LIVE_SOURCE.supportDbcDirectory).toContain("client-current/patch-S"); expect(COA_LIVE_SOURCE.synchronizedAt).toBe("2026-08-12T21:02:51+00:00"); expect(COA_LIVE_COUNTS.dbcMatchedSpells).toBeLessThan(COA_LIVE_COUNTS.uniqueSpells); expect(COA_LIVE_CLASSES).toHaveLength(COA_CLASS_IDS.length); expect(COA_TREE_ENTRIES).toHaveLength(COA_LIVE_COUNTS.entries); }); it("has live trees and ranked spell chains for every custom class", () => { for (const classId of COA_CLASS_IDS) { const entries = coaEntriesForClass(classId); const chains = coaProgressionForClass(classId); expect(entries.length, classId).toBeGreaterThan(150); expect(chains.length, classId).toBeGreaterThan(9); for (const chain of chains) { expect(chain.ranks.length, `${classId}: ${chain.name}`).toBeGreaterThan(0); for (let index = 0; index < chain.ranks.length; index += 1) { const rank = chain.ranks[index]; if (index > 0) expect(rank.rank).toBeGreaterThan(chain.ranks[index - 1].rank); expect(coaSpellById(rank.spellId), `${chain.name} rank ${rank.rank}`).not.toBeNull(); } } } expect(COA_PROGRESSION_CHAINS).toHaveLength(COA_LIVE_COUNTS.coaProgressionChains); }); it("has Ascension rank chains for every default class without advancement spells", () => { for (const classId of BASE_CLASS_IDS) { const chains = ascensionProgressionForClass(classId); expect(chains.length, classId).toBeGreaterThan(70); expect(chains.some((chain) => !chain.talented), classId).toBe(true); for (const chain of chains.filter((candidate) => !candidate.talented)) { expect(chain.advancementType, `${classId}: ${chain.name}`).toBe(""); } } expect(ASCENSION_CLASSIC_PROGRESSION_CHAINS).toHaveLength(COA_LIVE_COUNTS.classicProgressionChains); expect( ASCENSION_CLASSIC_PROGRESSION_CHAINS.length + COA_PROGRESSION_CHAINS.length, ).toBe(COA_LIVE_COUNTS.progressionChains); }); it("preserves every node rank tooltip and spell id", () => { let rankCount = 0; for (const entry of COA_TREE_ENTRIES) { expect(entry.name.length).toBeGreaterThan(0); expect(entry.rankDescriptions.length).toBeGreaterThan(0); expect(entry.maxPoints).toBeGreaterThanOrEqual(entry.rankDescriptions.length); for (const rank of entry.rankDescriptions) { expect(rank.spellId).toBeGreaterThan(0); expect(rank.description.length).toBeGreaterThan(0); expect(coaSpellById(rank.spellId)).not.toBeNull(); expect(coaSpellById(rank.spellId)?.dbc, `node ${entry.id} rank ${rank.rank}`).toBeDefined(); rankCount += 1; } } expect(rankCount).toBe(COA_LIVE_COUNTS.rankedNodeSpells); }); });