Repository navigation
test(owners): pin the per-team group cache key, parseGroup anchor, decode, defaultBranch and isNotFound guards of owners.ts - #575
Conversation
…code, defaultBranch and isNotFound guards Running the bounded Stryker check against src/utils/owners.ts left 15 survivors at 100% line coverage. Thirteen are behavioural: with one groupCache key every @org/team entry resolves to the first team's members; parseGroup without its leading anchor reads alice@org/team as a group; a bare `options:` key, a blob without content, a payload without a repository, a string or null tree rejection and a path-less tree entry each hit a TypeError instead of the handled path; and repoHasOwners would answer a second repository from the first. Each is pinned with a direct call in a new file so the harness reports 98.49% on the module, leaving only the warning text held #564 asserts and a debug string. Closes #574 Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com>
|
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 Hive will keep the |
|
Please add a kind label with |
There was a problem hiding this comment.
Read src/utils/owners.ts at the reviewed head and ran the new file (npx vitest run __tests__/utils/ownersGuards.test.ts → 10 passed). Each test pins a guard that is actually in the source:
- per-team
groupCachekey${owner}/${slug}and thecatch-to-empty fallback —src/utils/owners.ts:151-164 parseGroupleading^@anchor soalice@myorg/teamstays a plain login —src/utils/owners.ts:99-100- other-org warning text via
warnOnce—src/utils/owners.ts:139 - bare
options:(YAML null) →noParentOwners: false—src/utils/owners.ts:51-54 decoderejecting a blob withencodingbut nocontent—src/utils/owners.ts:278-280repoHasOwnersfalling back torepos.getwhen the payload has norepository(defaultBranch,src/utils/owners.ts:468-477) and the per-repohasOwnersCachekey —src/utils/owners.ts:398isNotFound'stypeof error === 'object' && error !== nullguard keeping a string/nullrejection out of theinoperator —src/utils/owners.ts:481-483; the path-less tree-entry skip —src/utils/owners.ts:447
The diff adds one new test file only — no src/ or existing-test changes, so the claimed disjointness from #564/#569/#571 holds by file set, and the fake-client paginate shape matches the real call site (octokit.paginate(octokit.teams.listMembersInOrg, …), line 153). The expand-groups test's assertion that the second team is read separately would indeed fail if the cache key dropped the slug.
Checks are green and the PR body's claims match the code. Looks correct to me; the hold label is the quality lane's gate, so a maintainer sign-off is what's left.
— hive: agent=reviewer backend=copilot model=claude-fable-5 copilot=1.0.88
Test Improvement
Files / cluster claimed:
__tests__/utils/ownersGuards.test.ts(new). Nosrc/,dist/or existing-test change. Disjoint from the held PRs on this module: #564 adds__tests__/utils/ownersGroupPagination.test.ts(group paginator fail-closed), #569 adds the bundleownersParseArms/ownersProbeArmsscenarios, #571 editsownersAuth.test.ts/repoHasOwners.test.ts. Uses #572's harness only to measure; does not depend on it merging.Ten unit tests pinning the thirteen behavioural contracts of
src/utils/owners.tsthat a Stryker run (--mutate src/utils/owners.ts, main @ e3119ad: 332 mutants, 15 survived, 95.48%) found unasserted, each applied by hand at its reported span to confirm it is killable:expandGroups: two same-org teams resolve to their own members and each is read once (groupCachekey${owner}/${slug}, line 151 — with one key the second team silently gets the first team's members);alice@myorg/teamstays a plain login and fetches no team (parseGroupleading anchor, line 99); the other-organization warning names the group and the supported org (line 139).parseOwners: a bareoptions:key (YAML null) means no options (line 52).loadOwnersTree: a blob with anencodingbut nocontentis rejected with the "invalid OWNERS file returned from GitHub API for OWNERS" message (line 278; only encoding-less blobs were tested).repoHasOwners: a payload with norepositoryat all falls back torepos.get(repository?.default_branch, line 468); a second repository is not answered from the first (hasOwnersCachekey, line 398).branchHasOwners: a string and anullrejection fromgit.getTreeare reported as "error listing the tree of main: …" rather than tripping theinoperator (isNotFound, line 482, six mutants); a tree entry without a path is skipped and the OWNERS file after it still found (line 447).Re-running the harness with this file: 15 → 2 survivors (98.49%). The two left are
owners.ts:161(warning text #564 asserts exactly — not duplicated here) andowners.ts:317(core.debugtext, equivalent by the review standard #572 documents).Validation
npx vitest run __tests__/utils/ownersGuards.test.ts→ 10 passednpm run test:coverage→ 168 files / 2340 passed, 99.92 / 99.35 / 100 / 99.91 (unchanged: the module was already at 100%)npx eslint __tests__/utils/ownersGuards.test.ts→ cleannpx stryker run --mutate src/utils/owners.ts --force(on test(mutation): add a bounded Stryker harness for the merge-decision code #572's config,psshimmed) before/after: 304→315 killed, 15→5 survived; the three pins added after the second run (options:null, string/null rejection) each verified by applying the mutant by hand and watching one test failRelated Issue
Closes #574 — merging leaves nothing for the issue to track.
Refs #554 ("Strengthen assertions and the test harness": a consumer of the mutation harness, not one of its boxes).
Filed by quality agent (hold-gated mode). Human review required.
— hive: agent=quality backend=copilot model=claude-fable-5.1 copilot=1.0.88 requested_by=@mrbobbytables