Files
orca/src/main/github/client-pr-state.test.ts
T
Brennan Benson df95f03101 Show ready and close actions for draft reviews (#16889)
* Fix draft review sidebar actions

* Drop unused React import in draft actions test

The automatic JSX runtime makes the default React import dead, and
tsconfig.tc.web.json failed the branch on TS6133.

* Add localization keys for draft review actions

The new Ready for review controls introduced five untranslated keys and
the static analysis job requires them present in en.json.

* Name the draft action for what it does

The button read 'Ready for review', which states a status rather than an
action, directly under a header already showing the PR state. The i18n
key (markReady), the in-flight label ('Marking ready...') and the success
toast ('marked ready for review') all already used the verb.
2026-08-28 12:31:55 -07:00

121 lines
4.4 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
import type * as GithubApiRepositoryModule from './github-api-repository'
import type * as GitHubEnterpriseRepositoryModule from './github-enterprise-repository'
const { clientMocks, moduleMocks } = await vi.hoisted(async () => {
const moduleMocks = await import('./client-test-mocks')
return { clientMocks: moduleMocks.createGitHubClientMocks(), moduleMocks }
})
vi.mock('./gh-utils', () => moduleMocks.ghUtilsModuleMock(clientMocks))
vi.mock('../git/runner', () => moduleMocks.gitRunnerModuleMock(clientMocks))
vi.mock('../providers/ssh-git-dispatch', () => moduleMocks.sshGitDispatchModuleMock(clientMocks))
vi.mock('./local-git-config-signature', () =>
moduleMocks.localGitConfigSignatureModuleMock(clientMocks)
)
vi.mock('./github-enterprise-repository', async (importOriginal) =>
moduleMocks.githubEnterpriseRepositoryModuleMock(
await importOriginal<typeof GitHubEnterpriseRepositoryModule>()
)
)
vi.mock('./rate-limit', () => moduleMocks.rateLimitModuleMock(clientMocks))
vi.mock('./github-api-repository', async (importOriginal) =>
moduleMocks.githubApiRepositoryModuleMock(
clientMocks,
await importOriginal<typeof GithubApiRepositoryModule>()
)
)
import { markPRReadyForReview, updatePRState, _resetOwnerRepoCache } from './client'
import { resetOriginRepositoryCache } from './client-test-harness'
const {
ghExecFileAsyncMock,
getOwnerRepoMock,
getOwnerRepoForRemoteMock,
ghRepoExecOptionsMock,
githubRepoContextMock,
acquireMock,
releaseMock
} = clientMocks
describe('pull request state mutations', () => {
beforeEach(() => {
resetOriginRepositoryCache()
ghExecFileAsyncMock.mockReset()
getOwnerRepoMock.mockReset()
getOwnerRepoForRemoteMock.mockReset()
// Why: updatePRState resolves origin through getOwnerRepoForRemote.
getOwnerRepoForRemoteMock.mockImplementation(
async (repoPath: string, remoteName: string, connectionId?: string | null, opts = {}) =>
remoteName === 'origin' ? getOwnerRepoMock(repoPath, connectionId, opts) : null
)
ghRepoExecOptionsMock.mockClear()
githubRepoContextMock.mockClear()
acquireMock.mockReset()
releaseMock.mockReset()
acquireMock.mockResolvedValue(undefined)
_resetOwnerRepoCache()
})
it('reopens pull requests through the gh PR command', async () => {
getOwnerRepoMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' })
ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '', stderr: '' })
await expect(updatePRState('/repo-root', 3977, { state: 'open' })).resolves.toEqual({
ok: true
})
expect(ghExecFileAsyncMock).toHaveBeenCalledWith(
['pr', 'reopen', '3977', '--repo', 'stablyai/orca'],
{ cwd: '/repo-root', host: 'github.com' }
)
expect(acquireMock).toHaveBeenCalledTimes(1)
expect(releaseMock).toHaveBeenCalledTimes(1)
})
it('closes pull requests through the gh PR command', async () => {
getOwnerRepoMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' })
ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '', stderr: '' })
await expect(updatePRState('/repo-root', 3977, { state: 'closed' })).resolves.toEqual({
ok: true
})
expect(ghExecFileAsyncMock).toHaveBeenCalledWith(
['pr', 'close', '3977', '--repo', 'stablyai/orca'],
{ cwd: '/repo-root', host: 'github.com' }
)
})
it('reopens SSH-backed pull requests without local cwd options', async () => {
getOwnerRepoMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' })
ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '', stderr: '' })
await expect(
updatePRState('/remote/repo-root', 3977, { state: 'open' }, 'ssh-1')
).resolves.toEqual({
ok: true
})
expect(ghExecFileAsyncMock).toHaveBeenCalledWith(
['pr', 'reopen', '3977', '--repo', 'stablyai/orca'],
{ host: 'github.com' }
)
})
it('marks pull requests ready for review through gh', async () => {
getOwnerRepoMock.mockResolvedValueOnce({ owner: 'stablyai', repo: 'orca' })
ghExecFileAsyncMock.mockResolvedValueOnce({ stdout: '', stderr: '' })
await expect(markPRReadyForReview('/repo-root', 3977)).resolves.toEqual({ ok: true })
expect(ghExecFileAsyncMock).toHaveBeenCalledWith(
['pr', 'ready', '3977', '--repo', 'stablyai/orca'],
{ cwd: '/repo-root', host: 'github.com' }
)
expect(acquireMock).toHaveBeenCalledTimes(1)
expect(releaseMock).toHaveBeenCalledTimes(1)
})
})