const mockInsert = jest.fn().mockReturnValue({ values: jest.fn().mockResolvedValue(undefined), }); jest.mock('@/db', () => ({ db: { insert: mockInsert, }, })); jest.mock('nanoid', () => ({ nanoid: jest.fn(() => 'test-id'), })); import { createAuditLog, getActionLabel, getActionColor } from './audit'; describe('audit', () => { beforeEach(() => { jest.clearAllMocks(); }); describe('createAuditLog', () => { it('should create audit log successfully', async () => { const mockValues = jest.fn().mockResolvedValue(undefined); mockInsert.mockReturnValue({ values: mockValues }); const logData = { userId: 'user-123', action: 'LOGIN', details: { ip: '192.168.1.1' }, }; await createAuditLog(logData); expect(mockValues).toHaveBeenCalledWith( expect.objectContaining({ id: 'test-id', userId: 'user-123', action: 'LOGIN', details: { ip: '192.168.1.1' }, timestamp: expect.any(Date), }) ); }); it('should handle missing optional fields', async () => { const mockValues = jest.fn().mockResolvedValue(undefined); mockInsert.mockReturnValue({ values: mockValues }); const logData = { userId: 'user-456', action: 'LOGOUT', }; await createAuditLog(logData); expect(mockValues).toHaveBeenCalledWith( expect.objectContaining({ id: 'test-id', userId: 'user-456', action: 'LOGOUT', timestamp: expect.any(Date), }) ); }); it('should handle database errors gracefully', async () => { const mockValues = jest.fn().mockRejectedValue(new Error('Database error')); mockInsert.mockReturnValue({ values: mockValues }); const consoleSpy = jest.spyOn(console, 'error').mockImplementation(); await createAuditLog({ userId: 'user-789', action: 'LOGIN', }); expect(consoleSpy).toHaveBeenCalled(); consoleSpy.mockRestore(); }); }); describe('getActionLabel', () => { it('should return correct label for known actions', () => { expect(getActionLabel('login')).toBe('登录'); expect(getActionLabel('logout')).toBe('登出'); expect(getActionLabel('create')).toBe('创建'); expect(getActionLabel('update')).toBe('更新'); expect(getActionLabel('delete')).toBe('删除'); expect(getActionLabel('publish')).toBe('发布'); expect(getActionLabel('upload')).toBe('上传'); }); }); describe('getActionColor', () => { it('should return correct color for known actions', () => { expect(getActionColor('login')).toBe('bg-cyan-100 text-cyan-800'); expect(getActionColor('logout')).toBe('bg-gray-100 text-gray-800'); expect(getActionColor('create')).toBe('bg-green-100 text-green-800'); expect(getActionColor('update')).toBe('bg-blue-100 text-blue-800'); expect(getActionColor('delete')).toBe('bg-red-100 text-red-800'); expect(getActionColor('publish')).toBe('bg-purple-100 text-purple-800'); expect(getActionColor('upload')).toBe('bg-yellow-100 text-yellow-800'); }); }); });