feat: surface coverage status in repositories and repository - #48
feat: surface coverage status in repositories and repository#48alerizzo wants to merge 3 commits into
Conversation
The API now returns a CoverageStatus (None/UpToDate/Waiting/Stopped) on Coverage, so the CLI can tell apart three situations that previously looked identical: a stale percentage, a repository that stopped receiving reports, and one that never had coverage at all. Mirrors codacy-spa#3110. The field rides on Coverage, embedded only in RepositoryWithAnalysis, so `repositories` and `repository` are the only commands that can show it. `repositories` marks a Waiting value with a dim glyph and replaces a Stopped one (the API sends no percentage) with its own, explained by a legend that only lists the statuses actually present. `repository`'s Metrics row spells the state out with dates and commit, and notes when a stopped repository's coverage gate is no longer enforced. Also replaces formatAnalysisStatus's coverage heuristic for `repository`. It inferred state from a separate listCoverageReports call plus "is a percentage present", which was wrong for Waiting -- a waiting repository still reports a stale percentage, so the row stayed silent in exactly the case worth surfacing. Reading the real status drops that request, and because getRepositoryWithAnalysis is whitelisted for repository tokens while listCoverageReports is not, coverage state reaches repository-token users for the first time. `pull-request` keeps the heuristic: its coverage models carry no status field. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 51 |
| Duplication | 12 |
AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Pull Request Overview
No merge-blocking security or logic issues were identified. Codacy is up to standards, but the coverage report is unavailable, so production-line test coverage cannot be independently verified.
Two acceptance-related scenarios remain unverified: status-less repository dashboard behavior and continued pull-request heuristic behavior. The main test file is also high-maintenance due to its size, as noted in the file comment.
About this PR
- Add automated coverage for status-less repository dashboard behavior and preservation of pull-request heuristic behavior.
- The coverage report is empty, so production-line coverage for the new behavior cannot be independently verified.
1 comment outside of the diff
src/utils/formatting.test.ts
line 1🟡 MEDIUM RISK
Suggestion: Split this test file into focused files for repository coverage-status behavior and general formatting cases, with shared fixtures/helpers kept in a small module.
Test suggestions
- Waiting repository table renders stale percentage, glyph, and conditional legend
- Stopped repository table renders only
⊘and conditional legend - Healthy, None, absent, and status-less repository table rendering remains compatible
- Conditional coverage legend deduplicates and includes only present statuses
- Repository detail renders Waiting provenance and Stopped last-report information
- Coverage gate consequence appears only when a goal is configured
- None repository detail renders
Not set up - Analysis status prioritizes Waiting/Stopped over the heuristic and leaves UpToDate/None silent
- Coverage formatting helpers preserve threshold coloring and sanitize commit identifiers
- Repository JSON projects coverage status fields and None-only payload
- Repository-token dashboard skips pull requests and reports only
pullRequestsunavailable - Status-less repository dashboard preserves the prior heuristic-removal behavior
- Pull-request command remains behaviorally covered by the heuristic after repository changes
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Status-less repository dashboard preserves the prior heuristic-removal behavior
2. Pull-request command remains behaviorally covered by the heuristic after repository changes
TIP How was this review? Give us feedback
From a pre-review pass over the branch. A `Waiting` payload with no `coveragePercentage` rendered as "N/A ⋯" under a legend reading "showing the last known value", and as "N/A Not reported yet ... — value from 11h ago" in the detail view — both describing a number that isn't on screen. Observed payloads always carry a stale percentage, but the field is documented as present only for the latest commit, which a waiting repository by definition doesn't have, so gate both claims on a value actually being there rather than on the status alone. Also replaces the two non-null assertions with `&& glyph` / `&& note` guards, so a missing marker degrades to the ordinary metric instead of printing the string "undefined", and adds COVERAGE_STATUS_GLYPH as a Record<CoverageStatus, …>. The four renderers all fall through to "render nothing", so a new status member from `npm run update-api` would have compiled clean and silently disappeared; now it fails to compile at the Record. AGENTS.md claimed `None` renders "exactly as before", which is true of the table but not the detail view — the same PR deliberately renders it as "Not set up". Corrected, since that file is loaded as project instructions and would have talked the next agent out of intended behavior. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both gaps were real. `pull-request` is now `formatAnalysisStatus`'s only caller of the expectsCoverage/hasCoverageData heuristic, but its tests only ever mocked hasCoverageOverview: false, so the hint path was never exercised at the command level and nothing would have failed if someone deleted the heuristic outright. Adds a test that drives it past the 3h grace period and asserts "Missing coverage reports", pinning the threshold rather than just that some hint appears. The status-less dashboard case was only covered incidentally (the shared repo fixture happens to carry no status). Since "no coverage hint when status is undefined" is a deliberate behavior removal, it now has an explicit test rather than resting on a fixture detail. Also broadens the test-file bullet in the Codacy review instructions. It already said length and duplication findings on *.test.ts are expected, but the reviewer suggested splitting formatting.test.ts by theme, which the wording didn't cover. Tests are co-located one-per-module by design, so a helper's tests belong beside its source however long that file grows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Thanks — both flagged test gaps were real, and both are now covered. Added: pull-request heuristic coverage ( Added: status-less dashboard behavior ( Not doing: splitting On the empty coverage report: this repository has no coverage set up at all ( Also folded in a separate pre-review pass ( 668 tests pass; all checks green. 🤖 Generated by /pr-fixup command |
Summary
The API now returns a
CoverageStatus(None/UpToDate/Waiting/Stopped) onCoverage, so the CLI can finally tell apart three situations that looked identical before: a stale percentage, a repository that stopped receiving reports, and one that never had coverage. Mirrors codacy-spa#3110. No API bump — pinned57.4.17already ships the field.repositories— a dim⋯after aWaitingvalue, a dim⊘instead of aStoppedone (the API sends no percentage), and a legend under the table listing only the statuses actually present. Glyphs follow the existing vocabulary:⋯is alreadyformatStandards's "not final yet" marker,⊘shares the Mathematical Operators block with the⊙public-repo marker. No emojis.repository— the Metrics row spells the state out with the date and commit of the last report, notes when a stopped repository's coverage gate is no longer enforced, and rendersNoneasNot set uprather than a bareN/A.formatAnalysisStatusgained an authoritativecoverageStatusthat wins over itsexpectsCoverage/hasCoverageDataheuristic. That heuristic was wrong forWaiting: a waiting repository still reports a stale percentage, sohasCoverageDatawas true and the row said nothing in exactly the case worth surfacing.pull-requestkeeps the heuristic — its coverage models carry no status field — and is untouched.Worth a reviewer's attention
listCoverageReportscall takesrepositoryfrom 5 parallel requests to 4. BecausegetRepositoryWithAnalysisis whitelisted for repository tokens whilelistCoverageReportsis not, repository-token users get the coverage state for the first time, andunavailableis now["pullRequests"]alone.statusisundefined(39 of 248 repos in thecodacyorg), the Analysis row now shows no coverage hint where the heuristic might have said "Missing coverage reports". That's the honest reading of an absent status, but it is a behavior removal. If you'd rather not, the fallback is to keep the call and let the status win only when defined — 3 lines informatAnalysisStatus.repositories.ts's localformatMetricwas deleted — a stale copy of the sharedcolorMetric. Leaving it would have let coverage and complexity/duplication drift inside the same table. Side effect: absent metrics there now render a dimN/Ainstead of a bare one.Waitingkeeps its threshold coloring on the stale value, matching the SPA. The glyph is what marks it stale. Happy to change if that reads as misleading.Test plan
npx tsc --noEmit && npm test— 664 tests (39 new).codacy repo gh codacy codacy-cloud-cli -o json | jq '.repository.coverage'→{"status":"None"}and nothing else.pull-requestunaffected:codacy pr gh codacy portal <n>still shows its Analysis row from the 3h heuristic.Verified end to end against the live API on all of the above except the repository-token path, which rests on the unit test asserting
unavailable === ["pullRequests"].🤖 Generated with Claude Code