/** * dashboard + actionInbox API 契约测试 */ import { describe, it, expect, vi, beforeEach } from 'vitest' const mockGet = vi.fn() const mockPost = vi.fn() const mockPut = vi.fn() const mockDelete = vi.fn() vi.mock('../client', () => ({ default: { get: (...args: unknown[]) => mockGet(...args), post: (...args: unknown[]) => mockPost(...args), put: (...args: unknown[]) => mockPut(...args), delete: (...args: unknown[]) => mockDelete(...args), }, })) import { dashboardApi } from './dashboard' import { actionInboxApi } from './actionInbox' beforeEach(() => { vi.clearAllMocks() }) describe('dashboardApi', () => { const fakeRes = { data: { data: {} } } it('getSystemHealth 应调用 GET /health/admin/system-health', async () => { mockGet.mockResolvedValue(fakeRes) await dashboardApi.getSystemHealth() expect(mockGet).toHaveBeenCalledWith('/health/admin/system-health') }) it('getUserActivity 应调用 GET /health/admin/user-activity', async () => { mockGet.mockResolvedValue(fakeRes) await dashboardApi.getUserActivity() expect(mockGet).toHaveBeenCalledWith('/health/admin/user-activity') }) it('getModuleStatus 应调用 GET /health/admin/modules', async () => { mockGet.mockResolvedValue(fakeRes) await dashboardApi.getModuleStatus() expect(mockGet).toHaveBeenCalledWith('/health/admin/modules') }) it('getPointsRecentActivity 应调用 GET /health/points/recent-activity', async () => { mockGet.mockResolvedValue(fakeRes) await dashboardApi.getPointsRecentActivity() expect(mockGet).toHaveBeenCalledWith('/health/points/recent-activity') }) it('getArticleStats 应调用 GET /health/articles/stats', async () => { mockGet.mockResolvedValue(fakeRes) await dashboardApi.getArticleStats() expect(mockGet).toHaveBeenCalledWith('/health/articles/stats') }) }) describe('actionInboxApi', () => { const fakeRes = { data: { success: true, data: {} } } it('list 应调用 GET /health/action-inbox 并传递查询参数', async () => { mockGet.mockResolvedValue(fakeRes) await actionInboxApi.list({ status: 'pending', type: 'alert', page: 1, page_size: 20 }) expect(mockGet).toHaveBeenCalledWith('/health/action-inbox', { params: { status: 'pending', type: 'alert', page: 1, page_size: 20 }, }) }) it('getThread 应调用 GET /health/action-inbox/:sourceRef/thread', async () => { mockGet.mockResolvedValue(fakeRes) await actionInboxApi.getThread('ref-001') expect(mockGet).toHaveBeenCalledWith('/health/action-inbox/ref-001/thread') }) it('getThread 应对特殊字符 URL 编码', async () => { mockGet.mockResolvedValue(fakeRes) await actionInboxApi.getThread('ref/with:special') expect(mockGet).toHaveBeenCalledWith('/health/action-inbox/ref%2Fwith%3Aspecial/thread') }) it('stats 应调用 GET /health/action-inbox/stats', async () => { mockGet.mockResolvedValue(fakeRes) await actionInboxApi.stats() expect(mockGet).toHaveBeenCalledWith('/health/action-inbox/stats') }) it('team 应调用 GET /health/action-inbox/team', async () => { mockGet.mockResolvedValue(fakeRes) await actionInboxApi.team() expect(mockGet).toHaveBeenCalledWith('/health/action-inbox/team') }) })