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;
30 const actions: ApiActions = {
31 progressFn: (id: string, working: boolean) => { },
32 errorFn: (id: string, message: string) => { }
34 let importMocks: any[];
38 services = createServices(mockConfig({}), actions, axiosInst);
39 store = configureStore(createBrowserHistory(), services, config);
45 importMocks.map(m => m.restore());
48 it('initializes preselected tree picker nodes', async () => {
49 const dispatchMock = jest.fn();
50 const dispatchWrapper = (action: any) => {
52 return store.dispatch(action);
55 const emptyCollectionUuid = "zzzzz-4zz18-000000000000000";
56 const collectionUuid = "zzzzz-4zz18-111111111111111";
57 const parentProjectUuid = "zzzzz-j7d0g-000000000000000";
58 const childCollectionUuid = "zzzzz-4zz18-222222222222222";
60 const fakeResources = {
61 [emptyCollectionUuid]: {
62 kind: ResourceKind.COLLECTION,
67 kind: ResourceKind.COLLECTION,
70 id: `${collectionUuid}/directory`,
73 type: CollectionFileType.DIRECTORY,
74 url: `/c=${collectionUuid}/directory/`,
77 [parentProjectUuid]: {
78 kind: ResourceKind.GROUP,
81 [childCollectionUuid]: {
82 kind: ResourceKind.COLLECTION,
83 ownerUuid: parentProjectUuid,
86 id: `${childCollectionUuid}/mainDir`,
89 type: CollectionFileType.DIRECTORY,
90 url: `/c=${childCollectionUuid}/mainDir/`,
93 id: `${childCollectionUuid}/mainDir/subDir`,
96 type: CollectionFileType.DIRECTORY,
97 url: `/c=${childCollectionUuid}/mainDir/subDir`,
103 services.ancestorsService.ancestors = jest.fn(async (startUuid, endUuid) => {
104 let ancestors: (GroupResource | CollectionResource)[] = [];
105 let uuid = startUuid;
106 while (uuid?.length && fakeResources[uuid]) {
107 const resource = fakeResources[uuid];
108 if (resource.kind === ResourceKind.COLLECTION) {
110 uuid, kind: resource.kind,
111 ownerUuid: resource.ownerUuid,
112 } as CollectionResource);
113 } else if (resource.kind === ResourceKind.GROUP) {
115 uuid, kind: resource.kind,
116 ownerUuid: resource.ownerUuid,
119 uuid = resource.ownerUuid;
124 services.collectionService.files = jest.fn(async (uuid): Promise<(CollectionDirectory | CollectionFile)[]> => {
125 return fakeResources[uuid]?.files || [];
128 services.groupsService.contents = jest.fn(async (uuid, args) => {
129 const items = Object.keys(fakeResources).map(uuid => ({...fakeResources[uuid], uuid})).filter(item => item.ownerUuid === uuid);
130 return {items: items as GroupContentsResource[], itemsAvailable: items.length} as ListResults<GroupContentsResource>;
133 const pickerId = "pickerId";
135 // When collection preselected
136 await initProjectsTreePicker(pickerId, {
137 selectedItemUuids: [emptyCollectionUuid],
138 includeDirectories: true,
141 })(dispatchWrapper, store.getState, services);
143 // Expect ancestor service to be called
144 expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(emptyCollectionUuid, '');
145 // Expect top level to be expanded and node to be selected
146 expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
147 expect(store.getState().treePicker["pickerId_shared"][emptyCollectionUuid].selected).toBe(true);
150 // When collection subdirectory is preselected
151 await initProjectsTreePicker(pickerId, {
152 selectedItemUuids: [`${collectionUuid}/directory`],
153 includeDirectories: true,
156 })(dispatchWrapper, store.getState, services);
158 // Expect ancestor service to be called
159 expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(collectionUuid, '');
160 // Expect top level to be expanded and node to be selected
161 expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
162 expect(store.getState().treePicker["pickerId_shared"][collectionUuid].expanded).toBe(true);
163 expect(store.getState().treePicker["pickerId_shared"][collectionUuid].selected).toBe(false);
164 expect(store.getState().treePicker["pickerId_shared"][`${collectionUuid}/directory`].selected).toBe(true);
167 // When subdirectory of collection inside project is preselected
168 await initProjectsTreePicker(pickerId, {
169 selectedItemUuids: [`${childCollectionUuid}/mainDir/subDir`],
170 includeDirectories: true,
173 })(dispatchWrapper, store.getState, services);
175 // Expect ancestor service to be called
176 expect(services.ancestorsService.ancestors).toHaveBeenCalledWith(childCollectionUuid, '');
177 // Expect parent project and collection to be expanded
178 expect(store.getState().treePicker["pickerId_shared"][SHARED_PROJECT_ID].expanded).toBe(true);
179 expect(store.getState().treePicker["pickerId_shared"][parentProjectUuid].expanded).toBe(true);
180 expect(store.getState().treePicker["pickerId_shared"][parentProjectUuid].selected).toBe(false);
181 expect(store.getState().treePicker["pickerId_shared"][childCollectionUuid].expanded).toBe(true);
182 expect(store.getState().treePicker["pickerId_shared"][childCollectionUuid].selected).toBe(false);
183 // Expect main directory to be expanded
184 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir`].expanded).toBe(true);
185 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir`].selected).toBe(false);
186 // Expect sub directory to be selected
187 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir/subDir`].expanded).toBe(false);
188 expect(store.getState().treePicker["pickerId_shared"][`${childCollectionUuid}/mainDir/subDir`].selected).toBe(true);