Skip to content

Commit d33e119

Browse files
gnapseclaude
andauthored
feat: Add searchCompletedTasks method (#347)
Co-authored-by: Claude <[email protected]>
1 parent 1199a78 commit d33e119

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

src/TodoistApi.tasks.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
ENDPOINT_REST_TASKS_FILTER,
1515
ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE,
1616
ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE,
17+
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
1718
ENDPOINT_SYNC_QUICK_ADD,
1819
} from './consts/endpoints'
1920
import { setupRestClientMock } from './testUtils/mocks'
@@ -430,4 +431,50 @@ describe('TodoistApi task endpoints', () => {
430431
).rejects.toThrow()
431432
})
432433
})
434+
435+
describe('searchCompletedTasks', () => {
436+
const DEFAULT_SEARCH_COMPLETED_TASKS_ARGS = {
437+
query: 'buy milk',
438+
cursor: null,
439+
limit: 10,
440+
}
441+
442+
test('calls get request with expected url', async () => {
443+
const requestMock = setupRestClientMock({ items: [DEFAULT_TASK], nextCursor: null })
444+
const api = getTarget()
445+
446+
await api.searchCompletedTasks(DEFAULT_SEARCH_COMPLETED_TASKS_ARGS)
447+
448+
expect(requestMock).toHaveBeenCalledTimes(1)
449+
expect(requestMock).toHaveBeenCalledWith(
450+
'GET',
451+
getSyncBaseUri(),
452+
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
453+
DEFAULT_AUTH_TOKEN,
454+
DEFAULT_SEARCH_COMPLETED_TASKS_ARGS,
455+
)
456+
})
457+
458+
test('returns result from rest client', async () => {
459+
setupRestClientMock({ items: [DEFAULT_TASK], nextCursor: '789' })
460+
const api = getTarget()
461+
462+
const response = await api.searchCompletedTasks(DEFAULT_SEARCH_COMPLETED_TASKS_ARGS)
463+
464+
expect(response).toEqual({
465+
items: [DEFAULT_TASK],
466+
nextCursor: '789',
467+
})
468+
})
469+
470+
test('validates task array in response', async () => {
471+
const invalidTask = { ...DEFAULT_TASK, due: '2020-01-31' }
472+
setupRestClientMock({ items: [invalidTask], nextCursor: null })
473+
const api = getTarget()
474+
475+
await expect(
476+
api.searchCompletedTasks(DEFAULT_SEARCH_COMPLETED_TASKS_ARGS),
477+
).rejects.toThrow()
478+
})
479+
})
433480
})

src/TodoistApi.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import {
4444
GetCompletedTasksResponse,
4545
GetArchivedProjectsArgs,
4646
GetArchivedProjectsResponse,
47+
SearchCompletedTasksArgs,
4748
} from './types/requests'
4849
import { request, isSuccess } from './restClient'
4950
import {
@@ -52,6 +53,7 @@ import {
5253
ENDPOINT_REST_TASKS_FILTER,
5354
ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE,
5455
ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE,
56+
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
5557
ENDPOINT_REST_PROJECTS,
5658
ENDPOINT_SYNC_QUICK_ADD,
5759
ENDPOINT_REST_TASK_CLOSE,
@@ -271,6 +273,29 @@ export class TodoistApi {
271273
}
272274
}
273275

276+
/**
277+
* Searches completed tasks by query string.
278+
*
279+
* @param args - Parameters for searching, including the query string.
280+
* @returns A promise that resolves to a paginated response of completed tasks.
281+
*/
282+
async searchCompletedTasks(args: SearchCompletedTasksArgs): Promise<GetCompletedTasksResponse> {
283+
const {
284+
data: { items, nextCursor },
285+
} = await request<GetCompletedTasksResponse>(
286+
'GET',
287+
this.syncApiBase,
288+
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
289+
this.authToken,
290+
args,
291+
)
292+
293+
return {
294+
items: validateTaskArray(items),
295+
nextCursor,
296+
}
297+
}
298+
274299
/**
275300
* Creates a new task with the provided parameters.
276301
*

src/consts/endpoints.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export const ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE =
2323
ENDPOINT_REST_TASKS + '/completed/by_completion_date'
2424
export const ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE =
2525
ENDPOINT_REST_TASKS + '/completed/by_due_date'
26+
export const ENDPOINT_REST_TASKS_COMPLETED_SEARCH = 'completed/search'
2627
export const ENDPOINT_REST_SECTIONS = 'sections'
2728
export const ENDPOINT_REST_LABELS = 'labels'
2829
export const ENDPOINT_REST_LABELS_SHARED = ENDPOINT_REST_LABELS + '/shared'

src/types/requests.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,15 @@ export type GetCompletedTasksByDueDateArgs = {
9898
limit?: number
9999
}
100100

101+
/**
102+
* Arguments for searching completed tasks.
103+
*/
104+
export type SearchCompletedTasksArgs = {
105+
query: string
106+
cursor?: string | null
107+
limit?: number
108+
}
109+
101110
/**
102111
* @see https://todoist.com/api/v1/docs#tag/Tasks/operation/get_tasks_api_v1_tasks_get
103112
*/

0 commit comments

Comments
 (0)