No checks reported
; } return ( -{presentation.label}
diff --git a/apps/web/src/components/pullRequest/pullRequestDetail.logic.test.ts b/apps/web/src/components/pullRequest/pullRequestDetail.logic.test.ts index dd12d045f040..f9139f7d586b 100644 --- a/apps/web/src/components/pullRequest/pullRequestDetail.logic.test.ts +++ b/apps/web/src/components/pullRequest/pullRequestDetail.logic.test.ts @@ -15,6 +15,7 @@ import { buildMessageContext, reviewCommentContextReference } from "~/lib/compos import { buildAddSelectionToAgentHandoff, classifyPullRequestChecks, + groupPullRequestChecks, describePullRequestChecks, resolveThreadPanelPullRequestAction, buildAskAboutPullRequestHandoff, @@ -54,6 +55,27 @@ import { } from "./pullRequestDetail.logic"; import type { ReviewCommentContext } from "~/reviewCommentContext"; +it("groups checks needing attention before running and completed checks without losing any", () => { + const checks = ( + [ + "success", + "pending", + "failure", + "skipped", + "action-required", + "cancelled", + "neutral", + "pending", + ] as const + ).map((status, index) => ({ name: `check-${index}`, status, description: null, url: null })); + const grouped = groupPullRequestChecks(checks); + expect(grouped.attention.map((check) => check.name)).toEqual(["check-2", "check-4", "check-5"]); + expect(grouped.running.map((check) => check.name)).toEqual(["check-1", "check-7"]); + expect(grouped.completed.map((check) => check.name)).toEqual(["check-0", "check-3", "check-6"]); + expect(checks[0]?.status).toBe("success"); + expect(groupPullRequestChecks([])).toEqual({ attention: [], running: [], completed: [] }); +}); + describe("pull request checkout commands", () => { it.each([ ["github", "feature", null, "gh pr checkout 42"], @@ -1479,6 +1501,9 @@ describe("the compact row's single action slot", () => { openDetail({ checks: [check("success"), check("pending")] }), ), ).toBeNull(); + expect( + resolveThreadPanelPullRequestAction(openDetail({ checks: [check("action-required")] })), + ).toBeNull(); }); it("ranks conflicts above everything, then draft, then failing checks", () => { @@ -1527,6 +1552,10 @@ describe("the compact row's single action slot", () => { ]), ).toBe("7 of 16 running · 1 failed"); expect(describePullRequestChecks([check("failure"), check("success")])).toBe("1 of 2 failing"); + expect(describePullRequestChecks([check("action-required")])).toBe("1 of 1 awaiting action"); + expect(describePullRequestChecks([check("action-required"), check("failure")])).toBe( + "1 of 2 awaiting action · 1 failed", + ); }); it("reads the checks as one word, failing outranking running", () => { diff --git a/apps/web/src/components/pullRequest/pullRequestDetail.logic.ts b/apps/web/src/components/pullRequest/pullRequestDetail.logic.ts index b904d49918bb..a655b44d42e5 100644 --- a/apps/web/src/components/pullRequest/pullRequestDetail.logic.ts +++ b/apps/web/src/components/pullRequest/pullRequestDetail.logic.ts @@ -288,7 +288,9 @@ export function classifyPullRequestChecks( if (checks.some((check) => check.status === "failure" || check.status === "cancelled")) { return "failing"; } - if (checks.some((check) => check.status === "pending")) return "pending"; + if (checks.some((check) => check.status === "pending" || check.status === "action-required")) { + return "pending"; + } return "passing"; } @@ -303,11 +305,13 @@ export function describePullRequestChecks(checks: ReadonlyArray