This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git

commit 16b917c4538c7772c223d26047a1e0233648f419
Author: Matthew B. <[email protected]>
AuthorDate: Thu Jul 16 22:21:59 2026 -0700

    test(frontend): add unit tests for ComputingUnitActionsService (#6468)
    
    ### What changes were proposed in this PR?
    - Adds computing-unit-actions.service.spec.ts covering
    ComputingUnitActionsService; no production code changed.
    - Verifies create routing (kubernetes/local) and that an unsupported
    type throws.
    - Covers the share-access modal config and the terminate confirmation
    flow (invalid unit, confirm, success and failure notifications).
    ### Any related issues, documentation, discussions?
    Closes: #6456
    ### How was this PR tested?
    - Run `cd frontend && npx nx test gui
    --include="**/computing-unit-actions.service.spec.ts"`, expect 10
    passed.
    - Full frontend suite runs in CI via `yarn test:ci`, selected by the
    auto-applied `frontend` label.
    ### Was this PR authored or co-authored using generative AI tooling?
    Co-authored with Claude Opus 4.8 in compliance with ASF
---
 .../computing-unit-actions.service.spec.ts         | 161 +++++++++++++++++++++
 1 file changed, 161 insertions(+)

diff --git 
a/frontend/src/app/common/service/computing-unit/computing-unit-actions/computing-unit-actions.service.spec.ts
 
b/frontend/src/app/common/service/computing-unit/computing-unit-actions/computing-unit-actions.service.spec.ts
new file mode 100644
index 0000000000..fe208457a4
--- /dev/null
+++ 
b/frontend/src/app/common/service/computing-unit/computing-unit-actions/computing-unit-actions.service.spec.ts
@@ -0,0 +1,161 @@
+/**
+ * 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.
+ */
+
+import { TestBed } from "@angular/core/testing";
+import { of, throwError } from "rxjs";
+import { NzModalService } from "ng-zorro-antd/modal";
+import { ComputingUnitActionsService, StartComputingUnitRequest } from 
"./computing-unit-actions.service";
+import { WorkflowComputingUnitManagingService } from 
"../workflow-computing-unit/workflow-computing-unit-managing.service";
+import { NotificationService } from "../../notification/notification.service";
+import { ComputingUnitStatusService } from 
"../computing-unit-status/computing-unit-status.service";
+
+describe("ComputingUnitActionsService", () => {
+  let service: ComputingUnitActionsService;
+  let modalService: { create: ReturnType<typeof vi.fn>; confirm: 
ReturnType<typeof vi.fn> };
+  let computingUnitService: {
+    createKubernetesBasedComputingUnit: ReturnType<typeof vi.fn>;
+    createLocalComputingUnit: ReturnType<typeof vi.fn>;
+  };
+  let notificationService: { error: ReturnType<typeof vi.fn>; success: 
ReturnType<typeof vi.fn> };
+  let statusService: { terminateComputingUnit: ReturnType<typeof vi.fn> };
+
+  const baseRequest: StartComputingUnitRequest = {
+    type: "kubernetes",
+    name: "unit",
+    cpu: "2",
+    memory: "4G",
+    gpu: "1",
+    jvmMemorySize: "1G",
+    shmSize: "64M",
+    localUri: "http://localhost:8080";,
+  };
+
+  beforeEach(() => {
+    modalService = { create: vi.fn(), confirm: vi.fn() };
+    computingUnitService = {
+      createKubernetesBasedComputingUnit: vi.fn().mockReturnValue(of({} as 
any)),
+      createLocalComputingUnit: vi.fn().mockReturnValue(of({} as any)),
+    };
+    notificationService = { error: vi.fn(), success: vi.fn() };
+    statusService = { terminateComputingUnit: 
vi.fn().mockReturnValue(of(true)) };
+
+    TestBed.configureTestingModule({
+      providers: [
+        ComputingUnitActionsService,
+        { provide: NzModalService, useValue: modalService },
+        { provide: WorkflowComputingUnitManagingService, useValue: 
computingUnitService },
+        { provide: NotificationService, useValue: notificationService },
+        { provide: ComputingUnitStatusService, useValue: statusService },
+      ],
+    });
+    service = TestBed.inject(ComputingUnitActionsService);
+  });
+
+  it("should be created", () => {
+    expect(service).toBeTruthy();
+  });
+
+  describe("create", () => {
+    it("routes a kubernetes request to createKubernetesBasedComputingUnit", () 
=> {
+      service.create({ ...baseRequest, type: "kubernetes" });
+
+      
expect(computingUnitService.createKubernetesBasedComputingUnit).toHaveBeenCalledWith(
+        "unit",
+        "2",
+        "4G",
+        "1",
+        "1G",
+        "64M"
+      );
+      
expect(computingUnitService.createLocalComputingUnit).not.toHaveBeenCalled();
+    });
+
+    it("routes a local request to createLocalComputingUnit with name and 
localUri", () => {
+      service.create({ ...baseRequest, type: "local" });
+
+      
expect(computingUnitService.createLocalComputingUnit).toHaveBeenCalledWith("unit",
 "http://localhost:8080";);
+    });
+
+    it("throws for an unsupported computing unit type", () => {
+      expect(() => service.create({ ...baseRequest, type: "quantum" as any 
})).toThrowError(
+        "Unsupported computing unit type"
+      );
+    });
+  });
+
+  describe("openShareAccessModal", () => {
+    it("opens the share modal seeded with the computing unit id and workspace 
flag", () => {
+      service.openShareAccessModal(55, false);
+
+      expect(modalService.create).toHaveBeenCalledTimes(1);
+      const config = modalService.create.mock.calls[0][0];
+      expect(config.nzData).toMatchObject({ type: "computing-unit", id: 55, 
inWorkspace: false, writeAccess: true });
+    });
+
+    it("defaults inWorkspace to true", () => {
+      service.openShareAccessModal(1);
+      
expect(modalService.create.mock.calls[0][0].nzData.inWorkspace).toBe(true);
+    });
+  });
+
+  describe("confirmAndTerminate", () => {
+    const unit = (overrides: any = {}) =>
+      ({ computingUnit: { uri: "http://x";, name: "unit1", type: "kubernetes", 
...overrides } }) as any;
+
+    it("errors and skips the modal when the unit has no uri", () => {
+      service.confirmAndTerminate(1, unit({ uri: "" }));
+
+      expect(notificationService.error).toHaveBeenCalledWith("Invalid 
computing unit.");
+      expect(modalService.confirm).not.toHaveBeenCalled();
+    });
+
+    it("opens a confirmation modal for a valid unit", () => {
+      service.confirmAndTerminate(1, unit());
+      expect(modalService.confirm).toHaveBeenCalledTimes(1);
+    });
+
+    it("notifies success when the confirmed termination succeeds", () => {
+      statusService.terminateComputingUnit.mockReturnValue(of(true));
+      service.confirmAndTerminate(7, unit());
+
+      modalService.confirm.mock.calls[0][0].nzOnOk();
+
+      expect(statusService.terminateComputingUnit).toHaveBeenCalledWith(7);
+      expect(notificationService.success).toHaveBeenCalledWith("Terminated 
Computing Unit: unit1");
+    });
+
+    it("notifies an error when the confirmed termination reports failure", () 
=> {
+      statusService.terminateComputingUnit.mockReturnValue(of(false));
+      service.confirmAndTerminate(7, unit());
+
+      modalService.confirm.mock.calls[0][0].nzOnOk();
+
+      expect(notificationService.error).toHaveBeenCalledWith("Failed to 
terminate computing unit");
+    });
+
+    it("notifies an error with the extracted message when the termination 
observable errors", () => {
+      statusService.terminateComputingUnit.mockReturnValue(throwError(() => 
new Error("kaboom")));
+      service.confirmAndTerminate(7, unit());
+
+      modalService.confirm.mock.calls[0][0].nzOnOk();
+
+      expect(notificationService.error).toHaveBeenCalledWith("Failed to 
terminate computing unit: kaboom");
+    });
+  });
+});

Reply via email to