Files
orca/src/main/ipc/linear.test.ts
T
Jinjing 6166f6c47a feat(linear): add server-side issue filters for status and other properties (#8021)
Add attribute filters (status, priority, assignee, labels) to the Linear
issues list, applied in GraphQL before pagination so hasMore matches the
filtered set. Thread filters through IPC/RPC/store cache with invalidation
on issue mutations, and mirror GitHub-style filter chrome on TaskPage.
2026-07-09 22:23:56 -07:00

165 lines
4.2 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
const {
handleMock,
listIssuesMock,
listProjectIssuesMock,
listCustomViewIssuesMock,
connectMock,
disconnectMock,
getStatusMock,
selectWorkspaceMock,
testConnectionMock
} = vi.hoisted(() => ({
handleMock: vi.fn(),
listIssuesMock: vi.fn(),
listProjectIssuesMock: vi.fn(),
listCustomViewIssuesMock: vi.fn(),
connectMock: vi.fn(),
disconnectMock: vi.fn(),
getStatusMock: vi.fn(),
selectWorkspaceMock: vi.fn(),
testConnectionMock: vi.fn()
}))
vi.mock('electron', () => ({
ipcMain: {
handle: handleMock
}
}))
vi.mock('../linear/client', () => ({
connect: connectMock,
disconnect: disconnectMock,
getStatus: getStatusMock,
selectWorkspace: selectWorkspaceMock,
testConnection: testConnectionMock
}))
vi.mock('../linear/issues', () => ({
getIssue: vi.fn(),
searchIssues: vi.fn(),
listIssues: listIssuesMock,
createIssue: vi.fn(),
updateIssue: vi.fn(),
addIssueComment: vi.fn(),
getIssueComments: vi.fn()
}))
vi.mock('../linear/projects', () => ({
getCustomView: vi.fn(),
getProject: vi.fn(),
listCustomViewIssues: listCustomViewIssuesMock,
listCustomViewProjects: vi.fn(),
listCustomViews: vi.fn(),
listProjectIssues: listProjectIssuesMock,
listProjects: vi.fn()
}))
vi.mock('../linear/teams', () => ({
listTeams: vi.fn(),
getTeamStates: vi.fn(),
getTeamLabels: vi.fn(),
getTeamMembers: vi.fn()
}))
vi.mock('./preflight', () => ({
_resetPreflightCache: vi.fn()
}))
import { registerLinearHandlers } from './linear'
type HandlerMap = Record<string, (_event: unknown, args: unknown) => unknown>
describe('registerLinearHandlers', () => {
const handlers: HandlerMap = {}
beforeEach(() => {
handleMock.mockReset()
listIssuesMock.mockReset()
listProjectIssuesMock.mockReset()
listCustomViewIssuesMock.mockReset()
for (const key of Object.keys(handlers)) {
delete handlers[key]
}
handleMock.mockImplementation((channel, handler) => {
handlers[channel] = handler
})
})
it('forwards expanded Linear issue list limits through local IPC', async () => {
listIssuesMock.mockResolvedValue({ items: [], hasMore: true })
registerLinearHandlers()
await handlers['linear:listIssues'](null, {
filter: 'all',
limit: 216,
workspaceId: 'workspace-1'
})
expect(listIssuesMock).toHaveBeenCalledWith('all', 216, 'workspace-1', {
attributeFilter: undefined
})
})
it('parses attribute filters and rejects malformed payloads before listIssues', async () => {
listIssuesMock.mockResolvedValue({ items: [], hasMore: false })
registerLinearHandlers()
await handlers['linear:listIssues'](null, {
filter: 'all',
limit: 20,
workspaceId: 'workspace-1',
attributeFilter: {
stateIds: ['state-1'],
priorities: [1],
assignee: { kind: 'unassigned' },
labelIds: []
}
})
expect(listIssuesMock).toHaveBeenCalledWith('all', 20, 'workspace-1', {
attributeFilter: {
stateIds: ['state-1'],
priorities: [1],
assignee: { kind: 'unassigned' },
labelIds: []
}
})
listIssuesMock.mockClear()
await expect(
handlers['linear:listIssues'](null, {
filter: 'all',
attributeFilter: { stateIds: [] }
})
).rejects.toThrow(/required/)
expect(listIssuesMock).not.toHaveBeenCalled()
})
it('forwards expanded Linear project issue limits through local IPC', async () => {
listProjectIssuesMock.mockResolvedValue({ items: [], hasMore: true })
registerLinearHandlers()
await handlers['linear:listProjectIssues'](null, {
projectId: 'project-1',
limit: 216,
workspaceId: 'workspace-1'
})
expect(listProjectIssuesMock).toHaveBeenCalledWith('project-1', 216, 'workspace-1', false)
})
it('forwards expanded Linear custom view issue limits through local IPC', async () => {
listCustomViewIssuesMock.mockResolvedValue({ items: [], hasMore: true })
registerLinearHandlers()
await handlers['linear:listCustomViewIssues'](null, {
viewId: 'view-1',
limit: 216,
workspaceId: 'workspace-1'
})
expect(listCustomViewIssuesMock).toHaveBeenCalledWith('view-1', 216, 'workspace-1', false)
})
})