Skip to content

test(sweep,meow,command,approve): pin the delayed-reviewer guards, image validation edges, tilde-fence opener and /approve cancel's review author - #593

Merged
jeefy merged 3 commits into
mainfrom
quality/test-dispatcher-cron-survivors
Oct 29, 2026
Merged

jeefy merged 3 commits into
mainfrom
quality/test-dispatcher-cron-survivors

Conversation

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Test Improvement

Pins the ten behavioural Stryker survivors reported in #592, found by running the repository's stryker.config.mjs harness over the fifteen dispatcher, cron and command modules no earlier probe had run through Stryker in full (main @ 9acb046, 1189 mutants, 1015 killed, 61 timed out, 113 survived, 90.50%; the other 103 are log strings, required: true folds, payload ?. chains or equivalents — see the issue).

Files / cluster claimed — four new test files; no src/, dist/ or existing test is edited, so this is disjoint from held #591 (blunderbuss / requireMatchingLabel / approveReview tests):

file pins
__tests__/cronJobTest/sweepDelayGuards.test.ts requestReviewersIfDue / lastReadyForReview in src/cronJobs/sweep.ts: a former draft with a later labeled event is still timed from its ready_for_review (:247, the filter); a draft is skipped before any timeline read (:204); a due pull request by an ignore_authors login gets nothing while its sibling does (:235, explicit: false)
__tests__/issueCommentTest/meowImageEdges.test.ts parseCatImage / isTrustedImageSource in src/issueComment/meow.ts: https://evil.example/cdn2.thecatapi.com/… is refused (:154); username-only and password-only urls are refused (:136, :137); exactly 4096 characters renders, 4097 does not (:123)
__tests__/utils/commandTildeFence.test.ts fenceOpener in src/utils/command.ts: a ~~~ fence with a backtick in its info string opens a code block (:133)
__tests__/issueCommentTest/approveCancelAuthor.test.ts cancel in src/issueComment/approve.ts: with a human APPROVED review listed after the bot's, /approve cancel dismisses review 80 and never touches 81 (:167)

Each mutant was applied by hand at its exact span: every new case fails under its own mutant (one case per mutant) and passes on main.

Testing

  • npx vitest run __tests__/cronJobTest/sweepDelayGuards.test.ts __tests__/issueCommentTest/meowImageEdges.test.ts __tests__/utils/commandTildeFence.test.ts __tests__/issueCommentTest/approveCancelAuthor.test.ts — 11 passed
  • npx vitest run --coverage — 195 files, 2483 passed, 75 skipped; 100 / 99.76 / 100 / 100
  • npm run test:coverage:e2e — 90 files, 542 passed; 100 / 99.82 / 100 / 100
  • npx eslint on the four files — clean; npx tsc --noEmit — clean

Related Issue

Closes #592


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

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

…ges, the tilde-fence opener and /approve cancel's review author

Ten Stryker survivors of a probe over the dispatcher, cron and command
modules change an observable effect yet no test distinguishes them:

- sweep.ts lastReadyForReview: any later timeline event moved the review
  clock; a draft was timed through the timeline before being skipped; the
  delayed path lost ignore_authors when called as explicit
- meow.ts: a foreign host carrying the provider's path prefix was rendered;
  a url with only a username or only a password passed; the 4096 bound
- command.ts fenceOpener: a ~~~ fence with a backtick in its info string
- approve.ts cancel: the last APPROVED review of anyone, not the bot's

Each new case fails under its mutant and passes on main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@hivecommons-hive
hivecommons-hive Bot requested a review from jpmcb as a code owner October 26, 2026 23:37
@hivecommons-hive hivecommons-hive Bot added the hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 26, 2026
@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.

