Skip to content

test: /approve cancel skips a review whose user is null and still dismisses the bot's own approval - #660

Merged
jeefy merged 1 commit into
mainfrom
quality/test-approve-cancel-ghost-reviewer
Nov 1, 2026
Merged

jeefy merged 1 commit into
mainfrom
quality/test-approve-cancel-ghost-reviewer

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Test Improvement

A local Stryker run over the fourteen command files #638/#639 changed (src/issueComment/*, src/labels/{prefixed,remove}.ts, src/utils/{command,comments}.ts; stryker.config.mjs base with --mutate narrowed, main@a192ee1, 1035 mutants: 916 killed, 35 timed out, 83 survived) leaves exactly one survivor that changes an observable effect: src/issueComment/approve.ts:167 e.user?.login !== undefined && … → true && …. Without the guard normalizeLogin(e.user.login) throws on a review whose user is null — what GitHub returns for a deleted account — so /approve cancel fails before dismissing anything. No review list in the tests carried a null user, so the guard could be dropped with every test green.

This adds one case to __tests__/issueCommentTest/approve.test.ts, next to "fails /approve cancel when the bot has no approved review": the fixture's review list gets a user: null review ahead of the bot's approved one, and the test asserts that review 80 is still dismissed and setFailed is not called. With the mutant applied by hand the case fails; without it 29/29 pass.

The other 82 survivors were read at their exact span and are equivalent or text nobody asserts: ?. → . on payload.comment/payload.issue fields every issue_comment event carries; log.debug/log.info text and ', ' joiners; protectedPrefixes.some → every on a one-element list; labels.some → every where exclusive mode already caps labels at one; stale.length > 0 / present.length === 0 guards whose only effect is skipping removeLabels([]), which sends nothing; commandLines' inIndentedCode writes, which afterBlockBoundary makes redundant; the /\[bot\]$/ anchor on logins GitHub never produces mid-string. None is filed.

Files: __tests__/issueCommentTest/approve.test.ts only. No src/ or dist/ change; eslint and tsc -p tsconfig.test.json clean. Disjoint from #658 and #659.

Related Issue

None: this pins an existing guard outside the nightly mutation set (stryker.nightly.config.mjs), whose scope the maintainers bounded deliberately in #635, so it is a test addition rather than a gate finding.


Filed by quality agent (hold-gated mode). Human review required.

— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88

…misses the bot's own

A review authored by a deleted account arrives with user: null. The
loop in cancelApproval guards that before normalizeLogin, but no review
list in the tests carried one, so dropping the guard (and crashing the
cancel on a ghost review) left every test green; a local Stryker run
over the v3.5.0 command files reports it as the one behavioural
survivor of 1035 mutants.

Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@hivecommons-hive hivecommons-hive Bot added the hold Indicates that a PR should not merge because someone has issued a /hold command. label Nov 1, 2026
@hivecommons-hive
hivecommons-hive Bot requested a review from jpmcb as a code owner November 1, 2026 09:10
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Important

Held for human review by the hive's ACMM level gate.

This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Agent PRs are held at ACMM L3–L5; an outreach PR that targets a repository this hive does not manage is held at every level because it publishes project-facing communication into someone else's project.

Hive will keep the hold label until a human removes it. Operators can make a deliberate one-off release during an ACMM level change with release_level_holds=true, but level changes never release this hold automatically.

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Please add a kind label with /kind feature, /kind failing-test or /kind cleanup.

@hivecommons-hive hivecommons-hive Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read the guard and the test against main, not just the diff. This looks correct to me.

  • src/issueComment/approve.ts:167 — the guard is e.user?.login !== undefined && normalizeLogin(e.user.login) === self && e.state === 'APPROVED'. With the Stryker mutant (true && …) applied, a user: null review makes e.user.login throw a TypeError before any dismissal, exactly as the PR body claims.
  • __tests__/fixtures/pullReq/pullReqListReviews.json carries a single review (id 80, github-actions[bot], APPROVED), so unshifting { ...reviews[0], id: 79, user: null } puts the null-user review ahead of the bot's — the loop must survive it to reach review 80.
  • The kill is double-locked: under the mutant, observeReq.called() rejects after its 2 s timeout (__tests__/testUtils.ts:261-274) and setFailed is invoked, so either assertion alone fails the test. Without the mutant, the PUT to .../reviews/80/dismissals is observed and setFailed stays silent.
  • The case is a faithful sibling of "fails /approve cancel when the bot has no approved review" (same OWNERS-404 / org-404 / collaborator-204 handler set, same some-user commenter), so it follows the file's existing idiom.

Test-only change, no src/ edits, CI green. No findings.

— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88

@jeefy jeefy added kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. and removed hold Indicates that a PR should not merge because someone has issued a /hold command. needs-kind labels Nov 1, 2026
@jeefy
jeefy merged commit 4c150aa into main Nov 1, 2026
21 checks passed
@jeefy
jeefy deleted the quality/test-approve-cancel-ghost-reviewer branch November 1, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant