You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@texera.apache.org by "aglinxinyuan (via GitHub)" <gi...@apache.org> on 2026/07/22 06:22:22 UTC
[PR] test(frontend): extend CardItemComponent unit test coverage [texera]
aglinxinyuan opened a new pull request, #6780:
URL: https://github.com/apache/texera/pull/6780
### What changes were proposed in this PR?
Extends `card-item.component.spec.ts` for `CardItemComponent`, covering the entry-type render branches and the open/duplicate/delete/share/like action handlers, including the workflow and dataset share-access modal flows (with the modal `refresh` stream). Coverage 83% -> high. No existing tests modified.
### Any related issues, documentation, discussions?
Closes #6774.
### How was this PR tested?
`ng test --include='**/card-item.component.spec.ts'` -> 64/64 passing. `yarn format:ci` passes.
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Opus 4.8 [1M context])
--
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: notifications-unsubscribe@texera.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] test(frontend): extend CardItemComponent unit test coverage [texera]
Posted by "aglinxinyuan (via GitHub)" <gi...@apache.org>.
aglinxinyuan merged PR #6780:
URL: https://github.com/apache/texera/pull/6780
--
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: notifications-unsubscribe@texera.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] test(frontend): extend CardItemComponent unit test coverage [texera]
Posted by "Copilot (via GitHub)" <gi...@apache.org>.
Copilot commented on code in PR #6780:
URL: https://github.com/apache/texera/pull/6780#discussion_r3627943053
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
Review Comment:
This test reaches into the component’s private `_entry` field, which couples the spec to an implementation detail. Prefer using the public setter with an `any` cast so the test only depends on the public `entry` API.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
Review Comment:
This test spies on a constructor-injected private field via `(component as any).downloadService`, which makes the spec brittle to refactors. Prefer injecting the service from the TestBed and spying on that instance.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, workflow: { name: "myflow" } } } as any);
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).toHaveBeenCalledWith(7, "myflow");
+ });
+
+ it("onClickDownload downloads a dataset via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset").mockReturnValue(of(new Blob()));
Review Comment:
Same as above: avoid accessing the component’s private `downloadService` field; inject `DownloadService` from the TestBed to spy on its methods.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, workflow: { name: "myflow" } } } as any);
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).toHaveBeenCalledWith(7, "myflow");
+ });
+
+ it("onClickDownload downloads a dataset via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset").mockReturnValue(of(new Blob()));
+ component.entry = makeDatasetEntry({ id: 5, name: "mydataset", coverImageUrl: undefined });
+
+ component.onClickDownload();
+
+ expect(downloadDatasetSpy).toHaveBeenCalledWith(5, "mydataset");
+ });
+
+ it("onClickDownload is a no-op when the entry has no id", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow");
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset");
+ component.entry = makeWorkflowEntry({ id: undefined });
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).not.toHaveBeenCalled();
+ expect(downloadDatasetSpy).not.toHaveBeenCalled();
+ });
+
+ it("onClickOpenShareAccess opens the workflow share modal and forwards refresh events", async () => {
+ const modalService = TestBed.inject(NzModalService);
+ const refresh$ = new Subject<void>();
+ const createSpy = vi
+ .spyOn(modalService, "create")
+ .mockReturnValue({ componentInstance: { refresh: refresh$ } } as any);
+ (workflowPersistService as any).retrieveOwners = vi.fn().mockReturnValue(of(["alice", "bob"]));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, accessLevel: "WRITE" } } as any);
+
+ await component.onClickOpenShareAccess();
+
+ expect(createSpy).toHaveBeenCalledTimes(1);
+ const cfg = createSpy.mock.calls[0][0];
+ expect(cfg.nzData).toEqual({
+ writeAccess: true,
+ type: "workflow",
+ id: 7,
+ allOwners: ["alice", "bob"],
+ inWorkspace: false,
+ });
+ expect(cfg.nzTitle).toBe("Share this workflow with others");
+
+ const refreshSpy = vi.fn();
+ component.refresh.subscribe(refreshSpy);
+ refresh$.next();
+ expect(refreshSpy).toHaveBeenCalledTimes(1);
Review Comment:
The test subscribes to `component.refresh` but never unsubscribes; over a growing suite this can contribute to retained references and harder-to-debug leaks. Capture the subscription and unsubscribe after the assertion.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, workflow: { name: "myflow" } } } as any);
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).toHaveBeenCalledWith(7, "myflow");
+ });
+
+ it("onClickDownload downloads a dataset via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset").mockReturnValue(of(new Blob()));
+ component.entry = makeDatasetEntry({ id: 5, name: "mydataset", coverImageUrl: undefined });
+
+ component.onClickDownload();
+
+ expect(downloadDatasetSpy).toHaveBeenCalledWith(5, "mydataset");
+ });
+
+ it("onClickDownload is a no-op when the entry has no id", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow");
Review Comment:
Same as above: spy on `DownloadService` via `TestBed.inject(...)` rather than reaching into a private field on the component.
--
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: notifications-unsubscribe@texera.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] test(frontend): extend CardItemComponent unit test coverage [texera]
Posted by "aglinxinyuan (via GitHub)" <gi...@apache.org>.
aglinxinyuan closed pull request #6780: test(frontend): extend CardItemComponent unit test coverage
URL: https://github.com/apache/texera/pull/6780
--
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: notifications-unsubscribe@texera.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] test(frontend): extend CardItemComponent unit test coverage [texera]
Posted by "aglinxinyuan (via GitHub)" <gi...@apache.org>.
aglinxinyuan commented on code in PR #6780:
URL: https://github.com/apache/texera/pull/6780#discussion_r3628043700
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
Review Comment:
Fixed — now uses the public setter (component.entry = undefined as any) instead of the private _entry field.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
Review Comment:
Fixed — the three download tests now spy on TestBed.inject(DownloadService) (providedIn root, same instance) instead of the component's private downloadService field.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, workflow: { name: "myflow" } } } as any);
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).toHaveBeenCalledWith(7, "myflow");
+ });
+
+ it("onClickDownload downloads a dataset via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset").mockReturnValue(of(new Blob()));
Review Comment:
Fixed — spies on TestBed.inject(DownloadService) now.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, workflow: { name: "myflow" } } } as any);
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).toHaveBeenCalledWith(7, "myflow");
+ });
+
+ it("onClickDownload downloads a dataset via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset").mockReturnValue(of(new Blob()));
+ component.entry = makeDatasetEntry({ id: 5, name: "mydataset", coverImageUrl: undefined });
+
+ component.onClickDownload();
+
+ expect(downloadDatasetSpy).toHaveBeenCalledWith(5, "mydataset");
+ });
+
+ it("onClickDownload is a no-op when the entry has no id", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow");
Review Comment:
Fixed — spies on TestBed.inject(DownloadService) now.
##########
frontend/src/app/dashboard/component/user/list-item/card-item/card-item.component.spec.ts:
##########
@@ -635,4 +645,252 @@ describe("CardItemComponent", () => {
expect(postLikeSpy).not.toHaveBeenCalled();
});
+
+ describe("extended coverage", () => {
+ it("entry getter throws when no entry has been provided", () => {
+ (component as any)._entry = undefined;
+ expect(() => component.entry).toThrow("entry property must be provided.");
+ });
+
+ it("initializeEntry routes an owning dataset user to the user dataset view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: true },
+ accessibleUserIds: [42],
+ coverImageUrl: undefined, // skips the cover fetch
+ size: 55,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([USER_DATASET, "5"]);
+ expect(component.iconType).toBe("database");
+ expect(component.disableDelete).toBe(false); // owner
+ expect(component.size).toBe(55);
+ });
+
+ it("initializeEntry routes a non-owning dataset user to the hub dataset detail view", () => {
+ component.currentUid = 42;
+ component.entry = makeDatasetEntry({
+ id: 5,
+ dataset: { isOwner: false },
+ accessibleUserIds: [99],
+ coverImageUrl: undefined,
+ } as any);
+
+ component.initializeEntry();
+
+ expect(component.entryLink).toEqual([HUB_DATASET_RESULT_DETAIL, "5"]);
+ expect(component.disableDelete).toBe(true); // !isOwner
+ });
+
+ it("onClickDownload downloads a workflow via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow").mockReturnValue(of({} as any));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, workflow: { name: "myflow" } } } as any);
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).toHaveBeenCalledWith(7, "myflow");
+ });
+
+ it("onClickDownload downloads a dataset via the download service", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset").mockReturnValue(of(new Blob()));
+ component.entry = makeDatasetEntry({ id: 5, name: "mydataset", coverImageUrl: undefined });
+
+ component.onClickDownload();
+
+ expect(downloadDatasetSpy).toHaveBeenCalledWith(5, "mydataset");
+ });
+
+ it("onClickDownload is a no-op when the entry has no id", () => {
+ const downloadService = (component as any).downloadService as DownloadService;
+ const downloadWorkflowSpy = vi.spyOn(downloadService, "downloadWorkflow");
+ const downloadDatasetSpy = vi.spyOn(downloadService, "downloadDataset");
+ component.entry = makeWorkflowEntry({ id: undefined });
+
+ component.onClickDownload();
+
+ expect(downloadWorkflowSpy).not.toHaveBeenCalled();
+ expect(downloadDatasetSpy).not.toHaveBeenCalled();
+ });
+
+ it("onClickOpenShareAccess opens the workflow share modal and forwards refresh events", async () => {
+ const modalService = TestBed.inject(NzModalService);
+ const refresh$ = new Subject<void>();
+ const createSpy = vi
+ .spyOn(modalService, "create")
+ .mockReturnValue({ componentInstance: { refresh: refresh$ } } as any);
+ (workflowPersistService as any).retrieveOwners = vi.fn().mockReturnValue(of(["alice", "bob"]));
+ component.entry = makeWorkflowEntry({ id: 7, workflow: { isOwner: true, accessLevel: "WRITE" } } as any);
+
+ await component.onClickOpenShareAccess();
+
+ expect(createSpy).toHaveBeenCalledTimes(1);
+ const cfg = createSpy.mock.calls[0][0];
+ expect(cfg.nzData).toEqual({
+ writeAccess: true,
+ type: "workflow",
+ id: 7,
+ allOwners: ["alice", "bob"],
+ inWorkspace: false,
+ });
+ expect(cfg.nzTitle).toBe("Share this workflow with others");
+
+ const refreshSpy = vi.fn();
+ component.refresh.subscribe(refreshSpy);
+ refresh$.next();
+ expect(refreshSpy).toHaveBeenCalledTimes(1);
Review Comment:
Fixed — the refresh subscription is now captured and unsubscribed after the assertion.
--
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: notifications-unsubscribe@texera.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] test(frontend): extend CardItemComponent unit test coverage [texera]
Posted by "codecov-commenter (via GitHub)" <gi...@apache.org>.
codecov-commenter commented on PR #6780:
URL: https://github.com/apache/texera/pull/6780#issuecomment-5043497658
## [Codecov](https://app.codecov.io/gh/apache/texera/pull/6780?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 75.12%. Comparing base ([`a9f384e`](https://app.codecov.io/gh/apache/texera/commit/a9f384eab44c8e1595792e02b32c2c1bfc16e77e?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`3a86c50`](https://app.codecov.io/gh/apache/texera/commit/3a86c50bbcd483e6190256ebca8d2525d0d28885?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
:white_check_mark: All tests successful. No failed tests found.
<details><summary>Additional details and impacted files</summary>
```diff
@@ Coverage Diff @@
## main #6780 +/- ##
============================================
- Coverage 75.20% 75.12% -0.09%
- Complexity 3446 3449 +3
============================================
Files 1160 1160
Lines 45807 45807
Branches 5071 5071
============================================
- Hits 34449 34412 -37
- Misses 9746 9777 +31
- Partials 1612 1618 +6
```
| [Flag](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | | *Carryforward flag |
|---|---|---|---|
| [access-control-service](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `70.00% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [agent-service](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `76.76% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [amber](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `67.19% <ø> (+0.02%)` | :arrow_up: | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [computing-unit-managing-service](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `20.49% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [config-service](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `66.66% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [file-service](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `67.21% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [frontend](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `79.22% <ø> (-0.21%)` | :arrow_down: | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [notebook-migration-service](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `78.94% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [pyamber](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `92.15% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
| [workflow-compiling-service](https://app.codecov.io/gh/apache/texera/pull/6780/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `55.14% <ø> (ø)` | | Carriedforward from [9a6af68](https://app.codecov.io/gh/apache/texera/commit/9a6af689468679b6d99905e834f836270ffb3986?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
*This pull request uses carry forward flags. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) to find out more.
</details>
[:umbrella: View full report in Codecov by Harness](https://app.codecov.io/gh/apache/texera/pull/6780?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
<details><summary> :rocket: New features to boost your workflow: </summary>
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
--
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: notifications-unsubscribe@texera.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] test(frontend): extend CardItemComponent unit test coverage [texera]
Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #6780:
URL: https://github.com/apache/texera/pull/6780#issuecomment-5042592569
<!-- texera-reviewer-suggestion -->
### Automated Reviewer Suggestions
Based on the `git blame` history of the changed files, we recommend the following reviewers:
- **Contributors with relevant context:** `@mengw15`
You can notify them by mentioning `@mengw15` in a comment.
--
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: notifications-unsubscribe@texera.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org