import { describe, expect, it, vi } from "vitest"; vi.mock("server-only", () => ({})); import { auditLog } from "@/db/schema"; import { AUDIT_ACTION_LABELS, AUDIT_ACTIONS, AUDIT_TARGET_LABELS, AUDIT_TARGET_TYPES, auditActor, isAuditTargetType, writeAuditLog, } from "@/lib/audit-log"; describe("audit log", () => { it("builds a stable actor snapshot", () => { expect(auditActor({ id: "admin-1", name: " Editor ", email: "editor@example.com" })) .toEqual({ id: "admin-1", label: "Editor" }); expect(auditActor({ id: "admin-2", name: "", email: "fallback@example.com" })) .toEqual({ id: "admin-2", label: "fallback@example.com" }); }); it("keeps action and target labels complete", () => { expect(Object.keys(AUDIT_ACTION_LABELS)).toHaveLength(AUDIT_ACTIONS.length); expect(Object.keys(AUDIT_TARGET_LABELS)).toHaveLength(AUDIT_TARGET_TYPES.length); expect(isAuditTargetType("guide")).toBe(true); expect(isAuditTargetType("unknown")).toBe(false); }); it("writes only the explicit compact event envelope", async () => { const values = vi.fn().mockResolvedValue(undefined); const insert = vi.fn(() => ({ values })); await writeAuditLog( { insert } as never, { id: "admin-1", label: "Editor" }, { action: "guide.weapon.saved", targetType: "guide", targetId: "guide-1", scope: "weapon", resultingVersion: 4, metadata: { guideName: "Amber", overwrite: true }, }, ); expect(insert).toHaveBeenCalledWith(auditLog); expect(values).toHaveBeenCalledWith({ authorId: "admin-1", author: "Editor", text: "บันทึก Weapons", details: { target: { type: "guide", id: "guide-1" }, scope: "weapon", version: 4, guideName: "Amber", overwrite: true, }, }); }); });