import { beforeEach, describe, expect, it, vi } from 'vitest' const FILE = '00000000-0000-4000-8000-0000000000ff' const mocks = vi.hoisted(() => ({ del: vi.fn(async () => {}), log: vi.fn(async () => {}), revalidatePath: vi.fn(), loggerInfo: vi.fn(), loggerRecordException: vi.fn(), removed: [] as Array<{ id: string; url: string }>, })) const fakeDb = { delete: () => ({ where: () => ({ returning: async () => mocks.removed, }), }), } vi.mock('next/cache', () => ({ revalidatePath: mocks.revalidatePath })) vi.mock('@/shared/api', () => ({ db: () => fakeDb, audit: () => ({ log: mocks.log }), blob: () => ({ del: mocks.del }), logger: () => ({ info: mocks.loggerInfo, recordException: mocks.loggerRecordException }), })) vi.mock('@/shared/lib/visitor-session', () => ({ ensureVisitor: async () => 'visitor-1' })) import { deleteFile } from '@/features/delete-file/api/actions' describe('deleteFile', () => { beforeEach(() => { mocks.del.mockClear() mocks.log.mockClear() mocks.revalidatePath.mockClear() mocks.loggerInfo.mockClear() mocks.loggerRecordException.mockClear() mocks.removed.length = 0 }) it('removes the stored bytes and audits file.deleted once, and logs it', async () => { mocks.removed.push({ id: FILE, url: 'https://blob.example.com/notes/n/a.png' }) await deleteFile(FILE) expect(mocks.del).toHaveBeenCalledWith('https://blob.example.com/notes/n/a.png') expect(mocks.log).toHaveBeenCalledTimes(1) expect(mocks.log).toHaveBeenCalledWith('file.deleted', { actor: { kind: 'human', id: 'visitor-1' }, target: { id: FILE }, }) expect(mocks.loggerInfo).toHaveBeenCalledTimes(1) expect(mocks.loggerInfo).toHaveBeenCalledWith('file.deleted', { 'file.id': FILE, outcome: 'ok' }) expect(mocks.loggerRecordException).not.toHaveBeenCalled() }) it('touches nothing when the visitor did not attach the file, and logs it denied', async () => { await deleteFile(FILE) expect(mocks.del).not.toHaveBeenCalled() expect(mocks.log).not.toHaveBeenCalled() expect(mocks.loggerInfo).toHaveBeenCalledWith('file.deleted', { 'file.id': FILE, outcome: 'denied' }) expect(mocks.loggerRecordException).not.toHaveBeenCalled() }) })