Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/TodoistApi.tasks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ENDPOINT_REST_TASKS_FILTER,
ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE,
ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE,
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
ENDPOINT_SYNC_QUICK_ADD,
} from './consts/endpoints'
import { setupRestClientMock } from './testUtils/mocks'
Expand Down Expand Up @@ -430,4 +431,50 @@ describe('TodoistApi task endpoints', () => {
).rejects.toThrow()
})
})

describe('searchCompletedTasks', () => {
const DEFAULT_SEARCH_COMPLETED_TASKS_ARGS = {
query: 'buy milk',
cursor: null,
limit: 10,
}

test('calls get request with expected url', async () => {
const requestMock = setupRestClientMock({ items: [DEFAULT_TASK], nextCursor: null })
const api = getTarget()

await api.searchCompletedTasks(DEFAULT_SEARCH_COMPLETED_TASKS_ARGS)

expect(requestMock).toHaveBeenCalledTimes(1)
expect(requestMock).toHaveBeenCalledWith(
'GET',
getSyncBaseUri(),
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
DEFAULT_AUTH_TOKEN,
DEFAULT_SEARCH_COMPLETED_TASKS_ARGS,
)
})

test('returns result from rest client', async () => {
setupRestClientMock({ items: [DEFAULT_TASK], nextCursor: '789' })
const api = getTarget()

const response = await api.searchCompletedTasks(DEFAULT_SEARCH_COMPLETED_TASKS_ARGS)

expect(response).toEqual({
items: [DEFAULT_TASK],
nextCursor: '789',
})
})

test('validates task array in response', async () => {
const invalidTask = { ...DEFAULT_TASK, due: '2020-01-31' }
setupRestClientMock({ items: [invalidTask], nextCursor: null })
const api = getTarget()

await expect(
api.searchCompletedTasks(DEFAULT_SEARCH_COMPLETED_TASKS_ARGS),
).rejects.toThrow()
})
})
})
25 changes: 25 additions & 0 deletions src/TodoistApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
GetCompletedTasksResponse,
GetArchivedProjectsArgs,
GetArchivedProjectsResponse,
SearchCompletedTasksArgs,
} from './types/requests'
import { request, isSuccess } from './restClient'
import {
Expand All @@ -52,6 +53,7 @@ import {
ENDPOINT_REST_TASKS_FILTER,
ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE,
ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE,
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
ENDPOINT_REST_PROJECTS,
ENDPOINT_SYNC_QUICK_ADD,
ENDPOINT_REST_TASK_CLOSE,
Expand Down Expand Up @@ -271,6 +273,29 @@ export class TodoistApi {
}
}

/**
* Searches completed tasks by query string.
*
* @param args - Parameters for searching, including the query string.
* @returns A promise that resolves to a paginated response of completed tasks.
*/
async searchCompletedTasks(args: SearchCompletedTasksArgs): Promise<GetCompletedTasksResponse> {
const {
data: { items, nextCursor },
} = await request<GetCompletedTasksResponse>(
'GET',
this.syncApiBase,
ENDPOINT_REST_TASKS_COMPLETED_SEARCH,
this.authToken,
args,
)

return {
items: validateTaskArray(items),
nextCursor,
}
}

/**
* Creates a new task with the provided parameters.
*
Expand Down
1 change: 1 addition & 0 deletions src/consts/endpoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const ENDPOINT_REST_TASKS_COMPLETED_BY_COMPLETION_DATE =
ENDPOINT_REST_TASKS + '/completed/by_completion_date'
export const ENDPOINT_REST_TASKS_COMPLETED_BY_DUE_DATE =
ENDPOINT_REST_TASKS + '/completed/by_due_date'
export const ENDPOINT_REST_TASKS_COMPLETED_SEARCH = 'completed/search'
export const ENDPOINT_REST_SECTIONS = 'sections'
export const ENDPOINT_REST_LABELS = 'labels'
export const ENDPOINT_REST_LABELS_SHARED = ENDPOINT_REST_LABELS + '/shared'
Expand Down
9 changes: 9 additions & 0 deletions src/types/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,15 @@ export type GetCompletedTasksByDueDateArgs = {
limit?: number
}

/**
* Arguments for searching completed tasks.
*/
export type SearchCompletedTasksArgs = {
query: string
cursor?: string | null
limit?: number
}

/**
* @see https://todoist.com/api/v1/docs#tag/Tasks/operation/get_tasks_api_v1_tasks_get
*/
Expand Down