@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,294 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import { extractStructuredContent, extractTextContent } from '../../utils/test-helpers.js';
3
- import { ToolNames } from '../../utils/tool-names.js';
4
- import { updateComments } from '../update-comments.js';
5
- // Mock the Todoist API
6
- const mockTodoistApi = {
7
- updateComment: jest.fn(),
8
- };
9
- const { UPDATE_COMMENTS } = ToolNames;
10
- const createMockComment = (overrides = {}) => ({
11
- id: '12345',
12
- content: 'Updated comment content',
13
- postedAt: '2024-01-01T12:00:00Z',
14
- postedUid: 'user123',
15
- taskId: 'task123',
16
- projectId: undefined,
17
- fileAttachment: null,
18
- uidsToNotify: null,
19
- reactions: null,
20
- isDeleted: false,
21
- ...overrides,
22
- });
23
- describe(`${UPDATE_COMMENTS} tool`, () => {
24
- beforeEach(() => {
25
- jest.clearAllMocks();
26
- });
27
- it('should update comment content', async () => {
28
- const mockComment = createMockComment({
29
- id: '98765',
30
- content: 'Updated content here',
31
- taskId: 'task456',
32
- });
33
- mockTodoistApi.updateComment.mockResolvedValue(mockComment);
34
- const result = await updateComments.execute({
35
- comments: [
36
- {
37
- id: '98765',
38
- content: 'Updated content here',
39
- },
40
- ],
41
- }, mockTodoistApi);
42
- expect(mockTodoistApi.updateComment).toHaveBeenCalledWith('98765', {
43
- content: 'Updated content here',
44
- });
45
- // Verify result is a concise summary
46
- expect(extractTextContent(result)).toMatchSnapshot();
47
- // Verify structured content
48
- const structuredContent = extractStructuredContent(result);
49
- expect(structuredContent).toEqual(expect.objectContaining({
50
- comments: [
51
- expect.objectContaining({
52
- id: '98765',
53
- content: 'Updated content here',
54
- taskId: 'task456',
55
- }),
56
- ],
57
- totalCount: 1,
58
- updatedCommentIds: ['98765'],
59
- appliedOperations: {
60
- updateCount: 1,
61
- },
62
- }));
63
- });
64
- it('should handle project comment', async () => {
65
- const mockComment = createMockComment({
66
- id: '98767',
67
- content: 'Updated project comment',
68
- taskId: undefined,
69
- projectId: 'project789',
70
- });
71
- mockTodoistApi.updateComment.mockResolvedValue(mockComment);
72
- const result = await updateComments.execute({
73
- comments: [
74
- {
75
- id: '98767',
76
- content: 'Updated project comment',
77
- },
78
- ],
79
- }, mockTodoistApi);
80
- // Verify result is a concise summary
81
- expect(extractTextContent(result)).toMatchSnapshot();
82
- // Verify structured content
83
- const structuredContent = extractStructuredContent(result);
84
- expect(structuredContent).toEqual(expect.objectContaining({
85
- comments: [
86
- expect.objectContaining({
87
- id: '98767',
88
- content: 'Updated project comment',
89
- taskId: undefined,
90
- projectId: 'project789',
91
- }),
92
- ],
93
- totalCount: 1,
94
- updatedCommentIds: ['98767'],
95
- appliedOperations: {
96
- updateCount: 1,
97
- },
98
- }));
99
- });
100
- describe('bulk operations', () => {
101
- it('should update multiple comments from different entities (task + project)', async () => {
102
- const mockTaskComment = createMockComment({
103
- id: '11111',
104
- content: 'Updated task comment',
105
- taskId: 'task123',
106
- projectId: undefined,
107
- });
108
- const mockProjectComment = createMockComment({
109
- id: '22222',
110
- content: 'Updated project comment',
111
- taskId: undefined,
112
- projectId: 'project456',
113
- });
114
- mockTodoistApi.updateComment
115
- .mockResolvedValueOnce(mockTaskComment)
116
- .mockResolvedValueOnce(mockProjectComment);
117
- const result = await updateComments.execute({
118
- comments: [
119
- { id: '11111', content: 'Updated task comment' },
120
- { id: '22222', content: 'Updated project comment' },
121
- ],
122
- }, mockTodoistApi);
123
- expect(mockTodoistApi.updateComment).toHaveBeenCalledTimes(2);
124
- expect(mockTodoistApi.updateComment).toHaveBeenCalledWith('11111', {
125
- content: 'Updated task comment',
126
- });
127
- expect(mockTodoistApi.updateComment).toHaveBeenCalledWith('22222', {
128
- content: 'Updated project comment',
129
- });
130
- // Verify result is a concise summary
131
- expect(extractTextContent(result)).toMatchSnapshot();
132
- const structuredContent = extractStructuredContent(result);
133
- expect(structuredContent).toEqual(expect.objectContaining({
134
- comments: [
135
- expect.objectContaining({
136
- id: '11111',
137
- content: 'Updated task comment',
138
- taskId: 'task123',
139
- }),
140
- expect.objectContaining({
141
- id: '22222',
142
- content: 'Updated project comment',
143
- projectId: 'project456',
144
- }),
145
- ],
146
- totalCount: 2,
147
- updatedCommentIds: ['11111', '22222'],
148
- appliedOperations: {
149
- updateCount: 2,
150
- },
151
- }));
152
- });
153
- it('should update multiple comments from different tasks', async () => {
154
- const mockComment1 = createMockComment({
155
- id: '33333',
156
- content: 'Updated first task comment',
157
- taskId: 'task111',
158
- });
159
- const mockComment2 = createMockComment({
160
- id: '44444',
161
- content: 'Updated second task comment',
162
- taskId: 'task222',
163
- });
164
- mockTodoistApi.updateComment
165
- .mockResolvedValueOnce(mockComment1)
166
- .mockResolvedValueOnce(mockComment2);
167
- const result = await updateComments.execute({
168
- comments: [
169
- { id: '33333', content: 'Updated first task comment' },
170
- { id: '44444', content: 'Updated second task comment' },
171
- ],
172
- }, mockTodoistApi);
173
- expect(mockTodoistApi.updateComment).toHaveBeenCalledTimes(2);
174
- // Verify result is a concise summary
175
- expect(extractTextContent(result)).toMatchSnapshot();
176
- const structuredContent = extractStructuredContent(result);
177
- expect(structuredContent).toEqual(expect.objectContaining({
178
- comments: expect.arrayContaining([
179
- expect.objectContaining({
180
- id: '33333',
181
- content: 'Updated first task comment',
182
- taskId: 'task111',
183
- }),
184
- expect.objectContaining({
185
- id: '44444',
186
- content: 'Updated second task comment',
187
- taskId: 'task222',
188
- }),
189
- ]),
190
- totalCount: 2,
191
- updatedCommentIds: ['33333', '44444'],
192
- appliedOperations: {
193
- updateCount: 2,
194
- },
195
- }));
196
- });
197
- it('should update multiple comments from the same task', async () => {
198
- const mockComment1 = createMockComment({
199
- id: '55555',
200
- content: 'Updated first comment on same task',
201
- taskId: 'task999',
202
- });
203
- const mockComment2 = createMockComment({
204
- id: '66666',
205
- content: 'Updated second comment on same task',
206
- taskId: 'task999',
207
- });
208
- mockTodoistApi.updateComment
209
- .mockResolvedValueOnce(mockComment1)
210
- .mockResolvedValueOnce(mockComment2);
211
- const result = await updateComments.execute({
212
- comments: [
213
- { id: '55555', content: 'Updated first comment on same task' },
214
- { id: '66666', content: 'Updated second comment on same task' },
215
- ],
216
- }, mockTodoistApi);
217
- expect(mockTodoistApi.updateComment).toHaveBeenCalledTimes(2);
218
- expect(mockTodoistApi.updateComment).toHaveBeenCalledWith('55555', {
219
- content: 'Updated first comment on same task',
220
- });
221
- expect(mockTodoistApi.updateComment).toHaveBeenCalledWith('66666', {
222
- content: 'Updated second comment on same task',
223
- });
224
- // Verify result is a concise summary
225
- expect(extractTextContent(result)).toMatchSnapshot();
226
- const structuredContent = extractStructuredContent(result);
227
- expect(structuredContent).toEqual(expect.objectContaining({
228
- comments: expect.arrayContaining([
229
- expect.objectContaining({
230
- id: '55555',
231
- content: 'Updated first comment on same task',
232
- taskId: 'task999',
233
- }),
234
- expect.objectContaining({
235
- id: '66666',
236
- content: 'Updated second comment on same task',
237
- taskId: 'task999',
238
- }),
239
- ]),
240
- totalCount: 2,
241
- updatedCommentIds: ['55555', '66666'],
242
- appliedOperations: {
243
- updateCount: 2,
244
- },
245
- }));
246
- });
247
- it('should update multiple comments from the same project', async () => {
248
- const mockComment1 = createMockComment({
249
- id: '77777',
250
- content: 'Updated first project comment',
251
- taskId: undefined,
252
- projectId: 'project888',
253
- });
254
- const mockComment2 = createMockComment({
255
- id: '88888',
256
- content: 'Updated second project comment',
257
- taskId: undefined,
258
- projectId: 'project888',
259
- });
260
- mockTodoistApi.updateComment
261
- .mockResolvedValueOnce(mockComment1)
262
- .mockResolvedValueOnce(mockComment2);
263
- const result = await updateComments.execute({
264
- comments: [
265
- { id: '77777', content: 'Updated first project comment' },
266
- { id: '88888', content: 'Updated second project comment' },
267
- ],
268
- }, mockTodoistApi);
269
- expect(mockTodoistApi.updateComment).toHaveBeenCalledTimes(2);
270
- // Verify result is a concise summary
271
- expect(extractTextContent(result)).toMatchSnapshot();
272
- const structuredContent = extractStructuredContent(result);
273
- expect(structuredContent).toEqual(expect.objectContaining({
274
- comments: expect.arrayContaining([
275
- expect.objectContaining({
276
- id: '77777',
277
- content: 'Updated first project comment',
278
- projectId: 'project888',
279
- }),
280
- expect.objectContaining({
281
- id: '88888',
282
- content: 'Updated second project comment',
283
- projectId: 'project888',
284
- }),
285
- ]),
286
- totalCount: 2,
287
- updatedCommentIds: ['77777', '88888'],
288
- appliedOperations: {
289
- updateCount: 2,
290
- },
291
- }));
292
- });
293
- });
294
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=update-projects.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"update-projects.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/update-projects.test.ts"],"names":[],"mappings":""}
@@ -1,217 +0,0 @@
1
- import { jest } from '@jest/globals';
2
- import { createMockProject, extractStructuredContent, extractTextContent, } from '../../utils/test-helpers.js';
3
- import { ToolNames } from '../../utils/tool-names.js';
4
- import { updateProjects } from '../update-projects.js';
5
- // Mock the Todoist API
6
- const mockTodoistApi = {
7
- updateProject: jest.fn(),
8
- };
9
- const { FIND_PROJECTS, UPDATE_PROJECTS, GET_OVERVIEW } = ToolNames;
10
- describe(`${UPDATE_PROJECTS} tool`, () => {
11
- beforeEach(() => {
12
- jest.clearAllMocks();
13
- });
14
- describe('updating a single project', () => {
15
- it('should update a project when id and name are provided', async () => {
16
- const mockApiResponse = {
17
- url: 'https://todoist.com/projects/existing-project-123',
18
- id: 'existing-project-123',
19
- parentId: null,
20
- isDeleted: false,
21
- updatedAt: '2025-08-13T22:10:30.000000Z',
22
- childOrder: 1,
23
- description: '',
24
- isCollapsed: false,
25
- canAssignTasks: false,
26
- color: 'red',
27
- isFavorite: false,
28
- isFrozen: false,
29
- name: 'Updated Project Name',
30
- viewStyle: 'list',
31
- isArchived: false,
32
- inboxProject: false,
33
- isShared: false,
34
- createdAt: '2024-01-01T00:00:00Z',
35
- defaultOrder: 0,
36
- };
37
- mockTodoistApi.updateProject.mockResolvedValue(mockApiResponse);
38
- const result = await updateProjects.execute({ projects: [{ id: 'existing-project-123', name: 'Updated Project Name' }] }, mockTodoistApi);
39
- expect(mockTodoistApi.updateProject).toHaveBeenCalledWith('existing-project-123', {
40
- name: 'Updated Project Name',
41
- });
42
- const textContent = extractTextContent(result);
43
- expect(textContent).toMatchSnapshot();
44
- expect(textContent).toContain('Updated 1 project:');
45
- expect(textContent).toContain('Updated Project Name (id=existing-project-123)');
46
- expect(textContent).toContain(`Use ${GET_OVERVIEW} with projectId=existing-project-123`);
47
- // Verify structured content
48
- const structuredContent = extractStructuredContent(result);
49
- expect(structuredContent).toEqual(expect.objectContaining({
50
- projects: expect.arrayContaining([
51
- expect.objectContaining({
52
- id: 'existing-project-123',
53
- name: 'Updated Project Name',
54
- }),
55
- ]),
56
- totalCount: 1,
57
- updatedProjectIds: ['existing-project-123'],
58
- appliedOperations: {
59
- updateCount: 1,
60
- skippedCount: 0,
61
- },
62
- }));
63
- });
64
- it('should update project with isFavorite and viewStyle options', async () => {
65
- const mockApiResponse = {
66
- url: 'https://todoist.com/projects/project-123',
67
- id: 'project-123',
68
- parentId: null,
69
- isDeleted: false,
70
- updatedAt: '2025-08-13T22:10:30.000000Z',
71
- childOrder: 1,
72
- description: '',
73
- isCollapsed: false,
74
- canAssignTasks: false,
75
- color: 'red',
76
- isFavorite: true,
77
- isFrozen: false,
78
- name: 'Updated Favorite Project',
79
- viewStyle: 'board',
80
- isArchived: false,
81
- inboxProject: false,
82
- isShared: false,
83
- createdAt: '2024-01-01T00:00:00Z',
84
- defaultOrder: 0,
85
- };
86
- mockTodoistApi.updateProject.mockResolvedValue(mockApiResponse);
87
- const result = await updateProjects.execute({
88
- projects: [
89
- {
90
- id: 'project-123',
91
- name: 'Updated Favorite Project',
92
- isFavorite: true,
93
- viewStyle: 'board',
94
- },
95
- ],
96
- }, mockTodoistApi);
97
- expect(mockTodoistApi.updateProject).toHaveBeenCalledWith('project-123', {
98
- name: 'Updated Favorite Project',
99
- isFavorite: true,
100
- viewStyle: 'board',
101
- });
102
- const textContent = extractTextContent(result);
103
- expect(textContent).toMatchSnapshot();
104
- expect(textContent).toContain('Updated 1 project:');
105
- expect(textContent).toContain('Updated Favorite Project (id=project-123)');
106
- });
107
- });
108
- describe('updating multiple projects', () => {
109
- it('should update multiple projects and return mapped results', async () => {
110
- const mockProjects = [
111
- createMockProject({ id: 'project-1', name: 'Updated First Project' }),
112
- createMockProject({ id: 'project-2', name: 'Updated Second Project' }),
113
- createMockProject({ id: 'project-3', name: 'Updated Third Project' }),
114
- ];
115
- const [project1, project2, project3] = mockProjects;
116
- mockTodoistApi.updateProject
117
- .mockResolvedValueOnce(project1)
118
- .mockResolvedValueOnce(project2)
119
- .mockResolvedValueOnce(project3);
120
- const result = await updateProjects.execute({
121
- projects: [
122
- { id: 'project-1', name: 'Updated First Project' },
123
- { id: 'project-2', name: 'Updated Second Project' },
124
- { id: 'project-3', name: 'Updated Third Project' },
125
- ],
126
- }, mockTodoistApi);
127
- // Verify API was called correctly for each project
128
- expect(mockTodoistApi.updateProject).toHaveBeenCalledTimes(3);
129
- expect(mockTodoistApi.updateProject).toHaveBeenNthCalledWith(1, 'project-1', {
130
- name: 'Updated First Project',
131
- });
132
- expect(mockTodoistApi.updateProject).toHaveBeenNthCalledWith(2, 'project-2', {
133
- name: 'Updated Second Project',
134
- });
135
- expect(mockTodoistApi.updateProject).toHaveBeenNthCalledWith(3, 'project-3', {
136
- name: 'Updated Third Project',
137
- });
138
- const textContent = extractTextContent(result);
139
- expect(textContent).toMatchSnapshot();
140
- expect(textContent).toContain('Updated 3 projects:');
141
- expect(textContent).toContain('Updated First Project (id=project-1)');
142
- expect(textContent).toContain('Updated Second Project (id=project-2)');
143
- expect(textContent).toContain('Updated Third Project (id=project-3)');
144
- expect(textContent).toContain(`Use ${FIND_PROJECTS} to see all projects`);
145
- // Verify structured content
146
- const structuredContent = extractStructuredContent(result);
147
- expect(structuredContent).toEqual(expect.objectContaining({
148
- projects: expect.arrayContaining([
149
- expect.objectContaining({ id: 'project-1', name: 'Updated First Project' }),
150
- expect.objectContaining({
151
- id: 'project-2',
152
- name: 'Updated Second Project',
153
- }),
154
- expect.objectContaining({ id: 'project-3', name: 'Updated Third Project' }),
155
- ]),
156
- totalCount: 3,
157
- updatedProjectIds: ['project-1', 'project-2', 'project-3'],
158
- appliedOperations: {
159
- updateCount: 3,
160
- skippedCount: 0,
161
- },
162
- }));
163
- });
164
- it('should skip projects with no updates and report correctly', async () => {
165
- const mockProject = createMockProject({
166
- id: 'project-1',
167
- name: 'Updated Project',
168
- });
169
- mockTodoistApi.updateProject.mockResolvedValue(mockProject);
170
- const result = await updateProjects.execute({
171
- projects: [
172
- { id: 'project-1', name: 'Updated Project' },
173
- { id: 'project-2' }, // No name provided, should be skipped
174
- ],
175
- }, mockTodoistApi);
176
- // Should only call API once for the project with actual updates
177
- expect(mockTodoistApi.updateProject).toHaveBeenCalledTimes(1);
178
- expect(mockTodoistApi.updateProject).toHaveBeenCalledWith('project-1', {
179
- name: 'Updated Project',
180
- });
181
- const textContent = extractTextContent(result);
182
- expect(textContent).toMatchSnapshot();
183
- expect(textContent).toContain('Updated 1 project (1 skipped - no changes):');
184
- expect(textContent).toContain('Updated Project (id=project-1)');
185
- // Verify structured content reflects skipped count
186
- const structuredContent = extractStructuredContent(result);
187
- expect(structuredContent).toEqual(expect.objectContaining({
188
- appliedOperations: {
189
- updateCount: 1,
190
- skippedCount: 1,
191
- },
192
- }));
193
- });
194
- });
195
- describe('error handling', () => {
196
- it('should propagate API errors', async () => {
197
- const apiError = new Error('API Error: Project not found');
198
- mockTodoistApi.updateProject.mockRejectedValue(apiError);
199
- await expect(updateProjects.execute({ projects: [{ id: 'nonexistent', name: 'New Name' }] }, mockTodoistApi)).rejects.toThrow('API Error: Project not found');
200
- });
201
- it('should handle partial failures in multiple projects', async () => {
202
- const mockProject = createMockProject({
203
- id: 'project-1',
204
- name: 'Updated Project',
205
- });
206
- mockTodoistApi.updateProject
207
- .mockResolvedValueOnce(mockProject)
208
- .mockRejectedValueOnce(new Error('API Error: Project not found'));
209
- await expect(updateProjects.execute({
210
- projects: [
211
- { id: 'project-1', name: 'Updated Project' },
212
- { id: 'nonexistent', name: 'New Name' },
213
- ],
214
- }, mockTodoistApi)).rejects.toThrow('API Error: Project not found');
215
- });
216
- });
217
- });
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=update-sections.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"update-sections.test.d.ts","sourceRoot":"","sources":["../../../src/tools/__tests__/update-sections.test.ts"],"names":[],"mappings":""}