@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 four new test files against the source at f6446bb. Each pinned behavior exists in the tree as claimed:

  • src/cronJobs/sweep.ts: the draft skip (settings.ignore_drafts && pr.draft === true) returns before any timeline read; lastReadyForReview filters on event === 'ready_for_review' && created_at !== undefined, so the later labeled event and the dateless entry in the fixture are correctly ignored; the delayed path calls requestOwnersReviewers(..., { explicit: false }), which carries ignore_authors.
  • src/issueComment/meow.ts: parseCatImage rejects url.length > 4096 (4096 inclusive) and any nonempty username/password; isTrustedImageSource checks image.hostname, so https://evil.example/cdn2.thecatapi.com/... is refused as an unexpected host.
  • src/utils/command.ts fenceOpener: the info-string backtick rejection is gated on char === '', so a ~~~` fence with a backtick still opens — the test matches CommonMark.
  • src/issueComment/approve.ts cancel: the loop matches only github-actions[bot] + APPROVED, so review 80 is dismissed and the human's 81 untouched.

Test-only (four new files, no src//dist//existing-test edits), disjoint from #591 as the body states. CI is green. Looks correct to me — ready for a maintainer to lift the hold.

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

@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Heads-up from #599 (type-checks __tests__/ with tsc -p tsconfig.test.json): this branch merges cleanly with it, but once a npm run typecheck CI step lands, __tests__/issueCommentTest/meowImageEdges.test.ts:45 fails with TS2344: Type '"createComment"' does not satisfy the constraint 'never'. One-line fix on this branch: declare the spy as let createComment: MockInstance<typeof comments.createComment> (import type { MockInstance } from 'vitest'). Not pushed here to avoid moving a held head.


🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: e2f71df

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

@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

/kind cleanup


🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: 9acb046

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

hivecommons-hive Bot and others added 2 commits October 29, 2026 08:46
…() instead of the removed resetOwnersCaches()

#607 moved the OWNERS caches into the run's RunState and deleted the
test-only resetOwnersCaches export; the sibling sweepDelay*.test.ts files
were migrated in that change, this one was still open and kept importing it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
@hivecommons-hive

Copy link
Copy Markdown
Contributor Author

Updated this branch: merged `main@282b8e0` and replaced the one stale line in `tests/cronJobTest/sweepDelayGuards.test.ts`.

Why. #607 moved the OWNERS caches into the run's `RunState` and deleted the test-only `resetOwnersCaches` export, migrating the five sibling `sweepDelay*.test.ts` files to `utils.newRun()`. This PR was still open and kept the import, so although GitHub's merge state read CLEAN (no textual conflict) and the check rollup was still green (it ran before #607 landed), merging the branch onto current `main` fails three tests with `TypeError: resetOwnersCaches is not a function`. The other 13 held PRs were checked the same way (each head merged onto `main@282b8e0`, its own test files run; #598/#599 the full unit suite) and all pass.

Change: `-import { resetOwnersCaches } …` / `-resetOwnersCaches()` → `+utils.newRun()`, the same migration #607 applied. `npx vitest run` on the four files in this PR: 10 passed; eslint clean.

The hold guard will flag this push as drift — that is expected; the PR needs fresh review either way since its previous green was stale.


🐝 Hive Agent: quality | Instance: hosted-available-lke648397-260827-5q9t | SHA: d578c8c

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

@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 four new test files against the sources they pin at head d578c8c; the change is test-only (4 new files, 0 deletions, no src/ or existing test touched) and every claim in the body checks out. Looks correct to me.

Verified against the tree:

  • src/cronJobs/sweep.ts:245 filters the timeline to ready_for_review events with a created_at, so the labeled-after-the-window case and the event without a timestamp in sweepDelayGuards.test.ts exercise exactly that filter; :202 skips a draft before lastReadyForReview is called, matching the timelineReads assertion; :234 passes explicit: false into requestOwnersReviewers, which is what carries ignore_authors into the delayed path.
  • src/issueComment/meow.ts:149-154 — the s3 fallback requires hostname === 's3.us-west-2.amazonaws.com' in addition to the /cdn2.thecatapi.com/ path prefix, so the evil.example case pins a real guard; :134-135 refuse username/password separately; :121 is > 4096, making the bound inclusive exactly as the 4096/4097 pair asserts.
  • src/utils/command.ts:133 restricts the no-backtick-in-info-string rule to ` fences only, which is what the ~~~ \code` ~~~` opener test distinguishes.
  • src/issueComment/approve.ts:165 matches only github-actions[bot] + APPROVED, and the new test's human review (id 81) asserting notCalled on its dismissal endpoint pins that author check.

The head commit also replaces the removed resetOwnersCaches() with utils.newRun() (__tests__/testUtils.ts:174), resolving the conflict with the #607 refactor that broke the earlier head. All helpers the tests import (newRun, noMergeQueue, ObserveRequest, noOrgOrRepoConfigExcept, blobSha) exist at this head, and the full rollup (build-test, e2e-coverage, prow, DCO) is green on d578c8c.

The PR carries a hold label by the quality lane's own hold-gated convention, so landing remains a maintainer call; nothing in the diff argues against it.

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

@jeefy jeefy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Four additive pinning tests; already re-based onto #607's newRun(). The #599 heads-up about meowImageEdges.test.ts:45 is for whoever lands the typecheck step, not a blocker here.

@jeefy jeefy removed the hold Indicates that a PR should not merge because someone has issued a /hold command. label Oct 29, 2026
@jeefy

jeefy commented Oct 29, 2026

Copy link
Copy Markdown
Member

/kind cleanup

@jeefy
jeefy merged commit 5315764 into main Oct 29, 2026
14 checks passed
@jeefy
jeefy deleted the quality/test-dispatcher-cron-survivors branch October 29, 2026 15:35
mrbobbytables added a commit that referenced this pull request Oct 29, 2026
…to quality/test-typecheck-tests

