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";
18 describe('tree-picker-actions', () => {
19 const axiosInst = Axios.create({ headers: {} });
20 const axiosMock = new MockAdapter(axiosInst);
23 let services: ServiceRepository;
28 const actions: ApiActions = {
29 progressFn: (id: string, working: boolean) => { },
30 errorFn: (id: string, message: string) => { }
32 let importMocks: any[];
36 services = createServices(mockConfig({}), actions, axiosInst);
37 store = configureStore(createBrowserHistory(), services, config);
43 importMocks.map(m => m.restore());
46 it('initializes preselected tree picker nodes', async () => {
47 const dispatchMock = jest.fn();
48 const dispatchWrapper = (action: any) => {
50 return store.dispatch(action);
53 const emptyCollectionUuid = "zzzzz-4zz18-000000000000000";
54 const collectionUuid = "zzzzz-4zz18-111111111111111";
55 const parentProjectUuid = "zzzzz-j7d0g-000000000000000";
56 const childCollectionUuid = "zzzzz-4zz18-222222222222222";
58 const fakeResources = {
59 [emptyCollectionUuid]: {
60 kind: ResourceKind.COLLECTION,
65 kind: ResourceKind.COLLECTION,
68 id: `${collectionUuid}/directory`,
71 type: CollectionFileType.DIRECTORY,
72 url: `/c=${collectionUuid}/directory/`,
75 [parentProjectUuid]: {
76 kind: ResourceKind.GROUP,
79 [childCollectionUuid]: {
80 kind: ResourceKind.COLLECTION,
81 ownerUuid: parentProjectUuid,
84 id: `${childCollectionUuid}/mainDir`,
87 type: CollectionFileType.DIRECTORY,
88 url: `/c=${childCollectionUuid}/mainDir/`,
91 id: `${childCollectionUuid}/mainDir/subDir`,
94 type: CollectionFileType.DIRECTORY,
95 url: `/c=${childCollectionUuid}/mainDir/subDir`,
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) {
108 uuid, kind: resource.kind,
109 ownerUuid: resource.ownerUuid,
110 } as CollectionResource);
111 } else if (resource.kind === ResourceKind.GROUP) {
113 uuid, kind: resource.kind,
114 ownerUuid: resource.ownerUuid,
117 uuid = resource.ownerUuid;
122 services.collectionService.files = jest.fn(async (uuid): Promise<(CollectionDirectory | CollectionFile)[]> => {
123 return fakeResources[uuid]?.files || [];
126 const pickerId = "pickerId";
128 // When collection preselected
129 await initProjectsTreePicker(pickerId, {
130 selectedItemUuids: [emptyCollectionUuid],
131 includeDirectories: true,
134 })(dispatchWrapper, store.getState, services);
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);
143 // When collection subdirectory is preselected
144 await initProjectsTreePicker(pickerId, {
145 selectedItemUuids: [`${collectionUuid}/directory`],
146 includeDirectories: true,
149 })(dispatchWrapper, store.getState, services);
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);
160 // When subdirectory of collection inside project is preselected
161 await initProjectsTreePicker(pickerId, {
162 selectedItemUuids: [`${childCollectionUuid}/mainDir/subDir`],
163 includeDirectories: true,
166 })(dispatchWrapper, store.getState, services);
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);