Merge branch '21221-groups-panel-member-count' into main. Closes #21221
[arvados.git] / services / workbench2 / src / store / groups-panel / groups-panel-middleware-service.test.ts
diff --git a/services/workbench2/src/store/groups-panel/groups-panel-middleware-service.test.ts b/services/workbench2/src/store/groups-panel/groups-panel-middleware-service.test.ts
new file mode 100644 (file)
index 0000000..42d88a9
--- /dev/null
@@ -0,0 +1,160 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import Axios, { AxiosInstance, AxiosResponse } from "axios";
+import { mockConfig } from "common/config";
+import { createBrowserHistory } from "history";
+import { GroupsPanelMiddlewareService } from "./groups-panel-middleware-service";
+import { dataExplorerMiddleware } from "store/data-explorer/data-explorer-middleware";
+import { Dispatch, MiddlewareAPI } from "redux";
+import { DataColumns } from "components/data-table/data-table";
+import { dataExplorerActions } from "store/data-explorer/data-explorer-action";
+import { SortDirection } from "components/data-table/data-column";
+import { createTree } from 'models/tree';
+import { DataTableFilterItem } from "components/data-table-filters/data-table-filters-tree";
+import { GROUPS_PANEL_ID } from "./groups-panel-actions";
+import { RootState, RootStore, configureStore } from "store/store";
+import { ServiceRepository, createServices } from "services/services";
+import { ApiActions } from "services/api/api-actions";
+import { ListResults } from "services/common-service/common-service";
+import { GroupResource } from "models/group";
+import { getResource } from "store/resources/resources";
+
+describe("GroupsPanelMiddlewareService", () => {
+    let axiosInst: AxiosInstance;
+    let store: RootStore;
+    let services: ServiceRepository;
+    const config: any = {};
+    const actions: ApiActions = {
+        progressFn: (id: string, working: boolean) => { },
+        errorFn: (id: string, message: string) => { }
+    };
+
+    beforeEach(() => {
+        axiosInst = Axios.create({ headers: {} });
+        services = createServices(mockConfig({}), actions, axiosInst);
+        store = configureStore(createBrowserHistory(), services, config);
+    });
+
+    it("requests group member counts and updates resource store", async () => {
+        // Given
+        const fakeUuid = "zzzzz-j7d0g-000000000000000";
+        axiosInst.get = jest.fn((url: string) => {
+            if (url === '/groups') {
+                return Promise.resolve(
+                    { data: {
+                        kind: "",
+                        offset: 0,
+                        limit: 100,
+                        items: [{
+                            can_manage: true,
+                            can_write: true,
+                            created_at: "2023-11-15T20:57:01.723043000Z",
+                            delete_at: null,
+                            description: null,
+                            etag: "0000000000000000000000000",
+                            frozen_by_uuid: null,
+                            group_class: "role",
+                            href: `/groups/${fakeUuid}`,
+                            is_trashed: false,
+                            kind: "arvados#group",
+                            modified_at: "2023-11-15T20:57:01.719986000Z",
+                            modified_by_client_uuid: null,
+                            modified_by_user_uuid: "zzzzz-tpzed-000000000000000",
+                            name: "Test Group",
+                            owner_uuid: "zzzzz-tpzed-000000000000000",
+                            properties: {},
+                            trash_at: null,
+                            uuid: fakeUuid,
+                            writable_by: [
+                                "zzzzz-tpzed-000000000000000",
+                            ]
+                        }],
+                        items_available: 1,
+                    }} as AxiosResponse);
+            } else if (url === '/links') {
+                return Promise.resolve(
+                    { data: {
+                        items: [],
+                        items_available: 234,
+                        kind: "arvados#linkList",
+                        limit: 0,
+                        offset: 0
+                    }} as AxiosResponse);
+            } else {
+                return Promise.resolve(
+                    { data: {}} as AxiosResponse);
+            }
+        });
+
+        // When
+        await store.dispatch(dataExplorerActions.REQUEST_ITEMS({id: GROUPS_PANEL_ID}));
+        // Wait for async fetching of group count promises to resolve
+        await new Promise(setImmediate);
+
+        // Expect
+        expect(axiosInst.get).toHaveBeenCalledTimes(2);
+        expect(axiosInst.get).toHaveBeenCalledWith('/groups', expect.anything());
+        expect(axiosInst.get).toHaveBeenCalledWith('/links', expect.anything());
+        const group = getResource<GroupResource>(fakeUuid)(store.getState().resources);
+        expect(group?.memberCount).toBe(234);
+    });
+
+    it('requests group member count and stores null on failure', async () => {
+        // Given
+        const fakeUuid = "zzzzz-j7d0g-000000000000000";
+        axiosInst.get = jest.fn((url: string) => {
+            if (url === '/groups') {
+                return Promise.resolve(
+                    { data: {
+                        kind: "",
+                        offset: 0,
+                        limit: 100,
+                        items: [{
+                            can_manage: true,
+                            can_write: true,
+                            created_at: "2023-11-15T20:57:01.723043000Z",
+                            delete_at: null,
+                            description: null,
+                            etag: "0000000000000000000000000",
+                            frozen_by_uuid: null,
+                            group_class: "role",
+                            href: `/groups/${fakeUuid}`,
+                            is_trashed: false,
+                            kind: "arvados#group",
+                            modified_at: "2023-11-15T20:57:01.719986000Z",
+                            modified_by_client_uuid: null,
+                            modified_by_user_uuid: "zzzzz-tpzed-000000000000000",
+                            name: "Test Group",
+                            owner_uuid: "zzzzz-tpzed-000000000000000",
+                            properties: {},
+                            trash_at: null,
+                            uuid: fakeUuid,
+                            writable_by: [
+                                "zzzzz-tpzed-000000000000000",
+                            ]
+                        }],
+                        items_available: 1,
+                    }} as AxiosResponse);
+            } else if (url === '/links') {
+                return Promise.reject();
+            } else {
+                return Promise.resolve({ data: {}} as AxiosResponse);
+            }
+        });
+
+        // When
+        await store.dispatch(dataExplorerActions.REQUEST_ITEMS({id: GROUPS_PANEL_ID}));
+        // Wait for async fetching of group count promises to resolve
+        await new Promise(setImmediate);
+
+        // Expect
+        expect(axiosInst.get).toHaveBeenCalledTimes(2);
+        expect(axiosInst.get).toHaveBeenCalledWith('/groups', expect.anything());
+        expect(axiosInst.get).toHaveBeenCalledWith('/links', expect.anything());
+        const group = getResource<GroupResource>(fakeUuid)(store.getState().resources);
+        expect(group?.memberCount).toBe(null);
+    });
+
+});