import { afterEach, describe, expect, it } from "vitest"; import { assertExportConsent, ConsentRequiredError, consentIssues, consentRequirements, enforceConsentFlags, participantsOf, } from "./media-consent.js"; import type { PrivacyHarness } from "./media-privacy-fixtures.js"; import { ACTOR, createPrivacyHarness, testEdl, testProfile } from "./media-privacy-fixtures.js"; const now = new Date("2026-06-01T12:00:00Z"); const past = new Date("2026-01-01T00:00:00Z"); let harness: PrivacyHarness | null = null; afterEach(async () => { await harness?.cleanup(); harness = null; }); describe("consent rules", () => { it("always requires consent and age proof for paid video", () => { expect(consentRequirements(testProfile())).toEqual({ consent: false, age: false }); expect(consentRequirements(testProfile({ kind: "paid_video" }))).toEqual({ consent: true, age: true, }); expect(enforceConsentFlags(testProfile({ kind: "paid_video" })).consent).toEqual({ requirePerformerConsent: true, requireAgeVerification: true, }); }); it("accepts only recorded, past proof with a verification method", () => { const paid = testProfile({ kind: "paid_video" }); const ok = { id: "a", consentRecordedAt: past, ageVerifiedAt: past, ageVerificationMethod: "platform_verified", }; expect(consentIssues(paid, [ok], [], now)).toEqual([]); const future = { ...ok, consentRecordedAt: new Date("2027-01-01T00:00:00Z") }; const noMethod = { ...ok, id: "b", ageVerificationMethod: "none" }; expect(consentIssues(paid, [future, noMethod], [{ atMs: 10 }], now).map((i) => i.code)).toEqual( ["consent_missing", "age_unverified", "unknown_performer"], ); expect(consentIssues(testProfile(), [noMethod], [{}], now)).toEqual([]); }); it("collects the people and unassigned faces inside the clip ranges", () => { const edl = testEdl([{ id: "c1", assetId: "a1", inMs: 1000, outMs: 2000 }]); expect( participantsOf(edl, [ { assetId: "a1", personId: "alice", startMs: 0, endMs: 1200 }, { assetId: "a1", personId: "bob", startMs: 2500, endMs: 3000 }, { assetId: "a1", personId: null, startMs: 1500, endMs: 1600 }, { assetId: "a2", personId: "carol", startMs: 0, endMs: 5000 }, ]), ).toEqual({ personIds: ["alice"], unassigned: [{ assetId: "a1", startMs: 1500, endMs: 1600 }], }); }); }); describe("export consent", () => { it("blocks a paid export until every participant has consent and age proof", async () => { harness = await createPrivacyHarness(() => null); const alice = harness.addPerson("alice", "none"); harness.store.tracks.push({ id: "t1", assetId: "a1", personId: "alice", startMs: 0, endMs: 1000, confidenceMin: 0.9, keyframesPath: "x.json", modelVersion: "v1", }); const edl = testEdl([{ id: "c1", assetId: "a1", inMs: 0, outMs: 1000 }]); const paid = testProfile({ kind: "paid_video" }); await expect(assertExportConsent(harness.deps, ACTOR, { edl, profile: paid })).rejects.toThrow( ConsentRequiredError, ); await expect( assertExportConsent(harness.deps, ACTOR, { edl, profile: testProfile() }), ).resolves.toBeUndefined(); alice.consentRecordedAt = past; alice.ageVerifiedAt = past; alice.ageVerificationMethod = "document_on_file"; await expect( assertExportConsent(harness.deps, ACTOR, { edl, profile: paid }), ).resolves.toBeUndefined(); }); });