import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("~/database/context", () => ({ database: vi.fn(), })); import { anonymizeUserAccount } from "../user"; import { database } from "~/database/context"; import * as schema from "~/database/schema"; const USER_ID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"; function makeTransactionDb() { const whereFn = vi.fn().mockResolvedValue(undefined); const setFn = vi.fn().mockReturnValue({ where: whereFn }); const deleteFn = vi.fn().mockReturnValue({ where: vi.fn().mockResolvedValue(undefined) }); const updateFn = vi.fn().mockReturnValue({ set: setFn }); const tx = { delete: deleteFn, update: updateFn }; const db = { transaction: vi.fn().mockImplementation((fn: (t: typeof tx) => Promise) => fn(tx)), }; return { db, tx, deleteFn, updateFn, setFn, whereFn }; } beforeEach(() => { vi.clearAllMocks(); }); describe("anonymizeUserAccount", () => { it("deletes sessions then accounts inside a transaction", async () => { const { db, tx, deleteFn } = makeTransactionDb(); vi.mocked(database).mockReturnValue(db as never); await anonymizeUserAccount(USER_ID); expect(db.transaction).toHaveBeenCalledTimes(1); expect(deleteFn).toHaveBeenCalledTimes(2); expect(deleteFn).toHaveBeenNthCalledWith(1, schema.sessions); expect(deleteFn).toHaveBeenNthCalledWith(2, schema.accounts); expect(tx.update).toHaveBeenCalledWith(schema.users); }); it("calls update on the users table with anonymized fields", async () => { const { db, setFn } = makeTransactionDb(); vi.mocked(database).mockReturnValue(db as never); await anonymizeUserAccount(USER_ID); const setCall = setFn.mock.calls[0][0]; expect(setCall.email).toMatch(/^deleted-[a-f0-9]{8}@deleted\.brackt\.com$/); expect(setCall.displayName).toBeNull(); expect(setCall.username).toBeNull(); expect(setCall.imageUrl).toBeNull(); expect(setCall.customAvatarUrl).toBeNull(); expect(setCall.flagConfig).toBeNull(); expect(setCall.avatarType).toBe("flag"); expect(setCall.deletedAt).toBeInstanceOf(Date); }); it("derives the short ID from the UUID", async () => { const { db, setFn } = makeTransactionDb(); vi.mocked(database).mockReturnValue(db as never); await anonymizeUserAccount(USER_ID); const setCall = setFn.mock.calls[0][0]; // USER_ID without dashes: "a1b2c3d4e5f67890abcdef1234567890" → first 8 = "a1b2c3d4" expect(setCall.email).toBe("deleted-a1b2c3d4@deleted.brackt.com"); }); });