import { createMockTmdb, type MockTmdb, TMDB_FIXTURES, type TmdbFixture } from "@umt/testkit"; import { afterAll, beforeAll, describe, expect, it } from "vitest"; import { refreshMetadata } from "../../src/modules/sources-identity/service/metadata.ts"; import { resolveRelease } from "../../src/modules/sources-identity/service/resolve.ts"; import { createHarness, type Harness, pgAvailable, seedSite } from "./harness.ts"; // 自动识别新建作品后排一次 full 元数据刷新:新建档没有季表,绝对集号资源按原号滞后放行(unverified); // 刷新补齐季表后重算为换算结果。已有作品的再次识别不重复排刷新。 const pg = await pgAvailable(); const season = (n: number, eps: number, start: string) => ({ season_number: n, air_date: start, names: { "zh-CN": `第 ${n} 季`, "en-US": `Season ${n}` }, episodes: Array.from({ length: eps }, (_, k) => ({ episode_number: k + 1, air_date: new Date(Date.parse(start) + k * 7 * 86_400_000).toISOString().slice(0, 10), names: { "zh-CN": `第 ${k + 1} 集`, "en-US": `Episode ${k + 1}` }, })), }); // 已完结:S1 = 12、S2 = 13(ANi 连续编号 25 → S02E13) const SHOW: TmdbFixture = { type: "tv", id: 990101, original_title: "Hoshikuzu Telepath", original_language: "ja", origin_country: ["JP"], date: "2023-10-06", titles: { "zh-CN": "星屑心灵感应", "en-US": "Hoshikuzu Telepath" }, popularity: 30, alternative_titles: [], external_ids: {}, rich: { status: "Ended" }, seasons: [season(1, 12, "2023-10-06"), season(2, 13, "2025-01-10")], }; describe.skipIf(!pg)("自动识别新建作品排元数据刷新", () => { let h: Harness; let tmdb: MockTmdb; let siteId: string; let n = 0; beforeAll(async () => { tmdb = await createMockTmdb({ fixtures: [...TMDB_FIXTURES, SHOW] }); h = await createHarness("auto_created_entity_refresh", { tmdbUrl: tmdb.url }); siteId = (await seedSite(h, { baseUrl: "https://acgrip.example/" })).site.id; }); afterAll(async () => { await h?.close(); await tmdb?.close(); }); const resolve = async (title: string) => { const r = await h.db .insertInto("source_release") .values({ site_id: siteId, site_release_id: String(810000 + ++n), title, subtitle: "星屑心灵感应" }) .returningAll() .executeTakeFirstOrThrow(); const res = await resolveRelease(h.rt, { sourceReleaseId: r.id, trigger: "manual" }); expect(res.outcome, JSON.stringify(res)).toBe("auto"); return { id: r.id, entityId: res.mediaEntityId as string }; }; const resolution = async (id: string) => ( await h.db .selectFrom("source_release") .select("episode_resolution") .where("id", "=", id) .executeTakeFirstOrThrow() ).episode_resolution as Record; const refreshJobs = () => h.engine.enqueued.filter((e) => e.task === "refreshMetadata"); it("新建作品后入队一次 full 刷新;刷新后 unverified 的 `- 25` 重算为 S02E13;再次识别不重复入队", async () => { const first = await resolve("[ANi] Hoshikuzu Telepath - 25 [1080P][Baha][WEB-DL][AAC AVC][CHT][MP4]"); expect(await resolution(first.id)).toMatchObject({ method: "unverified" }); expect(refreshJobs()).toEqual([ { task: "refreshMetadata", input: { mediaEntityId: first.entityId, full: true }, key: `refreshMetadata:created:${first.entityId}`, }, ]); // 执行入队的刷新任务(同 refreshMetadata 任务处理器的调用) const r = await refreshMetadata(h.rt, first.entityId, { full: true }); expect(r.status).toBe("refreshed"); expect(await resolution(first.id)).toMatchObject({ method: "absolute_cross_season", canonical: { season: 2, episodes: { start: 13, end: 13 } }, }); const second = await resolve("[ANi] Hoshikuzu Telepath - 24 [1080P][Baha][WEB-DL][AAC AVC][CHT][MP4]"); expect(second.entityId).toBe(first.entityId); expect(refreshJobs()).toHaveLength(1); }); });