Skip to content
Closed
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
41 changes: 41 additions & 0 deletions src/main/jira/jira-issue-search.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { describe, expect, it } from 'vitest'
import type { JiraIssueFilter } from '../../shared/jira-types'
import { filterToJql } from './jira-issue-search'

const PRESETS: JiraIssueFilter[] = ['assigned', 'reported', 'done', 'all']

describe('filterToJql', () => {
it('scopes the assigned preset to open issues by status category', () => {
expect(filterToJql('assigned')).toBe(
'assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC'
)
})

it('scopes the reported preset to open issues by status category', () => {
expect(filterToJql('reported')).toBe(
'reporter = currentUser() AND statusCategory != Done ORDER BY updated DESC'
)
})

it('scopes the done preset to completed issues by status category', () => {
expect(filterToJql('done')).toBe(
'assignee = currentUser() AND statusCategory = Done ORDER BY updated DESC'
)
})

it('scopes the all preset to every open issue by status category', () => {
expect(filterToJql('all')).toBe('statusCategory != Done ORDER BY updated DESC')
})

it('never keys a preset on the resolution field', () => {
for (const preset of PRESETS) {
expect(filterToJql(preset)).not.toContain('resolution')
}
})

it('keeps every preset sorted by most recently updated', () => {
for (const preset of PRESETS) {
expect(filterToJql(preset)).toContain('ORDER BY updated DESC')
}
})
})
16 changes: 11 additions & 5 deletions src/main/jira/jira-issue-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,23 @@ function sortAndLimitIssues(issues: JiraIssue[], limit: number): JiraIssue[] {
.slice(0, limit)
}

function filterToJql(filter: JiraIssueFilter): string {
/**
* Build the JQL for a preset issue filter.
* Why: `resolution` is only written by a workflow post-function, so a preset keyed on it
* misreports every project that has none; `statusCategory` is derived from the status
* itself and is always populated.
*/
export function filterToJql(filter: JiraIssueFilter): string {
if (filter === 'assigned') {
return 'assignee = currentUser() AND resolution = Unresolved ORDER BY updated DESC'
return 'assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC'
}
if (filter === 'reported') {
return 'reporter = currentUser() AND resolution = Unresolved ORDER BY updated DESC'
return 'reporter = currentUser() AND statusCategory != Done ORDER BY updated DESC'
}
if (filter === 'done') {
return 'assignee = currentUser() AND resolution IS NOT EMPTY ORDER BY updated DESC'
return 'assignee = currentUser() AND statusCategory = Done ORDER BY updated DESC'
}
return 'resolution = Unresolved ORDER BY updated DESC'
return 'statusCategory != Done ORDER BY updated DESC'
}

async function searchIssuesForClient(
Expand Down