mirror of
https://github.com/stablyai/orca.git
synced 2026-09-24 08:02:33 +00:00
* 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>
93 lines
2.2 KiB
TypeScript
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)
|
|
})
|
|
})
|