import { parseRelease } from "@umt/domain"; import { createMockTmdb, type MockTmdb, TMDB_FIXTURES } from "@umt/testkit"; import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest"; import { HookRegistry } from "../../src/hooks/index.ts"; import { resolveRelease } from "../../src/modules/sources-identity/service/resolve.ts"; import { createHarness, type Harness, pgAvailable, seedSite } from "../sources-identity/harness.ts"; // 链式钩子 name.recognize(ADR-006,对照 MP ChainEventType.NameRecognize):资源标题解析之后、召回之前改写解析结果。 const up = await pgAvailable(); const GARBLED = "Zhuo.Wu.Ming.2023.2160p.UHD.BluRay.REMUX.HDR.HEVC-FGT"; describe.skipIf(!up)("name.recognize 钩子改写解析结果", () => { let h: Harness; let tmdb: MockTmdb; let siteId: string; let n = 0; const release = async (title: string) => h.db .insertInto("source_release") .values({ site_id: siteId, site_release_id: String(910000 + ++n), title }) .returningAll() .executeTakeFirstOrThrow(); beforeAll(async () => { tmdb = await createMockTmdb({ fixtures: TMDB_FIXTURES }); h = await createHarness("name_hook", { tmdbUrl: tmdb.url }); siteId = (await seedSite(h, { baseUrl: "https://hook.example/" })).site.id; await h.db .insertInto("settings") .values({ key: "identity", value: JSON.stringify({ eagerTmdbLookup: true }) } as never) .execute(); }); afterEach(() => { h.ctx.hooks = undefined; }); afterAll(async () => { await h?.close(); await tmdb?.close(); }); it("没有钩子:认不出的标题照常不自动识别", async () => { const r = await release(GARBLED); const res = await resolveRelease(h.rt, { sourceReleaseId: r.id }); expect(res.outcome).not.toBe("auto"); }); it("钩子按站点别名改写解析结果后自动识别;上下文带原标题与来源资源", async () => { const seen: unknown[] = []; const hooks = new HookRegistry(); hooks.forModule("test").rewrite("name.recognize", (p, c) => { seen.push({ title: c.title, sourceReleaseId: c.sourceReleaseId, trigger: c.trigger }); return c.title.startsWith("Zhuo.Wu.Ming") ? parseRelease(c.title.replace("Zhuo.Wu.Ming", "Oppenheimer")) : p; }); h.ctx.hooks = hooks; const r = await release(GARBLED); const res = await resolveRelease(h.rt, { sourceReleaseId: r.id }); expect(res.outcome).toBe("auto"); const e = await h.db .selectFrom("external_identity") .select("external_id") .where("media_entity_id", "=", res.mediaEntityId!) .where("provider", "=", "tmdb") .executeTakeFirstOrThrow(); expect(e.external_id).toBe("872585"); expect(seen).toEqual([{ title: GARBLED, sourceReleaseId: r.id, trigger: "observed" }]); }); });