]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
c8d47c3115457baff95120ecdbed374339d3f40f
[ceph-ci.git] /
1 import { ComponentFixture, TestBed } from '@angular/core/testing';
2 import { RouterTestingModule } from '@angular/router/testing';
3
4 import { configureTestBed, PermissionHelper } from '../../../../testing/unit-test-helper';
5 import { ComponentsModule } from '../../components/components.module';
6 import { CdTableAction } from '../../models/cd-table-action';
7 import { CdTableSelection } from '../../models/cd-table-selection';
8 import { Permission } from '../../models/permissions';
9 import { TableActionsComponent } from './table-actions.component';
10
11 describe('TableActionsComponent', () => {
12   let component: TableActionsComponent;
13   let fixture: ComponentFixture<TableActionsComponent>;
14   let addAction: CdTableAction;
15   let editAction: CdTableAction;
16   let protectAction: CdTableAction;
17   let unprotectAction: CdTableAction;
18   let deleteAction: CdTableAction;
19   let copyAction: CdTableAction;
20   let scenario;
21   let permissionHelper: PermissionHelper;
22
23   const getTableActionComponent = (): TableActionsComponent => {
24     component.tableActions = [
25       addAction,
26       editAction,
27       protectAction,
28       unprotectAction,
29       copyAction,
30       deleteAction
31     ];
32     component.ngOnInit();
33     return component;
34   };
35
36   configureTestBed({
37     declarations: [TableActionsComponent],
38     imports: [ComponentsModule, RouterTestingModule]
39   });
40
41   beforeEach(() => {
42     addAction = {
43       permission: 'create',
44       icon: 'fa-plus',
45       canBePrimary: (selection: CdTableSelection) => !selection.hasSelection,
46       name: 'Add'
47     };
48     editAction = {
49       permission: 'update',
50       icon: 'fa-pencil',
51       name: 'Edit'
52     };
53     copyAction = {
54       permission: 'create',
55       icon: 'fa-copy',
56       canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection,
57       disable: (selection: CdTableSelection) =>
58         !selection.hasSingleSelection || selection.first().cdExecuting,
59       name: 'Copy'
60     };
61     deleteAction = {
62       permission: 'delete',
63       icon: 'fa-times',
64       canBePrimary: (selection: CdTableSelection) => selection.hasSelection,
65       disable: (selection: CdTableSelection) =>
66         !selection.hasSelection || selection.first().cdExecuting,
67       name: 'Delete'
68     };
69     protectAction = {
70       permission: 'update',
71       icon: 'fa-lock',
72       canBePrimary: () => false,
73       visible: (selection: CdTableSelection) => selection.hasSingleSelection,
74       name: 'Protect'
75     };
76     unprotectAction = {
77       permission: 'update',
78       icon: 'fa-unlock',
79       canBePrimary: () => false,
80       visible: (selection: CdTableSelection) => !selection.hasSingleSelection,
81       name: 'Unprotect'
82     };
83     fixture = TestBed.createComponent(TableActionsComponent);
84     component = fixture.componentInstance;
85     component.selection = new CdTableSelection();
86     component.permission = new Permission();
87     component.permission.read = true;
88     permissionHelper = new PermissionHelper(component.permission, () => getTableActionComponent());
89     permissionHelper.setPermissionsAndGetActions(1, 1, 1);
90   });
91
92   it('should create', () => {
93     expect(component).toBeTruthy();
94   });
95
96   it('should ngInit should be called with no permissions', () => {
97     component.permission = undefined;
98     component.ngOnInit();
99     expect(component.tableActions).toEqual([]);
100     expect(component.dropDownActions).toEqual([]);
101   });
102
103   describe('useRouterLink', () => {
104     const testLink = '/api/some/link';
105     it('should use a link generated from a function', () => {
106       addAction.routerLink = () => testLink;
107       expect(component.useRouterLink(addAction)).toBe(testLink);
108     });
109
110     it('should use the link as it is because it is a string', () => {
111       addAction.routerLink = testLink;
112       expect(component.useRouterLink(addAction)).toBe(testLink);
113     });
114
115     it('should not return anything because no link is defined', () => {
116       expect(component.useRouterLink(addAction)).toBe(undefined);
117     });
118
119     it('should not return anything because the action is disabled', () => {
120       editAction.routerLink = testLink;
121       expect(component.useRouterLink(editAction)).toBe(undefined);
122     });
123   });
124
125   describe('disableSelectionAction', () => {
126     beforeEach(() => {
127       scenario = {
128         fn: () => null,
129         multiple: false,
130         singleExecuting: false,
131         single: false,
132         empty: false
133       };
134     });
135
136     it('tests disabling addAction', () => {
137       scenario.fn = () => component.disableSelectionAction(addAction);
138       permissionHelper.testScenarios(scenario);
139     });
140
141     it('tests disabling editAction', () => {
142       scenario.fn = () => component.disableSelectionAction(editAction);
143       scenario.multiple = true;
144       scenario.empty = true;
145       scenario.singleExecuting = true;
146       permissionHelper.testScenarios(scenario);
147     });
148
149     it('tests disabling deleteAction', () => {
150       scenario.fn = () => component.disableSelectionAction(deleteAction);
151       scenario.multiple = false;
152       scenario.empty = true;
153       scenario.singleExecuting = true;
154       permissionHelper.testScenarios(scenario);
155     });
156
157     it('tests disabling copyAction', () => {
158       scenario.fn = () => component.disableSelectionAction(copyAction);
159       scenario.multiple = true;
160       scenario.empty = true;
161       scenario.singleExecuting = true;
162       permissionHelper.testScenarios(scenario);
163     });
164   });
165
166   describe('get current button', () => {
167     const hiddenScenario = () => {
168       scenario.multiple = undefined;
169       scenario.empty = undefined;
170       scenario.singleExecuting = undefined;
171       scenario.single = undefined;
172     };
173
174     const setScenario = (defaultAction, selectionAction) => {
175       scenario.single = selectionAction;
176       scenario.singleExecuting = selectionAction;
177       scenario.multiple = defaultAction;
178       scenario.empty = defaultAction;
179     };
180
181     beforeEach(() => {
182       scenario = {
183         fn: () => component.getCurrentButton(),
184         singleExecuting: copyAction,
185         single: copyAction,
186         empty: addAction
187       };
188     });
189
190     it('gets add for no, edit for single and delete for multiple selections', () => {
191       setScenario(addAction, editAction);
192       scenario.multiple = deleteAction;
193       permissionHelper.setPermissionsAndGetActions(1, 1, 1);
194       permissionHelper.testScenarios(scenario);
195     });
196
197     it('gets add action except for selections where it shows edit action', () => {
198       setScenario(addAction, editAction);
199       permissionHelper.setPermissionsAndGetActions(1, 1, 0);
200       permissionHelper.testScenarios(scenario);
201     });
202
203     it('gets add for no, copy for single and delete for multiple selections', () => {
204       setScenario(addAction, copyAction);
205       scenario.multiple = deleteAction;
206       permissionHelper.setPermissionsAndGetActions(1, 0, 1);
207       permissionHelper.testScenarios(scenario);
208     });
209
210     it('gets add action except for selections where it shows copy action', () => {
211       setScenario(addAction, copyAction);
212       permissionHelper.setPermissionsAndGetActions(1, 0, 0);
213       permissionHelper.testScenarios(scenario);
214     });
215
216     it('should always get edit action except delete for multiple items', () => {
217       setScenario(editAction, editAction);
218       scenario.multiple = deleteAction;
219       permissionHelper.setPermissionsAndGetActions(0, 1, 1);
220       permissionHelper.testScenarios(scenario);
221     });
222
223     it('should always get edit action', () => {
224       setScenario(editAction, editAction);
225       permissionHelper.setPermissionsAndGetActions(0, 1, 0);
226       permissionHelper.testScenarios(scenario);
227     });
228
229     it('should always get delete action', () => {
230       setScenario(deleteAction, deleteAction);
231       permissionHelper.setPermissionsAndGetActions(0, 0, 1);
232       permissionHelper.testScenarios(scenario);
233     });
234
235     it('should not get any button with no permissions, except the true action', () => {
236       hiddenScenario();
237       permissionHelper.setPermissionsAndGetActions(0, 0, 0);
238       permissionHelper.testScenarios(scenario);
239     });
240
241     it('should not get any button if only a drop down should be shown', () => {
242       hiddenScenario();
243       component.dropDownOnly = 'Drop down label that is shown';
244       permissionHelper.setPermissionsAndGetActions(1, 1, 1);
245       permissionHelper.testScenarios(scenario);
246     });
247   });
248
249   describe('show drop down', () => {
250     const testShowDropDownActions = (perms, expected) => {
251       permissionHelper.setPermissionsAndGetActions(perms[0], perms[1], perms[2]);
252       expect(`${perms} ${component.showDropDownActions()}`).toBe(`${perms} ${expected}`);
253     };
254
255     it('is shown if multiple items are found depending on the permissions', () => {
256       [[1, 0, 0], [1, 1, 1], [1, 1, 0], [1, 0, 1], [0, 1, 1], [0, 1, 0]].forEach((perms) => {
257         testShowDropDownActions(perms, true);
258       });
259     });
260
261     it('is not shown if only 1 or less items are found depending on the permissions', () => {
262       [[0, 0, 1], [0, 0, 0]].forEach((perms) => {
263         testShowDropDownActions(perms, false);
264       });
265     });
266   });
267
268   describe('all visible actions with all different permissions', () => {
269     it('with create, update and delete', () => {
270       permissionHelper.setPermissionsAndGetActions(1, 1, 1);
271       expect(component.dropDownActions).toEqual([
272         addAction,
273         editAction,
274         unprotectAction,
275         copyAction,
276         deleteAction
277       ]);
278     });
279
280     it('with create and delete', () => {
281       permissionHelper.setPermissionsAndGetActions(1, 0, 1);
282       expect(component.dropDownActions).toEqual([addAction, copyAction, deleteAction]);
283     });
284
285     it('with create and update', () => {
286       permissionHelper.setPermissionsAndGetActions(1, 1, 0);
287       expect(component.dropDownActions).toEqual([
288         addAction,
289         editAction,
290         unprotectAction,
291         copyAction
292       ]);
293     });
294
295     it('with create', () => {
296       permissionHelper.setPermissionsAndGetActions(1, 0, 0);
297       expect(component.dropDownActions).toEqual([addAction, copyAction]);
298     });
299
300     it('with update and delete', () => {
301       permissionHelper.setPermissionsAndGetActions(0, 1, 1);
302       expect(component.dropDownActions).toEqual([editAction, unprotectAction, deleteAction]);
303     });
304
305     it('with update', () => {
306       permissionHelper.setPermissionsAndGetActions(0, 1, 0);
307       expect(component.dropDownActions).toEqual([editAction, unprotectAction]);
308     });
309
310     it('with delete', () => {
311       permissionHelper.setPermissionsAndGetActions(0, 0, 1);
312       expect(component.dropDownActions).toEqual([deleteAction]);
313     });
314
315     it('without any', () => {
316       permissionHelper.setPermissionsAndGetActions(0, 0, 0);
317       expect(component.dropDownActions).toEqual([]);
318     });
319   });
320
321   it('should convert any name to a proper CSS class', () => {
322     expect(component.toClassName('Create')).toBe('create');
323     expect(component.toClassName('Mark x down')).toBe('mark-x-down');
324     expect(component.toClassName('?Su*per!')).toBe('super');
325   });
326
327   describe('useDisableDesc', () => {
328     it('should return a description if disableDesc is set for action', () => {
329       const deleteWithDescAction: CdTableAction = {
330         permission: 'delete',
331         icon: 'fa-times',
332         canBePrimary: (selection: CdTableSelection) => selection.hasSelection,
333         disableDesc: () => {
334           return 'Delete action disabled description';
335         },
336         name: 'DeleteDesc'
337       };
338
339       expect(component.useDisableDesc(deleteWithDescAction)).toBe(
340         'Delete action disabled description'
341       );
342     });
343
344     it('should return no description if disableDesc is not set for action', () => {
345       expect(component.useDisableDesc(deleteAction)).toBeUndefined();
346     });
347   });
348
349   describe('useClickAction', () => {
350     const editClickAction: CdTableAction = {
351       permission: 'update',
352       icon: 'fa-pencil',
353       name: 'Edit',
354       click: () => {
355         return 'Edit action click';
356       }
357     };
358
359     it('should call click action if action is not disabled', () => {
360       editClickAction.disable = () => {
361         return false;
362       };
363       expect(component.useClickAction(editClickAction)).toBe('Edit action click');
364     });
365
366     it('should not call click action if action is disabled', () => {
367       editClickAction.disable = () => {
368         return true;
369       };
370       expect(component.useClickAction(editClickAction)).toBeFalsy();
371     });
372   });
373 });