1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
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 import { GroupContentsResource } from "services/groups-service/groups-service";
18 import { ListResults } from "services/common-service/common-service";
20 describe('tree-picker-actions', () => {
21 const axiosInst = Axios.create({ headers: {} });
22 const axiosMock = new MockAdapter(axiosInst);
25 let services: ServiceRepository;
26 const config: any = {};
27 const actions: ApiActions = {
28 progressFn: (id: string, working: boolean) => { },
29 errorFn: (id: string, message: string) => { }
31 let importMocks: any[];
35 services = createServices(mockConfig({}), actions, axiosInst);
36 store = configureStore(createBrowserHistory(), services, config);
42 importMocks.map(m => m.restore());
45 it('initializes preselected tree picker nodes', async () => {
46 const dispatchMock = jest.fn();
47 const dispatchWrapper = (action: any) => {
49 return store.dispatch(action);
52 const emptyCollectionUuid = "zzzzz-4zz18-000000000000000";
53 const collectionUuid = "zzzzz-4zz18-111111111111111";
54 const parentProjectUuid = "zzzzz-j7d0g-000000000000000";
55 const childCollectionUuid = "zzzzz-4zz18-222222222222222";
57 const fakeResources = {
58 [emptyCollectionUuid]: {
59 kind: ResourceKind.COLLECTION,
64 kind: ResourceKind.COLLECTION,
67 id: `${collectionUuid}/directory`,
70 type: CollectionFileType.DIRECTORY,
71 url: `/c=${collectionUuid}/directory/`,
74 [parentProjectUuid]: {
75 kind: ResourceKind.GROUP,
78 [childCollectionUuid]: {
79 kind: ResourceKind.COLLECTION,
80 ownerUuid: parentProjectUuid,
83 id: `${childCollectionUuid}/mainDir`,
86 type: CollectionFileType.DIRECTORY,
87 url: `/c=${childCollectionUuid}/mainDir/`,
90 id: `${childCollectionUuid}/mainDir/subDir`,
93 type: CollectionFileType.DIRECTORY,
94 url: `/c=${childCollectionUuid}/mainDir/subDir`,
100 services.ancestorsService.ancestors = jest.fn(async (startUuid, endUuid) => {
101 let ancestors: (GroupResource | CollectionResource)[] = [];
102 let uuid = startUuid;
103 while (uuid?.length && fakeResources[uuid]) {
104 const resource = fakeResources[uuid];
105 if (resource.kind === ResourceKind.COLLECTION) {
107 uuid, kind: resource.kind,
108 ownerUuid: resource.ownerUuid,
109 } as CollectionResource);
110 } else if (resource.kind === ResourceKind.GROUP) {
112 uuid, kind: resource.kind,
113 ownerUuid: resource.ownerUuid,
116 uuid = resource.ownerUuid;
121 services.collectionService.files = jest.fn(async (uuid): Promise<(CollectionDirectory | CollectionFile)[]> => {
122 return fakeResources[uuid]?.files || [];
125 services.groupsService.contents = jest.fn(async (uuid, args) => {
126 const items = Object.keys(fakeResources).map(uuid => ({...fakeResources[uuid], uuid})).filter(item => item.ownerUuid === uuid);
127 return {items: items as GroupContentsResource[], itemsAvailable: items.length} as ListResults<GroupContentsResource>;
130 const pickerId = "pickerId";
132 // When collection preselected
133 await initProjectsTreePicker(pickerId, {
134 selectedItemUuids: [emptyCollectionUuid],
135 includeDirectories: true,
138 })(dispatchWrapper, store.getState, services);
140 // Expect ancestor service to be called
141 expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(emptyCollectionUuid, '');
142 // Expect top level to be expanded and node to be selected
143 expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
144 expect(store.getState().treePicker["pickerId_shared"][emptyCollectionUuid].selected).toBe(true);
147 // When collection subdirectory is preselected
148 await initProjectsTreePicker(pickerId, {
149 selectedItemUuids: [`${collectionUuid}/directory`],
150 includeDirectories: true,
153 })(dispatchWrapper, store.getState, services);
155 // Expect ancestor service to be called
156 expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(collectionUuid, '');
157 // Expect top level to be expanded and node to be selected
158 expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
159 expect(store.getState().treePicker["pickerId_shared"][collectionUuid].expanded).toBe(true);
160 expect(store.getState().treePicker["pickerId_shared"][collectionUuid].selected).toBe(false);
161 expect(store.getState().treePicker["pickerId_shared"][`${collectionUuid}/directory`].selected).toBe(true);
164 // When subdirectory of collection inside project is preselected
165 await initProjectsTreePicker(pickerId, {
166 selectedItemUuids: [`${childCollectionUuid}/mainDir/subDir`],
167 includeDirectories: true,
170 })(dispatchWrapper, store.getState, services);
172 // Expect ancestor service to be called
173 expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(childCollectionUuid, '');
174 // Expect parent project and collection to be expanded
175 expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
176 expect(store.getState().treePicker["pickerId_shared"][parentProjectUuid].expanded).toBe(true);
177 expect(store.getState().treePicker["pickerId_shared"][parentProjectUuid].selected).toBe(false);
178 expect(store.getState().treePicker["pickerId_shared"][childCollectionUuid].expanded).toBe(true);
179 expect(store.getState().treePicker["pickerId_shared"][childCollectionUuid].selected).toBe(false);
180 // Expect main directory to be expanded
181 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir`].expanded).toBe(true);
182 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir`].selected).toBe(false);
183 // Expect sub directory to be selected
184 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir/subDir`].expanded).toBe(false);
185 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir/subDir`].selected).toBe(true);