import { describe, it, expect, vi } from "vitest"; import { createAuditErasureHook } from "./audit-erasure-hook"; import type { IAuditLog } from "../audit-log.interface"; function makeAuditLog(): IAuditLog { return { record: vi.fn().mockResolvedValue(undefined), eraseSubject: vi.fn().mockResolvedValue(undefined), }; } /** Minimal CollectionAfterDeleteHook args shape (only `doc` matters here). */ function hookArgs(id: unknown) { return { doc: { id }, req: {} as never, id: String(id), collection: {} as never, context: {}, }; } describe("createAuditErasureHook", () => { it("defaults to 'pseudonymize' mode", async () => { const auditLog = makeAuditLog(); const hook = createAuditErasureHook({ auditLog }); await hook(hookArgs("user_1") as never); expect(auditLog.eraseSubject).toHaveBeenCalledWith("user_1", "pseudonymize"); }); it("respects explicit mode='delete'", async () => { const auditLog = makeAuditLog(); const hook = createAuditErasureHook({ auditLog, mode: "delete" }); await hook(hookArgs("user_2") as never); expect(auditLog.eraseSubject).toHaveBeenCalledWith("user_2", "delete"); }); it("coerces numeric id to string", async () => { const auditLog = makeAuditLog(); const hook = createAuditErasureHook({ auditLog }); await hook(hookArgs(42) as never); expect(auditLog.eraseSubject).toHaveBeenCalledWith("42", "pseudonymize"); }); it("skips when doc.id is undefined", async () => { const auditLog = makeAuditLog(); const hook = createAuditErasureHook({ auditLog }); await hook(hookArgs(undefined) as never); expect(auditLog.eraseSubject).not.toHaveBeenCalled(); }); it("skips when doc.id is null", async () => { const auditLog = makeAuditLog(); const hook = createAuditErasureHook({ auditLog }); await hook(hookArgs(null) as never); expect(auditLog.eraseSubject).not.toHaveBeenCalled(); }); it("skips when doc.id is an object", async () => { const auditLog = makeAuditLog(); const hook = createAuditErasureHook({ auditLog }); await hook(hookArgs({ nested: true }) as never); expect(auditLog.eraseSubject).not.toHaveBeenCalled(); }); });