import type { EpisodeMappingPreview } from "@umt/contracts"; import { describe, expect, it } from "vitest"; import { EXCLUDE_REASON } from "../organize-wizard/model.ts"; import { absoluteGroups, canonicalText, groupMethodsText, lineFromSearch, METHOD_LABEL, mappingHref, methodText, reresolveToast, sourceText, } from "./model.ts"; describe("集数映射文案", () => { it("方式名称给人话,覆盖全部方式", () => { expect(METHOD_LABEL).toEqual({ raw: "原号", rule: "按作品识别词", absolute_in_season: "季内绝对集号", absolute_cross_season: "跨季绝对集号", air_date: "按播出日期", tmdb_season: "按 TMDB 默认季集换算", unverified: "元数据未覆盖,先按原号", unresolved: "待确认", skipped: "不适用", }); expect(methodText({ method: "rule", special: "ignore" })).toBe("按作品识别词:忽略"); expect(methodText(null)).toBe("未解析"); }); it("季集写法:原始 / 规范 / 特别篇 / 播出日期", () => { expect(sourceText({ source: { season: 1, episodes: { start: 25, end: 25 } } })).toBe("S01E25"); expect(sourceText({ source: { episodes: { start: 13, end: 14 } } })).toBe("E13-E14"); expect(sourceText({ source: { airDate: "20250314" } })).toBe("2025-03-14"); expect( canonicalText({ method: "absolute_cross_season", canonical: { season: 2, episodes: { start: 1, end: 1 } } }), ).toBe("S02E01"); expect(canonicalText({ method: "rule", canonical: null, special: "extra" })).toBe("花絮"); expect(canonicalText({ method: "unresolved", canonical: null })).toBe("—"); }); it("整理向导的排除原因有「集数待确认」与特典花絮", () => { expect(EXCLUDE_REASON.episode_unresolved).toBe("集数待确认"); expect(EXCLUDE_REASON.special_extra).toBeTruthy(); }); }); describe("作品页地址", () => { it("集数待确认「修改」带上要追加的一行,作品页能读回", () => { const href = mappingHref("/console/library/x", "S01 @ANi >> S02 EP-12"); expect(href).toBe("/console/library/x?mapLine=S01+%40ANi+%3E%3E+S02+EP-12#episode-mapping"); const sp = new URLSearchParams(href.slice(href.indexOf("?") + 1, href.indexOf("#"))); expect(lineFromSearch(sp)).toBe("S01 @ANi >> S02 EP-12"); expect(lineFromSearch(new URLSearchParams())).toBeNull(); expect(mappingHref("/console/library/x")).toBe("/console/library/x#episode-mapping"); }); }); describe("按发布组统计", () => { const preview = { groups: [ { releaseGroup: "ANi", total: 5, pending: 0, suggestion: null, methods: [ { method: "raw", count: 1 }, { method: "absolute_cross_season", count: 4 }, ], }, { releaseGroup: null, total: 1, pending: 1, suggestion: null, methods: [{ method: "unresolved", count: 1 }] }, ], } as unknown as EpisodeMappingPreview; it("一句话统计按数量排序", () => { expect(groupMethodsText(preview.groups[0]!)).toBe("ANi:跨季绝对集号 4、原号 1"); expect(groupMethodsText(preview.groups[1]!)).toBe("未知发布组:待确认 1"); }); it("找出用绝对集号的发布组", () => { expect(absoluteGroups(preview)).toEqual(["ANi"]); expect(absoluteGroups(undefined)).toEqual([]); }); }); describe("保存后的提示", () => { it("只列非零项", () => { expect(reresolveToast({ releases: 12, changed: 2, resolved: 2 })).toBe( "已保存:重算 12 条资源,2 条有变化,2 条待确认已解决", ); expect(reresolveToast({ releases: 3, changed: 0, resolved: 0 }, "已写入")).toBe("已写入:重算 3 条资源"); }); });