]>
Commit | Line | Data |
---|---|---|
522d829b | 1 | import { HttpClientTestingModule } from '@angular/common/http/testing'; |
11fdf7f2 | 2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; |
9f95a23c | 3 | import { By } from '@angular/platform-browser'; |
39ae355f | 4 | import { RouterTestingModule } from '@angular/router/testing'; |
11fdf7f2 | 5 | |
39ae355f TL |
6 | import { ToastrModule } from 'ngx-toastr'; |
7 | import { SimplebarAngularModule } from 'simplebar-angular'; | |
9f95a23c TL |
8 | import { of } from 'rxjs'; |
9 | ||
f67539c2 TL |
10 | import { Permission, Permissions } from '~/app/shared/models/permissions'; |
11 | import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; | |
9f95a23c TL |
12 | import { |
13 | Features, | |
14 | FeatureTogglesMap, | |
15 | FeatureTogglesService | |
f67539c2 TL |
16 | } from '~/app/shared/services/feature-toggles.service'; |
17 | import { PrometheusAlertService } from '~/app/shared/services/prometheus-alert.service'; | |
18 | import { SummaryService } from '~/app/shared/services/summary.service'; | |
39ae355f | 19 | import { SharedModule } from '~/app/shared/shared.module'; |
f67539c2 | 20 | import { configureTestBed } from '~/testing/unit-test-helper'; |
11fdf7f2 | 21 | import { NavigationComponent } from './navigation.component'; |
39ae355f TL |
22 | import { NotificationsComponent } from '../notifications/notifications.component'; |
23 | import { AdministrationComponent } from '../administration/administration.component'; | |
24 | import { IdentityComponent } from '../identity/identity.component'; | |
25 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; | |
26 | import { DashboardHelpComponent } from '../dashboard-help/dashboard-help.component'; | |
11fdf7f2 | 27 | |
9f95a23c TL |
28 | function everythingPermittedExcept(disabledPermissions: string[] = []): any { |
29 | const permissions: Permissions = new Permissions({}); | |
30 | Object.keys(permissions).forEach( | |
31 | (key) => (permissions[key] = new Permission(disabledPermissions.includes(key) ? [] : ['read'])) | |
32 | ); | |
33 | return permissions; | |
34 | } | |
35 | ||
36 | function onlyPermitted(enabledPermissions: string[] = []): any { | |
37 | const permissions: Permissions = new Permissions({}); | |
38 | enabledPermissions.forEach((key) => (permissions[key] = new Permission(['read']))); | |
39 | return permissions; | |
40 | } | |
41 | ||
42 | function everythingEnabledExcept(features: Features[] = []): FeatureTogglesMap { | |
43 | const featureTogglesMap: FeatureTogglesMap = new FeatureTogglesMap(); | |
44 | features.forEach((key) => (featureTogglesMap[key] = false)); | |
45 | return featureTogglesMap; | |
46 | } | |
47 | ||
48 | function onlyEnabled(features: Features[] = []): FeatureTogglesMap { | |
49 | const featureTogglesMap: FeatureTogglesMap = new FeatureTogglesMap(); | |
50 | Object.keys(featureTogglesMap).forEach( | |
51 | (key) => (featureTogglesMap[key] = features.includes(<Features>key)) | |
52 | ); | |
53 | return featureTogglesMap; | |
54 | } | |
55 | ||
11fdf7f2 TL |
56 | describe('NavigationComponent', () => { |
57 | let component: NavigationComponent; | |
58 | let fixture: ComponentFixture<NavigationComponent>; | |
59 | ||
f6b5b4d7 | 60 | configureTestBed({ |
39ae355f TL |
61 | declarations: [ |
62 | NavigationComponent, | |
63 | NotificationsComponent, | |
64 | AdministrationComponent, | |
65 | DashboardHelpComponent, | |
66 | IdentityComponent | |
67 | ], | |
68 | imports: [ | |
69 | HttpClientTestingModule, | |
70 | SharedModule, | |
71 | ToastrModule.forRoot(), | |
72 | RouterTestingModule, | |
73 | SimplebarAngularModule, | |
74 | NgbModule | |
75 | ], | |
76 | providers: [AuthStorageService, SummaryService, FeatureTogglesService, PrometheusAlertService] | |
11fdf7f2 TL |
77 | }); |
78 | ||
79 | beforeEach(() => { | |
39ae355f TL |
80 | spyOn(TestBed.inject(AuthStorageService), 'getPermissions').and.callFake(() => |
81 | everythingPermittedExcept() | |
82 | ); | |
83 | ||
84 | spyOn(TestBed.inject(FeatureTogglesService), 'get').and.callFake(() => | |
85 | of(everythingEnabledExcept()) | |
86 | ); | |
87 | spyOn(TestBed.inject(SummaryService), 'subscribe').and.callFake(() => | |
88 | of({ health: { status: 'HEALTH_OK' } }) | |
89 | ); | |
90 | spyOn(TestBed.inject(PrometheusAlertService), 'getAlerts').and.callFake(() => of([])); | |
11fdf7f2 TL |
91 | fixture = TestBed.createComponent(NavigationComponent); |
92 | component = fixture.componentInstance; | |
39ae355f TL |
93 | fixture.detectChanges(); |
94 | }); | |
95 | ||
96 | afterEach(() => { | |
97 | fixture.destroy(); | |
11fdf7f2 TL |
98 | }); |
99 | ||
9f95a23c TL |
100 | describe('Test Permissions', () => { |
101 | const testCases: [string[], string[]][] = [ | |
102 | [ | |
103 | ['hosts'], | |
104 | [ | |
105 | '.tc_submenuitem_hosts', | |
106 | '.tc_submenuitem_cluster_inventory', | |
107 | '.tc_submenuitem_cluster_services' | |
108 | ] | |
109 | ], | |
110 | [['monitor'], ['.tc_submenuitem_cluster_monitor']], | |
111 | [['osd'], ['.tc_submenuitem_osds', '.tc_submenuitem_crush']], | |
1e59de90 TL |
112 | [ |
113 | ['configOpt'], | |
114 | ['.tc_submenuitem_configuration', '.tc_submenuitem_modules', '.tc_submenuitem_users'] | |
115 | ], | |
9f95a23c TL |
116 | [['log'], ['.tc_submenuitem_log']], |
117 | [['prometheus'], ['.tc_submenuitem_monitoring']], | |
118 | [['pool'], ['.tc_menuitem_pool']], | |
119 | [['rbdImage'], ['.tc_submenuitem_block_images']], | |
120 | [['rbdMirroring'], ['.tc_submenuitem_block_mirroring']], | |
121 | [['iscsi'], ['.tc_submenuitem_block_iscsi']], | |
122 | [['rbdImage', 'rbdMirroring', 'iscsi'], ['.tc_menuitem_block']], | |
123 | [['nfs'], ['.tc_menuitem_nfs']], | |
124 | [['cephfs'], ['.tc_menuitem_cephfs']], | |
125 | [ | |
126 | ['rgw'], | |
127 | [ | |
128 | '.tc_menuitem_rgw', | |
129 | '.tc_submenuitem_rgw_daemons', | |
130 | '.tc_submenuitem_rgw_buckets', | |
131 | '.tc_submenuitem_rgw_users' | |
132 | ] | |
133 | ] | |
134 | ]; | |
135 | ||
136 | for (const [disabledPermissions, selectors] of testCases) { | |
137 | it(`When disabled permissions: ${JSON.stringify( | |
138 | disabledPermissions | |
139 | )} => hidden: "${selectors}"`, () => { | |
140 | component.permissions = everythingPermittedExcept(disabledPermissions); | |
141 | component.enabledFeature$ = of(everythingEnabledExcept()); | |
142 | ||
143 | fixture.detectChanges(); | |
144 | for (const selector of selectors) { | |
145 | expect(fixture.debugElement.query(By.css(selector))).toBeFalsy(); | |
146 | } | |
147 | }); | |
148 | } | |
149 | ||
150 | for (const [enabledPermissions, selectors] of testCases) { | |
151 | it(`When enabled permissions: ${JSON.stringify( | |
152 | enabledPermissions | |
153 | )} => visible: "${selectors}"`, () => { | |
154 | component.permissions = onlyPermitted(enabledPermissions); | |
155 | component.enabledFeature$ = of(everythingEnabledExcept()); | |
156 | ||
157 | fixture.detectChanges(); | |
158 | for (const selector of selectors) { | |
159 | expect(fixture.debugElement.query(By.css(selector))).toBeTruthy(); | |
160 | } | |
161 | }); | |
162 | } | |
92f5a8d4 TL |
163 | }); |
164 | ||
9f95a23c TL |
165 | describe('Test FeatureToggles', () => { |
166 | const testCases: [Features[], string[]][] = [ | |
167 | [['rbd'], ['.tc_submenuitem_block_images']], | |
168 | [['mirroring'], ['.tc_submenuitem_block_mirroring']], | |
169 | [['iscsi'], ['.tc_submenuitem_block_iscsi']], | |
170 | [['rbd', 'mirroring', 'iscsi'], ['.tc_menuitem_block']], | |
171 | [['nfs'], ['.tc_menuitem_nfs']], | |
172 | [['cephfs'], ['.tc_menuitem_cephfs']], | |
173 | [ | |
174 | ['rgw'], | |
175 | [ | |
176 | '.tc_menuitem_rgw', | |
177 | '.tc_submenuitem_rgw_daemons', | |
178 | '.tc_submenuitem_rgw_buckets', | |
179 | '.tc_submenuitem_rgw_users' | |
180 | ] | |
181 | ] | |
182 | ]; | |
183 | ||
184 | for (const [disabledFeatures, selectors] of testCases) { | |
185 | it(`When disabled features: ${JSON.stringify( | |
186 | disabledFeatures | |
187 | )} => hidden: "${selectors}"`, () => { | |
188 | component.enabledFeature$ = of(everythingEnabledExcept(disabledFeatures)); | |
189 | component.permissions = everythingPermittedExcept(); | |
190 | ||
191 | fixture.detectChanges(); | |
192 | for (const selector of selectors) { | |
193 | expect(fixture.debugElement.query(By.css(selector))).toBeFalsy(); | |
194 | } | |
195 | }); | |
196 | } | |
197 | ||
198 | for (const [enabledFeatures, selectors] of testCases) { | |
199 | it(`When enabled features: ${JSON.stringify( | |
200 | enabledFeatures | |
201 | )} => visible: "${selectors}"`, () => { | |
202 | component.enabledFeature$ = of(onlyEnabled(enabledFeatures)); | |
203 | component.permissions = everythingPermittedExcept(); | |
92f5a8d4 | 204 | |
9f95a23c TL |
205 | fixture.detectChanges(); |
206 | for (const selector of selectors) { | |
207 | expect(fixture.debugElement.query(By.css(selector))).toBeTruthy(); | |
208 | } | |
209 | }); | |
210 | } | |
11fdf7f2 | 211 | }); |
f6b5b4d7 TL |
212 | |
213 | describe('showTopNotification', () => { | |
214 | const notification1 = 'notificationName1'; | |
215 | const notification2 = 'notificationName2'; | |
216 | ||
217 | beforeEach(() => { | |
218 | component.notifications = []; | |
219 | }); | |
220 | ||
221 | it('should show notification', () => { | |
222 | component.showTopNotification(notification1, true); | |
223 | expect(component.notifications.includes(notification1)).toBeTruthy(); | |
224 | expect(component.notifications.length).toBe(1); | |
225 | }); | |
226 | ||
227 | it('should not add a second notification if it is already shown', () => { | |
228 | component.showTopNotification(notification1, true); | |
229 | component.showTopNotification(notification1, true); | |
230 | expect(component.notifications.includes(notification1)).toBeTruthy(); | |
231 | expect(component.notifications.length).toBe(1); | |
232 | }); | |
233 | ||
234 | it('should add a second notification if the first one is different', () => { | |
235 | component.showTopNotification(notification1, true); | |
236 | component.showTopNotification(notification2, true); | |
237 | expect(component.notifications.includes(notification1)).toBeTruthy(); | |
238 | expect(component.notifications.includes(notification2)).toBeTruthy(); | |
239 | expect(component.notifications.length).toBe(2); | |
240 | }); | |
241 | ||
242 | it('should hide an active notification', () => { | |
243 | component.showTopNotification(notification1, true); | |
244 | expect(component.notifications.includes(notification1)).toBeTruthy(); | |
245 | expect(component.notifications.length).toBe(1); | |
246 | component.showTopNotification(notification1, false); | |
247 | expect(component.notifications.length).toBe(0); | |
248 | }); | |
249 | ||
250 | it('should not fail if it tries to hide an inactive notification', () => { | |
251 | expect(() => component.showTopNotification(notification1, false)).not.toThrow(); | |
252 | expect(component.notifications.length).toBe(0); | |
253 | }); | |
254 | ||
255 | it('should keep other notifications if it hides one', () => { | |
256 | component.showTopNotification(notification1, true); | |
257 | component.showTopNotification(notification2, true); | |
258 | expect(component.notifications.length).toBe(2); | |
259 | component.showTopNotification(notification2, false); | |
260 | expect(component.notifications.length).toBe(1); | |
261 | expect(component.notifications.includes(notification1)).toBeTruthy(); | |
262 | }); | |
263 | }); | |
11fdf7f2 | 264 | }); |