test(frontend): close the user, hub and resource-registry service gaps - #8336
Conversation
Automated Reviewer SuggestionsBased on the
|
There was a problem hiding this comment.
🟢 Approval recommended
The changes are limited to test-only additions that align with existing production behavior and improve branch coverage without introducing functional risk.
Pull request overview
This PR extends the Angular/Vitest frontend unit test suite to close remaining coverage gaps called out in #8334, focusing on previously unexercised guard branches and template binding write-backs without changing production code.
Changes:
- Adds BrowseSectionComponent spec coverage for cover-image caching behavior and guard paths when a descriptor lacks
coverUrlor returns an empty URL. - Extends ResourceRegistryService specs to cover the
hubRoute-absent branch (private-page-only kinds). - Extends UserService and EmailRequestModalComponent specs to cover additional edge paths (null access token on verify, avatar cache expiry revoke/delete path, ngModel write-back for code input).
File summaries
| File | Description |
|---|---|
frontend/src/app/hub/component/browse-section/browse-section.component.spec.ts |
Adds tests covering cover image cache guards, empty-cover handling, and avoiding duplicate descriptor calls across ngOnChanges. |
frontend/src/app/dashboard/service/user/resource-registry/resource-registry.service.spec.ts |
Adds a test covering entryLink behavior when a descriptor has a privateRoute but no hubRoute. |
frontend/src/app/common/service/user/user.service.spec.ts |
Adds tests covering register-verify null-token behavior and avatar cache expiry behavior (revoke/delete + refetch). |
frontend/src/app/common/service/user/email-request-modal/email-request-modal.component.spec.ts |
Adds a test that types into the verification-code input and asserts ngModel write-back and correct label content. |
Review details
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #8336 +/- ##
============================================
+ Coverage 94.08% 94.17% +0.08%
+ Complexity 4810 4761 -49
============================================
Files 1197 1192 -5
Lines 48811 48520 -291
Branches 5906 5417 -489
============================================
- Hits 45925 45692 -233
+ Misses 1427 1418 -9
+ Partials 1459 1410 -49
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Xinyuan Lin <xinyual3@uci.edu>
What changes were proposed in this PR?
Four existing frontend specs extended. +10 fully-covered lines and +7 branch arms.
user.service.tsbrowse-section.component.tsresource-registry.service.tsemail-request-modal.component.htmlThree of the four reach 100%. The plain line-hit metric moves only +4 against Codecov's +10, because six of the gained lines were already executing and flip solely by completing a branch arm — the two numbers are not interchangeable and both are given.
Not-fully-covered across the bundle goes 13 → 3, and all three of those are deliberately declined (below).
The reviewer revised my own claim down
The build reported +11 lines and +8 arms. Independent re-measurement puts it at +10 and +7:
browse-section.component.tsgains 3 lines and 2 arms, not 4 and 3. Line 96 remains partial. The lower figure is the one in the table.Two files were in scope and contribute nothing
user-dataset-version-creator.component.tswas dropped entirely. Its only missed line isget formControlNames(), and a repo-wide grep across.tsand.htmlreturns exactly one hit — its own declaration. Zero call sites, zero template bindings. A test there would be a pure count-raiser, so the getter is flagged as a dead-code removal candidate instead.browse-section.component.html(24/24) andemail-request-modal.component.ts(8/9) were measured both ways and are unchanged.Deliberately not included
browse-section.component.ts:96stays partial, andemail-request-modal.component.ts:67is declined.One survivor is reported rather than chased: mutating
user.service.ts:108fromhandleAccessToken(accessToken ?? "")to a conditional survives the suite. That mutant is character-for-character the shaperegister()already uses for the samestring | nullpayload — it is arguably the fix, not a regression, so no test was written to pin the current form.user.service.ts:184(this.cache.delete(avatarUrl)) is covered but not independently pinned: the code immediately falls through to amapthat overwrites the entry either way, so no mutation isolates it. It rides along with lines 180 and 183 in one test, and that is stated rather than presented as a kill.Verification
Measured with the full 209-file suite in one command — no name filter and no
--includeat all — so there is no filter-attribution risk, withcoverage/deleted before each run. The baseline was rebuilt by writing theHEADversions of the four specs into place from a scratch extraction (nevergit checkout), running, then restoring from a hash-verified snapshot. Figures parsed straight fromcoverage/gui/lcov.info.Seven reviewer findings, all repaired — including one test that was deleted rather than kept, because it duplicated an existing assertion.
browse-section.component.ts:114needed a white-box assertion or the test would have been vacuous:getCoverImage()'s|| this.defaultBackgroundmakes the guarded and unguarded paths observably identical through the public API, so the test asserts on the privatecoverImageUrlsmap. That is unusual and is called out here rather than left for a reader to find.yarn format:cipasses.frontend/junit.xmlis regenerated by every run, is not gitignored, and is not committed. No production file is touched.Any related issues, documentation, discussions?
Closes #8334
How was this PR tested?
Re-run after rebasing onto current
main.Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 5)