Skip to content

Cover the workspace menu's run-button behavior and metadata handlers #7912

Description

@mengw15

Task Summary

MenuComponent's class file is at 86.27 % with 26 uncovered lines, concentrated in getRunButtonBehavior — the method that maps each execution state to the run/pause/resume button's label, icon and click handler. Two earlier passes (#7352, #7775) covered the operator-menu sub-component and the clipboard; this is the main component's run-button and metadata logic they left.

Pure EXTEND of menu.component.spec.ts. Vitest/jsdom; see frontend/TESTING.md and frontend/AGENTS.md. Use the local coverage report to catch what is left — the lines below are where the report points today, not a fence.

Behavior to add

MenuComponent (frontend/src/app/workspace/component/menu/menu.component.ts, codecov 86.27 % — EXTEND menu.component.spec.ts)

  • getRunButtonBehavior (392–456) — a switch (this.executionState) returning a different button descriptor per state. Set executionState to each ExecutionState value, call the method, and assert the returned { text, icon, onClick, disabled } — in particular that the onClick wired for the run-eligible states invokes runWorkflow (392, 407, 456) and that the paused/running/completed/failed states return their distinct descriptors (410, 431, 438, 445, 452). Assert the effect of calling the returned onClick, not its source text.
  • ngOnInit run-button wiring (222–241) — the execution-state subscription sets executionState and calls applyRunButtonBehavior(getRunButtonBehavior()); emit a state event and assert the button updates. Line 241 also sets isExportDeactivate from !config.env.exportExecutionResultEnabled || !hasResults — cover the flag on/off and results present/absent so both sides of the || are taken.
  • onClickGenerateReport (506–525) — the report assembly and its two failure branches: the operator-results retrieval error (516, 518) and the catch that reports (e as Error).message (523, 525). Stub the results service to succeed, to error on retrieval, and to throw, and assert notificationService.error / remove are called accordingly.
  • onClickEditDescription (614–643) — building the updatedWorkflow with description ?? "", calling setWorkflowMetadata, and the if (this.userService.isLogin()) branch that persists then closes the modal. Cover logged-in and logged-out.
  • persistWorkflow (663–668) — the filter(isDefined(localPid) && isDefined(workflow.wid)) gate feeding addWorkflowToProject, and the error handler. Cover a workflow with and without a project id/wid, and the error path.
  • onWorkflowNameChange (678) — the if (this.userService.isLogin()) guard.
  • registerWorkflowMetadataDisplayRefresh (694–700) and handleWorkflowVersionDisplay (722) — the metadata-refresh subscription that sets currentWorkflowName, schedules adjustWorkflowNameWidth, and derives autoSaveState from lastModifiedTime === undefined / creationTime === undefined. Emit metadata with and without those timestamps.
  • runWorkflow (794–805) — the currentWorkflowName-derived default name and the currentExecutionName || "Untitled Execution" fallback.

Determinism notes:

  • registerWorkflowMetadataDisplayRefresh calls setTimeout(() => this.adjustWorkflowNameWidth(), 0). Do not add vi.useFakeTimers() merely to stop it — a synchronous test body cannot let it fire, and fake timers over zone.js's patched setTimeout have caused Node-version-dependent failures. If you need to assert the width adjustment, call adjustWorkflowNameWidth directly.
  • Stub userService, notificationService, workflowActionService, userProjectService and the results service; emit with of(...) / throwError(...) so streams resolve synchronously — never a real backend.
  • fixture.detectChanges() after each state change and fixture.destroy() in afterEach; vi.restoreAllMocks() in afterEach.
  • Do not assert on DatePipe-rendered text or on measured geometry (adjustWorkflowNameWidth reads element widths, which are zero under jsdom — assert it was called, not the width it computed).

Note open PRs touch this component (#5774, and the toolbar entries) — rebase before finishing.

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