@doist/todoist-ai 4.16.0 → 4.17.0

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.
Files changed (178) hide show
  1. package/dist/filter-helpers.d.ts +1 -1
  2. package/dist/index.d.ts +1044 -196
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +61 -81
  5. package/dist/main.js +15 -23
  6. package/dist/mcp-helpers.d.ts +5 -5
  7. package/dist/mcp-helpers.d.ts.map +1 -1
  8. package/dist/mcp-server-BADReNAy.js +3092 -0
  9. package/dist/todoist-tool.d.ts +9 -3
  10. package/dist/todoist-tool.d.ts.map +1 -1
  11. package/dist/tool-helpers.d.ts +1 -1
  12. package/dist/tools/add-comments.d.ts +69 -3
  13. package/dist/tools/add-comments.d.ts.map +1 -1
  14. package/dist/tools/add-projects.d.ts +34 -3
  15. package/dist/tools/add-projects.d.ts.map +1 -1
  16. package/dist/tools/add-sections.d.ts +14 -1
  17. package/dist/tools/add-sections.d.ts.map +1 -1
  18. package/dist/tools/add-tasks.d.ts +65 -10
  19. package/dist/tools/add-tasks.d.ts.map +1 -1
  20. package/dist/tools/complete-tasks.d.ts +20 -1
  21. package/dist/tools/complete-tasks.d.ts.map +1 -1
  22. package/dist/tools/delete-object.d.ts +16 -3
  23. package/dist/tools/delete-object.d.ts.map +1 -1
  24. package/dist/tools/fetch.d.ts +8 -1
  25. package/dist/tools/fetch.d.ts.map +1 -1
  26. package/dist/tools/find-activity.d.ts +44 -7
  27. package/dist/tools/find-activity.d.ts.map +1 -1
  28. package/dist/tools/find-comments.d.ts +69 -3
  29. package/dist/tools/find-comments.d.ts.map +1 -1
  30. package/dist/tools/find-completed-tasks.d.ts +63 -5
  31. package/dist/tools/find-completed-tasks.d.ts.map +1 -1
  32. package/dist/tools/find-project-collaborators.d.ts +33 -2
  33. package/dist/tools/find-project-collaborators.d.ts.map +1 -1
  34. package/dist/tools/find-projects.d.ts +35 -1
  35. package/dist/tools/find-projects.d.ts.map +1 -1
  36. package/dist/tools/find-sections.d.ts +15 -1
  37. package/dist/tools/find-sections.d.ts.map +1 -1
  38. package/dist/tools/find-tasks-by-date.d.ts +61 -3
  39. package/dist/tools/find-tasks-by-date.d.ts.map +1 -1
  40. package/dist/tools/find-tasks.d.ts +63 -5
  41. package/dist/tools/find-tasks.d.ts.map +1 -1
  42. package/dist/tools/get-overview.d.ts +24 -1
  43. package/dist/tools/get-overview.d.ts.map +1 -1
  44. package/dist/tools/manage-assignments.d.ts +39 -2
  45. package/dist/tools/manage-assignments.d.ts.map +1 -1
  46. package/dist/tools/search.d.ts +17 -1
  47. package/dist/tools/search.d.ts.map +1 -1
  48. package/dist/tools/update-comments.d.ts +76 -3
  49. package/dist/tools/update-comments.d.ts.map +1 -1
  50. package/dist/tools/update-projects.d.ts +43 -1
  51. package/dist/tools/update-projects.d.ts.map +1 -1
  52. package/dist/tools/update-sections.d.ts +17 -3
  53. package/dist/tools/update-sections.d.ts.map +1 -1
  54. package/dist/tools/update-tasks.d.ts +79 -13
  55. package/dist/tools/update-tasks.d.ts.map +1 -1
  56. package/dist/tools/user-info.d.ts +19 -1
  57. package/dist/tools/user-info.d.ts.map +1 -1
  58. package/dist/utils/assignment-validator.d.ts +2 -2
  59. package/dist/utils/output-schemas.d.ts +233 -0
  60. package/dist/utils/output-schemas.d.ts.map +1 -0
  61. package/dist/utils/response-builders.d.ts +1 -3
  62. package/dist/utils/response-builders.d.ts.map +1 -1
  63. package/dist/utils/test-helpers.d.ts +1 -1
  64. package/dist/utils/user-resolver.d.ts +1 -1
  65. package/package.json +10 -8
  66. package/dist/filter-helpers.js +0 -79
  67. package/dist/mcp-helpers.js +0 -71
  68. package/dist/mcp-server.js +0 -142
  69. package/dist/todoist-tool.js +0 -1
  70. package/dist/tool-helpers.js +0 -125
  71. package/dist/tool-helpers.test.d.ts +0 -2
  72. package/dist/tool-helpers.test.d.ts.map +0 -1
  73. package/dist/tool-helpers.test.js +0 -223
  74. package/dist/tools/__tests__/add-comments.test.d.ts +0 -2
  75. package/dist/tools/__tests__/add-comments.test.d.ts.map +0 -1
  76. package/dist/tools/__tests__/add-comments.test.js +0 -241
  77. package/dist/tools/__tests__/add-projects.test.d.ts +0 -2
  78. package/dist/tools/__tests__/add-projects.test.d.ts.map +0 -1
  79. package/dist/tools/__tests__/add-projects.test.js +0 -174
  80. package/dist/tools/__tests__/add-sections.test.d.ts +0 -2
  81. package/dist/tools/__tests__/add-sections.test.d.ts.map +0 -1
  82. package/dist/tools/__tests__/add-sections.test.js +0 -185
  83. package/dist/tools/__tests__/add-tasks.test.d.ts +0 -2
  84. package/dist/tools/__tests__/add-tasks.test.d.ts.map +0 -1
  85. package/dist/tools/__tests__/add-tasks.test.js +0 -606
  86. package/dist/tools/__tests__/assignment-integration.test.d.ts +0 -2
  87. package/dist/tools/__tests__/assignment-integration.test.d.ts.map +0 -1
  88. package/dist/tools/__tests__/assignment-integration.test.js +0 -428
  89. package/dist/tools/__tests__/complete-tasks.test.d.ts +0 -2
  90. package/dist/tools/__tests__/complete-tasks.test.d.ts.map +0 -1
  91. package/dist/tools/__tests__/complete-tasks.test.js +0 -206
  92. package/dist/tools/__tests__/delete-object.test.d.ts +0 -2
  93. package/dist/tools/__tests__/delete-object.test.d.ts.map +0 -1
  94. package/dist/tools/__tests__/delete-object.test.js +0 -110
  95. package/dist/tools/__tests__/fetch.test.d.ts +0 -2
  96. package/dist/tools/__tests__/fetch.test.d.ts.map +0 -1
  97. package/dist/tools/__tests__/fetch.test.js +0 -279
  98. package/dist/tools/__tests__/find-activity.test.d.ts +0 -2
  99. package/dist/tools/__tests__/find-activity.test.d.ts.map +0 -1
  100. package/dist/tools/__tests__/find-activity.test.js +0 -229
  101. package/dist/tools/__tests__/find-comments.test.d.ts +0 -2
  102. package/dist/tools/__tests__/find-comments.test.d.ts.map +0 -1
  103. package/dist/tools/__tests__/find-comments.test.js +0 -236
  104. package/dist/tools/__tests__/find-completed-tasks.test.d.ts +0 -2
  105. package/dist/tools/__tests__/find-completed-tasks.test.d.ts.map +0 -1
  106. package/dist/tools/__tests__/find-completed-tasks.test.js +0 -423
  107. package/dist/tools/__tests__/find-projects.test.d.ts +0 -2
  108. package/dist/tools/__tests__/find-projects.test.d.ts.map +0 -1
  109. package/dist/tools/__tests__/find-projects.test.js +0 -154
  110. package/dist/tools/__tests__/find-sections.test.d.ts +0 -2
  111. package/dist/tools/__tests__/find-sections.test.d.ts.map +0 -1
  112. package/dist/tools/__tests__/find-sections.test.js +0 -313
  113. package/dist/tools/__tests__/find-tasks-by-date.test.d.ts +0 -2
  114. package/dist/tools/__tests__/find-tasks-by-date.test.d.ts.map +0 -1
  115. package/dist/tools/__tests__/find-tasks-by-date.test.js +0 -528
  116. package/dist/tools/__tests__/find-tasks.test.d.ts +0 -2
  117. package/dist/tools/__tests__/find-tasks.test.d.ts.map +0 -1
  118. package/dist/tools/__tests__/find-tasks.test.js +0 -771
  119. package/dist/tools/__tests__/get-overview.test.d.ts +0 -2
  120. package/dist/tools/__tests__/get-overview.test.d.ts.map +0 -1
  121. package/dist/tools/__tests__/get-overview.test.js +0 -225
  122. package/dist/tools/__tests__/search.test.d.ts +0 -2
  123. package/dist/tools/__tests__/search.test.d.ts.map +0 -1
  124. package/dist/tools/__tests__/search.test.js +0 -206
  125. package/dist/tools/__tests__/update-comments.test.d.ts +0 -2
  126. package/dist/tools/__tests__/update-comments.test.d.ts.map +0 -1
  127. package/dist/tools/__tests__/update-comments.test.js +0 -294
  128. package/dist/tools/__tests__/update-projects.test.d.ts +0 -2
  129. package/dist/tools/__tests__/update-projects.test.d.ts.map +0 -1
  130. package/dist/tools/__tests__/update-projects.test.js +0 -217
  131. package/dist/tools/__tests__/update-sections.test.d.ts +0 -2
  132. package/dist/tools/__tests__/update-sections.test.d.ts.map +0 -1
  133. package/dist/tools/__tests__/update-sections.test.js +0 -169
  134. package/dist/tools/__tests__/update-tasks.test.d.ts +0 -2
  135. package/dist/tools/__tests__/update-tasks.test.d.ts.map +0 -1
  136. package/dist/tools/__tests__/update-tasks.test.js +0 -788
  137. package/dist/tools/__tests__/user-info.test.d.ts +0 -2
  138. package/dist/tools/__tests__/user-info.test.d.ts.map +0 -1
  139. package/dist/tools/__tests__/user-info.test.js +0 -139
  140. package/dist/tools/add-comments.js +0 -89
  141. package/dist/tools/add-projects.js +0 -63
  142. package/dist/tools/add-sections.js +0 -74
  143. package/dist/tools/add-tasks.js +0 -169
  144. package/dist/tools/complete-tasks.js +0 -68
  145. package/dist/tools/delete-object.js +0 -79
  146. package/dist/tools/fetch.js +0 -102
  147. package/dist/tools/find-activity.js +0 -221
  148. package/dist/tools/find-comments.js +0 -148
  149. package/dist/tools/find-completed-tasks.js +0 -168
  150. package/dist/tools/find-project-collaborators.js +0 -151
  151. package/dist/tools/find-projects.js +0 -101
  152. package/dist/tools/find-sections.js +0 -101
  153. package/dist/tools/find-tasks-by-date.js +0 -198
  154. package/dist/tools/find-tasks.js +0 -329
  155. package/dist/tools/get-overview.js +0 -249
  156. package/dist/tools/manage-assignments.js +0 -337
  157. package/dist/tools/search.js +0 -65
  158. package/dist/tools/update-comments.js +0 -82
  159. package/dist/tools/update-projects.js +0 -84
  160. package/dist/tools/update-sections.js +0 -70
  161. package/dist/tools/update-tasks.js +0 -179
  162. package/dist/tools/user-info.js +0 -142
  163. package/dist/utils/assignment-validator.js +0 -253
  164. package/dist/utils/constants.js +0 -45
  165. package/dist/utils/duration-parser.js +0 -96
  166. package/dist/utils/duration-parser.test.d.ts +0 -2
  167. package/dist/utils/duration-parser.test.d.ts.map +0 -1
  168. package/dist/utils/duration-parser.test.js +0 -147
  169. package/dist/utils/labels.js +0 -18
  170. package/dist/utils/priorities.js +0 -20
  171. package/dist/utils/response-builders.js +0 -210
  172. package/dist/utils/sanitize-data.js +0 -37
  173. package/dist/utils/sanitize-data.test.d.ts +0 -2
  174. package/dist/utils/sanitize-data.test.d.ts.map +0 -1
  175. package/dist/utils/sanitize-data.test.js +0 -93
  176. package/dist/utils/test-helpers.js +0 -237
  177. package/dist/utils/tool-names.js +0 -40
  178. 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,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=find-sections.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"find-sections.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/find-sections.test.ts"],"names":[],"mappings":""}
