]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table-actions/table-actions.component.spec.ts
import ceph quincy 17.2.4
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / datatable / table-actions / table-actions.component.spec.ts
1 import { ComponentFixture, TestBed } from '@angular/core/testing';
2 import { RouterTestingModule } from '@angular/router/testing';
3
4 import { NgxPipeFunctionModule } from 'ngx-pipe-function';
5
6 import { ComponentsModule } from '~/app/shared/components/components.module';
7 import { CdTableAction } from '~/app/shared/models/cd-table-action';
8 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
9 import { Permission } from '~/app/shared/models/permissions';
10 import { configureTestBed, PermissionHelper } from '~/testing/unit-test-helper';
11 import { TableActionsComponent } from './table-actions.component';
12
13 describe('TableActionsComponent', () => {
14 let component: TableActionsComponent;
15 let fixture: ComponentFixture<TableActionsComponent>;
16 let addAction: CdTableAction;
17 let editAction: CdTableAction;
18 let protectAction: CdTableAction;
19 let unprotectAction: CdTableAction;
20 let deleteAction: CdTableAction;
21 let copyAction: CdTableAction;
22 let permissionHelper: PermissionHelper;
23
24 configureTestBed({
25 declarations: [TableActionsComponent],
26 imports: [ComponentsModule, NgxPipeFunctionModule, RouterTestingModule]
27 });
28
29 beforeEach(() => {
30 addAction = {
31 permission: 'create',
32 icon: 'fa-plus',
33 canBePrimary: (selection: CdTableSelection) => !selection.hasSelection,
34 name: 'Add'
35 };
36 editAction = {
37 permission: 'update',
38 icon: 'fa-pencil',
39 name: 'Edit'
40 };
41 copyAction = {
42 permission: 'create',
43 icon: 'fa-copy',
44 canBePrimary: (selection: CdTableSelection) => selection.hasSingleSelection,
45 disable: (selection: CdTableSelection) =>
46 !selection.hasSingleSelection || selection.first().cdExecuting,
47 name: 'Copy'
48 };
49 deleteAction = {
50 permission: 'delete',
51 icon: 'fa-times',
52 canBePrimary: (selection: CdTableSelection) => selection.hasSelection,
53 disable: (selection: CdTableSelection) =>
54 !selection.hasSelection || selection.first().cdExecuting,
55 name: 'Delete'
56 };
57 protectAction = {
58 permission: 'update',
59 icon: 'fa-lock',
60 canBePrimary: () => false,
61 visible: (selection: CdTableSelection) => selection.hasSingleSelection,
62 name: 'Protect'
63 };
64 unprotectAction = {
65 permission: 'update',
66 icon: 'fa-unlock',
67 canBePrimary: () => false,
68 visible: (selection: CdTableSelection) => !selection.hasSingleSelection,
69 name: 'Unprotect'
70 };
71 fixture = TestBed.createComponent(TableActionsComponent);
72 component = fixture.componentInstance;
73 component.selection = new CdTableSelection();
74 component.permission = new Permission();
75 component.permission.read = true;
76 component.tableActions = [
77 addAction,
78 editAction,
79 protectAction,
80 unprotectAction,
81 copyAction,
82 deleteAction
83 ];
84 permissionHelper = new PermissionHelper(component.permission);
85 permissionHelper.setPermissionsAndGetActions(component.tableActions);
86 });
87
88 it('should create', () => {
89 expect(component).toBeTruthy();
90 });
91
92 it('should call ngInit without permissions', () => {
93 component.permission = undefined;
94 component.ngOnInit();
95 expect(component.tableActions).toEqual([]);
96 expect(component.dropDownActions).toEqual([]);
97 });
98
99 describe('useRouterLink', () => {
100 const testLink = '/api/some/link';
101 it('should use a link generated from a function', () => {
102 addAction.routerLink = () => testLink;
103 expect(component.useRouterLink(addAction)).toBe(testLink);
104 });
105
106 it('should use the link as it is because it is a string', () => {
107 addAction.routerLink = testLink;
108 expect(component.useRouterLink(addAction)).toBe(testLink);
109 });
110
111 it('should not return anything because no link is defined', () => {
112 expect(component.useRouterLink(addAction)).toBe(undefined);
113 });
114
115 it('should not return anything because the action is disabled', () => {
116 editAction.routerLink = testLink;
117 expect(component.useRouterLink(editAction)).toBe(undefined);
118 });
119 });
120
121 it('should test all TableActions combinations', () => {
122 const tableActions: TableActionsComponent = permissionHelper.setPermissionsAndGetActions(
123 component.tableActions
124 );
125 expect(tableActions).toEqual({
126 'create,update,delete': {
127 actions: ['Add', 'Edit', 'Protect', 'Unprotect', 'Copy', 'Delete'],
128 primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Add' }
129 },
130 'create,update': {
131 actions: ['Add', 'Edit', 'Protect', 'Unprotect', 'Copy'],
132 primary: { multiple: 'Add', executing: 'Edit', single: 'Edit', no: 'Add' }
133 },
134 'create,delete': {
135 actions: ['Add', 'Copy', 'Delete'],
136 primary: { multiple: 'Delete', executing: 'Copy', single: 'Copy', no: 'Add' }
137 },
138 create: {
139 actions: ['Add', 'Copy'],
140 primary: { multiple: 'Add', executing: 'Copy', single: 'Copy', no: 'Add' }
141 },
142 'update,delete': {
143 actions: ['Edit', 'Protect', 'Unprotect', 'Delete'],
144 primary: { multiple: 'Delete', executing: 'Edit', single: 'Edit', no: 'Edit' }
145 },
146 update: {
147 actions: ['Edit', 'Protect', 'Unprotect'],
148 primary: { multiple: 'Edit', executing: 'Edit', single: 'Edit', no: 'Edit' }
149 },
150 delete: {
151 actions: ['Delete'],
152 primary: { multiple: 'Delete', executing: 'Delete', single: 'Delete', no: 'Delete' }
153 },
154 'no-permissions': {
155 actions: [],
156 primary: { multiple: '', executing: '', single: '', no: '' }
157 }
158 });
159 });
160
161 it('should convert any name to a proper CSS class', () => {
162 expect(component.toClassName({ name: 'Create' } as CdTableAction)).toBe('create');
163 expect(component.toClassName({ name: 'Mark x down' } as CdTableAction)).toBe('mark-x-down');
164 expect(component.toClassName({ name: '?Su*per!' } as CdTableAction)).toBe('super');
165 });
166
167 describe('useDisableDesc', () => {
168 it('should return a description if disable method returns a string', () => {
169 const deleteWithDescAction: CdTableAction = {
170 permission: 'delete',
171 icon: 'fa-times',
172 canBePrimary: (selection: CdTableSelection) => selection.hasSelection,
173 disable: () => {
174 return 'Delete action disabled description';
175 },
176 name: 'DeleteDesc'
177 };
178
179 expect(component.useDisableDesc(deleteWithDescAction)).toBe(
180 'Delete action disabled description'
181 );
182 });
183
184 it('should return no description if disable does not return string', () => {
185 expect(component.useDisableDesc(deleteAction)).toBeUndefined();
186 });
187 });
188
189 describe('useClickAction', () => {
190 const editClickAction: CdTableAction = {
191 permission: 'update',
192 icon: 'fa-pencil',
193 name: 'Edit',
194 click: () => {
195 return 'Edit action click';
196 }
197 };
198
199 it('should call click action if action is not disabled', () => {
200 editClickAction.disable = () => {
201 return false;
202 };
203 expect(component.useClickAction(editClickAction)).toBe('Edit action click');
204 });
205
206 it('should not call click action if action is disabled', () => {
207 editClickAction.disable = () => {
208 return true;
209 };
210 expect(component.useClickAction(editClickAction)).toBeFalsy();
211 });
212 });
213 });