Task Summary
Four frontend files each have a handful of uncovered lines and untaken branches — 11 partial branches and 13 unhit lines between them, worth roughly +13.3pp / +6.3pp / +5.9pp / +4.5pp on the respective files. Codecov computes coverage = hits / lines and does not count a partially-covered line as a hit, so both kinds cost percentage points.
Goal: cover the listed lines and take the missing side of each branch so these files reach full coverage. All four already have a spec; extend it and re-run the coverage report to catch anything left. Vitest/jsdom; see frontend/TESTING.md.
Every case below is reached by passing a different input value or toggling a component flag — none of them needs a timer, a clock, a specific OS, or concurrency, so there is no determinism hazard here. Assert on rendered text / bound attributes / component state, never on layout or geometry (zeros under jsdom).
Behavior to add
CoeditorUserIconComponent template (frontend/src/app/workspace/component/coeditor-user-icon/coeditor-user-icon.component.html, 53.3%, 2 partials + 5 unhit — the lowest-covered of the four)
- The shadowing menu is gated on
*ngIf="!(coeditorPresenceService.shadowingModeEnabled && …)" and its negation on the next block. Drive the presence-service double with shadowing off and on (and, for the compound condition, with each half flipped) so both menu variants render.
- With each variant rendered, click through the DOM:
(click)="shadowCoeditor()" in the off state and (click)="stopShadowing()" (plus its "Stop Shadowing" label) in the on state, asserting the service double received each call.
UserVenvComponent (frontend/src/app/dashboard/component/user/user-venv/user-venv.component.ts, 93.7%, 5 partials)
target.name || "(unnamed)" (two sites) — a package/environment whose name is empty so the "(unnamed)" fallback runs, plus one with a name.
Object.entries(record.packages ?? …) — a record with packages present and one where it is null/undefined.
version: match ? match[2] : raw ?? "" — a requirement line that matches the version regex, one that does not (falls back to raw), and one where raw is itself nullish (falls back to "").
(row.version ?? "").trim() — a row with a version and one with null.
FilesUploaderComponent template (frontend/src/app/dashboard/component/user/files-uploader/files-uploader.component.html, 70.6%, 1 partial + 4 unhit)
*ngIf="showUploadAlert && fileUploadingFinished" — set each flag independently (neither, one, both) so the alert block renders only in the both-true case and the partial resolves.
- With the alert rendered, assert its
nzMessage="{{fileUploadBannerMessage}}" text and fire (nzOnClose)="hideBanner()", asserting the banner state clears.
(click)="openFileSelector()" — click the selector trigger and assert the delegated call.
PresetWrapperComponent (frontend/src/app/workspace/component/preset-wrapper/preset-wrapper.component.ts, 89.5%, 3 partials + 4 unhit)
this.searchTerm = this.formControl.value !== null ? … : … — a form control holding a value and one holding null.
this.searchTerm = (value ?? "").toString() — call with a value and with null/undefined.
if (this.presetMenuVisible) — with the menu open and closed.
- The unhit lines: the
filter(presets => presets.type === this.presetType && presets.target === …) callback (emit presets that match and that do not, so the predicate runs both ways), the apply handler's this.basePreset = applyEvent.preset assignment, and the FormlyFieldConfig builder (call the method that constructs it).
Task Type
Task Summary
Four frontend files each have a handful of uncovered lines and untaken branches — 11 partial branches and 13 unhit lines between them, worth roughly +13.3pp / +6.3pp / +5.9pp / +4.5pp on the respective files. Codecov computes
coverage = hits / linesand does not count a partially-covered line as a hit, so both kinds cost percentage points.Goal: cover the listed lines and take the missing side of each branch so these files reach full coverage. All four already have a spec; extend it and re-run the coverage report to catch anything left. Vitest/jsdom; see
frontend/TESTING.md.Every case below is reached by passing a different input value or toggling a component flag — none of them needs a timer, a clock, a specific OS, or concurrency, so there is no determinism hazard here. Assert on rendered text / bound attributes / component state, never on layout or geometry (zeros under jsdom).
Behavior to add
CoeditorUserIconComponent template (
frontend/src/app/workspace/component/coeditor-user-icon/coeditor-user-icon.component.html, 53.3%, 2 partials + 5 unhit — the lowest-covered of the four)*ngIf="!(coeditorPresenceService.shadowingModeEnabled && …)"and its negation on the next block. Drive the presence-service double with shadowing off and on (and, for the compound condition, with each half flipped) so both menu variants render.(click)="shadowCoeditor()"in the off state and(click)="stopShadowing()"(plus its "Stop Shadowing" label) in the on state, asserting the service double received each call.UserVenvComponent (
frontend/src/app/dashboard/component/user/user-venv/user-venv.component.ts, 93.7%, 5 partials)target.name || "(unnamed)"(two sites) — a package/environment whosenameis empty so the"(unnamed)"fallback runs, plus one with a name.Object.entries(record.packages ?? …)— a record withpackagespresent and one where it is null/undefined.version: match ? match[2] : raw ?? ""— a requirement line that matches the version regex, one that does not (falls back toraw), and one whererawis itself nullish (falls back to"").(row.version ?? "").trim()— a row with a version and one withnull.FilesUploaderComponent template (
frontend/src/app/dashboard/component/user/files-uploader/files-uploader.component.html, 70.6%, 1 partial + 4 unhit)*ngIf="showUploadAlert && fileUploadingFinished"— set each flag independently (neither, one, both) so the alert block renders only in the both-true case and the partial resolves.nzMessage="{{fileUploadBannerMessage}}"text and fire(nzOnClose)="hideBanner()", asserting the banner state clears.(click)="openFileSelector()"— click the selector trigger and assert the delegated call.PresetWrapperComponent (
frontend/src/app/workspace/component/preset-wrapper/preset-wrapper.component.ts, 89.5%, 3 partials + 4 unhit)this.searchTerm = this.formControl.value !== null ? … : …— a form control holding a value and one holdingnull.this.searchTerm = (value ?? "").toString()— call with a value and withnull/undefined.if (this.presetMenuVisible)— with the menu open and closed.filter(presets => presets.type === this.presetType && presets.target === …)callback (emit presets that match and that do not, so the predicate runs both ways), the apply handler'sthis.basePreset = applyEvent.presetassignment, and theFormlyFieldConfigbuilder (call the method that constructs it).Task Type