Skip to content

cover the remaining branches in CoeditorUserIcon, UserVenv, FilesUploader, and PresetWrapper #7700

Description

@mengw15

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

  • Refactor / Cleanup
  • DevOps / Deployment / CI
  • Testing / QA
  • Documentation
  • Performance
  • Other

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions