UNPKG

feishu-mcp

Version:

Model Context Protocol server for Feishu integration

99 lines (98 loc) 4.15 kB
import { createTasks, listTasks, updateTask, deleteTasks } from '../taskToolApi.js'; function createMockApi() { const calls = []; return { createTasksNested: async (rootItems) => { calls.push({ method: 'createTasksNested', args: [rootItems] }); return { results: rootItems.map((r) => ({ task: { guid: 'mock', summary: r.summary } })), errors: [] }; }, listTasks: async (pageToken, completed) => { calls.push({ method: 'listTasks', args: [pageToken, completed] }); return { items: [], has_more: false }; }, updateTask: async (taskGuid, params) => { calls.push({ method: 'updateTask', args: [taskGuid, params] }); return { task: { guid: taskGuid } }; }, addTaskMembers: async () => ({}), removeTaskMembers: async () => ({}), addTaskReminder: async () => ({}), removeTaskReminders: async () => ({}), deleteTasks: async (guids) => { calls.push({ method: 'deleteTasks', args: [guids] }); return { deleted: guids, errors: [] }; }, get _calls() { return calls; }, }; } describe('taskToolApi', () => { describe('createTasks', () => { it('应校验参数并转换 TaskCreateItem 为 RootNestedCreateItem', async () => { const mockApi = createMockApi(); const taskItems = [ { summary: '任务1', assigneeIds: ['ou_xxx'], description: '描述', }, ]; const result = await createTasks(taskItems, mockApi); const calls = mockApi._calls; expect(calls).toHaveLength(1); expect(calls[0].method).toBe('createTasksNested'); const rootItems = calls[0].args[0]; expect(rootItems).toHaveLength(1); expect(rootItems[0].summary).toBe('任务1'); expect(rootItems[0].members).toEqual([{ id: 'ou_xxx', type: 'user', role: 'assignee' }]); expect(rootItems[0].description).toBe('描述'); expect(result.results).toHaveLength(1); }); it('空数组应抛出校验错误', async () => { const mockApi = createMockApi(); await expect(createTasks([], mockApi)).rejects.toThrow(/参数校验失败/); expect(mockApi._calls).toHaveLength(0); }); }); describe('listTasks', () => { it('应透传 pageToken 和 completed', async () => { const mockApi = createMockApi(); await listTasks({ pageToken: 'pt', completed: true }, mockApi); const calls = mockApi._calls; expect(calls[0].args).toEqual(['pt', true]); }); }); describe('updateTask', () => { it('至少需要一项更新', async () => { const mockApi = createMockApi(); await expect(updateTask({ taskGuid: 'g1' }, mockApi)).rejects.toThrow(/至少需要一项更新/); }); it('应正确转换字段更新', async () => { const mockApi = createMockApi(); await updateTask({ taskGuid: 'g1', summary: '新标题', dueTimestamp: '123', isDueAllDay: true, }, mockApi); const calls = mockApi._calls; expect(calls[0].args).toEqual([ 'g1', { summary: '新标题', due: { timestamp: '123', is_all_day: true } }, ]); }); }); describe('deleteTasks', () => { it('应校验 taskGuids 并调用 deleteTasks', async () => { const mockApi = createMockApi(); const result = await deleteTasks(['g1'], mockApi); expect(mockApi._calls[0].args[0]).toEqual(['g1']); expect(result.deleted).toEqual(['g1']); }); it('空数组应抛出校验错误', async () => { const mockApi = createMockApi(); await expect(deleteTasks([], mockApi)).rejects.toThrow(/参数校验失败/); }); }); });