import { describe, expect, it } from "vitest"; import type { ObservedEntity } from "@src/shared"; import { mergeSurfaces, resolveIdentity, entityConfidence } from "./index.ts"; const mk = (surface: "dom" | "network", over: Partial): ObservedEntity => ({ ref: "x", type: "video", platform: "youtube", platform_id: "v1", fingerprint: "youtube:video:v1", fields: { title: { value: over.name, provenance: [{ surface, confidence: surface === "network" ? 0.95 : 0.85 }] } }, provenance: [{ surface, confidence: surface === "network" ? 0.95 : 0.85 }], ...over }); describe("mergeSurfaces", () => { it("merges the same entity from network and DOM, keeping both provenances", () => { const net = [mk("network", { name: "IA au Québec — table ronde", author: "Chaîne", metrics: { views: 1200000 } })]; const dom = [mk("dom", { name: "IA au Québec — table ronde", url: "https://youtube.com/watch?v=v1" })]; const r = mergeSurfaces(net, dom); expect(r.merged).toHaveLength(1); expect(r.both).toBe(1); expect(r.field_agreements).toBe(1); const e = r.merged[0]!; expect(new Set(e.provenance.map((p) => p.surface))).toEqual(new Set(["dom", "network"])); expect(e.author).toBe("Chaîne"); expect(e.url).toContain("v1"); expect(e.ref).toBe("E1"); expect(entityConfidence(e)).toBeGreaterThan(0.95); }); it("reports conflicts", () => { const r = mergeSurfaces([mk("network", { name: "Titre A" })], [mk("dom", { name: "Complètement autre" })]); expect(r.field_conflicts).toHaveLength(1); }); }); describe("resolveIdentity", () => { it("never merges on display name alone", () => { const d = resolveIdentity({ id: "a", display_name: "Simon B", urls: [], usernames: [] }, { id: "b", display_name: "Simon B", urls: [], usernames: [] }); expect(d.merge).toBe(false); }); it("merges with a shared canonical url + username", () => { const d = resolveIdentity({ id: "a", display_name: "Simon B", urls: ["https://example.com"], usernames: ["@simon"] }, { id: "b", urls: ["https://example.com"], usernames: ["simon"] }); expect(d.merge).toBe(true); expect(d.evidence).toContain("same canonical url"); }); });