This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-5626-515d37221adb3d3e2ae282a8bd82151f547c3d51 in repository https://gitbox.apache.org/repos/asf/texera.git
commit 99b9ca281dd4524b0423bac9593ce1f9f136f14d Author: Prateek Ganigi <[email protected]> AuthorDate: Sat Jun 13 10:32:57 2026 -0700 test(frontend): share workflow-editor TestBed setup, drop double-run (#5626) ### What changes were proposed in this PR? Addresses the two review comments on [#5318](https://github.com/apache/texera/issues/5318)'s follow-up implementation: 1. Share a common TestBed setup so the jsdom and browser specs don't drift. The .browser.spec.ts split created two TestBed configurations for the same component - one in workflow-editor.component.spec.ts (External Module Integration describe), one in workflow-editor.browser.spec.ts. Both configured nearly identical imports/providers arrays, which would inevitably drift over time. Extracted them into a new sibling file workflow-editor.test-utils.ts exporting two arrays: export const workflowEditorTestImports = [ ... ]; export const workflowEditorTestProviders: Provider[] = [ ... ]; This follows the existing project convention in [frontend/src/app/common/testing/test-utils.ts](vscode-webview://1epki5h79lmkghv36u4evg54fuvmk17ndjca203mcg7opnnd5sg9/frontend/src/app/common/testing/test-utils.ts) (which exports commonTestImports and commonTestProviders the same way). Each spec's TestBed now collapses to: await TestBed.configureTestingModule({ imports: workflowEditorTestImports, providers: workflowEditorTestProviders, }).compileComponents(); Adding or removing a service from either spec's setup is now a single edit in one file. 2. Drop the explicit workflow-editor.component.spec.ts entry from the test-browser include in angular.json. With the six mouse-event tests now living in workflow-editor.browser.spec.ts (picked up by the **/*.browser.spec.ts glob), the explicit listing of workflow-editor.component.spec.ts in test-browser's include array was causing the file's 25 jsdom-friendly tests to run twice, once in jsdom (the default test target) and once in real Chrome (the test-browser target). Removed that explicit entry; the test-browser target now picks up only **/*.browser.spec.ts files. Scope note. The pre-existing JointJS Paper describe block at the top of workflow-editor.component.spec.ts has its own deliberately-different TestBed setup (ContextMenuComponent instead of NzModalCommentBoxComponent, Overlay, MockComputingUnitStatusService) and was left untouched, it wasn't part of the duplication introduced by the .browser.spec.ts split. ### Any related issues, documentation, discussions? Addresses review feedback on the follow-up PR for [#5318](https://github.com/apache/texera/issues/5318). Closes #5318 Related to #3614 / PR #5146 (this PR restores tests that were commented out during PR #5146 as collateral from the #3614 fix). ### How was this PR tested? Existing test runs: Verified no test-count regressions in either target, and the double-run is gone: ng test (jsdom, full suite): 947 pass / 0 fail / 2 skipped / 1 todo across 103 files ng run gui:test-browser: 13 pass / 0 fail across 2 files (6 from workflow-editor.browser.spec.ts + 7 from the pre-existing code-editor.component.browser.spec.ts) workflow-editor.component.spec.ts under jsdom: 25/25 pass (unchanged from before this PR) Browser test count dropped from 38 -> 13, confirming the 25 jsdom-friendly tests in workflow-editor.component.spec.ts no longer double-run in real Chrome. Static checks: tsc --noEmit and eslint clean on all four changed files. ### Was this PR authored or co-authored using generative AI tooling? Co-authored-by: Claude Code (Anthropic Claude Opus 4.7) --------- Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]> --- frontend/angular.json | 1 - .../workflow-editor.component.browser.spec.ts | 216 +++++++++++++++++++++ .../workflow-editor.component.spec.ts | 202 +------------------ .../workflow-editor/workflow-editor.test-utils.ts | 84 ++++++++ 4 files changed, 304 insertions(+), 199 deletions(-) diff --git a/frontend/angular.json b/frontend/angular.json index bc0fbca234..014f8e36d8 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -110,7 +110,6 @@ "runnerConfig": "vitest.browser.config.ts", "tsConfig": "src/tsconfig.spec.json", "include": [ - "**/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts", "**/*.browser.spec.ts" ] } diff --git a/frontend/src/app/workspace/component/workflow-editor/workflow-editor.component.browser.spec.ts b/frontend/src/app/workspace/component/workflow-editor/workflow-editor.component.browser.spec.ts new file mode 100644 index 0000000000..99fcf59ebf --- /dev/null +++ b/frontend/src/app/workspace/component/workflow-editor/workflow-editor.component.browser.spec.ts @@ -0,0 +1,216 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Mouse / pointer event tests for WorkflowEditorComponent. + * + * These tests exercise JointJS event paths (cell-view jQuery + * `.trigger("mousedown" | "dblclick")` dispatch, blank-area paper + * clicks, shift-click multi-select) that depend on real-DOM SVG hit + * testing and canvas measurement. jsdom does not implement those + * paths, so the tests live in a `.browser.spec.ts` file that is + * skipped by the default jsdom `test` target and picked up only by + * the `test-browser` target (Vitest + Playwright Chromium). + * + * Originally part of workflow-editor.component.spec.ts; commented out + * in PR #5146 to keep CI green after the file was added to the jsdom + * runner. Restored here per issue #5318. + */ + +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { NzModalRef, NzModalService } from "ng-zorro-antd/modal"; +import * as jQuery from "jquery"; + +import { WorkflowEditorComponent } from "./workflow-editor.component"; +import { NzModalCommentBoxComponent } from "./comment-box-modal/nz-modal-comment-box.component"; +import { workflowEditorTestImports, workflowEditorTestProviders } from "./workflow-editor.test-utils"; + +import { WorkflowActionService } from "../../service/workflow-graph/model/workflow-action.service"; +import { + mockCommentBox, + mockPoint, + mockResultPredicate, + mockScanPredicate, +} from "../../service/workflow-graph/model/mock-workflow-data"; +import { createYTypeFromObject } from "../../types/shared-editing.interface"; + +const createJQueryEvent = (event: string, properties?: object): JQuery.Event => + (jQuery as unknown as JQueryStatic).Event(event, properties); + +describe("WorkflowEditorComponent - mouse and pointer event integration", () => { + let component: WorkflowEditorComponent; + let fixture: ComponentFixture<WorkflowEditorComponent>; + let workflowActionService: WorkflowActionService; + let nzModalService: NzModalService; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: workflowEditorTestImports, + providers: workflowEditorTestProviders, + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(WorkflowEditorComponent); + component = fixture.componentInstance; + workflowActionService = TestBed.inject(WorkflowActionService); + workflowActionService.setHighlightingEnabled(true); + nzModalService = TestBed.inject(NzModalService); + fixture.detectChanges(); + }); + + it("should try to highlight the operator when user mouse clicks on an operator", () => { + const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); + // install a spy on the highlight operator function and pass the call through + vi.spyOn(jointGraphWrapper, "highlightOperators"); + workflowActionService.addOperator(mockScanPredicate, mockPoint); + + // unhighlight the operator in case it's automatically highlighted + jointGraphWrapper.unhighlightOperators(mockScanPredicate.operatorID); + + // find the joint Cell View object of the operator element + const jointCellView = component.paper.findViewByModel(mockScanPredicate.operatorID); + jointCellView.$el.trigger("mousedown"); + + fixture.detectChanges(); + + // assert the highlighted operator is correct + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toEqual([mockScanPredicate.operatorID]); + }); + + it("should highlight the commentBox when user clicks on a commentBox", () => { + const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); + vi.spyOn(jointGraphWrapper, "highlightCommentBoxes"); + workflowActionService.addCommentBox(mockCommentBox); + jointGraphWrapper.unhighlightCommentBoxes(mockCommentBox.commentBoxID); + const jointCellView = component.paper.findViewByModel(mockCommentBox.commentBoxID); + jointCellView.$el.trigger("mousedown"); + fixture.detectChanges(); + expect(jointGraphWrapper.getCurrentHighlightedCommentBoxIDs()).toEqual([mockCommentBox.commentBoxID]); + }); + + it("should open commentBox as NzModal when user double clicks on a commentBox", () => { + const modalRef: NzModalRef = nzModalService.create({ + nzTitle: "CommentBox", + nzContent: NzModalCommentBoxComponent, + nzData: { commentBox: createYTypeFromObject(mockCommentBox) }, + nzAutofocus: null, + nzFooter: [ + { + label: "OK", + onClick: () => { + modalRef.destroy(); + }, + type: "primary", + }, + ], + }); + vi.spyOn(nzModalService, "create").mockReturnValue(modalRef); + const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); + workflowActionService.addCommentBox(mockCommentBox); + jointGraphWrapper.highlightCommentBoxes(mockCommentBox.commentBoxID); + const jointCellView = component.paper.findViewByModel(mockCommentBox.commentBoxID); + jointCellView.$el.trigger("dblclick"); + expect(nzModalService.create).toHaveBeenCalled(); + fixture.detectChanges(); + modalRef.destroy(); + }); + + it("should unhighlight all highlighted operators when user mouse clicks on the blank space", () => { + const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); + + // add and highlight two operators + workflowActionService.addOperatorsAndLinks( + [ + { op: mockScanPredicate, pos: mockPoint }, + { op: mockResultPredicate, pos: mockPoint }, + ], + [] + ); + jointGraphWrapper.highlightOperators(mockScanPredicate.operatorID, mockResultPredicate.operatorID); + + // assert that both operators are highlighted + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockScanPredicate.operatorID); + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockResultPredicate.operatorID); + + // find a blank area on the JointJS paper + const blankPoint = { x: mockPoint.x + 100, y: mockPoint.y + 100 }; + expect(component.paper.findViewsFromPoint(blankPoint)).toEqual([]); + + // trigger a click on the blank area using JointJS paper's jQuery element + const point = component.paper.localToClientPoint(blankPoint); + const event = createJQueryEvent("mousedown", { + clientX: point.x, + clientY: point.y, + }); + component.paper.$el.trigger(event); + + fixture.detectChanges(); + + // assert that all operators are unhighlighted + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toEqual([]); + }); + + it("should highlight multiple operators when user clicks on them with shift key pressed", () => { + const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); + + workflowActionService.addOperator(mockScanPredicate, mockPoint); + workflowActionService.addOperator(mockResultPredicate, mockPoint); + jointGraphWrapper.highlightOperators(mockResultPredicate.operatorID); + + // assert that only the last operator is highlighted + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockResultPredicate.operatorID); + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).not.toContain(mockScanPredicate.operatorID); + + // find the joint Cell View object of the first operator element + const jointCellView = component.paper.findViewByModel(mockScanPredicate.operatorID); + + // trigger a shift click on the cell view using its jQuery element + const event = createJQueryEvent("mousedown", { shiftKey: true }); + jointCellView.$el.trigger(event); + + fixture.detectChanges(); + + // assert that both operators are highlighted + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockScanPredicate.operatorID); + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockResultPredicate.operatorID); + }); + + it("should unhighlight the highlighted operator when user clicks on it with shift key pressed", () => { + const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); + + workflowActionService.addOperator(mockScanPredicate, mockPoint); + jointGraphWrapper.highlightOperators(mockScanPredicate.operatorID); + + // assert that the operator is highlighted + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockScanPredicate.operatorID); + + // find the joint Cell View object of the operator element + const jointCellView = component.paper.findViewByModel(mockScanPredicate.operatorID); + + // trigger a shift click on the cell view using its jQuery element + const event = createJQueryEvent("mousedown", { shiftKey: true }); + jointCellView.$el.trigger(event); + + fixture.detectChanges(); + + // assert that the operator is unhighlighted + expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).not.toContain(mockScanPredicate.operatorID); + }); +}); diff --git a/frontend/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts b/frontend/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts index e2d1601e6c..c87ea058e7 100644 --- a/frontend/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts +++ b/frontend/src/app/workspace/component/workflow-editor/workflow-editor.component.spec.ts @@ -24,16 +24,15 @@ import { WorkflowUtilService } from "../../service/workflow-graph/util/workflow- import { ComponentFixture, TestBed } from "@angular/core/testing"; import { ValidationWorkflowService } from "../../service/validation/validation-workflow.service"; import { WorkflowEditorComponent } from "./workflow-editor.component"; -import { NzModalCommentBoxComponent } from "./comment-box-modal/nz-modal-comment-box.component"; +import { workflowEditorTestImports, workflowEditorTestProviders } from "./workflow-editor.test-utils"; import { OperatorMetadataService } from "../../service/operator-metadata/operator-metadata.service"; import { StubOperatorMetadataService } from "../../service/operator-metadata/stub-operator-metadata.service"; import { JointUIService } from "../../service/joint-ui/joint-ui.service"; -import { NzModalModule, NzModalRef, NzModalService } from "ng-zorro-antd/modal"; +import { NzModalModule } from "ng-zorro-antd/modal"; import { Overlay } from "@angular/cdk/overlay"; import * as joint from "jointjs"; import { marbles } from "rxjs-marbles"; import { - mockCommentBox, mockPoint, mockResultPredicate, mockScanPredicate, @@ -46,24 +45,16 @@ import { OperatorState } from "../../types/execute-workflow.interface"; import { ExecuteWorkflowService } from "../../service/execute-workflow/execute-workflow.service"; import { HttpClientTestingModule } from "@angular/common/http/testing"; import { OperatorLink, OperatorPredicate } from "../../types/workflow-common.interface"; -import { NoopAnimationsModule } from "@angular/platform-browser/animations"; import { tap } from "rxjs/operators"; -import { UserService } from "src/app/common/service/user/user.service"; -import { StubUserService } from "src/app/common/service/user/stub-user.service"; import { WorkflowVersionService } from "../../../dashboard/service/user/workflow-version/workflow-version.service"; import { of } from "rxjs"; import { NzContextMenuService, NzDropDownModule } from "ng-zorro-antd/dropdown"; import { RouterTestingModule } from "@angular/router/testing"; -import { createYTypeFromObject } from "../../types/shared-editing.interface"; -import * as jQuery from "jquery"; import { ContextMenuComponent } from "./context-menu/context-menu/context-menu.component"; import { ComputingUnitStatusService } from "../../../common/service/computing-unit/computing-unit-status/computing-unit-status.service"; import { MockComputingUnitStatusService } from "../../../common/service/computing-unit/computing-unit-status/mock-computing-unit-status.service"; import { commonTestProviders } from "../../../common/testing/test-utils"; -const createJQueryEvent = (event: string, properties?: object): JQuery.Event => - (jQuery as unknown as JQueryStatic).Event(event, properties); - describe("WorkflowEditorComponent", () => { /** * This sub test suite test if the JointJS paper is integrated with our Angular component well. @@ -235,44 +226,13 @@ describe("WorkflowEditorComponent", () => { let validationWorkflowService: ValidationWorkflowService; let dragDropService: DragDropService; let jointUIService: JointUIService; - let nzModalService: NzModalService; let undoRedoService: UndoRedoService; let workflowVersionService: WorkflowVersionService; beforeEach(async () => { await TestBed.configureTestingModule({ - imports: [ - RouterTestingModule, - HttpClientTestingModule, - NzModalModule, - NzDropDownModule, - NoopAnimationsModule, - WorkflowEditorComponent, - NzModalCommentBoxComponent, - ], - providers: [ - JointUIService, - WorkflowUtilService, - WorkflowActionService, - UndoRedoService, - ValidationWorkflowService, - DragDropService, - NzModalService, - NzContextMenuService, - { - provide: OperatorMetadataService, - useClass: StubOperatorMetadataService, - }, - { - provide: UserService, - useClass: StubUserService, - }, - WorkflowStatusService, - ExecuteWorkflowService, - UndoRedoService, - WorkflowVersionService, - ...commonTestProviders, - ], + imports: workflowEditorTestImports, + providers: workflowEditorTestProviders, }).compileComponents(); }); @@ -285,114 +245,11 @@ describe("WorkflowEditorComponent", () => { dragDropService = TestBed.inject(DragDropService); // detect changes to run ngAfterViewInit and bind Model jointUIService = TestBed.inject(JointUIService); - nzModalService = TestBed.inject(NzModalService); undoRedoService = TestBed.inject(UndoRedoService); workflowVersionService = TestBed.inject(WorkflowVersionService); fixture.detectChanges(); }); - // TODO(#3614): the following four mouse/click-event tests rely on JointJS - // event paths that jsdom does not implement (HTMLCanvasElement.getContext, - // SVG hit-testing, jQuery .trigger("mousedown"/"dblclick") dispatch to - // JointJS cell views). They pass under the test-browser target - // (ng run gui:test-browser, real Chrome via Playwright) but fail under - // the default jsdom-based test runner. Commented out so the spec file - // can be included in the default test run; revive once a jsdom-compatible - // path or a runtime-targeted skip helper is available. - // it("should try to highlight the operator when user mouse clicks on an operator", () => { - // const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); - // // install a spy on the highlight operator function and pass the call through - // vi.spyOn(jointGraphWrapper, "highlightOperators"); - // workflowActionService.addOperator(mockScanPredicate, mockPoint); - // - // // unhighlight the operator in case it's automatically highlighted - // jointGraphWrapper.unhighlightOperators(mockScanPredicate.operatorID); - // - // // find the joint Cell View object of the operator element - // const jointCellView = component.paper.findViewByModel(mockScanPredicate.operatorID); - // jointCellView.$el.trigger("mousedown"); - // - // fixture.detectChanges(); - // - // // assert the function is called once - // // expect(highlightOperatorFunctionSpy.calls.count()).toEqual(1); - // // assert the highlighted operator is correct - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toEqual([mockScanPredicate.operatorID]); - // }); - // - // it("should highlight the commentBox when user clicks on a commentBox", () => { - // const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); - // vi.spyOn(jointGraphWrapper, "highlightCommentBoxes"); - // workflowActionService.addCommentBox(mockCommentBox); - // jointGraphWrapper.unhighlightCommentBoxes(mockCommentBox.commentBoxID); - // const jointCellView = component.paper.findViewByModel(mockCommentBox.commentBoxID); - // jointCellView.$el.trigger("mousedown"); - // fixture.detectChanges(); - // expect(jointGraphWrapper.getCurrentHighlightedCommentBoxIDs()).toEqual([mockCommentBox.commentBoxID]); - // }); - // - // it("should open commentBox as NzModal when user double clicks on a commentBox", () => { - // const modalRef: NzModalRef = nzModalService.create({ - // nzTitle: "CommentBox", - // nzContent: NzModalCommentBoxComponent, - // nzData: { commentBox: createYTypeFromObject(mockCommentBox) }, - // nzAutofocus: null, - // nzFooter: [ - // { - // label: "OK", - // onClick: () => { - // modalRef.destroy(); - // }, - // type: "primary", - // }, - // ], - // }); - // vi.spyOn(nzModalService, "create").mockReturnValue(modalRef); - // const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); - // workflowActionService.addCommentBox(mockCommentBox); - // jointGraphWrapper.highlightCommentBoxes(mockCommentBox.commentBoxID); - // const jointCellView = component.paper.findViewByModel(mockCommentBox.commentBoxID); - // jointCellView.$el.trigger("dblclick"); - // expect(nzModalService.create).toHaveBeenCalled(); - // fixture.detectChanges(); - // modalRef.destroy(); - // }); - // - // it("should unhighlight all highlighted operators when user mouse clicks on the blank space", () => { - // const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); - // - // // add and highlight two operators - // workflowActionService.addOperatorsAndLinks( - // [ - // { op: mockScanPredicate, pos: mockPoint }, - // { op: mockResultPredicate, pos: mockPoint }, - // ], - // [] - // ); - // jointGraphWrapper.highlightOperators(mockScanPredicate.operatorID, mockResultPredicate.operatorID); - // - // // assert that both operators are highlighted - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockScanPredicate.operatorID); - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockResultPredicate.operatorID); - // - // // find a blank area on the JointJS paper - // const blankPoint = { x: mockPoint.x + 100, y: mockPoint.y + 100 }; - // expect(component.paper.findViewsFromPoint(blankPoint)).toEqual([]); - // - // // trigger a click on the blank area using JointJS paper's jQuery element - // const point = component.paper.localToClientPoint(blankPoint); - // const event = createJQueryEvent("mousedown", { - // clientX: point.x, - // clientY: point.y, - // }); - // component.paper.$el.trigger(event); - // - // fixture.detectChanges(); - // - // // assert that all operators are unhighlighted - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toEqual([]); - // }); - it("should react to operator highlight event and change the appearance of the operator to be highlighted", () => { const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); workflowActionService.addOperator(mockScanPredicate, mockPoint); @@ -911,57 +768,6 @@ describe("WorkflowEditorComponent", () => { // } // }); - // TODO(#3614): the next two shift-click multi-select tests also depend on - // jsdom-incompatible JointJS event paths (see the earlier mouse-event - // block above). Passing under ng run gui:test-browser; commented out so - // the spec file can run under the default jsdom test target. - // it("should highlight multiple operators when user clicks on them with shift key pressed", () => { - // const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); - // - // workflowActionService.addOperator(mockScanPredicate, mockPoint); - // workflowActionService.addOperator(mockResultPredicate, mockPoint); - // jointGraphWrapper.highlightOperators(mockResultPredicate.operatorID); - // - // // assert that only the last operator is highlighted - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockResultPredicate.operatorID); - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).not.toContain(mockScanPredicate.operatorID); - // - // // find the joint Cell View object of the first operator element - // const jointCellView = component.paper.findViewByModel(mockScanPredicate.operatorID); - // - // // trigger a shift click on the cell view using its jQuery element - // const event = createJQueryEvent("mousedown", { shiftKey: true }); - // jointCellView.$el.trigger(event); - // - // fixture.detectChanges(); - // - // // assert that both operators are highlighted - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockScanPredicate.operatorID); - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockResultPredicate.operatorID); - // }); - // - // it("should unhighlight the highlighted operator when user clicks on it with shift key pressed", () => { - // const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); - // - // workflowActionService.addOperator(mockScanPredicate, mockPoint); - // jointGraphWrapper.highlightOperators(mockScanPredicate.operatorID); - // - // // assert that the operator is highlighted - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).toContain(mockScanPredicate.operatorID); - // - // // find the joint Cell View object of the operator element - // const jointCellView = component.paper.findViewByModel(mockScanPredicate.operatorID); - // - // // trigger a shift click on the cell view using its jQuery element - // const event = createJQueryEvent("mousedown", { shiftKey: true }); - // jointCellView.$el.trigger(event); - // - // fixture.detectChanges(); - // - // // assert that the operator is unhighlighted - // expect(jointGraphWrapper.getCurrentHighlightedOperatorIDs()).not.toContain(mockScanPredicate.operatorID); - // }); - it("should highlight all operators when user presses command + A", () => { const jointGraphWrapper = workflowActionService.getJointGraphWrapper(); diff --git a/frontend/src/app/workspace/component/workflow-editor/workflow-editor.test-utils.ts b/frontend/src/app/workspace/component/workflow-editor/workflow-editor.test-utils.ts new file mode 100644 index 0000000000..62f7962702 --- /dev/null +++ b/frontend/src/app/workspace/component/workflow-editor/workflow-editor.test-utils.ts @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Shared TestBed configuration for WorkflowEditorComponent specs. + * + * The workflow editor has two spec files that drive the same component: + * - workflow-editor.component.spec.ts (jsdom test target) + * - workflow-editor.component.browser.spec.ts (test-browser target, + * for JointJS event paths + * that need real DOM/SVG) + * + * Both specs configure TestBed with the same set of imports and + * providers. Exporting the two arrays here keeps them in lock-step so + * the two TestBed setups don't drift over time. + */ + +import { Provider } from "@angular/core"; +import { HttpClientTestingModule } from "@angular/common/http/testing"; +import { NoopAnimationsModule } from "@angular/platform-browser/animations"; +import { RouterTestingModule } from "@angular/router/testing"; +import { NzModalModule, NzModalService } from "ng-zorro-antd/modal"; +import { NzContextMenuService, NzDropDownModule } from "ng-zorro-antd/dropdown"; + +import { WorkflowEditorComponent } from "./workflow-editor.component"; +import { NzModalCommentBoxComponent } from "./comment-box-modal/nz-modal-comment-box.component"; + +import { WorkflowActionService } from "../../service/workflow-graph/model/workflow-action.service"; +import { WorkflowUtilService } from "../../service/workflow-graph/util/workflow-util.service"; +import { UndoRedoService } from "../../service/undo-redo/undo-redo.service"; +import { DragDropService } from "../../service/drag-drop/drag-drop.service"; +import { ValidationWorkflowService } from "../../service/validation/validation-workflow.service"; +import { OperatorMetadataService } from "../../service/operator-metadata/operator-metadata.service"; +import { StubOperatorMetadataService } from "../../service/operator-metadata/stub-operator-metadata.service"; +import { JointUIService } from "../../service/joint-ui/joint-ui.service"; +import { WorkflowStatusService } from "../../service/workflow-status/workflow-status.service"; +import { ExecuteWorkflowService } from "../../service/execute-workflow/execute-workflow.service"; +import { WorkflowVersionService } from "../../../dashboard/service/user/workflow-version/workflow-version.service"; +import { UserService } from "src/app/common/service/user/user.service"; +import { StubUserService } from "src/app/common/service/user/stub-user.service"; +import { commonTestProviders } from "../../../common/testing/test-utils"; + +export const workflowEditorTestImports = [ + RouterTestingModule, + HttpClientTestingModule, + NzModalModule, + NzDropDownModule, + NoopAnimationsModule, + WorkflowEditorComponent, + NzModalCommentBoxComponent, +]; + +export const workflowEditorTestProviders: Provider[] = [ + JointUIService, + WorkflowUtilService, + WorkflowActionService, + UndoRedoService, + ValidationWorkflowService, + DragDropService, + NzModalService, + NzContextMenuService, + { provide: OperatorMetadataService, useClass: StubOperatorMetadataService }, + { provide: UserService, useClass: StubUserService }, + WorkflowStatusService, + ExecuteWorkflowService, + WorkflowVersionService, + ...commonTestProviders, +];
