Skip to content

Cover the property editor's Python-UDF environment loading and early-return guards #7910

Description

@mengw15

Task Summary

The other half of OperatorPropertyEditFrameComponent's gap (codecov 74.76 %, 73 uncovered lines) is the Python-UDF virtual-environment loading path — including its failure branch, which no test provokes — plus a set of early-return guards that only ever run on their "keep going" side. Two earlier passes (#6348, #6826) covered the component's other methods; these are what they left.

Pure EXTEND of operator-property-edit-frame.component.spec.ts. Vitest/jsdom; see frontend/TESTING.md and frontend/AGENTS.md.

Behavior to add

OperatorPropertyEditFrameComponent (frontend/src/app/workspace/component/property-editor/operator-property-edit-frame/operator-property-edit-frame.component.ts, codecov 74.76 % — EXTEND)

Python-UDF environment loading (rerenderEditorForm, lines 604–636)

The whole branch is unexercised. Render the frame with a Python UDF operator selected and stub computingUnitStatusService and workflowPveService:

  • 604–605 — if (isPythonUdf && this.formData.defaultEnv === undefined) seeds defaultEnv = true. Cover a form that has no defaultEnv and one that already sets it.
  • 616–618 — the computing-unit stream maps to unit?.computingUnit?.cuid and then cuid !== undefined ? workflowPveService.fetchPVEs(cuid) : …. Cover a unit with a cuid, and an emission with no unit or no cuid so the other arm is taken.
  • 625–627 — the success path: patchPythonUdfEnvironmentSchema(baseSchema, environments), setFormlyFormBinding(patchedSchema), hideEnvNameWhenDefaultEnvChecked(). Assert the environment names reach the rendered field.
  • 630–636 — the failure path: the error is logged, notificationService.error is called with Could not load Python virtual environments: ${err instanceof Error ? err.message : …}, and the form is then bound with an empty environment list. Cover both sides of the err instanceof Error ternary by failing the stream once with an Error and once with a non-Error value, and assert the fallback binding still happens.
  • patchPythonUdfEnvironmentSchema (471) — if (patchedSchema.properties && typeof patchedSchema.properties !== "boolean"); cover a schema whose properties is absent and one where it is a boolean, so the guard's false side runs.
  • hideEnvNameWhenDefaultEnvChecked (481) — the if (envField) guard, with and without the environment-name field present.

Early-return guards

Each of these returns early on a condition that is never met in the current tests:

  • ngOnChanges (492–493) — returns when currentOperatorId is unset.
  • ngOnInit (517–525) — the status-update subscription sets currentOperatorStatus only when currentOperatorId is set, and a second subscription returns when operatorId !== this.currentOperatorId. Emit an update for a different operator and assert nothing changes.
  • isHuggingFaceOperator (543) — returns false with no current operator.
  • checkOperatorProperty (683–684) — returns false when the operator is not found.
  • typeInferenceOnLambdaFunction (752–757) — two early returns: no input schema for the operator, and no schema for the first port.
  • registerOnFormChangeHandler (738) — the if (this.currentOperatorId) guard.
  • The port/attribute helpers at 1160–1209 — isDefined(portIndex) (1179–1180), isDefined(data) (1201–1202), and the inputAttributeType !== dataAttributeType comparison (1209). Cover a matching and a mismatching attribute type.

Determinism notes:

  • Stub computingUnitStatusService, workflowPveService and notificationService; emit with of(...) / throwError(...) so streams resolve synchronously — never a real backend.
  • fixture.detectChanges() after each state change and fixture.destroy() in afterEach, so the untilDestroyed subscriptions on the computing-unit stream stop between tests.
  • Do not assert on console.error output as the test's only assertion — assert on the notificationService.error argument and on the resulting bound form.
  • vi.restoreAllMocks() in afterEach.

Out of scope: the Quill title-editing methods, which #6826 deliberately set aside, and setFormlyFormBinding's per-key field rules, which are covered separately.

Note open PRs touch this component (#7644, #7351, #7184, #6897) — rebase before finishing.

Task Type

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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