@ieeesa-npm/tenants 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/.eslintrc.json +31 -0
  2. package/ng-package.json +8 -0
  3. package/package.json +12 -25
  4. package/src/lib/assets/constants.json +454 -0
  5. package/src/lib/assets/tenant-validations.ts +18 -0
  6. package/src/lib/assets/tenants-mock.ts +1240 -0
  7. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.html +15 -0
  8. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.scss +44 -0
  9. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.spec.ts +574 -0
  10. package/src/lib/components/create-modify-group-type/create-modify-group-type.component.ts +602 -0
  11. package/src/lib/components/create-modify-role/create-modify-role.component.html +15 -0
  12. package/src/lib/components/create-modify-role/create-modify-role.component.scss +83 -0
  13. package/src/lib/components/create-modify-role/create-modify-role.component.spec.ts +346 -0
  14. package/src/lib/components/create-modify-role/create-modify-role.component.ts +321 -0
  15. package/src/lib/components/create-tenant-application/create-tenant-application.component.html +18 -0
  16. package/src/lib/components/create-tenant-application/create-tenant-application.component.scss +73 -0
  17. package/src/lib/components/create-tenant-application/create-tenant-application.component.spec.ts +775 -0
  18. package/src/lib/components/create-tenant-application/create-tenant-application.component.ts +638 -0
  19. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.html +22 -0
  20. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.scss +79 -0
  21. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.spec.ts +716 -0
  22. package/src/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.ts +504 -0
  23. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.html +44 -0
  24. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.scss +16 -0
  25. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.spec.ts +115 -0
  26. package/src/lib/components/tenant-basic-details/tenant-basic-details.component.ts +109 -0
  27. package/src/lib/components/view-tenant-details/view-tenant-details.component.html +195 -0
  28. package/src/lib/components/view-tenant-details/view-tenant-details.component.scss +163 -0
  29. package/src/lib/components/view-tenant-details/view-tenant-details.component.spec.ts +1221 -0
  30. package/src/lib/components/view-tenant-details/view-tenant-details.component.ts +876 -0
  31. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.html +10 -0
  32. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.scss +44 -0
  33. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.spec.ts +410 -0
  34. package/src/lib/components/view-tenant-group-types/view-tenant-group-types.component.ts +219 -0
  35. package/src/lib/components/view-tenants-list/view-tenants-list.component.html +32 -0
  36. package/src/lib/components/view-tenants-list/view-tenants-list.component.scss +35 -0
  37. package/src/lib/components/view-tenants-list/view-tenants-list.component.spec.ts +464 -0
  38. package/src/lib/components/view-tenants-list/view-tenants-list.component.ts +388 -0
  39. package/src/lib/models/app-type-config.model.ts +14 -0
  40. package/src/lib/models/app-type.model.ts +5 -0
  41. package/src/lib/models/create-group-type-config.model.ts +18 -0
  42. package/src/lib/models/create-group-type.model.ts +46 -0
  43. package/src/lib/models/feature-permission-id.model.ts +6 -0
  44. package/src/lib/models/features.model.ts +15 -0
  45. package/src/lib/models/form-status.model.ts +5 -0
  46. package/src/lib/models/permission-type.model.ts +9 -0
  47. package/src/lib/models/role-menu-action.model.ts +5 -0
  48. package/src/lib/models/role-type.model.ts +34 -0
  49. package/src/lib/models/roles-and-permissions-table-type.model.ts +5 -0
  50. package/src/lib/models/roles-and-permissions.model.ts +113 -0
  51. package/src/lib/models/route-config.model.ts +4 -0
  52. package/src/lib/models/table-column-schema-view-tenant-list.model.ts +21 -0
  53. package/src/lib/models/tenant-function-type.model.ts +10 -0
  54. package/src/lib/models/tenant.model.ts +47 -0
  55. package/src/lib/models/tenants-permission.model.ts +9 -0
  56. package/src/lib/models/update-tenant-status.model.ts +12 -0
  57. package/src/lib/models/view-tenant-group-types.model.ts +34 -0
  58. package/src/lib/services/tenant-applications.service.spec.ts +1245 -0
  59. package/src/lib/services/tenant-applications.service.ts +798 -0
  60. package/src/lib/services/tenant-permissions-map.service.spec.ts +25 -0
  61. package/src/lib/services/tenant-permissions-map.service.ts +28 -0
  62. package/src/lib/services/tenant-permissions.service.spec.ts +62 -0
  63. package/src/lib/services/tenant-permissions.service.ts +49 -0
  64. package/src/lib/tenant-applications.component.html +0 -0
  65. package/src/lib/tenant-applications.component.scss +0 -0
  66. package/src/lib/tenant-applications.component.spec.ts +28 -0
  67. package/src/lib/tenant-applications.component.ts +12 -0
  68. package/src/lib/tenant-applications.module.ts +8 -0
  69. package/{public-api.d.ts → src/public-api.ts} +40 -30
  70. package/tsconfig.lib.json +14 -0
  71. package/tsconfig.lib.prod.json +10 -0
  72. package/tsconfig.spec.json +14 -0
  73. package/esm2022/ieeesa-npm-tenants.mjs +0 -5
  74. package/esm2022/lib/assets/constants.json +0 -390
  75. package/esm2022/lib/assets/tenant-validations.mjs +0 -13
  76. package/esm2022/lib/components/create-modify-role/create-modify-role.component.mjs +0 -280
  77. package/esm2022/lib/components/create-tenant-application/create-tenant-application.component.mjs +0 -512
  78. package/esm2022/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.mjs +0 -391
  79. package/esm2022/lib/components/tenant-basic-details/tenant-basic-details.component.mjs +0 -95
  80. package/esm2022/lib/components/view-tenant-details/view-tenant-details.component.mjs +0 -708
  81. package/esm2022/lib/components/view-tenant-group-types/view-tenant-group-types.component.mjs +0 -174
  82. package/esm2022/lib/components/view-tenants-list/view-tenants-list.component.mjs +0 -334
  83. package/esm2022/lib/models/app-type-config.model.mjs +0 -2
  84. package/esm2022/lib/models/app-type.model.mjs +0 -7
  85. package/esm2022/lib/models/feature-permission-id.model.mjs +0 -8
  86. package/esm2022/lib/models/features.model.mjs +0 -2
  87. package/esm2022/lib/models/form-status.model.mjs +0 -7
  88. package/esm2022/lib/models/permission-type.model.mjs +0 -12
  89. package/esm2022/lib/models/role-menu-action.model.mjs +0 -7
  90. package/esm2022/lib/models/role-type.model.mjs +0 -2
  91. package/esm2022/lib/models/roles-and-permissions-table-type.model.mjs +0 -7
  92. package/esm2022/lib/models/roles-and-permissions.model.mjs +0 -2
  93. package/esm2022/lib/models/route-config.model.mjs +0 -2
  94. package/esm2022/lib/models/table-column-schema-view-tenant-list.model.mjs +0 -16
  95. package/esm2022/lib/models/tenant-function-type.model.mjs +0 -10
  96. package/esm2022/lib/models/tenant.model.mjs +0 -2
  97. package/esm2022/lib/models/tenants-permission.model.mjs +0 -2
  98. package/esm2022/lib/models/update-tenant-status.model.mjs +0 -2
  99. package/esm2022/lib/models/view-tenant-group-types.model.mjs +0 -9
  100. package/esm2022/lib/services/tenant-applications.service.mjs +0 -542
  101. package/esm2022/lib/services/tenant-permissions-map.service.mjs +0 -36
  102. package/esm2022/lib/services/tenant-permissions.service.mjs +0 -38
  103. package/esm2022/lib/tenant-applications.component.mjs +0 -14
  104. package/esm2022/lib/tenant-applications.module.mjs +0 -16
  105. package/esm2022/public-api.mjs +0 -34
  106. package/fesm2022/ieeesa-npm-tenants.mjs +0 -3565
  107. package/fesm2022/ieeesa-npm-tenants.mjs.map +0 -1
  108. package/index.d.ts +0 -5
  109. package/lib/assets/tenant-validations.d.ts +0 -11
  110. package/lib/components/create-modify-role/create-modify-role.component.d.ts +0 -103
  111. package/lib/components/create-tenant-application/create-tenant-application.component.d.ts +0 -128
  112. package/lib/components/roles-and-permissions-mapping/roles-and-permissions-mapping.component.d.ts +0 -106
  113. package/lib/components/tenant-basic-details/tenant-basic-details.component.d.ts +0 -408
  114. package/lib/components/view-tenant-details/view-tenant-details.component.d.ts +0 -216
  115. package/lib/components/view-tenant-group-types/view-tenant-group-types.component.d.ts +0 -58
  116. package/lib/components/view-tenants-list/view-tenants-list.component.d.ts +0 -134
  117. package/lib/models/app-type-config.model.d.ts +0 -14
  118. package/lib/models/app-type.model.d.ts +0 -4
  119. package/lib/models/feature-permission-id.model.d.ts +0 -4
  120. package/lib/models/features.model.d.ts +0 -15
  121. package/lib/models/form-status.model.d.ts +0 -4
  122. package/lib/models/permission-type.model.d.ts +0 -8
  123. package/lib/models/role-menu-action.model.d.ts +0 -4
  124. package/lib/models/role-type.model.d.ts +0 -27
  125. package/lib/models/roles-and-permissions-table-type.model.d.ts +0 -4
  126. package/lib/models/roles-and-permissions.model.d.ts +0 -119
  127. package/lib/models/route-config.model.d.ts +0 -4
  128. package/lib/models/table-column-schema-view-tenant-list.model.d.ts +0 -20
  129. package/lib/models/tenant-function-type.model.d.ts +0 -7
  130. package/lib/models/tenant.model.d.ts +0 -51
  131. package/lib/models/tenants-permission.model.d.ts +0 -9
  132. package/lib/models/update-tenant-status.model.d.ts +0 -14
  133. package/lib/models/view-tenant-group-types.model.d.ts +0 -27
  134. package/lib/services/tenant-applications.service.d.ts +0 -357
  135. package/lib/services/tenant-permissions-map.service.d.ts +0 -13
  136. package/lib/services/tenant-permissions.service.d.ts +0 -22
  137. package/lib/tenant-applications.component.d.ts +0 -5
  138. package/lib/tenant-applications.module.d.ts +0 -6
