feat : add stygian guide
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
lunarisStygianScheduleSchema,
|
||||
selectedStygianBosses,
|
||||
stygianImageFileName,
|
||||
stygianImageName,
|
||||
stygianRecommendationsSchema,
|
||||
} from "@/lib/stygian/schema";
|
||||
|
||||
function level(monsterLevel: number) {
|
||||
return {
|
||||
monsterLevel,
|
||||
levelConfigs: Array.from({ length: 3 }, (_, index) => ({
|
||||
id: monsterLevel * 10 + index,
|
||||
specialMonsterIcon: `UI_MonsterIcon_Boss_${index}`,
|
||||
monsterStats: { hp: 1234.56 + index },
|
||||
enLevelName: `Boss ${index}`,
|
||||
enMonsterSpecialDesc: `Description ${index}`,
|
||||
enMonsterSpecialMechanicName: ["Mechanic", "", "Missing description"],
|
||||
enLevelMaxDescription: ["Do the thing", "Ignored", ""],
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
const schedule = {
|
||||
scheduleId: 5269001,
|
||||
challengeName: "5.7",
|
||||
scheduleStartTime: "2025-06-25 10:00:00",
|
||||
scheduleEndTime: "2025-08-06 09:59:59",
|
||||
levels: [level(40), level(105), level(110)],
|
||||
};
|
||||
|
||||
describe("Stygian Lunaris parsing", () => {
|
||||
it("selects exactly the three level 105 and 110 bosses", () => {
|
||||
const parsed = lunarisStygianScheduleSchema.parse(schedule);
|
||||
const bosses = selectedStygianBosses(parsed);
|
||||
expect(bosses).toHaveLength(6);
|
||||
expect(bosses.map((boss) => boss.level)).toEqual([105, 105, 105, 110, 110, 110]);
|
||||
expect(bosses[0]).toMatchObject({
|
||||
name: "Boss 0",
|
||||
hp: 1234.56,
|
||||
mechanics: [{ name: "Mechanic", description: "Do the thing" }],
|
||||
imageName: "UI_Img_LeyLineChallenge_Boss_0",
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects a schedule missing one of the three required bosses", () => {
|
||||
const parsed = lunarisStygianScheduleSchema.parse({
|
||||
...schedule,
|
||||
levels: [level(105), { ...level(110), levelConfigs: level(110).levelConfigs.slice(0, 2) }],
|
||||
});
|
||||
expect(() => selectedStygianBosses(parsed)).toThrow("exactly three level 110 bosses");
|
||||
});
|
||||
|
||||
it("preserves existing Ley Line image names", () => {
|
||||
expect(stygianImageName("UI_Img_LeyLineChallenge_Gastrobot01")).toBe("UI_Img_LeyLineChallenge_Gastrobot01");
|
||||
expect(stygianImageName("UI_Img_LeyLineChallenge_Gastrobot01.png")).toBe("UI_Img_LeyLineChallenge_Gastrobot01");
|
||||
expect(stygianImageFileName("UI_Img_LeyLineChallenge_Gastrobot01")).toBe("UI_Img_LeyLineChallenge_Gastrobot01.png");
|
||||
expect(stygianImageFileName("UI_Img_LeyLineChallenge_Gastrobot01.png")).toBe("UI_Img_LeyLineChallenge_Gastrobot01.png");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Stygian recommendation validation", () => {
|
||||
const base = { expectedVersion: 1, level: 110, bossPosition: 0, units: [] };
|
||||
|
||||
it("accepts teams containing one to four characters", () => {
|
||||
expect(stygianRecommendationsSchema.safeParse({
|
||||
...base,
|
||||
teams: [[
|
||||
{ kind: "character", catalogKey: "10000001", weaponKey: null, artifactKey: null, constellationLevel: null },
|
||||
{ kind: "character", catalogKey: "10000002", weaponKey: "WEAPON", artifactKey: null, constellationLevel: 2 },
|
||||
{ kind: "character", catalogKey: "10000003", weaponKey: null, artifactKey: "ARTIFACT", constellationLevel: 0 },
|
||||
{ kind: "character", catalogKey: "10000004", weaponKey: null, artifactKey: null, constellationLevel: 6 },
|
||||
]],
|
||||
}).success).toBe(true);
|
||||
expect(stygianRecommendationsSchema.safeParse({
|
||||
...base,
|
||||
teams: [[{ kind: "character", catalogKey: "10000001", weaponKey: null, artifactKey: null, constellationLevel: null }]],
|
||||
}).success).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects empty, non-character, oversized, or duplicate teams", () => {
|
||||
const character = { kind: "character", catalogKey: "10000001", weaponKey: null, artifactKey: null, constellationLevel: null };
|
||||
expect(stygianRecommendationsSchema.safeParse({ ...base, teams: [[]] }).success).toBe(false);
|
||||
expect(stygianRecommendationsSchema.safeParse({ ...base, teams: [[character, character]] }).success).toBe(false);
|
||||
expect(stygianRecommendationsSchema.safeParse({ ...base, teams: [[character, ...Array.from({ length: 4 }, (_, index) => ({ kind: "weapon", catalogKey: `W${index}` }))]] }).success).toBe(false);
|
||||
expect(stygianRecommendationsSchema.safeParse({ ...base, teams: [[character, { kind: "element", element: "Cryo" }, character, character]] }).success).toBe(false);
|
||||
});
|
||||
|
||||
it("allows an unrestricted number of team rows and flexible units", () => {
|
||||
const teams = Array.from({ length: 100 }, (_, index) => Array.from({ length: 4 }, (_, member) => ({ kind: "character", catalogKey: `C${index}-${member}`, weaponKey: null, artifactKey: null, constellationLevel: null })));
|
||||
const units = Array.from({ length: 100 }, (_, index) => ({ kind: "artifact", catalogKey: `A${index}` }));
|
||||
expect(stygianRecommendationsSchema.safeParse({ ...base, teams, units }).success).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user