Skip to content

Commit 55be32e

Browse files
authored
Add section URL helpers and tests (#326)
1 parent 5715493 commit 55be32e

File tree

4 files changed

+45
-16
lines changed

4 files changed

+45
-16
lines changed

src/TodoistApi.sections.test.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { TodoistApi } from '.'
22
import { DEFAULT_AUTH_TOKEN, DEFAULT_REQUEST_ID, DEFAULT_SECTION } from './testUtils/testDefaults'
33
import { getSyncBaseUri, ENDPOINT_REST_SECTIONS } from './consts/endpoints'
44
import { setupRestClientMock } from './testUtils/mocks'
5+
import { getSectionUrl } from './utils/urlHelpers'
56

67
function getTarget() {
78
return new TodoistApi(DEFAULT_AUTH_TOKEN)
@@ -32,6 +33,7 @@ describe('TodoistApi section endpoints', () => {
3233
const section = await api.getSection('123')
3334

3435
expect(section).toEqual(DEFAULT_SECTION)
36+
expect(section.url).toBe(getSectionUrl(section.id, section.name))
3537
})
3638
})
3739

@@ -124,7 +126,12 @@ describe('TodoistApi section endpoints', () => {
124126
})
125127

126128
test('returns success result from rest client', async () => {
127-
const returnedSection = { ...DEFAULT_SECTION, ...DEFAULT_UPDATE_SECTION_ARGS }
129+
const returnedSection = {
130+
...DEFAULT_SECTION,
131+
...DEFAULT_UPDATE_SECTION_ARGS,
132+
id: '123',
133+
url: getSectionUrl('123', 'a new name'),
134+
}
128135
setupRestClientMock(returnedSection, 204)
129136
const api = getTarget()
130137

src/testUtils/testDefaults.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
RawComment,
1010
PersonalProject,
1111
} from '../types'
12-
import { getProjectUrl, getTaskUrl } from '../utils/urlHelpers'
12+
import { getProjectUrl, getTaskUrl, getSectionUrl } from '../utils/urlHelpers'
1313

1414
export const DEFAULT_TASK_ID = '1234'
1515
export const DEFAULT_TASK_CONTENT = 'This is a task'
@@ -45,6 +45,7 @@ const DEFAULT_IS_COLLAPSED = false
4545
// URL constants using the helper functions
4646
const DEFAULT_TASK_URL = getTaskUrl(DEFAULT_TASK_ID, DEFAULT_TASK_CONTENT)
4747
const DEFAULT_PROJECT_URL = getProjectUrl(DEFAULT_PROJECT_ID, DEFAULT_PROJECT_NAME)
48+
const DEFAULT_SECTION_URL = getSectionUrl(DEFAULT_SECTION_ID, DEFAULT_SECTION_NAME)
4849

4950
export const DEFAULT_AUTH_TOKEN = 'AToken'
5051
export const DEFAULT_REQUEST_ID = 'ARequestID'
@@ -174,6 +175,7 @@ export const DEFAULT_SECTION: Section = {
174175
isArchived: false,
175176
isDeleted: false,
176177
isCollapsed: false,
178+
url: DEFAULT_SECTION_URL,
177179
}
178180

179181
export const INVALID_SECTION = {

src/types/entities.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from 'zod'
2-
import { getProjectUrl, getTaskUrl } from '../utils/urlHelpers'
2+
import { getProjectUrl, getTaskUrl, getSectionUrl } from '../utils/urlHelpers'
33

44
export const DueDateSchema = z
55
.object({
@@ -148,19 +148,26 @@ export type WorkspaceProject = z.infer<typeof WorkspaceProjectSchema>
148148
*/
149149
export type ProjectViewStyle = 'list' | 'board' | 'calendar'
150150

151-
export const SectionSchema = z.object({
152-
id: z.string(),
153-
userId: z.string(),
154-
projectId: z.string(),
155-
addedAt: z.string(),
156-
updatedAt: z.string(),
157-
archivedAt: z.string().nullable(),
158-
name: z.string(),
159-
sectionOrder: z.number().int(),
160-
isArchived: z.boolean(),
161-
isDeleted: z.boolean(),
162-
isCollapsed: z.boolean(),
163-
})
151+
export const SectionSchema = z
152+
.object({
153+
id: z.string(),
154+
userId: z.string(),
155+
projectId: z.string(),
156+
addedAt: z.string(),
157+
updatedAt: z.string(),
158+
archivedAt: z.string().nullable(),
159+
name: z.string(),
160+
sectionOrder: z.number().int(),
161+
isArchived: z.boolean(),
162+
isDeleted: z.boolean(),
163+
isCollapsed: z.boolean(),
164+
})
165+
.transform((data) => {
166+
return {
167+
...data,
168+
url: getSectionUrl(data.id, data.name),
169+
}
170+
})
164171
/**
165172
* Represents a section in a Todoist project.
166173
* @see https://todoist.com/api/v1/docs#tag/Sections

src/utils/urlHelpers.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,19 @@ export function getProjectUrl(projectId: string, name?: string): string {
2626
return `${TODOIST_WEB_URI}/project/${path}`
2727
}
2828

29+
/**
30+
* Generate the URL for a given section.
31+
*
32+
* @param sectionId The ID of the section.
33+
* @param name The name of the section.
34+
* @returns The URL string for the section view.
35+
*/
36+
export function getSectionUrl(sectionId: string, name?: string): string {
37+
const slug = name ? slugify(name) : undefined
38+
const path = slug ? `${slug}-${sectionId}` : sectionId
39+
return `${TODOIST_WEB_URI}/section/${path}`
40+
}
41+
2942
/**
3043
* Slugify function borrowed from Django.
3144
*

0 commit comments

Comments
 (0)