b1c42409ecc606fb307f67b3d72610a54f8a23cf
[arvados.git] / src / store / tree-picker / tree-picker-actions.test.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { ServiceRepository, createServices } from "services/services";
6 import { configureStore, RootStore } from "../store";
7 import { createBrowserHistory } from "history";
8 import { mockConfig } from 'common/config';
9 import { ApiActions } from "services/api/api-actions";
10 import Axios from "axios";
11 import MockAdapter from "axios-mock-adapter";
12 import { ResourceKind } from 'models/resource';
13 import { SHARED_PROJECT_ID, initProjectsTreePicker } from "./tree-picker-actions";
14 import { CollectionResource } from "models/collection";
15 import { GroupResource } from "models/group";
16 import { CollectionDirectory, CollectionFile, CollectionFileType } from "models/collection-file";
17
18 describe('tree-picker-actions', () => {
19     const axiosInst = Axios.create({ headers: {} });
20     const axiosMock = new MockAdapter(axiosInst);
21
22     let store: RootStore;
23     let services: ServiceRepository;
24     const config: any = {
25
26
27     };
28     const actions: ApiActions = {
29         progressFn: (id: string, working: boolean) => { },
30         errorFn: (id: string, message: string) => { }
31     };
32     let importMocks: any[];
33
34     beforeEach(() => {
35         axiosMock.reset();
36         services = createServices(mockConfig({}), actions, axiosInst);
37         store = configureStore(createBrowserHistory(), services, config);
38         localStorage.clear();
39         importMocks = [];
40     });
41
42     afterEach(() => {
43         importMocks.map(m => m.restore());
44     });
45
46     it('initializes preselected tree picker nodes', async () => {
47         const dispatchMock = jest.fn();
48         const dispatchWrapper = (action: any) => {
49             dispatchMock(action);
50             return store.dispatch(action);
51         };
52
53         const emptyCollectionUuid = "zzzzz-4zz18-000000000000000";
54         const collectionUuid = "zzzzz-4zz18-111111111111111";
55         const parentProjectUuid = "zzzzz-j7d0g-000000000000000";
56         const childCollectionUuid = "zzzzz-4zz18-222222222222222";
57
58         const fakeResources = {
59             [emptyCollectionUuid]: {
60                 kind: ResourceKind.COLLECTION,
61                 ownerUuid: '',
62                 files: [],
63             },
64             [collectionUuid]: {
65                 kind: ResourceKind.COLLECTION,
66                 ownerUuid: '',
67                 files: [{
68                     id: `${collectionUuid}/directory`,
69                     name: "directory",
70                     path: "",
71                     type: CollectionFileType.DIRECTORY,
72                     url: `/c=${collectionUuid}/directory/`,
73                 }]
74             },
75             [parentProjectUuid]: {
76                 kind: ResourceKind.GROUP,
77                 ownerUuid: '',
78             },
79             [childCollectionUuid]: {
80                 kind: ResourceKind.COLLECTION,
81                 ownerUuid: parentProjectUuid,
82                 files: [
83                     {
84                         id: `${childCollectionUuid}/mainDir`,
85                         name: "mainDir",
86                         path: "",
87                         type: CollectionFileType.DIRECTORY,
88                         url: `/c=${childCollectionUuid}/mainDir/`,
89                     },
90                     {
91                         id: `${childCollectionUuid}/mainDir/subDir`,
92                         name: "subDir",
93                         path: "/mainDir",
94                         type: CollectionFileType.DIRECTORY,
95                         url: `/c=${childCollectionUuid}/mainDir/subDir`,
96                     }
97                 ],
98             },
99         };
100
101         services.ancestorsService.ancestors = jest.fn(async (startUuid, endUuid) => {
102             let ancestors: (GroupResource | CollectionResource)[] = [];
103             let uuid = startUuid;
104             while (uuid?.length && fakeResources[uuid]) {
105                 const resource = fakeResources[uuid];
106                 if (resource.kind === ResourceKind.COLLECTION) {
107                     ancestors.unshift({
108                         uuid, kind: resource.kind,
109                         ownerUuid: resource.ownerUuid,
110                     } as CollectionResource);
111                 } else if (resource.kind === ResourceKind.GROUP) {
112                     ancestors.unshift({
113                         uuid, kind: resource.kind,
114                         ownerUuid: resource.ownerUuid,
115                     } as GroupResource);
116                 }
117                 uuid = resource.ownerUuid;
118             }
119             return ancestors;
120         });
121
122         services.collectionService.files = jest.fn(async (uuid): Promise<(CollectionDirectory | CollectionFile)[]> => {
123             return fakeResources[uuid]?.files || [];
124         });
125
126         const pickerId = "pickerId";
127
128         // When collection preselected
129         await initProjectsTreePicker(pickerId, {
130             selectedItemUuids: [emptyCollectionUuid],
131             includeDirectories: true,
132             includeFiles: false,
133             multi: true,
134         })(dispatchWrapper, store.getState, services);
135
136         // Expect ancestor service to be called
137         expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(emptyCollectionUuid, '');
138         // Expect top level to be expanded and node to be selected
139         expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
140         expect(store.getState().treePicker["pickerId_shared"][emptyCollectionUuid].selected).toBe(true);
141
142
143         // When collection subdirectory is preselected
144         await initProjectsTreePicker(pickerId, {
145             selectedItemUuids: [`${collectionUuid}/directory`],
146             includeDirectories: true,
147             includeFiles: false,
148             multi: true,
149         })(dispatchWrapper, store.getState, services);
150
151         // Expect ancestor service to be called
152         expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(collectionUuid, '');
153         // Expect top level to be expanded and node to be selected
154         expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
155         expect(store.getState().treePicker["pickerId_shared"][collectionUuid].expanded).toBe(true);
156         expect(store.getState().treePicker["pickerId_shared"][collectionUuid].selected).toBe(false);
157         expect(store.getState().treePicker["pickerId_shared"][`${collectionUuid}/directory`].selected).toBe(true);
158
159
160         // When subdirectory of collection inside project is preselected
161         await initProjectsTreePicker(pickerId, {
162             selectedItemUuids: [`${childCollectionUuid}/mainDir/subDir`],
163             includeDirectories: true,
164             includeFiles: false,
165             multi: true,
166         })(dispatchWrapper, store.getState, services);
167
168         // Expect ancestor service to be called
169         expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(childCollectionUuid, '');
170         // Expect parent project and collection to be expanded
171         expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
172         expect(store.getState().treePicker["pickerId_shared"][parentProjectUuid].expanded).toBe(true);
173         expect(store.getState().treePicker["pickerId_shared"][parentProjectUuid].selected).toBe(false);
174         expect(store.getState().treePicker["pickerId_shared"][childCollectionUuid].expanded).toBe(true);
175         expect(store.getState().treePicker["pickerId_shared"][childCollectionUuid].selected).toBe(false);
176         // Expect main directory to be expanded
177         expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir`].expanded).toBe(true);
178         expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir`].selected).toBe(false);
179         // Expect sub directory to be selected
180         expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir/subDir`].expanded).toBe(false);
181         expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir/subDir`].selected).toBe(true);
182
183
184     });
185 });