Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/queue/processors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13478,6 +13478,10 @@ async function maybeProcessGenerateTestsCommand(env: Env, deliveryId: string, pa
await recordGenerateTestsSkip(env, deliveryId, req.repoFullName, targetKey, req.actor, "cached_pr_missing");
return true;
}
if (pr.state !== "open") {
await recordGenerateTestsSkip(env, deliveryId, req.repoFullName, targetKey, req.actor, "pr_not_open");
return true;
}
const { authorization } = await authorizePrActionActor({ env, deliveryId, installationId: req.installationId, repoFullName: req.repoFullName, issue: payload.issue!, actor: req.actor, commandName: "generate-tests" as LoopOverMentionCommandName, settings, pr, needsMinerDetection: true });
if (!authorization.authorized) {
await recordAuditEvent(env, { eventType: "github_app.e2e_tests_generation_denied", actor: req.actor, targetKey, outcome: "denied", detail: authorization.reason, metadata: { deliveryId, repoFullName: req.repoFullName, allowedRoles: commandAuthorizationAllowedRoles(settings.commandAuthorization, "generate-tests") } });
Expand Down Expand Up @@ -14208,6 +14212,10 @@ async function maybeProcessPrPanelGenerateTests(
await recordGenerateTestsSkip(env, deliveryId, repoFullName, targetKey, actor, "cached_pr_missing");
return true;
}
if (pr.state !== "open") {
await recordGenerateTestsSkip(env, deliveryId, repoFullName, targetKey, actor, "pr_not_open");
return true;
}

const { authorization } = await authorizePrActionActor({
env,
Expand Down
77 changes: 77 additions & 0 deletions test/unit/queue-5.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4576,6 +4576,49 @@ describe("queue processors", () => {
expect(skipped?.detail).toBe("cached_pr_missing");
});

it("skips generation on a closed PR with pr_not_open and never calls the model (#9311)", async () => {
const repoFullName = "JSONbored/gen-tests-9311-closed";
const run = vi.fn();
const env = createTestEnv({
GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(),
AI: { run: async () => ({ response: run() }) } as unknown as Ai,
LOOPOVER_REVIEW_E2E_TESTS: "true",
AI_SUMMARIES_ENABLED: "true",
AI_PUBLIC_COMMENTS_ENABLED: "true",
});
await seedGenerateTestsPr(env, repoFullName, 9311, "gen-tests-9311-closed-sha");
await upsertPullRequestFromGitHub(env, repoFullName, {
number: 9311,
title: "Add retry to checkout",
state: "closed",
user: { login: "contributor" },
author_association: "CONTRIBUTOR",
head: { sha: "gen-tests-9311-closed-sha", ref: "feature/checkout-retry" },
labels: [],
body: "Retries the payment call once on a 5xx.",
});
let posted = 0;
vi.stubGlobal("fetch", async (input: RequestInfo | URL, init?: RequestInit) => {
const url = input.toString();
const method = init?.method ?? "GET";
if (url.includes("/access_tokens")) return Response.json({ token: "installation-token" });
if (url.includes("/collaborators/maintainer/permission")) return Response.json({ permission: "admin" });
if (url.includes("/issues/9311/comments") && method === "GET") return Response.json([]);
if (url.includes("/issues/9311/comments") && method === "POST") {
posted += 1;
return Response.json({ id: 93110 });
}
return new Response("not found", { status: 404 });
});

await processJob(env, generateTestsWebhook(repoFullName, 9311, "maintainer", { association: "MEMBER" }));

expect(run).not.toHaveBeenCalled();
expect(posted).toBe(0);
const skipped = await env.DB.prepare("select detail from audit_events where event_type = ?").bind("github_app.e2e_tests_generation_skipped").first<{ detail: string }>();
expect(skipped?.detail).toBe("pr_not_open");
});

it("declines (returns false) for a non-command comment, claiming nothing", async () => {
const repoFullName = "JSONbored/gen-tests-4195-decline";
const env = createTestEnv({ GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(), LOOPOVER_REVIEW_E2E_TESTS: "true", AI_SUMMARIES_ENABLED: "true", AI_PUBLIC_COMMENTS_ENABLED: "true" });
Expand Down Expand Up @@ -5749,6 +5792,40 @@ describe("queue processors", () => {
expect(skipped?.detail).toBe("dry_run");
});

it("skips generation on a closed PR with pr_not_open and never calls the model (#9311)", async () => {
const repoFullName = "JSONbored/checkbox-9311-closed";
const run = vi.fn();
const env = createTestEnv({
GITHUB_APP_PRIVATE_KEY: await generatePrivateKeyPem(),
AI: { run } as unknown as Ai,
LOOPOVER_REVIEW_E2E_TESTS: "true",
AI_SUMMARIES_ENABLED: "true",
AI_PUBLIC_COMMENTS_ENABLED: "true",
});
await seedCheckboxPr(env, repoFullName, 6015, "checkbox-9311-closed-sha");
await upsertPullRequestFromGitHub(env, repoFullName, {
number: 6015,
title: "Add retry to checkout",
state: "closed",
user: { login: "contributor" },
author_association: "CONTRIBUTOR",
head: { sha: "checkbox-9311-closed-sha", ref: "feature/checkout-retry" },
labels: [],
body: "No validation evidence mentioned here.",
});
const posted = { count: 0, body: "" };
stubCheckboxFetch(6015, "maintainer", "admin", posted);

await processJob(env, checkboxWebhook(repoFullName, 6015, 910, { login: "maintainer" }));

expect(run).not.toHaveBeenCalled();
expect(posted.count).toBe(0);
const skipped = await env.DB.prepare("select detail from audit_events where event_type = ?")
.bind("github_app.e2e_tests_generation_skipped")
.first<{ detail: string }>();
expect(skipped?.detail).toBe("pr_not_open");
});

it("respects the repo's configured commit delivery mode via the checkbox (NOT forced comment-only, unlike the auto-trigger)", async () => {
const repoFullName = "JSONbored/checkbox-4589-commit";
const env = createTestEnv({
Expand Down
Loading