@@ -1,313 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import { createMockSection, createMockUser, 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
- getUser: jest.fn(),
9
- };
10
- const { FIND_SECTIONS, ADD_SECTIONS } = ToolNames;
11
- describe(`${FIND_SECTIONS} tool`, () => {
12
- beforeEach(() => {
13
- jest.clearAllMocks();
14
- });
15
- describe('listing all sections in a project', () => {
16
- it('should list all sections when no search parameter is provided', async () => {
17
- const mockSections = [
18
- createMockSection({
19
- id: TEST_IDS.SECTION_1,
20
- projectId: TEST_IDS.PROJECT_TEST,
21
- name: 'To Do',
22
- }),
23
- createMockSection({
24
- id: TEST_IDS.SECTION_2,
25
- projectId: TEST_IDS.PROJECT_TEST,
26
- sectionOrder: 2,
27
- name: 'In Progress',
28
- }),
29
- createMockSection({
30
- id: 'section-789',
31
- projectId: TEST_IDS.PROJECT_TEST,
32
- sectionOrder: 3,
33
- name: 'Done',
34
- }),
35
- createMockSection({
36
- id: 'section-999',
37
- projectId: TEST_IDS.PROJECT_TEST,
38
- sectionOrder: 4,
39
- name: 'Backlog Items',
40
- }),
41
- ];
42
- mockTodoistApi.getSections.mockResolvedValue({
43
- results: mockSections,
44
- nextCursor: null,
45
- });
46
- const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST }, mockTodoistApi);
47
- expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
48
- projectId: TEST_IDS.PROJECT_TEST,
49
- });
50
- const textContent = extractTextContent(result);
51
- expect(textContent).toMatchSnapshot();
52
- expect(textContent).toContain('Sections in project');
53
- expect(textContent).toContain('To Do • id=');
54
- expect(textContent).toContain('In Progress • id=');
55
- expect(textContent).toContain('Done • id=');
56
- expect(textContent).toContain('Backlog Items • id=');
57
- // Verify structured content
58
- const structuredContent = extractStructuredContent(result);
59
- expect(structuredContent.sections).toHaveLength(4);
60
- expect(structuredContent.totalCount).toBe(4);
61
- expect(structuredContent.appliedFilters).toEqual({
62
- projectId: TEST_IDS.PROJECT_TEST,
63
- search: undefined,
64
- });
65
- });
66
- it('should handle project with no sections', async () => {
67
- mockTodoistApi.getSections.mockResolvedValue({
68
- results: [],
69
- nextCursor: null,
70
- });
71
- const result = await findSections.execute({ projectId: 'empty-project-id' }, mockTodoistApi);
72
- expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
73
- projectId: 'empty-project-id',
74
- });
75
- const textContent = extractTextContent(result);
76
- expect(textContent).toMatchSnapshot();
77
- expect(textContent).toContain('Project has no sections yet');
78
- expect(textContent).toContain(`Use ${ADD_SECTIONS} to create sections`);
79
- // Verify structured content
80
- const structuredContent = extractStructuredContent(result);
81
- expect(structuredContent.sections).toBeUndefined(); // Empty arrays are removed
82
- expect(structuredContent.totalCount).toBe(0);
83
- });
84
- });
85
- describe('searching sections by name', () => {
86
- it('should filter sections by search term (case insensitive)', async () => {
87
- const mockSections = [
88
- createMockSection({
89
- id: TEST_IDS.SECTION_1,
90
- projectId: TEST_IDS.PROJECT_TEST,
91
- name: 'To Do',
92
- }),
93
- createMockSection({
94
- id: TEST_IDS.SECTION_2,
95
- projectId: TEST_IDS.PROJECT_TEST,
96
- sectionOrder: 2,
97
- name: 'In Progress',
98
- }),
99
- createMockSection({
100
- id: 'section-789',
101
- projectId: TEST_IDS.PROJECT_TEST,
102
- sectionOrder: 3,
103
- name: 'Done',
104
- }),
105
- createMockSection({
106
- id: 'section-999',
107
- projectId: TEST_IDS.PROJECT_TEST,
108
- sectionOrder: 4,
109
- name: 'Progress Review',
110
- }),
111
- ];
112
- mockTodoistApi.getSections.mockResolvedValue({
113
- results: mockSections,
114
- nextCursor: null,
115
- });
116
- const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'progress' }, mockTodoistApi);
117
- expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
118
- projectId: TEST_IDS.PROJECT_TEST,
119
- });
120
- // Should return both "In Progress" and "Progress Review" (case insensitive partial match)
121
- const textContent = extractTextContent(result);
122
- expect(textContent).toMatchSnapshot();
123
- expect(textContent).toContain('matching "progress"');
124
- expect(textContent).toContain('In Progress • id=');
125
- expect(textContent).toContain('Progress Review • id=');
126
- });
127
- it('should handle search with no matches', async () => {
128
- const mockSections = [
129
- createMockSection({
130
- id: TEST_IDS.SECTION_1,
131
- projectId: TEST_IDS.PROJECT_TEST,
132
- name: 'To Do',
133
- }),
134
- createMockSection({
135
- id: TEST_IDS.SECTION_2,
136
- projectId: TEST_IDS.PROJECT_TEST,
137
- sectionOrder: 2,
138
- name: 'In Progress',
139
- }),
140
- ];
141
- mockTodoistApi.getSections.mockResolvedValue({
142
- results: mockSections,
143
- nextCursor: null,
144
- });
145
- const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'nonexistent' }, mockTodoistApi);
146
- const textContent = extractTextContent(result);
147
- expect(textContent).toMatchSnapshot();
148
- expect(textContent).toContain('Try broader search terms');
149
- expect(textContent).toContain('Check spelling');
150
- expect(textContent).toContain('Remove search to see all sections');
151
- });
152
- it('should handle case sensitive search correctly', async () => {
153
- const mockSections = [
154
- createMockSection({
155
- id: TEST_IDS.SECTION_1,
156
- projectId: TEST_IDS.PROJECT_TEST,
157
- name: 'Important Tasks',
158
- }),
159
- createMockSection({
160
- id: TEST_IDS.SECTION_2,
161
- projectId: TEST_IDS.PROJECT_TEST,
162
- sectionOrder: 2,
163
- name: 'Regular Work',
164
- }),
165
- ];
166
- mockTodoistApi.getSections.mockResolvedValue({
167
- results: mockSections,
168
- nextCursor: null,
169
- });
170
- const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'IMPORTANT' }, mockTodoistApi);
171
- // Should match despite different case
172
- const textContent = extractTextContent(result);
173
- expect(textContent).toMatchSnapshot();
174
- expect(textContent).toContain('matching "IMPORTANT"');
175
- expect(textContent).toContain('Important Tasks • id=');
176
- });
177
- it('should handle partial matches correctly', async () => {
178
- const mockSections = [
179
- createMockSection({
180
- id: TEST_IDS.SECTION_1,
181
- projectId: TEST_IDS.PROJECT_TEST,
182
- name: 'Development Tasks',
183
- }),
184
- createMockSection({
185
- id: TEST_IDS.SECTION_2,
186
- projectId: TEST_IDS.PROJECT_TEST,
187
- sectionOrder: 2,
188
- name: 'Testing Tasks',
189
- }),
190
- createMockSection({
191
- id: 'section-789',
192
- projectId: TEST_IDS.PROJECT_TEST,
193
- sectionOrder: 3,
194
- name: 'Deployment',
195
- }),
196
- ];
197
- mockTodoistApi.getSections.mockResolvedValue({
198
- results: mockSections,
199
- nextCursor: null,
200
- });
201
- const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'task' }, mockTodoistApi);
202
- // Should match both sections with "task" in the name
203
- const textContent = extractTextContent(result);
204
- expect(textContent).toMatchSnapshot();
205
- expect(textContent).toContain('matching "task"');
206
- expect(textContent).toContain('Development Tasks • id=');
207
- expect(textContent).toContain('Testing Tasks • id=');
208
- });
209
- it('should handle exact matches', async () => {
210
- const mockSections = [
211
- createMockSection({
212
- id: TEST_IDS.SECTION_1,
213
- projectId: TEST_IDS.PROJECT_TEST,
214
- name: 'Done',
215
- }),
216
- createMockSection({
217
- id: TEST_IDS.SECTION_2,
218
- projectId: TEST_IDS.PROJECT_TEST,
219
- sectionOrder: 2,
220
- name: 'Done Soon',
221
- }),
222
- ];
223
- mockTodoistApi.getSections.mockResolvedValue({
224
- results: mockSections,
225
- nextCursor: null,
226
- });
227
- const result = await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST, search: 'done' }, mockTodoistApi);
228
- // Should match both sections containing "done"
229
- const textContent = extractTextContent(result);
230
- expect(textContent).toMatchSnapshot();
231
- expect(textContent).toContain('matching "done"');
232
- expect(textContent).toContain('Done • id=');
233
- expect(textContent).toContain('Done Soon • id=');
234
- });
235
- });
236
- describe('inbox project ID resolution', () => {
237
- it('should resolve "inbox" to actual inbox project ID', async () => {
238
- const mockUser = createMockUser({
239
- inboxProjectId: TEST_IDS.PROJECT_INBOX,
240
- });
241
- const mockSections = [
242
- createMockSection({
243
- id: TEST_IDS.SECTION_1,
244
- projectId: TEST_IDS.PROJECT_INBOX,
245
- name: 'Inbox Section 1',
246
- }),
247
- createMockSection({
248
- id: TEST_IDS.SECTION_2,
249
- projectId: TEST_IDS.PROJECT_INBOX,
250
- name: 'Inbox Section 2',
251
- sectionOrder: 2,
252
- }),
253
- ];
254
- // Mock getUser to return our mock user with inbox ID
255
- mockTodoistApi.getUser.mockResolvedValue(mockUser);
256
- // Mock the API response
257
- mockTodoistApi.getSections.mockResolvedValue({
258
- results: mockSections,
259
- nextCursor: null,
260
- });
261
- const result = await findSections.execute({ projectId: 'inbox' }, mockTodoistApi);
262
- // Verify getUser was called to resolve inbox
263
- expect(mockTodoistApi.getUser).toHaveBeenCalledTimes(1);
264
- // Verify getSections was called with resolved inbox project ID
265
- expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
266
- projectId: TEST_IDS.PROJECT_INBOX,
267
- });
268
- // Verify result contains the sections
269
- const textContent = extractTextContent(result);
270
- expect(textContent).toContain('Sections in project');
271
- expect(textContent).toContain('Inbox Section 1');
272
- expect(textContent).toContain('Inbox Section 2');
273
- // Verify structured content
274
- const structuredContent = extractStructuredContent(result);
275
- expect(structuredContent.totalCount).toBe(2);
276
- expect(structuredContent.sections).toEqual([
277
- { id: TEST_IDS.SECTION_1, name: 'Inbox Section 1' },
278
- { id: TEST_IDS.SECTION_2, name: 'Inbox Section 2' },
279
- ]);
280
- });
281
- it('should not call getUser when projectId is not "inbox"', async () => {
282
- const mockSections = [
283
- createMockSection({
284
- id: TEST_IDS.SECTION_1,
285
- projectId: TEST_IDS.PROJECT_TEST,
286
- name: 'Regular Section',
287
- }),
288
- ];
289
- // Mock the API response
290
- mockTodoistApi.getSections.mockResolvedValue({
291
- results: mockSections,
292
- nextCursor: null,
293
- });
294
- await findSections.execute({ projectId: TEST_IDS.PROJECT_TEST }, mockTodoistApi);
295
- // Verify getUser was NOT called for regular project ID
296
- expect(mockTodoistApi.getUser).not.toHaveBeenCalled();
297
- // Verify getSections was called with original project ID
298
- expect(mockTodoistApi.getSections).toHaveBeenCalledWith({
299
- projectId: TEST_IDS.PROJECT_TEST,
300
- });
301
- });
302
- });
303
- describe('error handling', () => {
304
- it.each([
305
- { error: 'API Error: Project not found', projectId: 'non-existent-project' },
306
- { error: TEST_ERRORS.API_UNAUTHORIZED, projectId: 'restricted-project' },
307
- { error: 'API Error: Invalid project ID format', projectId: 'invalid-id-format' },
308
- ])('should propagate $error', async ({ error, projectId }) => {
309
- mockTodoistApi.getSections.mockRejectedValue(new Error(error));
310
- await expect(findSections.execute({ projectId }, mockTodoistApi)).rejects.toThrow(error);
311
- });
312
- });
313
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=find-tasks-by-date.test.d.ts.map
@@ -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":""}