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