import { describe, it, expect, vi, beforeEach } from 'vitest' import { getAuditLogs, getAuditLogDetail, getAuditLogStats, getUserAuditLogs, getResourceAuditLogs } from '@/api/audit' import * as request from '@/utils/request' // Mock request module vi.mock('@/utils/request', () => ({ get: vi.fn(), post: vi.fn(), put: vi.fn(), del: vi.fn() })) // Mock audit logs data const mockAuditLogs = [ { id: '1', user_id: 'user-1', username: 'admin', action: 'create', resource: 'camera', resource_id: 'cam-001', ip_address: '192.168.1.1', created_at: 1704067200 }, { id: '2', user_id: 'user-1', username: 'admin', action: 'login', resource: 'auth', ip_address: '192.168.1.1', created_at: 1704063600 } ] describe('Audit API', () => { beforeEach(() => { vi.clearAllMocks() }) describe('getAuditLogs', () => { it('应该调用正确的 API 端点', async () => { const mockResponse = { code: 200, data: { rows: mockAuditLogs, total: 2 } } vi.mocked(request.get).mockResolvedValue(mockResponse) await getAuditLogs() expect(request.get).toHaveBeenCalledWith('/audit-logs', undefined) }) it('应该传递查询参数', async () => { const mockResponse = { code: 200, data: { rows: [], total: 0 } } vi.mocked(request.get).mockResolvedValue(mockResponse) const params = { action: 'create', resource: 'camera', page: 1, pageSize: 20 } await getAuditLogs(params) expect(request.get).toHaveBeenCalledWith('/audit-logs', params) }) it('应该返回审计日志列表', async () => { const mockResponse = { code: 200, data: { rows: mockAuditLogs, total: 2 } } vi.mocked(request.get).mockResolvedValue(mockResponse) const result = await getAuditLogs() expect(result.data.rows).toEqual(mockAuditLogs) expect(result.data.total).toBe(2) }) it('应该支持日期范围过滤', async () => { const mockResponse = { code: 200, data: { rows: [], total: 0 } } vi.mocked(request.get).mockResolvedValue(mockResponse) const params = { start_date: '2024-01-01', end_date: '2024-01-31' } await getAuditLogs(params) expect(request.get).toHaveBeenCalledWith('/audit-logs', params) }) }) describe('getAuditLogDetail', () => { it('应该调用正确的 API 端点', async () => { const mockResponse = { code: 200, data: mockAuditLogs[0] } vi.mocked(request.get).mockResolvedValue(mockResponse) await getAuditLogDetail('1') expect(request.get).toHaveBeenCalledWith('/audit-logs/1') }) it('应该返回审计日志详情', async () => { const mockResponse = { code: 200, data: mockAuditLogs[0] } vi.mocked(request.get).mockResolvedValue(mockResponse) const result = await getAuditLogDetail('1') expect(result.data).toEqual(mockAuditLogs[0]) }) }) describe('getAuditLogStats', () => { it('应该调用正确的 API 端点', async () => { const mockStats = { period_days: 7, total: 100, by_action: [{ action: 'create', count: 50 }], by_resource: [{ resource: 'camera', count: 30 }], by_user: [{ user_id: 'user-1', username: 'admin', count: 80 }], daily: [{ date: '2024-01-01', count: 15 }] } const mockResponse = { code: 200, data: mockStats } vi.mocked(request.get).mockResolvedValue(mockResponse) await getAuditLogStats() expect(request.get).toHaveBeenCalledWith('/audit-logs/stats/summary', { days: 7 }) }) it('应该支持自定义天数', async () => { const mockResponse = { code: 200, data: { period_days: 30 } } vi.mocked(request.get).mockResolvedValue(mockResponse) await getAuditLogStats(30) expect(request.get).toHaveBeenCalledWith('/audit-logs/stats/summary', { days: 30 }) }) it('应该返回统计数据', async () => { const mockStats = { period_days: 7, total: 100, by_action: [{ action: 'create', count: 50 }], by_resource: [{ resource: 'camera', count: 30 }], by_user: [{ user_id: 'user-1', username: 'admin', count: 80 }], daily: [{ date: '2024-01-01', count: 15 }] } const mockResponse = { code: 200, data: mockStats } vi.mocked(request.get).mockResolvedValue(mockResponse) const result = await getAuditLogStats() expect(result.data).toEqual(mockStats) }) }) describe('getUserAuditLogs', () => { it('应该调用正确的 API 端点', async () => { const mockResponse = { code: 200, data: { rows: mockAuditLogs, total: 2 } } vi.mocked(request.get).mockResolvedValue(mockResponse) await getUserAuditLogs('user-1') expect(request.get).toHaveBeenCalledWith('/audit-logs/user/user-1', undefined) }) it('应该传递分页参数', async () => { const mockResponse = { code: 200, data: { rows: [], total: 0 } } vi.mocked(request.get).mockResolvedValue(mockResponse) await getUserAuditLogs('user-1', { page: 2, pageSize: 10 }) expect(request.get).toHaveBeenCalledWith('/audit-logs/user/user-1', { page: 2, pageSize: 10 }) }) it('应该返回用户操作历史', async () => { const mockResponse = { code: 200, data: { rows: mockAuditLogs, total: 2 } } vi.mocked(request.get).mockResolvedValue(mockResponse) const result = await getUserAuditLogs('user-1') expect(result.data.rows).toEqual(mockAuditLogs) }) }) describe('getResourceAuditLogs', () => { it('应该调用正确的 API 端点', async () => { const mockResponse = { code: 200, data: { rows: [mockAuditLogs[0]], total: 1 } } vi.mocked(request.get).mockResolvedValue(mockResponse) await getResourceAuditLogs('camera', 'cam-001') expect(request.get).toHaveBeenCalledWith('/audit-logs/resource/camera/cam-001', undefined) }) it('应该传递分页参数', async () => { const mockResponse = { code: 200, data: { rows: [], total: 0 } } vi.mocked(request.get).mockResolvedValue(mockResponse) await getResourceAuditLogs('camera', 'cam-001', { page: 1, pageSize: 20 }) expect(request.get).toHaveBeenCalledWith('/audit-logs/resource/camera/cam-001', { page: 1, pageSize: 20 }) }) it('应该返回资源操作历史', async () => { const mockResponse = { code: 200, data: { rows: [mockAuditLogs[0]], total: 1 } } vi.mocked(request.get).mockResolvedValue(mockResponse) const result = await getResourceAuditLogs('camera', 'cam-001') expect(result.data.rows).toHaveLength(1) expect(result.data.rows[0].resource).toBe('camera') }) }) describe('错误处理', () => { it('API 错误应该被正确传递', async () => { const error = new Error('Network Error') vi.mocked(request.get).mockRejectedValue(error) await expect(getAuditLogs()).rejects.toThrow('Network Error') }) it('应该处理 API 返回的错误响应', async () => { const mockResponse = { code: 403, message: '无权限访问', data: null } vi.mocked(request.get).mockResolvedValue(mockResponse) const result = await getAuditLogs() expect(result.code).toBe(403) expect(result.message).toBe('无权限访问') }) }) })