@@ -0,0 +1,1221 @@
1
+ import {
2
+ ComponentFixture,
3
+ TestBed,
4
+ fakeAsync,
5
+ flush,
6
+ tick,
7
+ } from '@angular/core/testing';
8
+ import { ViewTenantDetailsComponent } from './view-tenant-details.component';
9
+ import { TenantApplicationsService } from '../../services/tenant-applications.service';
10
+ import {
11
+ AlertType,
12
+ AlertsService,
13
+ GlobalErrorHandlerService,
14
+ } from '@ieeesa-npm/utility';
15
+ import { Observable } from 'rxjs';
16
+ import { TenantsMocks } from '../../assets/tenants-mock';
17
+ import {
18
+ HttpBackend,
19
+ HttpClient,
20
+ HttpErrorResponse,
21
+ HttpHandler,
22
+ } from '@angular/common/http';
23
+ import { RouterTestingModule } from '@angular/router/testing';
24
+ import { CommonModule } from '@angular/common';
25
+ import { MatDialogModule, MatDialogRef } from '@angular/material/dialog';
26
+ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
27
+ import { SharedService } from '@ieeesa-npm/shared';
28
+ import { AccordionInfo } from '@presentation/models/accordion-info.model';
29
+ import {
30
+ ModalComponent,
31
+ ModalConfirmationComponent,
32
+ RadioOption,
33
+ TableColumnType,
34
+ } from '@ieeesa-npm/presentation';
35
+ import { CreateTenantApplicationComponent } from '../create-tenant-application/create-tenant-application.component';
36
+ import { RolesAndPermissions } from '../../models/roles-and-permissions.model';
37
+ import { TableColumnSchema } from '@presentation/models/table-schema.model';
38
+ import { TenantPermissionsService } from '../../services/tenant-permissions.service';
39
+ import { PermissionType } from '../../models/permission-type.model';
40
+ import { TenantFunctionType } from '../../models/tenant-function-type.model';
41
+ import { RolesAndPermissionsMappingComponent } from '../roles-and-permissions-mapping/roles-and-permissions-mapping.component';
42
+
43
+ describe('ViewTenantDetailsComponent', () => {
44
+ let component: ViewTenantDetailsComponent;
45
+ let fixture: ComponentFixture<ViewTenantDetailsComponent>;
46
+ let tenantsService: TenantApplicationsService;
47
+ let sharedService: SharedService;
48
+ let globalErrorHandlerService: GlobalErrorHandlerService;
49
+ let userPermissionService: TenantPermissionsService;
50
+ let alertsService: AlertsService;
51
+ const dialogOptions = {
52
+ heading: 'Tenant A',
53
+ isCloseNeeded: true,
54
+ componentReference: CreateTenantApplicationComponent,
55
+ modalType: 1,
56
+ };
57
+ const mapRolesAndPermissionsDialogOptions = {
58
+ heading: 'Map Permissions & Roles',
59
+ isCloseNeeded: true,
60
+ componentReference: RolesAndPermissionsMappingComponent,
61
+ modalType: 1,
62
+ };
63
+ const mockRoutePath = {
64
+ viewTenants: 'tenants/view-tenants-list',
65
+ viewTenantDetails: 'tenants/view-tenant-details',
66
+ createTenant: 'tenants/create-tenant',
67
+ };
68
+ const mockServerErrorResponse = new HttpErrorResponse({
69
+ error: 'test',
70
+ });
71
+ const mockPayload = {
72
+ payload: {
73
+ offset: 0,
74
+ pageSize: 10,
75
+ },
76
+ };
77
+ const mockUserPermissionRoles = {
78
+ status: true,
79
+ message: 'SUCCESS',
80
+ body: {
81
+ totalRecords: 174,
82
+ rolePermissionDetails: [
83
+ {
84
+ permissionId: 'PERM_f85ac7b1-cd9e-4ca9-88c9-fac048c4de3b',
85
+ permissionName:
86
+ 'Create, View, Edit Delete Meeting Agenda Template(s)',
87
+ roleList: [
88
+ {
89
+ roleId: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
90
+ roleName: 'Admin',
91
+ },
92
+ {
93
+ roleId: 'ROLE_NESC_68041ee9-3035-4136-9091-db42700a6204',
94
+ roleName: 'NESC Secretary',
95
+ },
96
+ ],
97
+ },
98
+ {
99
+ permissionId: 'PERM_4239b766-c491-44a8-bc9e-38b46354a5b7',
100
+ permissionName: 'View Events, Meetings & Export Meetings',
101
+ roleList: [
102
+ {
103
+ roleId: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
104
+ roleName: 'Admin',
105
+ },
106
+ {
107
+ roleId: 'ROLE_NESC_68041ee9-3035-4136-9091-db42700a6204',
108
+ roleName: 'NESC Secretary',
109
+ },
110
+ {
111
+ roleId: 'ROLE_NESC_ec0ec0cb-94a6-482e-8c84-31c3eb2a1526',
112
+ roleName: 'Editor',
113
+ },
114
+ ],
115
+ },
116
+ ],
117
+ },
118
+ };
119
+ const mockUserRoles = {
120
+ status: true,
121
+ message: 'SUCCESS',
122
+ body: [
123
+ {
124
+ roleId: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
125
+ roleName: 'Admin',
126
+ roleTypeName: 'System',
127
+ roleType: '11',
128
+ viewOrder: 1,
129
+ },
130
+ {
131
+ roleId: 'ROLE_NESC_ec0ec0cb-94a6-482e-8c84-31c3eb2a1526',
132
+ roleName: 'Editor',
133
+ roleTypeName: 'Officer',
134
+ roleType: '22',
135
+ viewOrder: 2,
136
+ },
137
+ ],
138
+ };
139
+ const tableData = [
140
+ {
141
+ permission: 'Create, View, Edit Delete Meeting Agenda Template(s)',
142
+ roleIdsList: [
143
+ 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
144
+ 'ROLE_NESC_68041ee9-3035-4136-9091-db42700a6204',
145
+ ],
146
+ },
147
+ {
148
+ permission: 'View Events, Meetings & Export Meetings',
149
+ roleIdsList: [
150
+ 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
151
+ 'ROLE_NESC_68041ee9-3035-4136-9091-db42700a6204',
152
+ 'ROLE_NESC_ec0ec0cb-94a6-482e-8c84-31c3eb2a1526',
153
+ ],
154
+ },
155
+ ];
156
+ beforeEach(() => {
157
+ TestBed.configureTestingModule({
158
+ imports: [
159
+ RouterTestingModule,
160
+ ViewTenantDetailsComponent,
161
+ CommonModule,
162
+ BrowserAnimationsModule,
163
+ MatDialogModule,
164
+ ],
165
+ providers: [
166
+ SharedService,
167
+ HttpClient,
168
+ HttpHandler,
169
+ TenantApplicationsService,
170
+ GlobalErrorHandlerService,
171
+ HttpBackend,
172
+ AlertsService,
173
+ ],
174
+ });
175
+
176
+ fixture = TestBed.createComponent(ViewTenantDetailsComponent);
177
+ component = fixture.componentInstance;
178
+ tenantsService = TestBed.inject(TenantApplicationsService);
179
+ globalErrorHandlerService = TestBed.inject(GlobalErrorHandlerService);
180
+ sharedService = TestBed.inject(SharedService);
181
+ userPermissionService = TestBed.inject(TenantPermissionsService);
182
+ alertsService = TestBed.inject(AlertsService);
183
+ component.routePaths = mockRoutePath;
184
+ fixture.detectChanges();
185
+ });
186
+
187
+ it('should create the component', () => {
188
+ expect(component).toBeTruthy();
189
+ });
190
+ describe('#ngOnInit', () => {
191
+ it('should initialize routePaths', () => {
192
+ component.routePaths = mockRoutePath;
193
+ component.ngOnInit();
194
+ expect(component.routePaths).toEqual(mockRoutePath);
195
+ });
196
+ });
197
+ describe('#showTenantDetails', () => {
198
+ it('should set visibility for roles and permissions if accordion id is 2', () => {
199
+ const getRolesSpy = spyOn(component, 'getRolesAndInitializeTableSchema');
200
+ const accordionInfo: AccordionInfo = {
201
+ id: 2,
202
+ title: 'Roles and Permissions',
203
+ isDisabled: false,
204
+ };
205
+ component.showTenantDetails(accordionInfo, true);
206
+ expect(component.isRolesAndPermissionsExpanded).toBe(true);
207
+ expect(component.columnSchema).toEqual([]);
208
+ expect(getRolesSpy).toHaveBeenCalled();
209
+ });
210
+ it('should not set visibility for roles and permissions if accordion id is not 2', () => {
211
+ const accordionInfo: AccordionInfo = {
212
+ id: 1,
213
+ title: 'Basic Details',
214
+ isDisabled: false,
215
+ };
216
+ component.showTenantDetails(accordionInfo, true);
217
+ expect(component.isRolesAndPermissionsExpanded).toBe(false);
218
+ });
219
+ it('should set visibility for group types if accordion id is 3', () => {
220
+ const accordionInfo: AccordionInfo = {
221
+ id: 3,
222
+ title: 'Group Types',
223
+ isDisabled: false,
224
+ };
225
+ component.showTenantDetails(accordionInfo, true);
226
+ expect(component.isGroupTypesExpanded).toEqual(true);
227
+ });
228
+ });
229
+ describe('#getRoles', () => {
230
+ it('should call get roles', () => {
231
+ spyOn(tenantsService, 'getRoles').and.returnValue(
232
+ new Observable((subscriber) => {
233
+ subscriber.next(mockUserRoles);
234
+ })
235
+ );
236
+ component.getRolesAndInitializeTableSchema();
237
+ const columnSchema: TableColumnSchema[] = [
238
+ {
239
+ id: 0,
240
+ columnDef: 'permissions',
241
+ heading: 'PERMISSIONS',
242
+ columnType: TableColumnType.TEXT,
243
+ cellData: (element: RolesAndPermissions) => element.permission,
244
+ isStickyColumn: true,
245
+ },
246
+ {
247
+ id: 1,
248
+ columnDef: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
249
+ heading: 'Admin',
250
+ columnType: TableColumnType.TEXT,
251
+ hasColumnActions: true,
252
+ cellData: () => {
253
+ return;
254
+ },
255
+ },
256
+ {
257
+ id: 2,
258
+ columnDef: 'ROLE_NESC_ec0ec0cb-94a6-482e-8c84-31c3eb2a1526',
259
+ heading: 'Editor',
260
+ columnType: TableColumnType.TEXT,
261
+ hasColumnActions: true,
262
+ cellData: () => {
263
+ return;
264
+ },
265
+ },
266
+ ];
267
+ expect(component.columnSchema.length).toEqual(columnSchema.length);
268
+ expect(component.columnSchema[0].columnDef).toEqual(
269
+ columnSchema[0].columnDef
270
+ );
271
+ expect(component.columnSchema[1].columnDef).toEqual(
272
+ columnSchema[1].columnDef
273
+ );
274
+ });
275
+ it('should call get roles and sortRolesByRoleType on subscription and map correct data on columnSchema ', () => {
276
+ const unsortedMockUserRoles = {
277
+ status: true,
278
+ message: 'SUCCESS',
279
+ body: [
280
+ {
281
+ roleId: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
282
+ roleName: 'Admin',
283
+ roleTypeName: 'System',
284
+ roleType: '11',
285
+ viewOrder: 1,
286
+ },
287
+ {
288
+ roleId: 'ROLE_NESC_3a805b6b-963e-432f-96bf-7797ec7d6eb6',
289
+ roleName: 'Vice Chair',
290
+ roleTypeName: 'Member Level',
291
+ roleType: '33',
292
+ viewOrder: 3,
293
+ },
294
+ {
295
+ roleId: 'ROLE_NESC_46ea2d1a-8004-485f-b0bc-9237a5ae1eb2',
296
+ roleName: 'Non-Voter',
297
+ roleTypeName: 'Officer',
298
+ roleType: '22',
299
+ viewOrder: 2,
300
+ },
301
+ ],
302
+ };
303
+ spyOn(tenantsService, 'getRoles').and.returnValue(
304
+ new Observable((subscriber) => {
305
+ subscriber.next(unsortedMockUserRoles);
306
+ })
307
+ );
308
+ const columnSchema: TableColumnSchema[] = [
309
+ {
310
+ id: 0,
311
+ columnDef: 'permissions',
312
+ heading: 'PERMISSIONS',
313
+ columnType: TableColumnType.TEXT,
314
+ cellData: (element: RolesAndPermissions) => element.permission,
315
+ isStickyColumn: true,
316
+ },
317
+ {
318
+ id: 1,
319
+ columnDef: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
320
+ heading: 'Admin',
321
+ columnType: TableColumnType.TEXT,
322
+ hasColumnActions: true,
323
+ cellData: () => {
324
+ return;
325
+ },
326
+ },
327
+ {
328
+ id: 2,
329
+ columnDef: 'ROLE_NESC_46ea2d1a-8004-485f-b0bc-9237a5ae1eb2',
330
+ heading: 'Editor',
331
+ columnType: TableColumnType.TEXT,
332
+ hasColumnActions: true,
333
+ cellData: () => {
334
+ return;
335
+ },
336
+ },
337
+ {
338
+ id: 3,
339
+ columnDef: 'ROLE_NESC_3a805b6b-963e-432f-96bf-7797ec7d6eb6',
340
+ heading: 'Vice Chair',
341
+ columnType: TableColumnType.TEXT,
342
+ hasColumnActions: true,
343
+ cellData: () => {
344
+ return;
345
+ },
346
+ },
347
+ ];
348
+ component.getRolesAndInitializeTableSchema();
349
+ expect(component.columnSchema.length).toEqual(columnSchema.length);
350
+ expect(component.columnSchema[0].columnDef).toEqual(
351
+ columnSchema[0].columnDef
352
+ );
353
+ expect(component.columnSchema[1].columnDef).toEqual(
354
+ columnSchema[1].columnDef
355
+ );
356
+ expect(component.columnSchema[2].columnDef).toEqual(
357
+ columnSchema[2].columnDef
358
+ );
359
+ });
360
+ it('should set permissions value', () => {
361
+ spyOn(tenantsService, 'getRoles').and.returnValue(
362
+ new Observable((subscriber) => {
363
+ subscriber.next(mockUserRoles);
364
+ })
365
+ );
366
+ component.getRolesAndInitializeTableSchema();
367
+ component.columnSchema[0].cellData(tableData[0]);
368
+ expect(component.columnSchema[0].cellData(tableData[0])).toEqual(
369
+ 'Create, View, Edit Delete Meeting Agenda Template(s)'
370
+ );
371
+ });
372
+ it('should set yes value if role id presents in roleIdsList array', () => {
373
+ spyOn(tenantsService, 'getRoles').and.returnValue(
374
+ new Observable((subscriber) => {
375
+ subscriber.next(mockUserRoles);
376
+ })
377
+ );
378
+ component.getRolesAndInitializeTableSchema();
379
+ component.columnSchema[2].cellData(tableData[0]);
380
+ expect(component.columnSchema[2].cellData(tableData[0])).toEqual('No');
381
+ });
382
+ it('should set no value if role id is not presents in roleIdsList array', () => {
383
+ spyOn(tenantsService, 'getRoles').and.returnValue(
384
+ new Observable((subscriber) => {
385
+ subscriber.next(mockUserRoles);
386
+ })
387
+ );
388
+ component.getRolesAndInitializeTableSchema();
389
+ expect(component.columnSchema[2].cellData(tableData[1])).toEqual('Yes');
390
+ });
391
+ it('should throw custom error in retrieving getRoles', () => {
392
+ const mockGetViewTenantsErrorResponse = {
393
+ error: {
394
+ status: false,
395
+ message: 'No Role(s) found.',
396
+ body: { errorCodes: ['3007'] },
397
+ },
398
+ status: 404,
399
+ statusText: 'OK',
400
+ };
401
+ spyOn(tenantsService, 'getRoles').and.returnValue(
402
+ new Observable((subscriber) => {
403
+ subscriber.error(mockGetViewTenantsErrorResponse);
404
+ })
405
+ );
406
+ spyOn(sharedService, 'handleErrors').and.callThrough();
407
+ component.getRolesAndInitializeTableSchema();
408
+ expect(tenantsService.getRoles).toHaveBeenCalled();
409
+ expect(sharedService.handleErrors).toHaveBeenCalled();
410
+ });
411
+ it('should throw and handle global error in retrieving getRoles', () => {
412
+ const mockServerErrorResponse = new HttpErrorResponse({
413
+ error: 'test',
414
+ });
415
+ spyOn(tenantsService, 'getRoles').and.returnValue(
416
+ new Observable((subscriber) => {
417
+ subscriber.error(mockServerErrorResponse);
418
+ })
419
+ );
420
+ spyOn(globalErrorHandlerService, 'handleError');
421
+ component.getRolesAndInitializeTableSchema();
422
+ expect(globalErrorHandlerService.handleError).toHaveBeenCalledWith(
423
+ mockServerErrorResponse
424
+ );
425
+ });
426
+ });
427
+ describe('#getRolesAndPermissions', () => {
428
+ it('should call get rolesAndPermissions', () => {
429
+ spyOn(tenantsService, 'getRolesAndPermissionsMappings').and.returnValue(
430
+ new Observable((subscriber) => {
431
+ subscriber.next(mockUserPermissionRoles);
432
+ })
433
+ );
434
+ component.getRolesAndPermissionsAndInitializeTableView(mockPayload);
435
+ expect(component.tableData).toEqual(tableData);
436
+ });
437
+ it('should throw custom error in retrieving rolesAndPermissions', () => {
438
+ const mockGetViewTenantsErrorResponse = {
439
+ error: {
440
+ status: false,
441
+ message: 'Unable to fetch Roles and Permissions Mapping.',
442
+ body: { errorCodes: ['3009'] },
443
+ },
444
+ status: 404,
445
+ statusText: 'OK',
446
+ };
447
+ spyOn(tenantsService, 'getRolesAndPermissionsMappings').and.returnValue(
448
+ new Observable((subscriber) => {
449
+ subscriber.error(mockGetViewTenantsErrorResponse);
450
+ })
451
+ );
452
+ spyOn(sharedService, 'handleErrors').and.callThrough();
453
+ component.getRolesAndPermissionsAndInitializeTableView(mockPayload);
454
+ expect(tenantsService.getRolesAndPermissionsMappings).toHaveBeenCalled();
455
+ expect(sharedService.handleErrors).toHaveBeenCalled();
456
+ });
457
+ it('should throw and handle global error in retrieving rolesAndPermissions', () => {
458
+ const mockServerErrorResponse = new HttpErrorResponse({
459
+ error: 'test',
460
+ });
461
+ spyOn(tenantsService, 'getRolesAndPermissionsMappings').and.returnValue(
462
+ new Observable((subscriber) => {
463
+ subscriber.error(mockServerErrorResponse);
464
+ })
465
+ );
466
+ spyOn(globalErrorHandlerService, 'handleError');
467
+ component.getRolesAndPermissionsAndInitializeTableView(mockPayload);
468
+ expect(globalErrorHandlerService.handleError).toHaveBeenCalledWith(
469
+ mockServerErrorResponse
470
+ );
471
+ });
472
+ });
473
+ describe('#onTablePaginationChange', () => {
474
+ it('should call getRolesAndPermissionsAndInitializeTableView with updated offset or page index', () => {
475
+ const pageEvent = {
476
+ pageIndex: 1,
477
+ pageSize: 10,
478
+ length: 100,
479
+ };
480
+ const getRolesAndPermissionsAndInitializeTableViewSpy = spyOn(
481
+ component,
482
+ 'getRolesAndPermissionsAndInitializeTableView'
483
+ );
484
+ component.onTablePaginationChange(pageEvent);
485
+ expect(
486
+ getRolesAndPermissionsAndInitializeTableViewSpy
487
+ ).toHaveBeenCalledWith({
488
+ payload: {
489
+ pageSize: 10,
490
+ offset: 1,
491
+ },
492
+ });
493
+ });
494
+ });
495
+ describe('#trackByAccordionFn', () => {
496
+ it('should call trackByAccordionFn method', () => {
497
+ const accordionId = component.trackByAccordionFn(
498
+ 0,
499
+ TenantsMocks.MockTenantAccordionInfo[0] as AccordionInfo
500
+ );
501
+ expect(accordionId).toBe(1);
502
+ });
503
+ });
504
+ describe('#getTenantDetails', () => {
505
+ it('should call get view tenant details', () => {
506
+ const appId = 'SAAPPS';
507
+ spyOn(tenantsService, 'getTenantDetails').and.returnValue(
508
+ new Observable((subscriber) => {
509
+ subscriber.next(TenantsMocks.viewTenantDetailsMockResponse);
510
+ })
511
+ );
512
+ component.getTenantDetails(appId);
513
+ expect(component.tenantDetails).toEqual(
514
+ TenantsMocks.viewTenantDetailsMockResponse.body
515
+ );
516
+ });
517
+ it('should call get view tenant details for inactive tenant', () => {
518
+ const appId = 'SAAPPS';
519
+ const viewTenantDetailsMockResponse = JSON.parse(
520
+ JSON.stringify(TenantsMocks.viewTenantDetailsMockResponse)
521
+ );
522
+ viewTenantDetailsMockResponse.body.status = false;
523
+ spyOn(tenantsService, 'getTenantDetails').and.returnValue(
524
+ new Observable((subscriber) => {
525
+ subscriber.next(viewTenantDetailsMockResponse);
526
+ })
527
+ );
528
+ component.getTenantDetails(appId);
529
+ expect(component.tenantDetails).toEqual(
530
+ viewTenantDetailsMockResponse.body
531
+ );
532
+ });
533
+ it('should throw custom error in retrieving getTenantDetails', () => {
534
+ const mockGetViewTenantsErrorResponse = {
535
+ error: {
536
+ status: false,
537
+ message: 'Tenant Details not found.',
538
+ body: { errorCodes: ['2050'] },
539
+ },
540
+ status: 404,
541
+ statusText: 'OK',
542
+ };
543
+ spyOn(tenantsService, 'getTenantDetails').and.returnValue(
544
+ new Observable((subscriber) => {
545
+ subscriber.error(mockGetViewTenantsErrorResponse);
546
+ })
547
+ );
548
+ spyOn(sharedService, 'handleErrors').and.callThrough();
549
+ component.getTenantDetails('');
550
+ expect(tenantsService.getTenantDetails).toHaveBeenCalled();
551
+ expect(sharedService.handleErrors).toHaveBeenCalled();
552
+ });
553
+ it('should throw and handle global error in retrieving getTenantDetails', () => {
554
+ spyOn(tenantsService, 'getTenantDetails').and.returnValue(
555
+ new Observable((subscriber) => {
556
+ subscriber.error(mockServerErrorResponse);
557
+ })
558
+ );
559
+ spyOn(globalErrorHandlerService, 'handleError');
560
+ component.getTenantDetails('');
561
+ expect(globalErrorHandlerService.handleError).toHaveBeenCalledWith(
562
+ mockServerErrorResponse
563
+ );
564
+ });
565
+ });
566
+ describe('#openEditTenantForm', () => {
567
+ it('should call openEditTenantForm method and open modal', () => {
568
+ const spyOpenModal = spyOn(component, 'openModal');
569
+ spyOn(component.dialog, 'open').and.callThrough();
570
+ component.openEditTenantForm();
571
+ expect(spyOpenModal).toHaveBeenCalled();
572
+ fixture.detectChanges();
573
+ component.dialog.open(ModalComponent, {
574
+ data: dialogOptions,
575
+ width: 'auto',
576
+ panelClass: ['ieeesa-modal-dialog'],
577
+ ariaModal: true,
578
+ });
579
+ expect(component.dialog.open).toHaveBeenCalledWith(ModalComponent, {
580
+ data: dialogOptions,
581
+ width: 'auto',
582
+ panelClass: ['ieeesa-modal-dialog'],
583
+ ariaModal: true,
584
+ });
585
+ });
586
+ });
587
+ describe('#getRoleTypes', () => {
588
+ it('should call getRoleTypes and set select options', () => {
589
+ const mockRoleTypes = TenantsMocks.mockRoleTypesFormattedResponse;
590
+ spyOn(tenantsService, 'getRoleTypes').and.returnValue(
591
+ new Observable((subscriber) => {
592
+ subscriber.next(TenantsMocks.mockRoleTypesResponse);
593
+ })
594
+ );
595
+ component.getRoleTypes();
596
+ expect(component.roleTypeOptions).toEqual(mockRoleTypes);
597
+ });
598
+ it('should throw error in retrieving getRoleTypes', () => {
599
+ const getRoleTypesSpy = spyOn(
600
+ tenantsService,
601
+ 'getRoleTypes'
602
+ ).and.returnValue(
603
+ new Observable((subscriber) => {
604
+ subscriber.error(mockServerErrorResponse);
605
+ })
606
+ );
607
+ spyOn(globalErrorHandlerService, 'handleError');
608
+ component.getRoleTypes();
609
+ expect(getRoleTypesSpy).toHaveBeenCalled();
610
+ expect(globalErrorHandlerService.handleError).toHaveBeenCalledWith(
611
+ mockServerErrorResponse
612
+ );
613
+ });
614
+ it('should call openCreateRoleForm method and open modal after getting roleTypeOptions from http server', () => {
615
+ component.functionType = TenantFunctionType.CREATE_ROLE;
616
+ tenantsService.setTenantFunctionType(TenantFunctionType.CREATE_ROLE);
617
+ const openCreateRoleFormSpy = spyOn(
618
+ component,
619
+ 'openCreateRoleForm'
620
+ ).and.callThrough();
621
+ spyOn(tenantsService, 'getRoleTypes').and.returnValue(
622
+ new Observable((subscriber) => {
623
+ subscriber.next(TenantsMocks.mockRoleTypesResponse);
624
+ })
625
+ );
626
+ component.getRoleTypes();
627
+ expect(openCreateRoleFormSpy).toHaveBeenCalled();
628
+ });
629
+ });
630
+ describe('#openCreateRoleForm', () => {
631
+ it('should call openCreateRoleForm method and open modal', () => {
632
+ const spyOpenModal = spyOn(component, 'openModal');
633
+ const spySetFunction = spyOn(tenantsService, 'setTenantFunctionType');
634
+ spyOn(component.dialog, 'open').and.callThrough();
635
+ tenantsService.setTenantFunctionType(TenantFunctionType.CREATE_ROLE);
636
+ const functionType = TenantFunctionType.CREATE_ROLE;
637
+ component.roleTypeOptions = TenantsMocks.mockRoleTypesFormattedResponse;
638
+ component.openCreateRoleForm();
639
+ expect(spyOpenModal).toHaveBeenCalled();
640
+ expect(spySetFunction).toHaveBeenCalled();
641
+ expect(component.functionType).toEqual(functionType);
642
+ });
643
+ it('should call openCreateRoleForm method and open modal', () => {
644
+ const spyGetRoleTypes = spyOn(component, 'getRoleTypes');
645
+ component.roleTypeOptions = [];
646
+ component.openCreateRoleForm();
647
+ fixture.detectChanges();
648
+ expect(spyGetRoleTypes).toHaveBeenCalled();
649
+ });
650
+ });
651
+ describe('#openEditRoleForm', () => {
652
+ it('should call openEditRoleForm() and getRoleTypes() when roleTypeOptions is empty', () => {
653
+ const spyOpenModal = spyOn(component, 'openModal');
654
+ const spySetFunction = spyOn(tenantsService, 'setTenantFunctionType');
655
+ spyOn(component.dialog, 'open').and.callThrough();
656
+ const functionType = TenantFunctionType.EDIT_ROLE;
657
+ component.openEditRoleForm();
658
+ expect(spyOpenModal).toHaveBeenCalled();
659
+ fixture.detectChanges();
660
+ expect(spySetFunction).toHaveBeenCalled();
661
+ expect(component.functionType).toEqual(functionType);
662
+ });
663
+ });
664
+ describe('#openModal', () => {
665
+ it('should open create tenant modal with the provided className', () => {
666
+ spyOn(component.dialog, 'open').and.callThrough();
667
+ component.openModal(dialogOptions);
668
+ fixture.detectChanges();
669
+ component.dialog.open(ModalComponent, {
670
+ data: dialogOptions,
671
+ width: 'auto',
672
+ panelClass: ['ieeesa-modal-dialog'],
673
+ ariaModal: true,
674
+ });
675
+ expect(component.dialog.open).toHaveBeenCalledWith(ModalComponent, {
676
+ data: dialogOptions,
677
+ width: 'auto',
678
+ panelClass: ['ieeesa-modal-dialog'],
679
+ ariaModal: true,
680
+ });
681
+ });
682
+ it('should edit the tenant successfully', () => {
683
+ component.tenantDetails = TenantsMocks.viewTenantDetailsMockResponse.body;
684
+ spyOn(alertsService, 'showMessage').and.callThrough();
685
+ const showAlertMessageSpy = spyOn(sharedService, 'showAlertMessage');
686
+ component.functionType = TenantFunctionType.EDIT;
687
+ component.openModal(dialogOptions, 'ieeesa-modal-dialog');
688
+ component.dialogRef.componentInstance.submitFormResponse.next(
689
+ TenantsMocks.editTenantMockResponse
690
+ );
691
+ fixture.detectChanges();
692
+ expect(showAlertMessageSpy).toHaveBeenCalledOnceWith(
693
+ AlertType.SUCCESS,
694
+ 'IEEE SA Collaboration Portal has been updated successfully.'
695
+ );
696
+ });
697
+ it('should handle edit tenant form submission cancel', fakeAsync(() => {
698
+ component.openModal(dialogOptions, 'ieeesa-modal-dialog');
699
+ component.dialogRef.componentInstance.formCancel.next();
700
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
701
+ const dialogRefSpy = jasmine.createSpyObj<MatDialogRef<any>>(
702
+ 'MatDialogRef',
703
+ ['close']
704
+ );
705
+ expect(dialogRefSpy.close).toBeTruthy();
706
+ tick();
707
+ flush();
708
+ }));
709
+ it('should handle successful role creation and call getRolesAndPermissionsAndInitializeTableView with roleAndPermissionInfo', () => {
710
+ component.functionType = TenantFunctionType.CREATE_ROLE;
711
+ component.tenantDetails = TenantsMocks.tenantInfoMock;
712
+ tenantsService.setNewlyCreatedRoleInfo(TenantsMocks.mockCreateRoleInfo);
713
+ const getRolesAndInitializeTableSchemaSpy = spyOn(
714
+ component,
715
+ 'getRolesAndInitializeTableSchema'
716
+ );
717
+ const showAlertMessageSpy = spyOn(
718
+ sharedService,
719
+ 'showAlertMessage'
720
+ ).and.callThrough();
721
+ component.openModal(dialogOptions, 'ieeesa-create-role');
722
+ component.dialogRef.componentInstance.submitFormResponse.next(
723
+ TenantsMocks.createRoleMockResponse
724
+ );
725
+ fixture.detectChanges();
726
+ expect(showAlertMessageSpy).toHaveBeenCalledOnceWith(
727
+ AlertType.SUCCESS,
728
+ 'New Secretary has been successfully added to the SA Collaboration portal. You can map the permissions for the newly added role.'
729
+ );
730
+ expect(getRolesAndInitializeTableSchemaSpy).toHaveBeenCalled();
731
+ });
732
+ it('should handle successful role modification and call getRolesAndPermissionsAndInitializeTableView with roleAndPermissionInfo', () => {
733
+ component.functionType = TenantFunctionType.EDIT_ROLE;
734
+ component.tenantDetails = TenantsMocks.tenantInfoMock;
735
+ tenantsService.setNewlyCreatedRoleInfo(TenantsMocks.mockCreateRoleInfo);
736
+ const getRolesAndInitializeTableSchemaSpy = spyOn(
737
+ component,
738
+ 'getRolesAndInitializeTableSchema'
739
+ );
740
+ const showAlertMessageSpy = spyOn(
741
+ sharedService,
742
+ 'showAlertMessage'
743
+ ).and.callThrough();
744
+ component.openModal(dialogOptions, 'ieeesa-edit-role');
745
+ component.dialogRef.componentInstance.submitFormResponse.next(
746
+ TenantsMocks.editRoleMockResponse
747
+ );
748
+ fixture.detectChanges();
749
+ expect(showAlertMessageSpy).toHaveBeenCalledOnceWith(
750
+ AlertType.SUCCESS,
751
+ 'Secretary has been successfully edited for the SA Collaboration portal.'
752
+ );
753
+ expect(getRolesAndInitializeTableSchemaSpy).toHaveBeenCalled();
754
+ });
755
+ it('should call the getRolesAndInitializeTableSchema method to update the data table on formCancel event.', () => {
756
+ const functionTypeSpy = spyOn(
757
+ tenantsService,
758
+ 'getTenantFunctionType'
759
+ ).and.returnValue(TenantFunctionType.MAP_PERMISSION_AND_ROLE);
760
+ const getRolesAndInitializeTableSchemaSpy = spyOn(
761
+ component,
762
+ 'getRolesAndInitializeTableSchema'
763
+ );
764
+ component.openModal(
765
+ mapRolesAndPermissionsDialogOptions,
766
+ 'map-permissions-roles'
767
+ );
768
+ component.dialogRef.componentInstance.formCancel.next(false);
769
+ fixture.detectChanges();
770
+ expect(getRolesAndInitializeTableSchemaSpy).toHaveBeenCalled();
771
+ expect(functionTypeSpy).toHaveBeenCalled();
772
+ });
773
+ it('should call the getRolesAndInitializeTableSchema method to update the data table on modalConfirm event.', () => {
774
+ const functionTypeSpy = spyOn(
775
+ tenantsService,
776
+ 'getTenantFunctionType'
777
+ ).and.returnValue(TenantFunctionType.MAP_PERMISSION_AND_ROLE);
778
+ const getRolesAndInitializeTableSchemaSpy = spyOn(
779
+ component,
780
+ 'getRolesAndInitializeTableSchema'
781
+ );
782
+ component.openModal(
783
+ mapRolesAndPermissionsDialogOptions,
784
+ 'map-permissions-roles'
785
+ );
786
+ component.dialogRef.componentInstance.modalConfirm.next(false);
787
+ fixture.detectChanges();
788
+ expect(getRolesAndInitializeTableSchemaSpy).toHaveBeenCalled();
789
+ expect(functionTypeSpy).toHaveBeenCalled();
790
+ });
791
+ });
792
+
793
+ describe('#onSlideToggleChange', () => {
794
+ it('should open the tenant status confirmation modal when slide toggle event changes', () => {
795
+ const slideToggleOption = {
796
+ id: 1,
797
+ label: 'Active',
798
+ checked: true,
799
+ };
800
+ const openTenantStatusSpy = spyOn(
801
+ component,
802
+ 'openTenantStatusConfirmationModal'
803
+ ).and.callThrough();
804
+ component.onSlideToggleChange(slideToggleOption);
805
+ expect(openTenantStatusSpy).toHaveBeenCalledWith(
806
+ slideToggleOption?.checked
807
+ );
808
+ });
809
+ });
810
+ describe('#openTenantStatusConfirmationModal', () => {
811
+ it('should open the tenant confirmation modal to prompt the reactivate message', fakeAsync(() => {
812
+ const tenantStatus = true;
813
+ spyOn(component.dialog, 'open').and.callThrough();
814
+ component.tenantDetails = TenantsMocks.viewTenantDetailsMockResponse.body;
815
+ const modalOptions = Object.assign(
816
+ {},
817
+ TenantsMocks?.openUpdateTenantStatusConfirmationModalOptions
818
+ );
819
+ const promptMessage = modalOptions?.promptMessage;
820
+ const status = tenantStatus ? 'reactivate' : 'inactivate';
821
+ modalOptions.promptMessage = `${promptMessage} ${status} ${component?.tenantDetails?.appTitle}?`;
822
+ spyOn(tenantsService, 'updateTenantStatus').and.callThrough();
823
+ component.openTenantStatusConfirmationModal(tenantStatus);
824
+ fixture.detectChanges();
825
+ expect(component.dialog.open).toHaveBeenCalledWith(
826
+ ModalConfirmationComponent,
827
+ {
828
+ data: modalOptions,
829
+ width: 'auto',
830
+ autoFocus: 'dialog',
831
+ ariaLabel: 'Alert',
832
+ }
833
+ );
834
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
835
+ const dialogRefSpy = jasmine.createSpyObj<MatDialogRef<any>>(
836
+ 'MatDialogRef',
837
+ ['close']
838
+ );
839
+ component.dialogRef.afterClosed().next(true);
840
+ expect(tenantsService.updateTenantStatus).toHaveBeenCalled();
841
+ expect(dialogRefSpy).toBeDefined();
842
+ expect(component.dialogRef).toBeDefined();
843
+ tick();
844
+ flush();
845
+ }));
846
+ it('should open the tenant confirmation modal to prompt the inactivate message', fakeAsync(() => {
847
+ const tenantStatus = false;
848
+ spyOn(component.dialog, 'open').and.callThrough();
849
+ component.tenantDetails = TenantsMocks.viewTenantDetailsMockResponse.body;
850
+ const modalOptions = Object.assign(
851
+ {},
852
+ TenantsMocks?.openUpdateTenantStatusConfirmationModalOptions
853
+ );
854
+ const promptMessage = modalOptions?.promptMessage;
855
+ const status = tenantStatus ? 'reactivate' : 'inactivate';
856
+ modalOptions.promptMessage = `${promptMessage} ${status} ${component?.tenantDetails?.appTitle}?`;
857
+ spyOn(tenantsService, 'updateTenantStatus').and.callThrough();
858
+ component.openTenantStatusConfirmationModal(tenantStatus);
859
+ fixture.detectChanges();
860
+ expect(component.dialog.open).toHaveBeenCalledWith(
861
+ ModalConfirmationComponent,
862
+ {
863
+ data: modalOptions,
864
+ width: 'auto',
865
+ autoFocus: 'dialog',
866
+ ariaLabel: 'Alert',
867
+ }
868
+ );
869
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
870
+ const dialogRefSpy = jasmine.createSpyObj<MatDialogRef<any>>(
871
+ 'MatDialogRef',
872
+ ['close']
873
+ );
874
+ component.dialogRef.afterClosed().next(false);
875
+ expect(tenantsService.updateTenantStatus).not.toHaveBeenCalled();
876
+ expect(dialogRefSpy).toBeDefined();
877
+ expect(component.dialogRef).toBeDefined();
878
+ tick();
879
+ flush();
880
+ }));
881
+ });
882
+
883
+ describe('#updateTenantStatus', () => {
884
+ it('should update the tenant status successfully.', () => {
885
+ const mockUpdateTenantStatusResponse =
886
+ TenantsMocks.updateTenantStatusMockResponse;
887
+ spyOn(tenantsService, 'updateTenantStatus').and.returnValue(
888
+ new Observable((subscriber) => {
889
+ subscriber.next(mockUpdateTenantStatusResponse);
890
+ })
891
+ );
892
+ component.tenantDetails = TenantsMocks.viewTenantDetailsMockResponse.body;
893
+ component.updateTenantStatus(true);
894
+ tenantsService
895
+ .updateTenantStatus(TenantsMocks.updateTenantStatusMockPayload)
896
+ .subscribe((response) => {
897
+ expect(response).toEqual(mockUpdateTenantStatusResponse);
898
+ });
899
+ });
900
+ it('should update the tenant status successfully when slide toggle changed to inactive state', () => {
901
+ const mockUpdateTenantStatusResponse =
902
+ TenantsMocks.updateTenantStatusMockResponse;
903
+ spyOn(tenantsService, 'updateTenantStatus').and.returnValue(
904
+ new Observable((subscriber) => {
905
+ subscriber.next(mockUpdateTenantStatusResponse);
906
+ })
907
+ );
908
+ component.tenantDetails = TenantsMocks.viewTenantDetailsMockResponse.body;
909
+ component.updateTenantStatus(false);
910
+ tenantsService
911
+ .updateTenantStatus(TenantsMocks.updateTenantStatusMockPayload)
912
+ .subscribe((response) => {
913
+ expect(response).toEqual(mockUpdateTenantStatusResponse);
914
+ });
915
+ });
916
+ it('should show a custom error while appId is missing in the payload', () => {
917
+ const mockUpdateTenantsErrorResponse = {
918
+ error: {
919
+ status: false,
920
+ message: 'Tenant Details not found.',
921
+ body: { errorCodes: ['2050'] },
922
+ },
923
+ status: false,
924
+ statusText: 'OK',
925
+ };
926
+ spyOn(tenantsService, 'updateTenantStatus').and.returnValue(
927
+ new Observable((subscriber) => {
928
+ subscriber.error(mockUpdateTenantsErrorResponse);
929
+ })
930
+ );
931
+ spyOn(sharedService, 'handleErrors').and.callThrough();
932
+ component.updateTenantStatus(true);
933
+ expect(tenantsService.updateTenantStatus).toHaveBeenCalled();
934
+ expect(sharedService.handleErrors).toHaveBeenCalled();
935
+ });
936
+ it('should throw HttpErrorResponse while updating tenant status.', () => {
937
+ const mockServerErrorResponse = new HttpErrorResponse({
938
+ error: 'test',
939
+ });
940
+ spyOn(component, 'setSlideToggleStatus');
941
+ spyOn(tenantsService, 'updateTenantStatus').and.returnValue(
942
+ new Observable((subscriber) => {
943
+ subscriber.error(mockServerErrorResponse);
944
+ })
945
+ );
946
+ const handleErrorSpy = spyOn(sharedService, 'handleErrors');
947
+ component.updateTenantStatus(true);
948
+ expect(handleErrorSpy).toHaveBeenCalled();
949
+ expect(component.setSlideToggleStatus).toHaveBeenCalledWith(true);
950
+ });
951
+ });
952
+
953
+ describe('#getApplicationTypes', () => {
954
+ it('should call getApplicationTypes and set application types', () => {
955
+ const mockAppTypes: RadioOption[] =
956
+ TenantsMocks.mockAppTypesFormattedResponse;
957
+ spyOn(tenantsService, 'getApplicationTypes').and.returnValue(
958
+ new Observable((subscriber) => {
959
+ subscriber.next(TenantsMocks.mockAppTypesResponse);
960
+ })
961
+ );
962
+ component.getApplicationTypes();
963
+ expect(component.appTypeOptions).toEqual(mockAppTypes);
964
+ });
965
+ it('should throw error in retrieving getApplicationTypes', () => {
966
+ spyOn(tenantsService, 'getApplicationTypes').and.returnValue(
967
+ new Observable((subscriber) => {
968
+ subscriber.error(mockServerErrorResponse);
969
+ })
970
+ );
971
+ spyOn(globalErrorHandlerService, 'handleError');
972
+ component.getApplicationTypes();
973
+ expect(globalErrorHandlerService.handleError).toHaveBeenCalledWith(
974
+ mockServerErrorResponse
975
+ );
976
+ });
977
+ });
978
+
979
+ describe('#validateAccess', () => {
980
+ it('should call validateAccess method with MANAGE_TENANT permission type and return true', () => {
981
+ component.userTenantsPermissions =
982
+ TenantsMocks.mockGlobalTenantsPermissions;
983
+ const validateAccessPermissionSpy = spyOn(
984
+ userPermissionService,
985
+ 'validateAccessPermission'
986
+ ).and.callThrough();
987
+ const isPermissionAccessAllowed = component.validateAccess(
988
+ PermissionType.MANAGE_TENANT
989
+ );
990
+ expect(validateAccessPermissionSpy).toHaveBeenCalled();
991
+ expect(isPermissionAccessAllowed).toBeTrue();
992
+ });
993
+ });
994
+
995
+ describe('#openDeleteRoleModal', () => {
996
+ it('should open the delete role confirmation modal to prompt the confirmation message', fakeAsync(() => {
997
+ spyOn(component.dialog, 'open').and.callThrough();
998
+ component.tenantDetails = TenantsMocks.viewTenantDetailsMockResponse.body;
999
+ component.selectedRoleInfo = {
1000
+ roleId: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
1001
+ roleName: 'Admin',
1002
+ };
1003
+ const modalOptions = {
1004
+ ...TenantsMocks?.openUpdateTenantStatusConfirmationModalOptions,
1005
+ };
1006
+ modalOptions.promptMessage = `Are you sure you want to delete the ${component?.selectedRoleInfo?.roleName}? Deleting this role will remove all current assignments in the ${component?.tenantDetails?.appTitle}.`;
1007
+ spyOn(tenantsService, 'deleteRole').and.callThrough();
1008
+ component.openDeleteRoleModal();
1009
+ fixture.detectChanges();
1010
+ expect(component.dialog.open).toHaveBeenCalledWith(
1011
+ ModalConfirmationComponent,
1012
+ {
1013
+ data: modalOptions,
1014
+ width: '25%',
1015
+ panelClass: [
1016
+ 'ieeesa-modal-confirm-dialog',
1017
+ 'ieeesa-delete-role-confirm-dialog',
1018
+ ],
1019
+ autoFocus: 'dialog',
1020
+ ariaLabel: 'Alert',
1021
+ }
1022
+ );
1023
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1024
+ const dialogRefSpy = jasmine.createSpyObj<MatDialogRef<any>>(
1025
+ 'MatDialogRef',
1026
+ ['close']
1027
+ );
1028
+ component.dialogRef.afterClosed().next(true);
1029
+ expect(tenantsService.deleteRole).toHaveBeenCalled();
1030
+ expect(dialogRefSpy).toBeDefined();
1031
+ expect(component.dialogRef).toBeDefined();
1032
+ tick();
1033
+ flush();
1034
+ }));
1035
+ it('should set the focus to menu element if confirmation modal result is false', fakeAsync(() => {
1036
+ spyOn(component.dialog, 'open').and.callThrough();
1037
+ component.tenantDetails = TenantsMocks.viewTenantDetailsMockResponse.body;
1038
+ component.selectedRoleInfo = {
1039
+ roleId: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
1040
+ roleName: 'Admin',
1041
+ };
1042
+ spyOn(component, 'deleteRole').and.callThrough();
1043
+ const element = document.createElement('button');
1044
+ component.roleMenuElement = element;
1045
+ spyOn(component.roleMenuElement, 'focus').and.callThrough();
1046
+ component.openDeleteRoleModal();
1047
+ fixture.detectChanges();
1048
+ component.dialogRef.afterClosed().next(false);
1049
+ expect(component.roleMenuElement.focus).toHaveBeenCalled();
1050
+ expect(component.deleteRole).not.toHaveBeenCalled();
1051
+ tick();
1052
+ flush();
1053
+ }));
1054
+ });
1055
+
1056
+ describe('#deleteRole', () => {
1057
+ it('should delete the role successfully.', () => {
1058
+ spyOn(tenantsService, 'deleteRole').and.returnValue(
1059
+ new Observable((subscriber) => {
1060
+ subscriber.next(TenantsMocks.deleteRoleMockResponse);
1061
+ })
1062
+ );
1063
+ component.deleteRole();
1064
+ tenantsService
1065
+ .deleteRole(TenantsMocks.deleteRoleMockPayload)
1066
+ .subscribe((response) => {
1067
+ expect(response).toEqual(TenantsMocks.deleteRoleMockResponse);
1068
+ });
1069
+ });
1070
+ it('should show a custom error while role Id is missing in the payload', () => {
1071
+ const mockDeleteRolesErrorResponse = {
1072
+ error: {
1073
+ status: false,
1074
+ message: 'Role Id not found.',
1075
+ body: { errorCodes: ['3010'] },
1076
+ },
1077
+ status: false,
1078
+ statusText: 'OK',
1079
+ };
1080
+ spyOn(tenantsService, 'deleteRole').and.returnValue(
1081
+ new Observable((subscriber) => {
1082
+ subscriber.error(mockDeleteRolesErrorResponse);
1083
+ })
1084
+ );
1085
+ spyOn(sharedService, 'handleErrors').and.callThrough();
1086
+ component.deleteRole();
1087
+ expect(tenantsService.deleteRole).toHaveBeenCalled();
1088
+ expect(sharedService.handleErrors).toHaveBeenCalled();
1089
+ });
1090
+ it('should throw HttpErrorResponse while deleting a role.', () => {
1091
+ const mockServerErrorResponse = new HttpErrorResponse({
1092
+ error: 'test',
1093
+ });
1094
+ spyOn(tenantsService, 'deleteRole').and.returnValue(
1095
+ new Observable((subscriber) => {
1096
+ subscriber.error(mockServerErrorResponse);
1097
+ })
1098
+ );
1099
+ const handleErrorSpy = spyOn(sharedService, 'handleErrors');
1100
+ component.deleteRole();
1101
+ expect(handleErrorSpy).toHaveBeenCalled();
1102
+ });
1103
+ });
1104
+
1105
+ describe('#onRoleMenuClick', () => {
1106
+ it('should invoke openDeleteRoleModal when Delete Role is clicked from the roles and permissions table menu', () => {
1107
+ spyOn(component, 'openDeleteRoleModal');
1108
+ const mockRoleMenuClickEvent = {
1109
+ tableColumnInfo: {
1110
+ id: 1,
1111
+ columnDef: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
1112
+ heading: 'Admin',
1113
+ columnType: TableColumnType.TEXT,
1114
+ hasColumnActions: true,
1115
+ cellData: {},
1116
+ },
1117
+ menuActionInfo: {
1118
+ id: 2,
1119
+ label: 'Delete Role',
1120
+ ariaLabel: 'Delete Role',
1121
+ iconURL: '',
1122
+ toolTip: '',
1123
+ isToolTipNeeded: false,
1124
+ },
1125
+ };
1126
+ component.onRoleMenuClick(mockRoleMenuClickEvent);
1127
+ expect(component.selectedRoleInfo).toEqual(TenantsMocks.mockRoleInfo);
1128
+ expect(component.openDeleteRoleModal).toHaveBeenCalled();
1129
+ });
1130
+ it('should invoke openEditRoleForm when Edit Role is clicked from the roles and permissions table menu', () => {
1131
+ spyOn(component, 'openEditRoleForm');
1132
+ const mockRoleMenuClickEvent = {
1133
+ tableColumnInfo: {
1134
+ id: 1,
1135
+ columnDef: 'ROLE_NESC_edaf1dcc-229f-4d4c-9635-7ac732b4dfd8',
1136
+ heading: 'Admin',
1137
+ columnType: TableColumnType.TEXT,
1138
+ hasColumnActions: true,
1139
+ cellData: {},
1140
+ },
1141
+ menuActionInfo: {
1142
+ id: 1,
1143
+ label: 'Edit Role',
1144
+ ariaLabel: 'Edit Role',
1145
+ iconURL: '',
1146
+ toolTip: '',
1147
+ isToolTipNeeded: false,
1148
+ },
1149
+ };
1150
+ component.onRoleMenuClick(mockRoleMenuClickEvent);
1151
+ expect(component.selectedRoleInfo).toEqual(TenantsMocks.mockRoleInfo);
1152
+ expect(component.openEditRoleForm).toHaveBeenCalled();
1153
+ });
1154
+ });
1155
+ describe('#roleMenuHtmlElement', () => {
1156
+ it('should set the role menu HTML element', () => {
1157
+ const element = document.createElement('div');
1158
+ component.selectedRoleMenuElement(element);
1159
+ expect(component.roleMenuElement).toEqual(element);
1160
+ });
1161
+ });
1162
+ describe('#openMapRolesAndPermissions', () => {
1163
+ it('should call openMapRolesAndPermissionsForm method and open modal', () => {
1164
+ spyOn(component.dialog, 'open').and.callThrough();
1165
+ component.openMapRolesAndPermissionsForm();
1166
+ expect(component.dialog.open).toHaveBeenCalledWith(ModalComponent, {
1167
+ data: mapRolesAndPermissionsDialogOptions,
1168
+ width: '',
1169
+ panelClass: ['ieeesa-modal-dialog', 'ieeesa-map-permissions-and-roles'],
1170
+ ariaModal: true,
1171
+ });
1172
+ expect(component.dialogRef).toBeDefined();
1173
+ });
1174
+ });
1175
+ describe('#openCreateGroupTypeForm', () => {
1176
+ it('should call openCreateGroupForm method and open modal', () => {
1177
+ const spyOpenModal = spyOn(component, 'openModal');
1178
+ const spySetFunction = spyOn(tenantsService, 'setTenantFunctionType');
1179
+ spyOn(component.dialog, 'open').and.callThrough();
1180
+ tenantsService.setTenantFunctionType(
1181
+ TenantFunctionType.CREATE_GROUP_TYPE
1182
+ );
1183
+ const functionType = TenantFunctionType.CREATE_GROUP_TYPE;
1184
+ component.openCreateGroupTypeForm();
1185
+ component['tenantAppService'].setNewlyCreatedGroupTypeInfo(
1186
+ TenantsMocks.mockCreateGroupType
1187
+ );
1188
+ expect(spyOpenModal).toHaveBeenCalled();
1189
+ expect(spySetFunction).toHaveBeenCalled();
1190
+ expect(component.functionType).toEqual(functionType);
1191
+ });
1192
+ it('should handle successful group type creation and emit isGroupTypeAddedOrModified', () => {
1193
+ component.functionType = TenantFunctionType.CREATE_GROUP_TYPE;
1194
+ const showAlertMessageSpy = spyOn(sharedService, 'showAlertMessage');
1195
+ const groupTypeTableUpdatedSpyOn = spyOn(
1196
+ component['tenantAppService'].isGroupTypeAddedOrModified,
1197
+ 'next'
1198
+ );
1199
+ component['tenantAppService'].setNewlyCreatedGroupTypeInfo(
1200
+ TenantsMocks.mockCreateGroupType
1201
+ );
1202
+ component.openModal(dialogOptions, 'ieeesa-create-group-type');
1203
+ component.dialogRef.componentInstance.submitFormResponse.next(
1204
+ TenantsMocks.mockCreateGroupTypeSuccessResponse
1205
+ );
1206
+ fixture.detectChanges();
1207
+ expect(showAlertMessageSpy).toHaveBeenCalled();
1208
+ expect(groupTypeTableUpdatedSpyOn).toHaveBeenCalledWith(true);
1209
+ });
1210
+ });
1211
+ describe('#ngOnDestroy', () => {
1212
+ it('should perform necessary cleanup tasks on ngOnDestroy', () => {
1213
+ component.roleTypeOptions = [];
1214
+ spyOn(component.destroy$, 'unsubscribe');
1215
+ component.ngOnDestroy();
1216
+ expect(component.roleTypeOptions.length).toBe(0);
1217
+ expect(component.destroy$.unsubscribe).toHaveBeenCalled();
1218
+ expect(component.destroy$.next).toBeTruthy();
1219
+ });
1220
+ });
1221
+ });