import { describe, expect, it } from "vitest"; import { commissionDraftKey, restoreCommissionDraft, serializeCommissionDraft } from "./draft"; import type { CommissionRequest } from "./request"; const now = 1_800_000_000_000; const catalog = { characters: [{ key: "character", weaponType: "sword" }], weapons: [{ key: "sword", weaponType: "sword" }, { key: "bow", weaponType: "bow" }], artifacts: [{ key: "artifact" }], }; const blank = { characterKey: "", weaponKey: "", artifactKey: "", constellation: "0", refinement: "1" } as const; const request: CommissionRequest = { teams: [{ members: [{ ...blank, characterKey: "character", weaponKey: "sword", artifactKey: "artifact" }, blank, blank, blank] }], weapons: [{ characterKey: "character", weaponKeys: ["sword", ""], refinements: { sword: "3" } }], constellations: [{ characterKey: "character", levels: [] }], }; describe("commission draft recovery", () => { it("preserves a partially completed request and its refinements", () => { expect(restoreCommissionDraft(serializeCommissionDraft(request, now), catalog, now)).toEqual(request); }); it("keeps drafts scoped to the account", () => { expect(commissionDraftKey("first")).not.toBe(commissionDraftKey("second")); }); it("ignores corrupt, unsupported, expired, and future drafts", () => { for (const serialized of ["broken", '{"version":2}', serializeCommissionDraft(request, now - 8 * 86400000), serializeCommissionDraft(request, now + 1)]) { expect(restoreCommissionDraft(serialized, catalog, now)).toBeNull(); } }); it("rejects malformed member arrays rather than breaking the picker UI", () => { expect(restoreCommissionDraft(JSON.stringify({ version: 1, savedAt: now, request: { ...request, teams: [{ members: [blank] }] } }), catalog, now)).toBeNull(); }); it("clears removed and incompatible items without losing the rest of the draft", () => { const changed = structuredClone(request); changed.teams[0].members[0].weaponKey = "bow"; changed.teams[0].members[0].artifactKey = "removed"; changed.weapons[0].weaponKeys = ["sword", "removed"]; changed.weapons[0].refinements = { sword: "3", removed: "5" }; changed.constellations[0] = { characterKey: "removed", levels: [2, 4] }; const restored = restoreCommissionDraft(serializeCommissionDraft(changed, now), catalog, now)!; expect(restored.teams[0].members[0]).toEqual({ ...blank, characterKey: "character" }); expect(restored.weapons[0]).toEqual({ characterKey: "character", weaponKeys: ["sword", ""], refinements: { sword: "3" } }); expect(restored.constellations[0]).toEqual({ characterKey: "", levels: [2, 4] }); }); });