diff --git a/src/main/linear/linear-issue-comments.test.ts b/src/main/linear/linear-issue-comments.test.ts new file mode 100644 index 00000000000..89427dcdf43 --- /dev/null +++ b/src/main/linear/linear-issue-comments.test.ts @@ -0,0 +1,53 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' + +const rawRequest = vi.fn() +const getClients = vi.fn() + +vi.mock('./linear-request-concurrency', () => ({ + acquire: vi.fn().mockResolvedValue(undefined), + release: vi.fn() +})) + +vi.mock('./linear-token-store', () => ({ + clearToken: vi.fn() +})) + +vi.mock('./client', () => ({ + getClients: (...args: unknown[]) => getClients(...args), + getPublicFileUrlClient: () => ({ client: { rawRequest } }), + isAuthError: () => false +})) + +function rawComment(id: string, body: string, createdAt: string) { + return { id, body, createdAt, user: { displayName: 'Ada', avatarUrl: null } } +} + +describe('getIssueComments', () => { + beforeEach(() => { + vi.clearAllMocks() + getClients.mockReturnValue([ + { workspace: { id: 'workspace-1' }, client: { client: { rawRequest } } } + ]) + }) + + it('returns comments oldest first, although Linear sends them newest first', async () => { + rawRequest.mockResolvedValueOnce({ + data: { + issue: { + comments: { + nodes: [ + rawComment('comment-3', 'Third', '2026-01-02T03:06:05.000Z'), + rawComment('comment-2', 'Second', '2026-01-02T03:05:05.000Z'), + rawComment('comment-1', 'First', '2026-01-02T03:04:05.000Z') + ] + } + } + } + }) + const { getIssueComments } = await import('./linear-issue-comments') + + const comments = await getIssueComments('issue-uuid', 'workspace-1') + + expect(comments.map((comment) => comment.body)).toEqual(['First', 'Second', 'Third']) + }) +}) diff --git a/src/main/linear/linear-issue-comments.ts b/src/main/linear/linear-issue-comments.ts index 5cba1ec0db5..69051e09c72 100644 --- a/src/main/linear/linear-issue-comments.ts +++ b/src/main/linear/linear-issue-comments.ts @@ -243,7 +243,7 @@ export async function getIssueComments( LinearRawVariables >(ISSUE_COMMENTS_QUERY, { id: issueId }) const nodes = result.data?.issue?.comments?.nodes ?? [] - return nodes.map((node) => ({ + const comments = nodes.map((node) => ({ id: node.id, body: node.body ?? '', createdAt: node.createdAt ?? '', @@ -254,6 +254,8 @@ export async function getIssueComments( } : undefined })) + // Why: Linear sends newest first; oldest-first matches linear.app and where new comments land. + return comments.sort((a, b) => a.createdAt.localeCompare(b.createdAt)) } catch (error) { if (isAuthError(error)) { clearToken(entry.workspace.id)