Files
orca/src/main/ipc/github.test.ts
T
JinjingandClaude Opus 4.6 4c0eee235b fix: extract path-security helpers, add tests, and improve type safety (#102)
* fix: extract path-security helpers and refactor IPC modules

- Extracted path-security helpers from filesystem.ts into filesystem-auth.ts to fix max-lines lint error (402 -> 293 lines)
- Extracted duplicated ENOENT detection into isENOENT() helper to eliminate code duplication
- Fixed missing curly braces on single-line if-return in isDescendantOrEqual (lint violation)
- Replaced any with unknown in test files to satisfy lint rules
- All tests passing (29/29)
- Lint clean (0 errors, 0 warnings)

* fix: bundle preload deps for sandbox mode and fix editor test types

The sandbox: true change in createMainWindow broke the app because
electron-vite was externalizing @electron-toolkit/preload, producing
a require() call that fails in sandboxed preload scripts. Exclude it
from externalization so it gets bundled inline.

Also fix type errors in editor.test.ts from the partial store setup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 09:59:19 -07:00

93 lines
2.2 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
const { handleMock, getPRForBranchMock, getIssueMock, listIssuesMock } = vi.hoisted(() => ({
handleMock: vi.fn(),
getPRForBranchMock: vi.fn(),
getIssueMock: vi.fn(),
listIssuesMock: vi.fn()
}))
vi.mock('electron', () => ({
ipcMain: {
handle: handleMock
}
}))
vi.mock('../github/client', () => ({
getPRForBranch: getPRForBranchMock,
getIssue: getIssueMock,
listIssues: listIssuesMock
}))
import { registerGitHubHandlers } from './github'
type HandlerMap = Record<string, (_event: unknown, args: unknown) => unknown>
describe('registerGitHubHandlers', () => {
const handlers: HandlerMap = {}
const store = {
getRepos: () => [
{
id: 'repo-1',
path: '/workspace/repo',
displayName: 'repo',
badgeColor: '#000',
addedAt: 0
}
]
}
beforeEach(() => {
handleMock.mockReset()
getPRForBranchMock.mockReset()
getIssueMock.mockReset()
listIssuesMock.mockReset()
for (const key of Object.keys(handlers)) {
delete handlers[key]
}
handleMock.mockImplementation((channel, handler) => {
handlers[channel] = handler
})
})
it('normalizes registered repo paths before invoking github clients', async () => {
getPRForBranchMock.mockResolvedValue({ number: 42 })
registerGitHubHandlers(store as never)
await handlers['gh:prForBranch'](null, {
repoPath: '/workspace/repo/../repo',
branch: 'feature/test'
})
expect(getPRForBranchMock).toHaveBeenCalledWith('/workspace/repo', 'feature/test')
})
it('rejects unknown repository paths', async () => {
registerGitHubHandlers(store as never)
expect(() =>
handlers['gh:issue'](null, {
repoPath: '/workspace/other',
number: 7
})
).toThrow('Access denied: unknown repository path')
expect(getIssueMock).not.toHaveBeenCalled()
})
it('forwards listIssues for registered repositories', async () => {
listIssuesMock.mockResolvedValue([])
registerGitHubHandlers(store as never)
await handlers['gh:listIssues'](null, {
repoPath: '/workspace/repo',
limit: 5
})
expect(listIssuesMock).toHaveBeenCalledWith('/workspace/repo', 5)
})
})