import { describe, it, expect, expectTypeOf, vi } from "vitest"; import { withAudit, type Audited } from "@/with-audit"; import type { IAuditLog } from "@/audit-log.interface"; import { isAudited } from "@repo/core-shared/conformance"; function makeAuditLog(): IAuditLog { return { record: vi.fn().mockResolvedValue(undefined), eraseSubject: vi.fn().mockResolvedValue(undefined), }; } describe("withAudit", () => { it("returns an Audited", () => { const auditLog = makeAuditLog(); const fn = async (_input: { id: string }) => ({ ok: true }); const wrapped = withAudit(auditLog, fn); expectTypeOf(wrapped).toMatchTypeOf>(); }); it("attaches __audited as a non-enumerable property on the wrapped function", () => { const auditLog = makeAuditLog(); const fn = async () => ({ ok: true }); const wrapped = withAudit(auditLog, fn); expect(isAudited(wrapped)).toBe(true); expect(Object.keys(wrapped)).not.toContain("__audited"); }); it("does NOT pollute the original input function with the brand", () => { const auditLog = makeAuditLog(); const fn = async () => ({ ok: true }); const wrapped = withAudit(auditLog, fn); expect(isAudited(fn)).toBe(false); expect(wrapped).not.toBe(fn); }); it("passes input and output through unchanged", async () => { const auditLog = makeAuditLog(); const fn = async (input: { id: string }) => ({ ok: true, id: input.id }); const wrapped = withAudit(auditLog, fn); const result = await wrapped({ id: "abc" }); expect(result).toEqual({ ok: true, id: "abc" }); }); it("propagates errors", async () => { const auditLog = makeAuditLog(); const err = new Error("boom"); const wrapped = withAudit(auditLog, async () => { throw err; }); await expect(wrapped()).rejects.toBe(err); }); });