Applies the three one-line type fixes the PR body predicted for #593 and
#595: meowImageEdges.test.ts types the spy as MockInstance, setup.ts types
overwriteMethod's _super, configTypeGuards.test.ts reads labels?.kind?.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mrbobbytables added a commit that referenced this pull request Oct 29, 2026
…ests__/

meowImageEdges.test.ts types the spy as MockInstance<typeof comments.createComment>,
setup.ts types overwriteMethod's _super parameter, and configTypeGuards.test.ts
reads labels?.kind? off parseProwConfig's Partial<ProwConfig>.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bob Killen <bkillen@linuxfoundation.org>
jeefy pushed a commit that referenced this pull request Oct 29, 2026
… and fix the 29 errors it finds (#599)

* test: make the unit suite order-independent under vitest --sequence.shuffle

`npx vitest run --sequence.shuffle` fails 11 tests in 8 files on main under
4 of 12 seeds tried; the default order passes only because each leaking
test happens to run before a neighbour that would not notice. Three
mechanisms, all within a file:

- a shared imported JSON fixture mutated and never restored: assign,
  unassign and handleIssueComment rewrite `comment.body`; the cron lgtm
  test pushed a `hold` label onto the list every other test is served.
  Clone the fixture or reset the field in beforeEach.
- loadProwConfig probes the organization and repository tiers under
  Promise.all, so when the tier a test exercises rejects, the other
  tier's sequential probe chain keeps issuing requests after the test
  returned, and the next test's unhandled-request guard or request:start
  listener records them. Waiting for the in-flight count to reach zero
  is satisfied in the gap between two probes. `utils.configFoundAt`
  serves an empty configuration at the other tier's first probe, so the
  only sibling request is already in flight when the rejection lands.
- module memos not reset: auth.test.ts's outer describes never reset the
  configuration cache and inherited a `trusted` policy; owners.test.ts's
  expandOwnersSet describe never reset the group memo; mergeQueueGuards
  imported @actions/core fresh after a sibling's vi.resetModules while
  still calling the statically imported queueState, so the assertion
  spied on a different core instance than the one the module warns
  through.

Adds `npm run test:shuffle` and a "Test order" section to
docs/contributing.md describing the three patterns. 18 seeds pass after
the change; the bundle suite was already order-independent.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>

* test(typecheck): type-check __tests__ with tsc -p tsconfig.test.json and fix the 29 errors it finds

tsconfig.json excludes __tests__/, and Vitest's esbuild transform strips
types without checking them, so nothing in the repository type-checks the
test suite. Running tsc over src/ and __tests__/ together reports 29 errors
in 17 files, several of them fixtures that drifted from the production
types they claim to be:

- PullRequestOwners gained headSha; the pullOwners() fixture in
  approve.test.ts, approveErrorPaths.test.ts and approveGuards.test.ts
  still builds the old shape
- ProwConfig gained approve, lgtm, sweep and authorization; the hand-built
  configs in blunderbuss.test.ts and requireMatchingLabel.test.ts still
  carry only the original six keys (now built from mergeProwConfig)
- msw 3 renamed SetupServerApi to SetupServer (testUtils.ts)
- missingNumberMessage.test.ts imports @actions/github/lib/context, which
  docs/contributing.md forbids; it now imports src/utils/context
- lgtmBinding.test.ts builds a sender without the type field the payload
  type requires
- the remainder are untyped spy declarations (tide.test.ts,
  tideGuards.test.ts), an untyped it.each table (ownersGuards.test.ts), an
  unresolved this (fakeGithub.ts), a delete on a required field
  (sweepArms.test.ts), an over-narrow createLabel parameter
  (labelSync.test.ts), a milestone type intersection that can never be
  null (milestone.test.ts), a spyOn over a module/name union
  (handleIssueComment.test.ts) and index-signature mismatches
  (configurationDocs.test.ts)

Adds tsconfig.test.json (extends tsconfig.json, noEmit, includes src/ and
__tests__/, excludes the coverageEntry build which has its own tsconfig)
and an npm run typecheck script that runs it. npm run build is unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>

* test(typecheck): fix the three type errors #593 and #595 added to __tests__/

meowImageEdges.test.ts types the spy as MockInstance<typeof comments.createComment>,
setup.ts types overwriteMethod's _super parameter, and configTypeGuards.test.ts
reads labels?.kind? off parseProwConfig's Partial<ProwConfig>.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bob Killen <bkillen@linuxfoundation.org>

---------

Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
Signed-off-by: Bob Killen <bkillen@linuxfoundation.org>
Co-authored-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Bob Killen <bkillen@linuxfoundation.org>
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

1 participant