aglinxinyuan commented on code in PR #6783:
URL: https://github.com/apache/texera/pull/6783#discussion_r3628045242
##########
frontend/src/app/dashboard/component/user/user-computing-unit/user-computing-unit-list-item/user-computing-unit-list-item.component.spec.ts:
##########
@@ -289,4 +310,183 @@ describe("UserComputingUnitListItemComponent", () => {
expect(component.showGpuSelection()).toBe(true);
});
});
+
+ describe("ngOnInit gpuOptions fallback", () => {
+ it("defaults gpuOptions to an empty array when the service omits
gpuLimitOptions", () => {
+ computingUnitService.getComputingUnitLimitOptions.mockReturnValue(
+ of({ cpuLimitOptions: [], memoryLimitOptions: [], gpuLimitOptions:
undefined as unknown as string[] })
+ );
+ const freshFixture =
TestBed.createComponent(UserComputingUnitListItemComponent);
+ freshFixture.componentInstance.entry = makeEntry();
+ freshFixture.detectChanges();
+ expect(freshFixture.componentInstance.gpuOptions).toEqual([]);
+ freshFixture.destroy();
+ });
+ });
+
+ describe("startEditingUnitName focus behavior", () => {
+ it("focuses and selects the rendered input after the timeout fires", () =>
{
+ const host = fixture.nativeElement as HTMLElement;
+ document.body.appendChild(host);
+ const focusSpy = vi.spyOn(HTMLInputElement.prototype,
"focus").mockImplementation(() => {});
+ const selectSpy = vi.spyOn(HTMLInputElement.prototype,
"select").mockImplementation(() => {});
+ vi.useFakeTimers();
+ try {
+ component.startEditingUnitName(makeEntry());
+ // The editable input is rendered synchronously via
cdr.detectChanges().
+ const input = document.querySelector(".unit-name-edit-input");
+ expect(input).toBeTruthy();
+ // The focus/select happen inside a setTimeout(0) callback.
Review Comment:
Fixed — the query is now scoped to (fixture.nativeElement as
HTMLElement).querySelector(...) so it can't match another fixture's input.
##########
frontend/src/app/dashboard/component/user/user-computing-unit/user-computing-unit-list-item/user-computing-unit-list-item.component.spec.ts:
##########
@@ -289,4 +310,183 @@ describe("UserComputingUnitListItemComponent", () => {
expect(component.showGpuSelection()).toBe(true);
});
});
+
+ describe("ngOnInit gpuOptions fallback", () => {
+ it("defaults gpuOptions to an empty array when the service omits
gpuLimitOptions", () => {
+ computingUnitService.getComputingUnitLimitOptions.mockReturnValue(
+ of({ cpuLimitOptions: [], memoryLimitOptions: [], gpuLimitOptions:
undefined as unknown as string[] })
+ );
+ const freshFixture =
TestBed.createComponent(UserComputingUnitListItemComponent);
+ freshFixture.componentInstance.entry = makeEntry();
+ freshFixture.detectChanges();
+ expect(freshFixture.componentInstance.gpuOptions).toEqual([]);
+ freshFixture.destroy();
+ });
+ });
+
+ describe("startEditingUnitName focus behavior", () => {
+ it("focuses and selects the rendered input after the timeout fires", () =>
{
+ const host = fixture.nativeElement as HTMLElement;
+ document.body.appendChild(host);
+ const focusSpy = vi.spyOn(HTMLInputElement.prototype,
"focus").mockImplementation(() => {});
+ const selectSpy = vi.spyOn(HTMLInputElement.prototype,
"select").mockImplementation(() => {});
+ vi.useFakeTimers();
+ try {
+ component.startEditingUnitName(makeEntry());
+ // The editable input is rendered synchronously via
cdr.detectChanges().
+ const input = document.querySelector(".unit-name-edit-input");
+ expect(input).toBeTruthy();
+ // The focus/select happen inside a setTimeout(0) callback.
+ expect(focusSpy).not.toHaveBeenCalled();
+ vi.advanceTimersByTime(1);
+ expect(focusSpy).toHaveBeenCalledTimes(1);
+ expect(selectSpy).toHaveBeenCalledTimes(1);
+ } finally {
+ host.remove();
+ }
+ });
+ });
+
+ describe("openComputingUnitMetadataModal", () => {
+ it("opens the metadata modal with the expected configuration", () => {
+ const modalService = TestBed.inject(NzModalService);
+ const createSpy = vi.spyOn(modalService, "create").mockReturnValue({} as
any);
+ const entry = makeEntry();
+
+ component.openComputingUnitMetadataModal(entry);
+
+ expect(createSpy).toHaveBeenCalledTimes(1);
+ expect(createSpy).toHaveBeenCalledWith(
+ expect.objectContaining({
+ nzTitle: "Computing Unit Information",
+ nzContent: ComputingUnitMetadataComponent,
+ nzData: entry,
+ nzFooter: null,
+ nzMaskClosable: true,
+ nzWidth: "600px",
+ })
+ );
+ });
+ });
+
+ describe("status and label computations", () => {
+ it("delegates badge color to the status util", () => {
+ expect(component.getBadgeColor("Running")).toBe("green");
+ expect(component.getBadgeColor("Pending")).toBe("gold");
+ expect(component.getBadgeColor("Terminated")).toBe("red");
+ });
+
+ it("delegates the status tooltip to the status util", () => {
+ expect(component.getUnitStatusTooltip(makeEntry({ status: "Running"
}))).toBe("Ready to use");
+ expect(component.getUnitStatusTooltip(makeEntry({ status: "Pending"
}))).toBe("Computing unit is starting up");
+ const terminated = {
+ ...makeEntry(),
+ status: "Terminated" as unknown as
DashboardWorkflowComputingUnit["status"],
+ };
+ expect(component.getUnitStatusTooltip(terminated)).toBe("Terminated");
+ });
+
+ it("computes CPU/memory percentages and maps them to progress statuses
under heavy load", () => {
+ component.entry = makeEntry({
+ metrics: { cpuUsage: "950m", memoryUsage: "950Mi" },
+ });
+ expect(component.getCpuPercentage()).toBeCloseTo(95, 1);
+ expect(component.getMemoryPercentage()).toBeCloseTo(92.77, 1);
+ expect(component.getCpuStatus()).toBe("exception");
+ expect(component.getMemoryStatus()).toBe("exception");
+ });
+
+ it("reports success statuses when there are no metrics", () => {
Review Comment:
Fixed — renamed to reflect that it exercises the default entry's N/A
(unavailable) metrics yielding 0% and success statuses.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]