/** * messages + messageTemplates 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 * as messagesApi from './messages' import * as templateApi from './messageTemplates' beforeEach(() => { vi.clearAllMocks() }) describe('messages API', () => { const fakeRes = { data: { success: true, data: {} } } it('listMessages 应调用 GET /messages 并传递查询参数', async () => { mockGet.mockResolvedValue(fakeRes) await messagesApi.listMessages({ page: 2, page_size: 10, is_read: false, priority: 'high' }) expect(mockGet).toHaveBeenCalledWith('/messages', { params: expect.objectContaining({ page: 2, page_size: 10, is_read: false, priority: 'high', }), }) }) it('getUnreadCount 应调用 GET /messages/unread-count', async () => { mockGet.mockResolvedValue(fakeRes) await messagesApi.getUnreadCount() expect(mockGet).toHaveBeenCalledWith('/messages/unread-count') }) it('markRead 应调用 PUT /messages/:id/read', async () => { mockPut.mockResolvedValue({ data: { success: true } }) await messagesApi.markRead('msg-001') expect(mockPut).toHaveBeenCalledWith('/messages/msg-001/read') }) it('markAllRead 应调用 PUT /messages/read-all', async () => { mockPut.mockResolvedValue({ data: { success: true } }) await messagesApi.markAllRead() expect(mockPut).toHaveBeenCalledWith('/messages/read-all') }) it('deleteMessage 应调用 DELETE /messages/:id', async () => { mockDelete.mockResolvedValue({ data: { success: true } }) await messagesApi.deleteMessage('msg-001') expect(mockDelete).toHaveBeenCalledWith('/messages/msg-001') }) it('sendMessage 应调用 POST /messages 并传递请求体', async () => { mockPost.mockResolvedValue(fakeRes) const req = { title: '通知', body: '内容', recipient_id: 'u-001' } await messagesApi.sendMessage(req) expect(mockPost).toHaveBeenCalledWith('/messages', req) }) }) describe('messageTemplates API', () => { const fakeRes = { data: { success: true, data: {} } } it('listTemplates 应调用 GET /message-templates 并传递分页参数', async () => { mockGet.mockResolvedValue(fakeRes) await templateApi.listTemplates(1, 10) expect(mockGet).toHaveBeenCalledWith('/message-templates', { params: { page: 1, page_size: 10 }, }) }) it('createTemplate 应调用 POST /message-templates', async () => { mockPost.mockResolvedValue(fakeRes) const req = { name: '预约提醒', code: 'appointment_reminder', title_template: '预约提醒', body_template: '您有预约' } await templateApi.createTemplate(req) expect(mockPost).toHaveBeenCalledWith('/message-templates', req) }) })