mirror of
https://github.com/stablyai/orca.git
synced 2026-09-27 00:02:37 +00:00
520 lines
18 KiB
TypeScript
520 lines
18 KiB
TypeScript
/* eslint-disable max-lines -- Why: runtime GitHub RPC methods share one dispatcher suite so repo-scoped and Project-scoped contract coverage cannot drift. */
|
|
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' })
|
|
)
|
|
|
|
expect(runtime.listRepoWorkItems).toHaveBeenCalledWith('repo-1', 10, 'is:pr', undefined)
|
|
expect(response).toMatchObject({ ok: true, result: { items: [] } })
|
|
})
|
|
|
|
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',
|
|
noCache: true
|
|
})
|
|
)
|
|
|
|
expect(runtime.getRepoPRChecks).toHaveBeenCalledWith('repo-1', 7, 'abc123', {
|
|
noCache: true
|
|
})
|
|
expect(response).toMatchObject({ ok: true, result: [] })
|
|
})
|
|
|
|
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,
|
|
path: 'src/app.ts',
|
|
status: 'modified',
|
|
headSha: 'head',
|
|
baseSha: 'base'
|
|
})
|
|
)
|
|
|
|
expect(runtime.getRepoPRFileContents).toHaveBeenCalledWith('repo-1', {
|
|
prNumber: 7,
|
|
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
|
|
})
|
|
)
|
|
|
|
expect(runtime.resolveRepoReviewThread).toHaveBeenCalledWith('repo-1', 'PRRT_1', 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'
|
|
})
|
|
)
|
|
|
|
expect(runtime.updateRepoPRTitle).toHaveBeenCalledWith('repo-1', 7, 'New title')
|
|
expect(response).toMatchObject({ ok: true, result: 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'
|
|
})
|
|
)
|
|
|
|
expect(runtime.mergeRepoPR).toHaveBeenCalledWith('repo-1', 7, 'squash')
|
|
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('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'
|
|
})
|
|
)
|
|
|
|
expect(runtime.addRepoIssueComment).toHaveBeenCalledWith('repo-1', 3, 'Looks good')
|
|
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,
|
|
commitId: 'head',
|
|
path: 'src/app.ts',
|
|
line: 12,
|
|
startLine: 10,
|
|
body: 'Please tweak'
|
|
})
|
|
)
|
|
|
|
expect(runtime.addRepoPRReviewComment).toHaveBeenCalledWith('repo-1', {
|
|
prNumber: 7,
|
|
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
|
|
})
|
|
)
|
|
|
|
expect(runtime.addRepoPRReviewCommentReply).toHaveBeenCalledWith('repo-1', {
|
|
prNumber: 7,
|
|
commentId: 2,
|
|
body: 'Done',
|
|
threadId: 'PRRT_1',
|
|
path: 'src/app.ts',
|
|
line: 12
|
|
})
|
|
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('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 } })
|
|
})
|
|
})
|