Files
orca/src/shared/hosted-review-github.test.ts
T
Jinjing 1c30d28113 Surface GitHub check suites awaiting approval (#6717)
* Surface GitHub check suites awaiting approval to unblock merge

- Query the check-suites API endpoint to find suites with an
  "action_required" conclusion, which are often workflows awaiting
  "Approve and run" and do not have any associated check runs.
- Map the "action_required" status distinctly instead of treating it as
  a standard failure or omitting it entirely.
- Update the UI to render these suites with a warning icon, a dedicated
  "Action required" label, and a localized hint explaining that manual
  approval is required on GitHub.
- Count "action_required" checks as failed/blocking when deriving overall
  PR and task statuses so the UI does not report all checks passing.

* Enhance visibility and handling of action-required PR check suites

* Include check suite IDs in pending approval check names and URLs to
  allow navigating directly to the specific workflow run.
* Add an "action required" count badge to PR dialog and page checks tabs.
* Prioritize action-required checks in the checks preview summary.
* Use correct check run state for the action-required fallback hint in
  the right sidebar details panel.
* Add translations for the new status across all supported locales.
2026-06-29 12:05:57 -07:00

138 lines
3.6 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
hostedReviewInfoFromGitHubPRInfo,
hostedReviewSummaryFromGitHubPRInfo
} from './hosted-review-github'
import type { PRInfo } from './types'
const pr: PRInfo = {
number: 12,
title: 'Add queue badges',
state: 'open',
url: 'https://github.com/acme/orca/pull/12',
checksStatus: 'pending',
updatedAt: '2026-05-12T00:00:00.000Z',
mergeable: 'MERGEABLE',
headSha: 'abc123'
}
describe('hostedReviewSummaryFromGitHubPRInfo', () => {
it('maps PRInfo into provider-neutral summary with host identity', () => {
const summary = hostedReviewSummaryFromGitHubPRInfo({
pr,
owner: 'acme',
repo: 'orca',
host: 'github.acme.internal'
})
expect(summary.identity).toEqual({
provider: 'github',
host: 'github.acme.internal',
owner: 'acme',
repo: 'orca',
number: 12
})
expect(summary.checksStatus).toBe('pending')
expect(summary.threadSummary).toBeUndefined()
})
it('derives unresolved thread count and failing status from enrichers', () => {
const summary = hostedReviewSummaryFromGitHubPRInfo({
pr: { ...pr, checksStatus: 'success' },
owner: 'acme',
repo: 'orca',
comments: [
{
id: 1,
author: 'a',
authorAvatarUrl: '',
body: '',
createdAt: '',
url: '',
threadId: 't1',
isResolved: false
},
{
id: 2,
author: 'b',
authorAvatarUrl: '',
body: '',
createdAt: '',
url: '',
threadId: 't1',
isResolved: false
},
{
id: 3,
author: 'c',
authorAvatarUrl: '',
body: '',
createdAt: '',
url: '',
threadId: 't2',
isResolved: true
}
],
checks: [{ name: 'ci', status: 'completed', conclusion: 'failure', url: null }]
})
expect(summary.threadSummary).toEqual({ unresolvedCount: 1, dataCompleteness: 'partial' })
expect(summary.checksStatus).toBe('failure')
})
it('treats cancelled checks as failed in hosted review summaries', () => {
const summary = hostedReviewSummaryFromGitHubPRInfo({
pr: { ...pr, checksStatus: 'success' },
owner: 'acme',
repo: 'orca',
checks: [{ name: 'ci', status: 'completed', conclusion: 'cancelled', url: null }]
})
expect(summary.checksStatus).toBe('failure')
})
it('treats action_required checks as failed so auto-merge sees the block', () => {
const summary = hostedReviewSummaryFromGitHubPRInfo({
pr: { ...pr, checksStatus: 'success' },
owner: 'acme',
repo: 'orca',
checks: [{ name: 'approval', status: 'completed', conclusion: 'action_required', url: null }]
})
expect(summary.checksStatus).toBe('failure')
})
it('distinguishes loaded empty comments from unknown comments', () => {
expect(
hostedReviewSummaryFromGitHubPRInfo({
pr,
owner: 'acme',
repo: 'orca'
}).threadSummary
).toBeUndefined()
expect(
hostedReviewSummaryFromGitHubPRInfo({
pr,
owner: 'acme',
repo: 'orca',
comments: []
}).threadSummary
).toEqual({ unresolvedCount: 0, dataCompleteness: 'partial' })
})
it('maps PRInfo into sidebar hosted review metadata', () => {
const review = hostedReviewInfoFromGitHubPRInfo(pr)
expect(review).toMatchObject({
provider: 'github',
number: 12,
title: 'Add queue badges',
state: 'open',
status: 'pending',
mergeable: 'MERGEABLE',
headSha: 'abc123'
})
})
})