Merge branch '17426-plug-ins' refs #17426
[arvados-workbench2.git] / src / store / context-menu / context-menu-actions.test.ts
index c3e78679278f69783ff5c7a055da5def03217729..36976336a8f7d1409f18db7ea3a228fbbaa8920e 100644 (file)
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import * as resource from '~/models/resource';
 import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
-import { resourceKindToContextMenuKind } from './context-menu-actions';
+import { resourceUuidToContextMenuKind } from './context-menu-actions';
+import configureStore from 'redux-mock-store';
+import thunk from 'redux-thunk';
+import { PROJECT_PANEL_CURRENT_UUID } from '../project-panel/project-panel-action';
+import { GroupClass } from '~/models/group';
 
 describe('context-menu-actions', () => {
-    describe('resourceKindToContextMenuKind', () => {
-        const uuid = '123';
-
-        describe('ResourceKind.PROJECT', () => {
-            beforeEach(() => {
-                // setup
-                jest.spyOn(resource, 'extractUuidKind')
-                    .mockImplementation(() => resource.ResourceKind.PROJECT);
-            });
-
-            it('should return ContextMenuKind.PROJECT_ADMIN', () => {
-                // given
-                const isAdmin = true;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.PROJECT_ADMIN);
-            });
-
-            it('should return ContextMenuKind.PROJECT', () => {
-                // given
-                const isAdmin = false;
-                const isEditable = true;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin, isEditable);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.PROJECT);
-            });
-
-            it('should return ContextMenuKind.READONLY_PROJECT', () => {
-                // given
-                const isAdmin = false;
-                const isEditable = false;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin, isEditable);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.READONLY_PROJECT);
-            });
-        });
-
-        describe('ResourceKind.COLLECTION', () => {
-            beforeEach(() => {
-                // setup
-                jest.spyOn(resource, 'extractUuidKind')
-                    .mockImplementation(() => resource.ResourceKind.COLLECTION);
-            });
-
-            it('should return ContextMenuKind.COLLECTION_ADMIN', () => {
-                // given
-                const isAdmin = true;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.COLLECTION_ADMIN);
-            });
-
-            it('should return ContextMenuKind.COLLECTION', () => {
-                // given
-                const isAdmin = false;
-                const isEditable = true;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin, isEditable);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.COLLECTION);
-            });
-
-            it('should return ContextMenuKind.READONLY_COLLECTION', () => {
-                // given
-                const isAdmin = false;
-                const isEditable = false;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin, isEditable);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.READONLY_COLLECTION);
-            });
-        });
-
-        describe('ResourceKind.PROCESS', () => {
-            beforeEach(() => {
-                // setup
-                jest.spyOn(resource, 'extractUuidKind')
-                    .mockImplementation(() => resource.ResourceKind.PROCESS);
-            });
-
-            it('should return ContextMenuKind.PROCESS_ADMIN', () => {
-                // given
-                const isAdmin = true;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.PROCESS_ADMIN);
-            });
-
-            it('should return ContextMenuKind.PROCESS_RESOURCE', () => {
-                // given
-                const isAdmin = false;
-
-                // when
-                const result = resourceKindToContextMenuKind(uuid, isAdmin);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.PROCESS_RESOURCE);
-            });
-        });
-
-        describe('ResourceKind.USER', () => {
-            beforeEach(() => {
-                // setup
-                jest.spyOn(resource, 'extractUuidKind')
-                    .mockImplementation(() => resource.ResourceKind.USER);
-            });
-
-            it('should return ContextMenuKind.ROOT_PROJECT', () => {
-                // when
-                const result = resourceKindToContextMenuKind(uuid);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.ROOT_PROJECT);
-            });
-        });
-
-        describe('ResourceKind.LINK', () => {
-            beforeEach(() => {
-                // setup
-                jest.spyOn(resource, 'extractUuidKind')
-                    .mockImplementation(() => resource.ResourceKind.LINK);
-            });
-
-            it('should return ContextMenuKind.LINK', () => {
-                // when
-                const result = resourceKindToContextMenuKind(uuid);
-
-                // then
-                expect(result).toEqual(ContextMenuKind.LINK);
+    describe('resourceUuidToContextMenuKind', () => {
+        const middlewares = [thunk];
+        const mockStore = configureStore(middlewares);
+        const userUuid = 'zzzzz-tpzed-bbbbbbbbbbbbbbb';
+        const otherUserUuid = 'zzzzz-tpzed-bbbbbbbbbbbbbbc';
+        const headCollectionUuid = 'zzzzz-4zz18-aaaaaaaaaaaaaaa';
+        const oldCollectionUuid = 'zzzzz-4zz18-aaaaaaaaaaaaaab';
+        const projectUuid = 'zzzzz-j7d0g-ccccccccccccccc';
+        const filterGroupUuid = 'zzzzz-j7d0g-ccccccccccccccd';
+        const linkUuid = 'zzzzz-o0j2j-0123456789abcde';
+        const containerRequestUuid = 'zzzzz-xvhdp-0123456789abcde';
+
+        it('should return the correct menu kind', () => {
+            const cases = [
+                // resourceUuid, isAdminUser, isEditable, isTrashed, forceReadonly, expected
+                [headCollectionUuid, false, true, true, false, ContextMenuKind.TRASHED_COLLECTION],
+                [headCollectionUuid, false, true, false, false, ContextMenuKind.COLLECTION],
+                [headCollectionUuid, false, true, false, true, ContextMenuKind.READONLY_COLLECTION],
+                [headCollectionUuid, false, false, true, false, ContextMenuKind.READONLY_COLLECTION],
+                [headCollectionUuid, false, false, false, false, ContextMenuKind.READONLY_COLLECTION],
+                [headCollectionUuid, true, true, true, false, ContextMenuKind.TRASHED_COLLECTION],
+                [headCollectionUuid, true, true, false, false, ContextMenuKind.COLLECTION_ADMIN],
+                [headCollectionUuid, true, false, true, false, ContextMenuKind.TRASHED_COLLECTION],
+                [headCollectionUuid, true, false, false, false, ContextMenuKind.COLLECTION_ADMIN],
+                [headCollectionUuid, true, false, false, true, ContextMenuKind.READONLY_COLLECTION],
+
+                [oldCollectionUuid, false, true, true, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+                [oldCollectionUuid, false, true, false, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+                [oldCollectionUuid, false, false, true, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+                [oldCollectionUuid, false, false, false, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+                [oldCollectionUuid, true, true, true, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+                [oldCollectionUuid, true, true, false, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+                [oldCollectionUuid, true, false, true, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+                [oldCollectionUuid, true, false, false, false, ContextMenuKind.OLD_VERSION_COLLECTION],
+
+                // FIXME: WB2 doesn't currently have context menu for trashed projects
+                // [projectUuid, false, true, true, false, ContextMenuKind.TRASHED_PROJECT],
+                [projectUuid, false, true, false, false, ContextMenuKind.PROJECT],
+                [projectUuid, false, true, false, true, ContextMenuKind.READONLY_PROJECT],
+                [projectUuid, false, false, true, false, ContextMenuKind.READONLY_PROJECT],
+                [projectUuid, false, false, false, false, ContextMenuKind.READONLY_PROJECT],
+                // [projectUuid, true, true, true, false, ContextMenuKind.TRASHED_PROJECT],
+                [projectUuid, true, true, false, false, ContextMenuKind.PROJECT_ADMIN],
+                // [projectUuid, true, false, true, false, ContextMenuKind.TRASHED_PROJECT],
+                [projectUuid, true, false, false, false, ContextMenuKind.PROJECT_ADMIN],
+                [projectUuid, true, false, false, true, ContextMenuKind.READONLY_PROJECT],
+
+                [linkUuid, false, true, true, false, ContextMenuKind.LINK],
+                [linkUuid, false, true, false, false, ContextMenuKind.LINK],
+                [linkUuid, false, false, true, false, ContextMenuKind.LINK],
+                [linkUuid, false, false, false, false, ContextMenuKind.LINK],
+                [linkUuid, true, true, true, false, ContextMenuKind.LINK],
+                [linkUuid, true, true, false, false, ContextMenuKind.LINK],
+                [linkUuid, true, false, true, false, ContextMenuKind.LINK],
+                [linkUuid, true, false, false, false, ContextMenuKind.LINK],
+
+                [userUuid, false, true, true, false, ContextMenuKind.ROOT_PROJECT],
+                [userUuid, false, true, false, false, ContextMenuKind.ROOT_PROJECT],
+                [userUuid, false, false, true, false, ContextMenuKind.ROOT_PROJECT],
+                [userUuid, false, false, false, false, ContextMenuKind.ROOT_PROJECT],
+                [userUuid, true, true, true, false, ContextMenuKind.ROOT_PROJECT],
+                [userUuid, true, true, false, false, ContextMenuKind.ROOT_PROJECT],
+                [userUuid, true, false, true, false, ContextMenuKind.ROOT_PROJECT],
+                [userUuid, true, false, false, false, ContextMenuKind.ROOT_PROJECT],
+
+                [containerRequestUuid, false, true, true, false, ContextMenuKind.PROCESS_RESOURCE],
+                [containerRequestUuid, false, true, false, false, ContextMenuKind.PROCESS_RESOURCE],
+                [containerRequestUuid, false, false, true, false, ContextMenuKind.PROCESS_RESOURCE],
+                [containerRequestUuid, false, false, false, false, ContextMenuKind.PROCESS_RESOURCE],
+                [containerRequestUuid, false, false, false, true, ContextMenuKind.READONLY_PROCESS_RESOURCE],
+                [containerRequestUuid, true, true, true, false, ContextMenuKind.PROCESS_ADMIN],
+                [containerRequestUuid, true, true, false, false, ContextMenuKind.PROCESS_ADMIN],
+                [containerRequestUuid, true, false, true, false, ContextMenuKind.PROCESS_ADMIN],
+                [containerRequestUuid, true, false, false, false, ContextMenuKind.PROCESS_ADMIN],
+                [containerRequestUuid, true, false, false, true, ContextMenuKind.READONLY_PROCESS_RESOURCE],
+            ]
+
+            cases.forEach(([resourceUuid, isAdminUser, isEditable, isTrashed, forceReadonly, expected]) => {
+                const initialState = {
+                    properties: {
+                        [PROJECT_PANEL_CURRENT_UUID]: projectUuid,
+                    },
+                    resources: {
+                        [headCollectionUuid]: {
+                            uuid: headCollectionUuid,
+                            ownerUuid: projectUuid,
+                            currentVersionUuid: headCollectionUuid,
+                            isTrashed: isTrashed,
+                        },
+                        [oldCollectionUuid]: {
+                            uuid: oldCollectionUuid,
+                            currentVersionUuid: headCollectionUuid,
+                            isTrashed: isTrashed,
+                        },
+                        [projectUuid]: {
+                            uuid: projectUuid,
+                            ownerUuid: isEditable ? userUuid : otherUserUuid,
+                            writableBy: isEditable ? [userUuid] : [otherUserUuid],
+                            groupClass: GroupClass.PROJECT,
+                        },
+                        [filterGroupUuid]: {
+                            uuid: filterGroupUuid,
+                            ownerUuid: isEditable ? userUuid : otherUserUuid,
+                            writableBy: isEditable ? [userUuid] : [otherUserUuid],
+                            groupClass: GroupClass.FILTER,
+                        },
+                        [linkUuid]: {
+                            uuid: linkUuid,
+                        },
+                        [userUuid]: {
+                            uuid: userUuid,
+                        },
+                        [containerRequestUuid]: {
+                            uuid: containerRequestUuid,
+                            ownerUuid: projectUuid,
+                        },
+                    },
+                    auth: {
+                        user: {
+                            uuid: userUuid,
+                            isAdmin: isAdminUser,
+                        },
+                    },
+                };
+                const store = mockStore(initialState);
+
+                let menuKind: any;
+                try {
+                    menuKind = store.dispatch<any>(resourceUuidToContextMenuKind(resourceUuid as string, forceReadonly as boolean))
+                    expect(menuKind).toBe(expected);
+                } catch (err) {
+                    throw new Error(`menuKind for resource ${JSON.stringify(initialState.resources[resourceUuid as string])} forceReadonly: ${forceReadonly} expected to be ${expected} but got ${menuKind}.`);
+                }
             });
         });
     });
-});
\ No newline at end of file
+});