import { describe, expect, it, vi } from 'vitest' import { RpcDispatcher } from '../dispatcher' import type { RpcRequest } from '../core' import type { OrcaRuntimeService } from '../../orca-runtime' import { GITHUB_METHODS } from './github' function makeRequest(method: string, params?: unknown): RpcRequest { return { id: 'req-1', authToken: 'tok', method, params } } describe('github RPC methods', () => { it('resolves the repo slug on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoSlug: vi.fn().mockResolvedValue({ owner: 'acme', repo: 'orca' }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch(makeRequest('github.repoSlug', { repo: 'repo-1' })) expect(runtime.getRepoSlug).toHaveBeenCalledWith('repo-1') expect(response).toMatchObject({ ok: true, result: { owner: 'acme', repo: 'orca' } }) }) it('fetches GitHub rate limits on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getGitHubRateLimit: vi.fn().mockResolvedValue({ ok: true, snapshot: { core: {} } }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch(makeRequest('github.rateLimit', { force: true })) expect(runtime.getGitHubRateLimit).toHaveBeenCalledWith({ force: true }) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) it('lists work items on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', listRepoWorkItems: vi.fn().mockResolvedValue({ items: [] }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.listWorkItems', { repo: 'repo-1', limit: 10, query: 'is:pr', noCache: true }) ) expect(runtime.listRepoWorkItems).toHaveBeenCalledWith('repo-1', 10, 'is:pr', undefined, true) expect(response).toMatchObject({ ok: true, result: { items: [] } }) }) it('lists issues on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', listRepoIssues: vi.fn().mockResolvedValue([{ number: 7, title: 'Bug' }]) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.listIssues', { repo: 'repo-1', limit: 10 }) ) expect(runtime.listRepoIssues).toHaveBeenCalledWith('repo-1', 10) expect(response).toMatchObject({ ok: true, result: [{ number: 7, title: 'Bug' }] }) }) it('looks up a single work item on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoWorkItem: vi.fn().mockResolvedValue({ number: 12, type: 'pr' }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.workItem', { repo: 'repo-1', number: 12, type: 'pr' }) ) expect(runtime.getRepoWorkItem).toHaveBeenCalledWith('repo-1', 12, 'pr') expect(response).toMatchObject({ ok: true, result: { number: 12, type: 'pr' } }) }) it('looks up a single work item by explicit owner/repo on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoWorkItemByOwnerRepo: vi.fn().mockResolvedValue({ number: 12, type: 'pr' }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.workItemByOwnerRepo', { repo: 'repo-1', owner: 'acme', ownerRepo: 'orca', number: 12, type: 'pr' }) ) expect(runtime.getRepoWorkItemByOwnerRepo).toHaveBeenCalledWith( 'repo-1', { owner: 'acme', repo: 'orca' }, 12, 'pr' ) expect(response).toMatchObject({ ok: true, result: { number: 12, type: 'pr' } }) }) it('fetches work item details on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoWorkItemDetails: vi.fn().mockResolvedValue({ body: 'Details' }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.workItemDetails', { repo: 'repo-1', number: 12, type: 'issue' }) ) expect(runtime.getRepoWorkItemDetails).toHaveBeenCalledWith('repo-1', 12, 'issue') expect(response).toMatchObject({ ok: true, result: { body: 'Details' } }) }) it('counts work items on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', countRepoWorkItems: vi.fn().mockResolvedValue(3) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.countWorkItems', { repo: 'repo-1', query: 'is:open' }) ) expect(runtime.countRepoWorkItems).toHaveBeenCalledWith('repo-1', 'is:open') expect(response).toMatchObject({ ok: true, result: 3 }) }) it('lists repo issue metadata on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', listRepoLabels: vi.fn().mockResolvedValue(['bug']), listRepoAssignableUsers: vi.fn().mockResolvedValue([{ login: 'octo' }]) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const labels = await dispatcher.dispatch(makeRequest('github.listLabels', { repo: 'repo-1' })) const users = await dispatcher.dispatch( makeRequest('github.listAssignableUsers', { repo: 'repo-1' }) ) expect(runtime.listRepoLabels).toHaveBeenCalledWith('repo-1') expect(runtime.listRepoAssignableUsers).toHaveBeenCalledWith('repo-1') expect(labels).toMatchObject({ ok: true, result: ['bug'] }) expect(users).toMatchObject({ ok: true, result: [{ login: 'octo' }] }) }) it('fetches PR checks on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoPRChecks: vi.fn().mockResolvedValue([]) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.prChecks', { repo: 'repo-1', prNumber: 7, headSha: 'abc123', prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme-corp.com' }, noCache: true }) ) expect(runtime.getRepoPRChecks).toHaveBeenCalledWith( 'repo-1', 7, 'abc123', { owner: 'acme', repo: 'widgets', host: 'github.acme-corp.com' }, { noCache: true } ) expect(response).toMatchObject({ ok: true, result: [] }) }) it('forwards request cancellation to PR check-details work', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoPRCheckDetails: vi.fn().mockResolvedValue(null) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const controller = new AbortController() await dispatcher.dispatch( makeRequest('github.prCheckDetails', { repo: 'repo-1', checkRunId: 9 }), { signal: controller.signal } ) expect(runtime.getRepoPRCheckDetails).toHaveBeenCalledWith( 'repo-1', { checkRunId: 9, workflowRunId: undefined, checkName: undefined, url: undefined, prRepo: null }, controller.signal ) }) it('fetches PR comments on the runtime server with explicit PR repo', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoPRComments: vi.fn().mockResolvedValue([]) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.prComments', { repo: 'repo-1', prNumber: 7, prRepo: { owner: 'acme', repo: 'widgets' }, noCache: true }) ) expect(runtime.getRepoPRComments).toHaveBeenCalledWith( 'repo-1', 7, { owner: 'acme', repo: 'widgets' }, { noCache: true } ) expect(response).toMatchObject({ ok: true, result: [] }) }) it('sets a PR comment reaction on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', setRepoPRCommentReaction: vi.fn().mockResolvedValue(true) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.setPRCommentReaction', { repo: 'repo-1', reactionSubjectId: 'IC_1', content: 'heart', reacted: true, prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' } }) ) expect(runtime.setRepoPRCommentReaction).toHaveBeenCalledWith('repo-1', 'IC_1', 'heart', true, { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }) expect(response).toMatchObject({ ok: true, result: true }) }) it('fetches PR file contents on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getRepoPRFileContents: vi.fn().mockResolvedValue({ original: '', modified: 'new', originalIsBinary: false, modifiedIsBinary: false }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.prFileContents', { repo: 'repo-1', prNumber: 7, prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }, path: 'src/app.ts', status: 'modified', headSha: 'head', baseSha: 'base' }) ) expect(runtime.getRepoPRFileContents).toHaveBeenCalledWith('repo-1', { prNumber: 7, prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }, path: 'src/app.ts', oldPath: undefined, status: 'modified', headSha: 'head', baseSha: 'base' }) expect(response).toMatchObject({ ok: true, result: { modified: 'new' } }) }) it('resolves review threads on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', resolveRepoReviewThread: vi.fn().mockResolvedValue(true) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.resolveReviewThread', { repo: 'repo-1', threadId: 'PRRT_1', resolve: true, prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' } }) ) expect(runtime.resolveRepoReviewThread).toHaveBeenCalledWith('repo-1', 'PRRT_1', true, { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }) expect(response).toMatchObject({ ok: true, result: true }) }) it('marks PR files viewed on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', setRepoPRFileViewed: vi.fn().mockResolvedValue(true) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.setPRFileViewed', { repo: 'repo-1', prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }, pullRequestId: 'PR_kwDO123', path: 'src/app.ts', viewed: true }) ) expect(runtime.setRepoPRFileViewed).toHaveBeenCalledWith('repo-1', { prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }, pullRequestId: 'PR_kwDO123', path: 'src/app.ts', viewed: true }) expect(response).toMatchObject({ ok: true, result: true }) }) it('updates PR titles on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', updateRepoPRTitle: vi.fn().mockResolvedValue(true) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.updatePRTitle', { repo: 'repo-1', prNumber: 7, title: 'New title', prRepo: { owner: 'acme', repo: 'widgets' } }) ) expect(runtime.updateRepoPRTitle).toHaveBeenCalledWith('repo-1', 7, 'New title', { owner: 'acme', repo: 'widgets' }) expect(response).toMatchObject({ ok: true, result: true }) }) it('updates PR metadata on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', updateRepoPRDetails: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.updatePR', { repo: 'repo-1', prNumber: 7, updates: { title: 'New title', body: 'Updated body' }, prRepo: { owner: 'acme', repo: 'widgets' } }) ) expect(runtime.updateRepoPRDetails).toHaveBeenCalledWith( 'repo-1', 7, { title: 'New title', body: 'Updated body' }, { owner: 'acme', repo: 'widgets' } ) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) it('merges PRs on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', mergeRepoPR: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.mergePR', { repo: 'repo-1', prNumber: 7, method: 'squash', prRepo: { owner: 'acme', repo: 'widgets' } }) ) expect(runtime.mergeRepoPR).toHaveBeenCalledWith('repo-1', 7, 'squash', { owner: 'acme', repo: 'widgets' }) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) it('sets PR auto-merge on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', setRepoPRAutoMerge: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.setPRAutoMerge', { repo: 'repo-1', prNumber: 7, enabled: true, method: 'squash', prRepo: { owner: 'acme', repo: 'widgets' } }) ) expect(runtime.setRepoPRAutoMerge).toHaveBeenCalledWith('repo-1', 7, true, 'squash', { owner: 'acme', repo: 'widgets' }) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) it('routes PR reviewer mutations on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', requestRepoPRReviewers: vi.fn().mockResolvedValue({ ok: true }), removeRepoPRReviewers: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const requestResponse = await dispatcher.dispatch( makeRequest('github.requestPRReviewers', { repo: 'repo-1', prNumber: 7, reviewers: ['octo'], prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' } }) ) const removeResponse = await dispatcher.dispatch( makeRequest('github.removePRReviewers', { repo: 'repo-1', prNumber: 7, reviewers: ['octo'], prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' } }) ) expect(runtime.requestRepoPRReviewers).toHaveBeenCalledWith('repo-1', 7, ['octo'], { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }) expect(runtime.removeRepoPRReviewers).toHaveBeenCalledWith('repo-1', 7, ['octo'], { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }) expect(requestResponse).toMatchObject({ ok: true, result: { ok: true } }) expect(removeResponse).toMatchObject({ ok: true, result: { ok: true } }) }) it('updates PR state on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', updateRepoPRState: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.updatePRState', { repo: 'repo-1', prNumber: 7, prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }, updates: { state: 'closed' } }) ) expect(runtime.updateRepoPRState).toHaveBeenCalledWith( 'repo-1', 7, { state: 'closed' }, { owner: 'acme', repo: 'widgets', host: 'github.acme.test' } ) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) it('creates issues on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', createRepoIssue: vi.fn().mockResolvedValue({ ok: true, number: 3, url: 'https://gh/3' }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.createIssue', { repo: 'repo-1', title: 'Bug', body: 'Body' }) ) expect(runtime.createRepoIssue).toHaveBeenCalledWith('repo-1', 'Bug', 'Body') expect(response).toMatchObject({ ok: true, result: { ok: true, number: 3 } }) }) it('creates issues with metadata on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', createRepoIssue: vi.fn().mockResolvedValue({ ok: true, number: 4, url: 'https://gh/4' }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.createIssue', { repo: 'repo-1', title: 'Bug', body: 'Body', labels: ['bug'], assignees: ['octo'] }) ) expect(runtime.createRepoIssue).toHaveBeenCalledWith('repo-1', 'Bug', 'Body', { labels: ['bug'], assignees: ['octo'] }) expect(response).toMatchObject({ ok: true, result: { ok: true, number: 4 } }) }) it('updates issues on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', updateRepoIssue: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.updateIssue', { repo: 'repo-1', number: 3, updates: { state: 'closed', addLabels: ['bug'] } }) ) expect(runtime.updateRepoIssue).toHaveBeenCalledWith('repo-1', 3, { state: 'closed', addLabels: ['bug'] }) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) it('adds issue comments on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', addRepoIssueComment: vi.fn().mockResolvedValue({ ok: true, comment: { id: 1 } }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.addIssueComment', { repo: 'repo-1', number: 3, body: 'Looks good', type: 'pr', prRepo: { owner: 'acme', repo: 'widgets' } }) ) expect(runtime.addRepoIssueComment).toHaveBeenCalledWith('repo-1', 3, 'Looks good', { owner: 'acme', repo: 'widgets' }) expect(response).toMatchObject({ ok: true, result: { ok: true, comment: { id: 1 } } }) }) it('adds PR review comments on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', addRepoPRReviewComment: vi.fn().mockResolvedValue({ ok: true, comment: { id: 2 } }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.addPRReviewComment', { repo: 'repo-1', prNumber: 7, prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }, commitId: 'head', path: 'src/app.ts', line: 12, startLine: 10, body: 'Please tweak' }) ) expect(runtime.addRepoPRReviewComment).toHaveBeenCalledWith('repo-1', { prNumber: 7, prRepo: { owner: 'acme', repo: 'widgets', host: 'github.acme.test' }, commitId: 'head', path: 'src/app.ts', line: 12, startLine: 10, body: 'Please tweak' }) expect(response).toMatchObject({ ok: true, result: { ok: true, comment: { id: 2 } } }) }) it('adds PR review comment replies on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', addRepoPRReviewCommentReply: vi.fn().mockResolvedValue({ ok: true, comment: { id: 4 } }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.addPRReviewCommentReply', { repo: 'repo-1', prNumber: 7, commentId: 2, body: 'Done', threadId: 'PRRT_1', path: 'src/app.ts', line: 12, prRepo: { owner: 'acme', repo: 'widgets' } }) ) expect(runtime.addRepoPRReviewCommentReply).toHaveBeenCalledWith('repo-1', { prNumber: 7, commentId: 2, body: 'Done', threadId: 'PRRT_1', path: 'src/app.ts', line: 12, prRepo: { owner: 'acme', repo: 'widgets' } }) expect(response).toMatchObject({ ok: true, result: { ok: true, comment: { id: 4 } } }) }) it('fetches GitHub project views on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', listGitHubProjectViews: vi.fn().mockResolvedValue({ ok: true, views: [] }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.project.listViews', { owner: 'acme', ownerType: 'organization', projectNumber: 1 }) ) expect(runtime.listGitHubProjectViews).toHaveBeenCalledWith({ owner: 'acme', ownerType: 'organization', projectNumber: 1 }) expect(response).toMatchObject({ ok: true, result: { ok: true, views: [] } }) }) it('lists slug-addressed issue metadata on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', listGitHubLabelsBySlug: vi.fn().mockResolvedValue({ ok: true, labels: ['bug'] }), listGitHubAssignableUsersBySlug: vi .fn() .mockResolvedValue({ ok: true, users: [{ login: 'octo' }] }), listGitHubIssueTypesBySlug: vi.fn().mockResolvedValue({ ok: true, types: [{ id: 'it-1' }] }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const labels = await dispatcher.dispatch( makeRequest('github.project.listLabelsBySlug', { owner: 'acme', repo: 'orca' }) ) const users = await dispatcher.dispatch( makeRequest('github.project.listAssignableUsersBySlug', { owner: 'acme', repo: 'orca', seedLogins: ['octo'] }) ) const issueTypes = await dispatcher.dispatch( makeRequest('github.project.listIssueTypesBySlug', { owner: 'acme', repo: 'orca' }) ) expect(runtime.listGitHubLabelsBySlug).toHaveBeenCalledWith({ owner: 'acme', repo: 'orca' }) expect(runtime.listGitHubAssignableUsersBySlug).toHaveBeenCalledWith({ owner: 'acme', repo: 'orca', seedLogins: ['octo'] }) expect(runtime.listGitHubIssueTypesBySlug).toHaveBeenCalledWith({ owner: 'acme', repo: 'orca' }) expect(labels).toMatchObject({ ok: true, result: { ok: true, labels: ['bug'] } }) expect(users).toMatchObject({ ok: true, result: { ok: true, users: [{ login: 'octo' }] } }) expect(issueTypes).toMatchObject({ ok: true, result: { ok: true, types: [{ id: 'it-1' }] } }) }) it('fetches GitHub project tables on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getGitHubProjectViewTable: vi.fn().mockResolvedValue({ ok: true, data: { rows: [] } }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.project.viewTable', { owner: 'acme', ownerType: 'organization', projectNumber: 1, viewId: 'view-1', queryOverride: 'is:open' }) ) expect(runtime.getGitHubProjectViewTable).toHaveBeenCalledWith({ owner: 'acme', ownerType: 'organization', projectNumber: 1, viewId: 'view-1', viewNumber: undefined, viewName: undefined, queryOverride: 'is:open' }) expect(response).toMatchObject({ ok: true, result: { ok: true, data: { rows: [] } } }) }) it('fetches GitHub project work item details by slug on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', getGitHubProjectWorkItemDetailsBySlug: vi.fn().mockResolvedValue({ ok: true, item: { number: 9, title: 'Bug' } }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.project.workItemDetailsBySlug', { owner: 'acme', repo: 'orca', number: 9, type: 'issue' }) ) expect(runtime.getGitHubProjectWorkItemDetailsBySlug).toHaveBeenCalledWith({ owner: 'acme', repo: 'orca', number: 9, type: 'issue' }) expect(response).toMatchObject({ ok: true, result: { ok: true, item: { number: 9, title: 'Bug' } } }) }) it('updates GitHub project item fields on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', updateGitHubProjectItemField: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.project.updateItemField', { projectId: 'project-1', itemId: 'item-1', fieldId: 'field-1', value: { kind: 'text', text: 'Now' } }) ) expect(runtime.updateGitHubProjectItemField).toHaveBeenCalledWith({ projectId: 'project-1', itemId: 'item-1', fieldId: 'field-1', value: { kind: 'text', text: 'Now' } }) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) it('updates GitHub project issue types on the runtime server', async () => { const runtime = { getRuntimeId: () => 'test-runtime', updateGitHubIssueTypeBySlug: vi.fn().mockResolvedValue({ ok: true }) } as unknown as OrcaRuntimeService const dispatcher = new RpcDispatcher({ runtime, methods: GITHUB_METHODS }) const response = await dispatcher.dispatch( makeRequest('github.project.updateIssueTypeBySlug', { owner: 'acme', repo: 'orca', number: 9, issueTypeId: null }) ) expect(runtime.updateGitHubIssueTypeBySlug).toHaveBeenCalledWith({ owner: 'acme', repo: 'orca', number: 9, issueTypeId: null }) expect(response).toMatchObject({ ok: true, result: { ok: true } }) }) })