import { describe, expect, it } from "vitest"; import { avatarIconName, ascensionSnapshot, baseStatsSnapshot, levelingSnapshot, characterDetailSchema, cleanLunarisText, constellationSnapshot, nameCardImageName, splashImageName, supportsWeaponType, talentSnapshot, } from "@/lib/catalog/lunaris"; describe("Lunaris character data", () => { it("maps CardImg names to the avatar icon endpoint", () => { expect(avatarIconName("UI_Gacha_AvatarIcon_Ineffa")).toBe( "UI_AvatarIcon_Ineffa", ); }); it("maps CardImg names to Lunaris character card assets", () => { expect(splashImageName("UI_Gacha_AvatarIcon_Ayaka")).toBe( "UI_Gacha_AvatarImg_Ayaka.png", ); expect(nameCardImageName("UI_Gacha_AvatarIcon_Ayaka")).toBe( "UI_NameCardPic_Ayaka_P.png", ); expect(nameCardImageName("UI_Gacha_AvatarIcon_Qin")).toBe( "UI_NameCardPic_Qin_P.png", ); }); it("removes display markup from constellation text", () => { expect(cleanLunarisText('"A {LINK#N1}bright{/LINK} morning"')).toBe("A bright morning"); }); it("converts escaped Lunaris newlines into displayable lines", () => { expect(cleanLunarisText("First line\\n\\nSecond line")).toBe("First line\n\nSecond line"); }); it("normalizes constellation levels and icon keys", () => { const result = constellationSnapshot({ constellations: { const1: { name: '"First"', description: "Detail", icon: "UI_Talent_Test_01" }, }, }, (icon) => `catalog/1/constellations/${icon}.webp`); expect(result).toEqual([{ level: 1, name: "First", description: "Detail", iconKey: "catalog/1/constellations/UI_Talent_Test_01.webp", }]); }); it("accepts characters that do not have constellations", () => { const detail = characterDetailSchema.parse({ constellations: null }); expect(constellationSnapshot(detail, (icon) => icon)).toEqual([]); }); it("normalizes scalar and grouped ascension materials", () => { const detail = characterDetailSchema.parse({ ascension: { "202": 7049900, exp: { "104001": 2, "104003": 418 }, }, }); expect(ascensionSnapshot(detail)).toEqual([ { type: "202", items: [{ key: "202", amount: 7049900 }] }, { type: "exp", items: [ { key: "104001", amount: 2 }, { key: "104003", amount: 418 }, ], }, ]); }); it("normalizes leveling materials by category", () => { const detail = characterDetailSchema.parse({ skills: { leveling: { crown: { "104319": 3 }, books: { "104365": 9, "104366": 63, "104367": 114 }, worldmonster: { "112146": 18, "112147": 66, "112148": 93 }, weekly: { "113088": 18 }, }, }, }); expect(levelingSnapshot(detail)).toEqual([ { type: "crown", items: [{ key: "104319", amount: 3 }] }, { type: "books", items: [{ key: "104365", amount: 9 }, { key: "104366", amount: 63 }, { key: "104367", amount: 114 }] }, { type: "worldmonster", items: [{ key: "112146", amount: 18 }, { key: "112147", amount: 66 }, { key: "112148", amount: 93 }] }, { type: "weekly", items: [{ key: "113088", amount: 18 }] }, ]); }); it("selects dynamic level 90 base stats", () => { const detail = characterDetailSchema.parse({ attributes: [ { level: 1, ascension: 0, hp: 1, atk: 2, def: 3 }, { level: 90, ascension: 6, hp: 12981, atk: 335, def: 787, "CRIT DMG%": "38.4" }, ], }); expect(baseStatsSnapshot(detail)).toEqual([ { key: "hp", value: 12981 }, { key: "atk", value: 335 }, { key: "def", value: 787 }, { key: "CRIT DMG%", value: "38.4" }, ]); }); it("selects base stats nested under info", () => { const detail = characterDetailSchema.parse({ info: { attributes: [{ level: 90, hp: 100, atk: 20, def: 30, EM: 40 }] }, }); expect(baseStatsSnapshot(detail)).toEqual([ { key: "hp", value: 100 }, { key: "atk", value: 20 }, { key: "def", value: 30 }, { key: "EM", value: 40 }, ]); }); it("reads the supported weapon type from character details", () => { const detail = characterDetailSchema.parse({ info: { element: "Cryo", weapon: "WEAPON_SWORD_ONE_HAND" }, constellations: null, }); expect(detail.info?.weapon).toBe("WEAPON_SWORD_ONE_HAND"); expect(detail.info?.element).toBe("Cryo"); }); it("maps normal, skill, and burst talent metadata", () => { const detail = characterDetailSchema.parse({ skills: { normalattack: { name: "Normal", description: "Line 1\\nLine 2", icon: "Skill_A_Test" }, elementalskill: { name: "Skill", description: "Skill detail", icon: "Skill_S_Test" }, elementalburst: { name: "Burst", description: "Burst detail", icon: "Skill_E_Test" }, }, }); expect(talentSnapshot(detail, (icon) => `${icon}.webp`)).toEqual([ { type: "NA", name: "Normal", description: "Line 1\nLine 2", iconKey: "Skill_A_Test.webp" }, { type: "E", name: "Skill", description: "Skill detail", iconKey: "Skill_S_Test.webp" }, { type: "Q", name: "Burst", description: "Burst detail", iconKey: "Skill_E_Test.webp" }, ]); }); it("matches only weapons supported by the character", () => { expect( supportsWeaponType("WEAPON_SWORD_ONE_HAND", "WEAPON_SWORD_ONE_HAND"), ).toBe(true); expect( supportsWeaponType("WEAPON_SWORD_ONE_HAND", "WEAPON_CATALYST"), ).toBe(false); expect(supportsWeaponType(undefined, "WEAPON_SWORD_ONE_HAND")).toBe(false); }); });