@doist/todoist-ai 4.15.1 → 4.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/filter-helpers.d.ts +1 -1
- package/dist/index.d.ts +175 -175
- package/dist/index.js +61 -81
- package/dist/main.js +15 -23
- package/dist/mcp-helpers.d.ts +4 -4
- package/dist/mcp-server-6tm7Rhyz.js +2840 -0
- package/dist/todoist-tool.d.ts +2 -2
- package/dist/tool-helpers.d.ts +1 -1
- package/dist/tools/add-comments.d.ts +1 -1
- package/dist/tools/add-comments.d.ts.map +1 -1
- package/dist/tools/add-projects.d.ts +4 -4
- package/dist/tools/add-projects.d.ts.map +1 -1
- package/dist/tools/add-sections.d.ts +1 -1
- package/dist/tools/add-sections.d.ts.map +1 -1
- package/dist/tools/add-tasks.d.ts +4 -4
- package/dist/tools/add-tasks.d.ts.map +1 -1
- package/dist/tools/complete-tasks.d.ts +1 -1
- package/dist/tools/complete-tasks.d.ts.map +1 -1
- package/dist/tools/delete-object.d.ts +3 -3
- package/dist/tools/delete-object.d.ts.map +1 -1
- package/dist/tools/fetch.d.ts +1 -1
- package/dist/tools/find-activity.d.ts +5 -5
- package/dist/tools/find-activity.d.ts.map +1 -1
- package/dist/tools/find-comments.d.ts +2 -2
- package/dist/tools/find-comments.d.ts.map +1 -1
- package/dist/tools/find-completed-tasks.d.ts +3 -3
- package/dist/tools/find-completed-tasks.d.ts.map +1 -1
- package/dist/tools/find-project-collaborators.d.ts +2 -2
- package/dist/tools/find-projects.d.ts +1 -1
- package/dist/tools/find-projects.d.ts.map +1 -1
- package/dist/tools/find-sections.d.ts +1 -1
- package/dist/tools/find-sections.d.ts.map +1 -1
- package/dist/tools/find-tasks-by-date.d.ts +1 -1
- package/dist/tools/find-tasks-by-date.d.ts.map +1 -1
- package/dist/tools/find-tasks.d.ts +3 -3
- package/dist/tools/find-tasks.d.ts.map +1 -1
- package/dist/tools/get-overview.d.ts +1 -1
- package/dist/tools/manage-assignments.d.ts +1 -1
- package/dist/tools/search.d.ts +1 -1
- package/dist/tools/update-comments.d.ts +4 -4
- package/dist/tools/update-comments.d.ts.map +1 -1
- package/dist/tools/update-projects.d.ts +1 -1
- package/dist/tools/update-projects.d.ts.map +1 -1
- package/dist/tools/update-sections.d.ts +4 -4
- package/dist/tools/update-sections.d.ts.map +1 -1
- package/dist/tools/update-tasks.d.ts +7 -7
- package/dist/tools/update-tasks.d.ts.map +1 -1
- package/dist/tools/user-info.d.ts +1 -1
- package/dist/utils/assignment-validator.d.ts +2 -2
- package/dist/utils/response-builders.d.ts +1 -3
- package/dist/utils/response-builders.d.ts.map +1 -1
- package/dist/utils/test-helpers.d.ts +1 -1
- package/dist/utils/user-resolver.d.ts +1 -1
- package/package.json +11 -9
- package/dist/filter-helpers.js +0 -79
- package/dist/mcp-helpers.js +0 -71
- package/dist/mcp-server.js +0 -142
- package/dist/todoist-tool.js +0 -1
- package/dist/tool-helpers.js +0 -125
- package/dist/tool-helpers.test.d.ts +0 -2
- package/dist/tool-helpers.test.d.ts.map +0 -1
- package/dist/tool-helpers.test.js +0 -223
- package/dist/tools/__tests__/add-comments.test.d.ts +0 -2
- package/dist/tools/__tests__/add-comments.test.d.ts.map +0 -1
- package/dist/tools/__tests__/add-comments.test.js +0 -241
- package/dist/tools/__tests__/add-projects.test.d.ts +0 -2
- package/dist/tools/__tests__/add-projects.test.d.ts.map +0 -1
- package/dist/tools/__tests__/add-projects.test.js +0 -174
- package/dist/tools/__tests__/add-sections.test.d.ts +0 -2
- package/dist/tools/__tests__/add-sections.test.d.ts.map +0 -1
- package/dist/tools/__tests__/add-sections.test.js +0 -185
- package/dist/tools/__tests__/add-tasks.test.d.ts +0 -2
- package/dist/tools/__tests__/add-tasks.test.d.ts.map +0 -1
- package/dist/tools/__tests__/add-tasks.test.js +0 -533
- package/dist/tools/__tests__/assignment-integration.test.d.ts +0 -2
- package/dist/tools/__tests__/assignment-integration.test.d.ts.map +0 -1
- package/dist/tools/__tests__/assignment-integration.test.js +0 -428
- package/dist/tools/__tests__/complete-tasks.test.d.ts +0 -2
- package/dist/tools/__tests__/complete-tasks.test.d.ts.map +0 -1
- package/dist/tools/__tests__/complete-tasks.test.js +0 -206
- package/dist/tools/__tests__/delete-object.test.d.ts +0 -2
- package/dist/tools/__tests__/delete-object.test.d.ts.map +0 -1
- package/dist/tools/__tests__/delete-object.test.js +0 -110
- package/dist/tools/__tests__/fetch.test.d.ts +0 -2
- package/dist/tools/__tests__/fetch.test.d.ts.map +0 -1
- package/dist/tools/__tests__/fetch.test.js +0 -279
- package/dist/tools/__tests__/find-activity.test.d.ts +0 -2
- package/dist/tools/__tests__/find-activity.test.d.ts.map +0 -1
- package/dist/tools/__tests__/find-activity.test.js +0 -229
- package/dist/tools/__tests__/find-comments.test.d.ts +0 -2
- package/dist/tools/__tests__/find-comments.test.d.ts.map +0 -1
- package/dist/tools/__tests__/find-comments.test.js +0 -236
- package/dist/tools/__tests__/find-completed-tasks.test.d.ts +0 -2
- package/dist/tools/__tests__/find-completed-tasks.test.d.ts.map +0 -1
- package/dist/tools/__tests__/find-completed-tasks.test.js +0 -324
- package/dist/tools/__tests__/find-projects.test.d.ts +0 -2
- package/dist/tools/__tests__/find-projects.test.d.ts.map +0 -1
- package/dist/tools/__tests__/find-projects.test.js +0 -154
- package/dist/tools/__tests__/find-sections.test.d.ts +0 -2
- package/dist/tools/__tests__/find-sections.test.d.ts.map +0 -1
- package/dist/tools/__tests__/find-sections.test.js +0 -245
- package/dist/tools/__tests__/find-tasks-by-date.test.d.ts +0 -2
- package/dist/tools/__tests__/find-tasks-by-date.test.d.ts.map +0 -1
- package/dist/tools/__tests__/find-tasks-by-date.test.js +0 -528
- package/dist/tools/__tests__/find-tasks.test.d.ts +0 -2
- package/dist/tools/__tests__/find-tasks.test.d.ts.map +0 -1
- package/dist/tools/__tests__/find-tasks.test.js +0 -771
- package/dist/tools/__tests__/get-overview.test.d.ts +0 -2
- package/dist/tools/__tests__/get-overview.test.d.ts.map +0 -1
- package/dist/tools/__tests__/get-overview.test.js +0 -225
- package/dist/tools/__tests__/search.test.d.ts +0 -2
- package/dist/tools/__tests__/search.test.d.ts.map +0 -1
- package/dist/tools/__tests__/search.test.js +0 -206
- package/dist/tools/__tests__/update-comments.test.d.ts +0 -2
- package/dist/tools/__tests__/update-comments.test.d.ts.map +0 -1
- package/dist/tools/__tests__/update-comments.test.js +0 -294
- package/dist/tools/__tests__/update-projects.test.d.ts +0 -2
- package/dist/tools/__tests__/update-projects.test.d.ts.map +0 -1
- package/dist/tools/__tests__/update-projects.test.js +0 -217
- package/dist/tools/__tests__/update-sections.test.d.ts +0 -2
- package/dist/tools/__tests__/update-sections.test.d.ts.map +0 -1
- package/dist/tools/__tests__/update-sections.test.js +0 -169
- package/dist/tools/__tests__/update-tasks.test.d.ts +0 -2
- package/dist/tools/__tests__/update-tasks.test.d.ts.map +0 -1
- package/dist/tools/__tests__/update-tasks.test.js +0 -788
- package/dist/tools/__tests__/user-info.test.d.ts +0 -2
- package/dist/tools/__tests__/user-info.test.d.ts.map +0 -1
- package/dist/tools/__tests__/user-info.test.js +0 -139
- package/dist/tools/add-comments.js +0 -79
- package/dist/tools/add-projects.js +0 -63
- package/dist/tools/add-sections.js +0 -61
- package/dist/tools/add-tasks.js +0 -160
- package/dist/tools/complete-tasks.js +0 -68
- package/dist/tools/delete-object.js +0 -79
- package/dist/tools/fetch.js +0 -102
- package/dist/tools/find-activity.js +0 -221
- package/dist/tools/find-comments.js +0 -143
- package/dist/tools/find-completed-tasks.js +0 -161
- package/dist/tools/find-project-collaborators.js +0 -151
- package/dist/tools/find-projects.js +0 -101
- package/dist/tools/find-sections.js +0 -96
- package/dist/tools/find-tasks-by-date.js +0 -198
- package/dist/tools/find-tasks.js +0 -329
- package/dist/tools/get-overview.js +0 -249
- package/dist/tools/manage-assignments.js +0 -337
- package/dist/tools/search.js +0 -65
- package/dist/tools/update-comments.js +0 -82
- package/dist/tools/update-projects.js +0 -84
- package/dist/tools/update-sections.js +0 -70
- package/dist/tools/update-tasks.js +0 -170
- package/dist/tools/user-info.js +0 -142
- package/dist/utils/assignment-validator.js +0 -253
- package/dist/utils/constants.js +0 -45
- package/dist/utils/duration-parser.js +0 -96
- package/dist/utils/duration-parser.test.d.ts +0 -2
- package/dist/utils/duration-parser.test.d.ts.map +0 -1
- package/dist/utils/duration-parser.test.js +0 -147
- package/dist/utils/labels.js +0 -18
- package/dist/utils/priorities.js +0 -20
- package/dist/utils/response-builders.js +0 -210
- package/dist/utils/sanitize-data.js +0 -37
- package/dist/utils/sanitize-data.test.d.ts +0 -2
- package/dist/utils/sanitize-data.test.d.ts.map +0 -1
- package/dist/utils/sanitize-data.test.js +0 -93
- package/dist/utils/test-helpers.js +0 -237
- package/dist/utils/tool-names.js +0 -40
- package/dist/utils/user-resolver.js +0 -179
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import { jest } from '@jest/globals';
|
|
2
|
-
import { createMockApiResponse, createMockProject, extractStructuredContent, extractTextContent, TEST_ERRORS, TEST_IDS, } from '../../utils/test-helpers.js';
|
|
3
|
-
import { ToolNames } from '../../utils/tool-names.js';
|
|
4
|
-
import { findProjects } from '../find-projects.js';
|
|
5
|
-
// Mock the Todoist API
|
|
6
|
-
const mockTodoistApi = {
|
|
7
|
-
getProjects: jest.fn(),
|
|
8
|
-
};
|
|
9
|
-
const { FIND_PROJECTS } = ToolNames;
|
|
10
|
-
describe(`${FIND_PROJECTS} tool`, () => {
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
jest.clearAllMocks();
|
|
13
|
-
});
|
|
14
|
-
describe('listing all projects', () => {
|
|
15
|
-
it('should list all projects when no search parameter is provided', async () => {
|
|
16
|
-
const mockProjects = [
|
|
17
|
-
createMockProject({
|
|
18
|
-
id: TEST_IDS.PROJECT_INBOX,
|
|
19
|
-
name: 'Inbox',
|
|
20
|
-
color: 'grey',
|
|
21
|
-
inboxProject: true,
|
|
22
|
-
childOrder: 0,
|
|
23
|
-
}),
|
|
24
|
-
createMockProject({
|
|
25
|
-
id: TEST_IDS.PROJECT_TEST,
|
|
26
|
-
name: 'test-abc123def456-project',
|
|
27
|
-
color: 'charcoal',
|
|
28
|
-
childOrder: 1,
|
|
29
|
-
}),
|
|
30
|
-
createMockProject({
|
|
31
|
-
id: TEST_IDS.PROJECT_WORK,
|
|
32
|
-
name: 'Work Project',
|
|
33
|
-
color: 'blue',
|
|
34
|
-
isFavorite: true,
|
|
35
|
-
isShared: true,
|
|
36
|
-
viewStyle: 'board',
|
|
37
|
-
childOrder: 2,
|
|
38
|
-
description: 'Important work tasks',
|
|
39
|
-
canAssignTasks: true,
|
|
40
|
-
}),
|
|
41
|
-
];
|
|
42
|
-
mockTodoistApi.getProjects.mockResolvedValue(createMockApiResponse(mockProjects));
|
|
43
|
-
const result = await findProjects.execute({ limit: 50 }, mockTodoistApi);
|
|
44
|
-
// Verify API was called correctly
|
|
45
|
-
expect(mockTodoistApi.getProjects).toHaveBeenCalledWith({
|
|
46
|
-
limit: 50,
|
|
47
|
-
cursor: null,
|
|
48
|
-
});
|
|
49
|
-
expect(extractTextContent(result)).toMatchSnapshot();
|
|
50
|
-
// Verify structured content
|
|
51
|
-
const structuredContent = extractStructuredContent(result);
|
|
52
|
-
expect(structuredContent).toEqual(expect.objectContaining({
|
|
53
|
-
projects: expect.any(Array),
|
|
54
|
-
totalCount: 3,
|
|
55
|
-
hasMore: false,
|
|
56
|
-
appliedFilters: {
|
|
57
|
-
search: undefined,
|
|
58
|
-
limit: 50,
|
|
59
|
-
cursor: undefined,
|
|
60
|
-
},
|
|
61
|
-
}));
|
|
62
|
-
expect(structuredContent.projects).toHaveLength(3);
|
|
63
|
-
});
|
|
64
|
-
it('should handle pagination with limit and cursor', async () => {
|
|
65
|
-
const mockProject = createMockProject({
|
|
66
|
-
id: 'project-1',
|
|
67
|
-
name: 'First Project',
|
|
68
|
-
color: 'red',
|
|
69
|
-
});
|
|
70
|
-
mockTodoistApi.getProjects.mockResolvedValue(createMockApiResponse([mockProject], 'next-page-cursor'));
|
|
71
|
-
const result = await findProjects.execute({ limit: 10, cursor: 'current-page-cursor' }, mockTodoistApi);
|
|
72
|
-
expect(mockTodoistApi.getProjects).toHaveBeenCalledWith({
|
|
73
|
-
limit: 10,
|
|
74
|
-
cursor: 'current-page-cursor',
|
|
75
|
-
});
|
|
76
|
-
expect(extractTextContent(result)).toMatchSnapshot();
|
|
77
|
-
// Verify structured content
|
|
78
|
-
const structuredContent = extractStructuredContent(result);
|
|
79
|
-
expect(structuredContent.projects).toHaveLength(1);
|
|
80
|
-
expect(structuredContent.totalCount).toBe(1);
|
|
81
|
-
expect(structuredContent.hasMore).toBe(true);
|
|
82
|
-
expect(structuredContent.nextCursor).toBe('next-page-cursor');
|
|
83
|
-
expect(structuredContent.appliedFilters).toEqual({
|
|
84
|
-
search: undefined,
|
|
85
|
-
limit: 10,
|
|
86
|
-
cursor: 'current-page-cursor',
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
describe('searching projects', () => {
|
|
91
|
-
it('should filter projects by search term (case insensitive)', async () => {
|
|
92
|
-
const mockProjects = [
|
|
93
|
-
createMockProject({
|
|
94
|
-
id: TEST_IDS.PROJECT_WORK,
|
|
95
|
-
name: 'Work Project',
|
|
96
|
-
color: 'blue',
|
|
97
|
-
}),
|
|
98
|
-
createMockProject({
|
|
99
|
-
id: 'personal-project-id',
|
|
100
|
-
name: 'Personal Tasks',
|
|
101
|
-
color: 'green',
|
|
102
|
-
}),
|
|
103
|
-
createMockProject({ id: 'hobby-project-id', name: 'Hobby Work', color: 'orange' }),
|
|
104
|
-
];
|
|
105
|
-
mockTodoistApi.getProjects.mockResolvedValue(createMockApiResponse(mockProjects));
|
|
106
|
-
const result = await findProjects.execute({ search: 'work', limit: 50 }, mockTodoistApi);
|
|
107
|
-
expect(mockTodoistApi.getProjects).toHaveBeenCalledWith({ limit: 50, cursor: null });
|
|
108
|
-
expect(extractTextContent(result)).toMatchSnapshot();
|
|
109
|
-
// Verify structured content with search filter
|
|
110
|
-
const structuredContent = extractStructuredContent(result);
|
|
111
|
-
expect(structuredContent.projects).toHaveLength(2); // Should match filtered results
|
|
112
|
-
expect(structuredContent.totalCount).toBe(2);
|
|
113
|
-
expect(structuredContent.hasMore).toBe(false);
|
|
114
|
-
expect(structuredContent.appliedFilters).toEqual({
|
|
115
|
-
search: 'work',
|
|
116
|
-
limit: 50,
|
|
117
|
-
cursor: undefined,
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
it.each([
|
|
121
|
-
{
|
|
122
|
-
search: 'nonexistent',
|
|
123
|
-
projects: ['Project One'],
|
|
124
|
-
expectedCount: 0,
|
|
125
|
-
description: 'no matches',
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
search: 'IMPORTANT',
|
|
129
|
-
projects: ['Important Project'],
|
|
130
|
-
expectedCount: 1,
|
|
131
|
-
description: 'case insensitive matching',
|
|
132
|
-
},
|
|
133
|
-
])('should handle search with $description', async ({ search, projects }) => {
|
|
134
|
-
const mockProjects = projects.map((name) => createMockProject({ name }));
|
|
135
|
-
mockTodoistApi.getProjects.mockResolvedValue(createMockApiResponse(mockProjects));
|
|
136
|
-
const result = await findProjects.execute({ search, limit: 50 }, mockTodoistApi);
|
|
137
|
-
expect(extractTextContent(result)).toMatchSnapshot();
|
|
138
|
-
// Verify structured content
|
|
139
|
-
const structuredContent = extractStructuredContent(result);
|
|
140
|
-
expect(structuredContent).toEqual(expect.objectContaining({
|
|
141
|
-
appliedFilters: expect.objectContaining({ search }),
|
|
142
|
-
}));
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
describe('error handling', () => {
|
|
146
|
-
it.each([
|
|
147
|
-
{ error: TEST_ERRORS.API_UNAUTHORIZED, params: { limit: 50 } },
|
|
148
|
-
{ error: TEST_ERRORS.INVALID_CURSOR, params: { cursor: 'invalid-cursor', limit: 50 } },
|
|
149
|
-
])('should propagate $error', async ({ error, params }) => {
|
|
150
|
-
mockTodoistApi.getProjects.mockRejectedValue(new Error(error));
|
|
151
|
-
await expect(findProjects.execute(params, mockTodoistApi)).rejects.toThrow(error);
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-sections.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/find-sections.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { jest } from '@jest/globals';
|
|
2
|
-
import { createMockSection, extractStructuredContent, extractTextContent, TEST_ERRORS, TEST_IDS, } from '../../utils/test-helpers.js';
|
|
3
|
-
import { ToolNames } from '../../utils/tool-names.js';
|
|
4
|
-
import { findSections } from '../find-sections.js';
|
|
5
|
-
// Mock the Todoist API
|
|
6
|
-
const mockTodoistApi = {
|
|
7
|
-
getSections: jest.fn(),
|
|
8
|
-
};
|
|
9
|
-
const { FIND_SECTIONS, ADD_SECTIONS } = ToolNames;
|
|
10
|
-
describe(`${FIND_SECTIONS} tool`, () => {
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
jest.clearAllMocks();
|
|
13
|
-
});
|
|
14
|
-
describe('listing all sections in a project', () => {
|
|
15
|
-
it('should list all sections when no search parameter is provided', async () => {
|
|
16
|
-
const mockSections = [
|
|
17
|
-
createMockSection({
|
|
18
|
-
id: TEST_IDS.SECTION_1,
|
|
19
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
20
|
-
name: 'To Do',
|
|
21
|
-
}),
|
|
22
|
-
createMockSection({
|
|
23
|
-
id: TEST_IDS.SECTION_2,
|
|
24
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
25
|
-
sectionOrder: 2,
|
|
26
|
-
name: 'In Progress',
|
|
27
|
-
}),
|
|
28
|
-
createMockSection({
|
|
29
|
-
id: 'section-789',
|
|
30
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
31
|
-
sectionOrder: 3,
|
|
32
|
-
name: 'Done',
|
|
33
|
-
}),
|
|
34
|
-
createMockSection({
|
|
35
|
-
id: 'section-999',
|
|
36
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
37
|
-
sectionOrder: 4,
|
|
38
|
-
name: 'Backlog Items',
|
|
39
|
-
}),
|
|
40
|
-
];
|
|
41
|
-
mockTodoistApi.getSections.mockResolvedValue({
|
|
42
|
-
results: mockSections,
|
|
43
|
-
nextCursor: null,
|
|
44
|
-
});
|
|
45
|
-
const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST }, mockTodoistApi);
|
|
46
|
-
expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
|
|
47
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
48
|
-
});
|
|
49
|
-
const textContent = extractTextContent(result);
|
|
50
|
-
expect(textContent).toMatchSnapshot();
|
|
51
|
-
expect(textContent).toContain('Sections in project');
|
|
52
|
-
expect(textContent).toContain('To Do • id=');
|
|
53
|
-
expect(textContent).toContain('In Progress • id=');
|
|
54
|
-
expect(textContent).toContain('Done • id=');
|
|
55
|
-
expect(textContent).toContain('Backlog Items • id=');
|
|
56
|
-
// Verify structured content
|
|
57
|
-
const structuredContent = extractStructuredContent(result);
|
|
58
|
-
expect(structuredContent.sections).toHaveLength(4);
|
|
59
|
-
expect(structuredContent.totalCount).toBe(4);
|
|
60
|
-
expect(structuredContent.appliedFilters).toEqual({
|
|
61
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
62
|
-
search: undefined,
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
it('should handle project with no sections', async () => {
|
|
66
|
-
mockTodoistApi.getSections.mockResolvedValue({
|
|
67
|
-
results: [],
|
|
68
|
-
nextCursor: null,
|
|
69
|
-
});
|
|
70
|
-
const result = await findSections.execute({ projectId: 'empty-project-id' }, mockTodoistApi);
|
|
71
|
-
expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
|
|
72
|
-
projectId: 'empty-project-id',
|
|
73
|
-
});
|
|
74
|
-
const textContent = extractTextContent(result);
|
|
75
|
-
expect(textContent).toMatchSnapshot();
|
|
76
|
-
expect(textContent).toContain('Project has no sections yet');
|
|
77
|
-
expect(textContent).toContain(`Use ${ADD_SECTIONS} to create sections`);
|
|
78
|
-
// Verify structured content
|
|
79
|
-
const structuredContent = extractStructuredContent(result);
|
|
80
|
-
expect(structuredContent.sections).toBeUndefined(); // Empty arrays are removed
|
|
81
|
-
expect(structuredContent.totalCount).toBe(0);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('searching sections by name', () => {
|
|
85
|
-
it('should filter sections by search term (case insensitive)', async () => {
|
|
86
|
-
const mockSections = [
|
|
87
|
-
createMockSection({
|
|
88
|
-
id: TEST_IDS.SECTION_1,
|
|
89
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
90
|
-
name: 'To Do',
|
|
91
|
-
}),
|
|
92
|
-
createMockSection({
|
|
93
|
-
id: TEST_IDS.SECTION_2,
|
|
94
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
95
|
-
sectionOrder: 2,
|
|
96
|
-
name: 'In Progress',
|
|
97
|
-
}),
|
|
98
|
-
createMockSection({
|
|
99
|
-
id: 'section-789',
|
|
100
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
101
|
-
sectionOrder: 3,
|
|
102
|
-
name: 'Done',
|
|
103
|
-
}),
|
|
104
|
-
createMockSection({
|
|
105
|
-
id: 'section-999',
|
|
106
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
107
|
-
sectionOrder: 4,
|
|
108
|
-
name: 'Progress Review',
|
|
109
|
-
}),
|
|
110
|
-
];
|
|
111
|
-
mockTodoistApi.getSections.mockResolvedValue({
|
|
112
|
-
results: mockSections,
|
|
113
|
-
nextCursor: null,
|
|
114
|
-
});
|
|
115
|
-
const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'progress' }, mockTodoistApi);
|
|
116
|
-
expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
|
|
117
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
118
|
-
});
|
|
119
|
-
// Should return both "In Progress" and "Progress Review" (case insensitive partial match)
|
|
120
|
-
const textContent = extractTextContent(result);
|
|
121
|
-
expect(textContent).toMatchSnapshot();
|
|
122
|
-
expect(textContent).toContain('matching "progress"');
|
|
123
|
-
expect(textContent).toContain('In Progress • id=');
|
|
124
|
-
expect(textContent).toContain('Progress Review • id=');
|
|
125
|
-
});
|
|
126
|
-
it('should handle search with no matches', async () => {
|
|
127
|
-
const mockSections = [
|
|
128
|
-
createMockSection({
|
|
129
|
-
id: TEST_IDS.SECTION_1,
|
|
130
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
131
|
-
name: 'To Do',
|
|
132
|
-
}),
|
|
133
|
-
createMockSection({
|
|
134
|
-
id: TEST_IDS.SECTION_2,
|
|
135
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
136
|
-
sectionOrder: 2,
|
|
137
|
-
name: 'In Progress',
|
|
138
|
-
}),
|
|
139
|
-
];
|
|
140
|
-
mockTodoistApi.getSections.mockResolvedValue({
|
|
141
|
-
results: mockSections,
|
|
142
|
-
nextCursor: null,
|
|
143
|
-
});
|
|
144
|
-
const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'nonexistent' }, mockTodoistApi);
|
|
145
|
-
const textContent = extractTextContent(result);
|
|
146
|
-
expect(textContent).toMatchSnapshot();
|
|
147
|
-
expect(textContent).toContain('Try broader search terms');
|
|
148
|
-
expect(textContent).toContain('Check spelling');
|
|
149
|
-
expect(textContent).toContain('Remove search to see all sections');
|
|
150
|
-
});
|
|
151
|
-
it('should handle case sensitive search correctly', async () => {
|
|
152
|
-
const mockSections = [
|
|
153
|
-
createMockSection({
|
|
154
|
-
id: TEST_IDS.SECTION_1,
|
|
155
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
156
|
-
name: 'Important Tasks',
|
|
157
|
-
}),
|
|
158
|
-
createMockSection({
|
|
159
|
-
id: TEST_IDS.SECTION_2,
|
|
160
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
161
|
-
sectionOrder: 2,
|
|
162
|
-
name: 'Regular Work',
|
|
163
|
-
}),
|
|
164
|
-
];
|
|
165
|
-
mockTodoistApi.getSections.mockResolvedValue({
|
|
166
|
-
results: mockSections,
|
|
167
|
-
nextCursor: null,
|
|
168
|
-
});
|
|
169
|
-
const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'IMPORTANT' }, mockTodoistApi);
|
|
170
|
-
// Should match despite different case
|
|
171
|
-
const textContent = extractTextContent(result);
|
|
172
|
-
expect(textContent).toMatchSnapshot();
|
|
173
|
-
expect(textContent).toContain('matching "IMPORTANT"');
|
|
174
|
-
expect(textContent).toContain('Important Tasks • id=');
|
|
175
|
-
});
|
|
176
|
-
it('should handle partial matches correctly', async () => {
|
|
177
|
-
const mockSections = [
|
|
178
|
-
createMockSection({
|
|
179
|
-
id: TEST_IDS.SECTION_1,
|
|
180
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
181
|
-
name: 'Development Tasks',
|
|
182
|
-
}),
|
|
183
|
-
createMockSection({
|
|
184
|
-
id: TEST_IDS.SECTION_2,
|
|
185
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
186
|
-
sectionOrder: 2,
|
|
187
|
-
name: 'Testing Tasks',
|
|
188
|
-
}),
|
|
189
|
-
createMockSection({
|
|
190
|
-
id: 'section-789',
|
|
191
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
192
|
-
sectionOrder: 3,
|
|
193
|
-
name: 'Deployment',
|
|
194
|
-
}),
|
|
195
|
-
];
|
|
196
|
-
mockTodoistApi.getSections.mockResolvedValue({
|
|
197
|
-
results: mockSections,
|
|
198
|
-
nextCursor: null,
|
|
199
|
-
});
|
|
200
|
-
const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'task' }, mockTodoistApi);
|
|
201
|
-
// Should match both sections with "task" in the name
|
|
202
|
-
const textContent = extractTextContent(result);
|
|
203
|
-
expect(textContent).toMatchSnapshot();
|
|
204
|
-
expect(textContent).toContain('matching "task"');
|
|
205
|
-
expect(textContent).toContain('Development Tasks • id=');
|
|
206
|
-
expect(textContent).toContain('Testing Tasks • id=');
|
|
207
|
-
});
|
|
208
|
-
it('should handle exact matches', async () => {
|
|
209
|
-
const mockSections = [
|
|
210
|
-
createMockSection({
|
|
211
|
-
id: TEST_IDS.SECTION_1,
|
|
212
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
213
|
-
name: 'Done',
|
|
214
|
-
}),
|
|
215
|
-
createMockSection({
|
|
216
|
-
id: TEST_IDS.SECTION_2,
|
|
217
|
-
projectId: TEST_IDS.PROJECT_TEST,
|
|
218
|
-
sectionOrder: 2,
|
|
219
|
-
name: 'Done Soon',
|
|
220
|
-
}),
|
|
221
|
-
];
|
|
222
|
-
mockTodoistApi.getSections.mockResolvedValue({
|
|
223
|
-
results: mockSections,
|
|
224
|
-
nextCursor: null,
|
|
225
|
-
});
|
|
226
|
-
const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'done' }, mockTodoistApi);
|
|
227
|
-
// Should match both sections containing "done"
|
|
228
|
-
const textContent = extractTextContent(result);
|
|
229
|
-
expect(textContent).toMatchSnapshot();
|
|
230
|
-
expect(textContent).toContain('matching "done"');
|
|
231
|
-
expect(textContent).toContain('Done • id=');
|
|
232
|
-
expect(textContent).toContain('Done Soon • id=');
|
|
233
|
-
});
|
|
234
|
-
});
|
|
235
|
-
describe('error handling', () => {
|
|
236
|
-
it.each([
|
|
237
|
-
{ error: 'API Error: Project not found', projectId: 'non-existent-project' },
|
|
238
|
-
{ error: TEST_ERRORS.API_UNAUTHORIZED, projectId: 'restricted-project' },
|
|
239
|
-
{ error: 'API Error: Invalid project ID format', projectId: 'invalid-id-format' },
|
|
240
|
-
])('should propagate $error', async ({ error, projectId }) => {
|
|
241
|
-
mockTodoistApi.getSections.mockRejectedValue(new Error(error));
|
|
242
|
-
await expect(findSections.execute({ projectId }, mockTodoistApi)).rejects.toThrow(error);
|
|
243
|
-
});
|
|
244
|
-
});
|
|
245
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-tasks-by-date.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/find-tasks-by-date.test.ts"],"names":[],"mappings":""}
|