]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
44318eda88e165b9a26b21b73e12c94b141726a2
[ceph-ci.git] /
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
3 import { ReactiveFormsModule } from '@angular/forms';
4 import { Router } from '@angular/router';
5 import { RouterTestingModule } from '@angular/router/testing';
6
7 import _ from 'lodash';
8 import { ToastrModule } from 'ngx-toastr';
9 import { of as observableOf } from 'rxjs';
10
11 import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service';
12 import { RgwSiteService } from '~/app/shared/api/rgw-site.service';
13 import { RgwUserService } from '~/app/shared/api/rgw-user.service';
14 import { NotificationType } from '~/app/shared/enum/notification-type.enum';
15 import { NotificationService } from '~/app/shared/services/notification.service';
16 import { SharedModule } from '~/app/shared/shared.module';
17 import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
18 import { RgwBucketMfaDelete } from '../models/rgw-bucket-mfa-delete';
19 import { RgwBucketVersioning } from '../models/rgw-bucket-versioning';
20 import { RgwBucketFormComponent } from './rgw-bucket-form.component';
21
22 describe('RgwBucketFormComponent', () => {
23   let component: RgwBucketFormComponent;
24   let fixture: ComponentFixture<RgwBucketFormComponent>;
25   let rgwBucketService: RgwBucketService;
26   let getPlacementTargetsSpy: jasmine.Spy;
27   let rgwBucketServiceGetSpy: jasmine.Spy;
28   let enumerateSpy: jasmine.Spy;
29   let formHelper: FormHelper;
30
31   configureTestBed({
32     declarations: [RgwBucketFormComponent],
33     imports: [
34       HttpClientTestingModule,
35       ReactiveFormsModule,
36       RouterTestingModule,
37       SharedModule,
38       ToastrModule.forRoot()
39     ]
40   });
41
42   beforeEach(() => {
43     fixture = TestBed.createComponent(RgwBucketFormComponent);
44     component = fixture.componentInstance;
45     rgwBucketService = TestBed.inject(RgwBucketService);
46     rgwBucketServiceGetSpy = spyOn(rgwBucketService, 'get');
47     getPlacementTargetsSpy = spyOn(TestBed.inject(RgwSiteService), 'get');
48     enumerateSpy = spyOn(TestBed.inject(RgwUserService), 'enumerate');
49     formHelper = new FormHelper(component.bucketForm);
50   });
51
52   it('should create', () => {
53     expect(component).toBeTruthy();
54   });
55
56   describe('bucketNameValidator', () => {
57     it('should validate empty name', fakeAsync(() => {
58       formHelper.expectErrorChange('bid', '', 'required', true);
59     }));
60   });
61
62   describe('zonegroup and placement targets', () => {
63     it('should get zonegroup and placement targets', () => {
64       const payload: Record<string, any> = {
65         zonegroup: 'default',
66         placement_targets: [
67           {
68             name: 'default-placement',
69             data_pool: 'default.rgw.buckets.data'
70           },
71           {
72             name: 'placement-target2',
73             data_pool: 'placement-target2.rgw.buckets.data'
74           }
75         ]
76       };
77       getPlacementTargetsSpy.and.returnValue(observableOf(payload));
78       enumerateSpy.and.returnValue(observableOf([]));
79       fixture.detectChanges();
80
81       expect(component.zonegroup).toBe(payload.zonegroup);
82       const placementTargets = [];
83       for (const placementTarget of payload['placement_targets']) {
84         placementTarget[
85           'description'
86         ] = `${placementTarget['name']} (pool: ${placementTarget['data_pool']})`;
87         placementTargets.push(placementTarget);
88       }
89       expect(component.placementTargets).toEqual(placementTargets);
90     });
91   });
92
93   describe('submit form', () => {
94     let notificationService: NotificationService;
95
96     beforeEach(() => {
97       spyOn(TestBed.inject(Router), 'navigate').and.stub();
98       notificationService = TestBed.inject(NotificationService);
99       spyOn(notificationService, 'show');
100     });
101
102     it('should validate name', () => {
103       component.editing = false;
104       component.createForm();
105       const control = component.bucketForm.get('bid');
106       expect(_.isFunction(control.asyncValidator)).toBeTruthy();
107     });
108
109     it('should not validate name', () => {
110       component.editing = true;
111       component.createForm();
112       const control = component.bucketForm.get('bid');
113       expect(control.asyncValidator).toBeNull();
114     });
115
116     it('tests create success notification', () => {
117       spyOn(rgwBucketService, 'create').and.returnValue(observableOf([]));
118       component.editing = false;
119       component.bucketForm.markAsDirty();
120       component.submit();
121       expect(notificationService.show).toHaveBeenCalledWith(
122         NotificationType.success,
123         `Created Object Gateway bucket 'null'`
124       );
125     });
126
127     it('tests update success notification', () => {
128       spyOn(rgwBucketService, 'update').and.returnValue(observableOf([]));
129       component.editing = true;
130       component.bucketForm.markAsDirty();
131       component.submit();
132       expect(notificationService.show).toHaveBeenCalledWith(
133         NotificationType.success,
134         `Updated Object Gateway bucket 'null'.`
135       );
136     });
137   });
138
139   describe('mfa credentials', () => {
140     const checkMfaCredentialsVisibility = (
141       fakeResponse: object,
142       versioningChecked: boolean,
143       mfaDeleteChecked: boolean,
144       expectedVisibility: boolean
145     ) => {
146       component['route'].params = observableOf({ bid: 'bid' });
147       component.editing = true;
148       rgwBucketServiceGetSpy.and.returnValue(observableOf(fakeResponse));
149       enumerateSpy.and.returnValue(observableOf([]));
150       component.ngOnInit();
151       component.bucketForm.patchValue({
152         versioning: versioningChecked,
153         'mfa-delete': mfaDeleteChecked
154       });
155       fixture.detectChanges();
156
157       const mfaTokenSerial = fixture.debugElement.nativeElement.querySelector('#mfa-token-serial');
158       const mfaTokenPin = fixture.debugElement.nativeElement.querySelector('#mfa-token-pin');
159       if (expectedVisibility) {
160         expect(mfaTokenSerial).toBeTruthy();
161         expect(mfaTokenPin).toBeTruthy();
162       } else {
163         expect(mfaTokenSerial).toBeFalsy();
164         expect(mfaTokenPin).toBeFalsy();
165       }
166     };
167
168     it('inputs should be visible when required', () => {
169       checkMfaCredentialsVisibility(
170         {
171           versioning: RgwBucketVersioning.SUSPENDED,
172           mfa_delete: RgwBucketMfaDelete.DISABLED
173         },
174         false,
175         false,
176         false
177       );
178       checkMfaCredentialsVisibility(
179         {
180           versioning: RgwBucketVersioning.SUSPENDED,
181           mfa_delete: RgwBucketMfaDelete.DISABLED
182         },
183         true,
184         false,
185         false
186       );
187       checkMfaCredentialsVisibility(
188         {
189           versioning: RgwBucketVersioning.ENABLED,
190           mfa_delete: RgwBucketMfaDelete.DISABLED
191         },
192         false,
193         false,
194         false
195       );
196       checkMfaCredentialsVisibility(
197         {
198           versioning: RgwBucketVersioning.ENABLED,
199           mfa_delete: RgwBucketMfaDelete.ENABLED
200         },
201         true,
202         true,
203         false
204       );
205       checkMfaCredentialsVisibility(
206         {
207           versioning: RgwBucketVersioning.SUSPENDED,
208           mfa_delete: RgwBucketMfaDelete.DISABLED
209         },
210         false,
211         true,
212         true
213       );
214       checkMfaCredentialsVisibility(
215         {
216           versioning: RgwBucketVersioning.SUSPENDED,
217           mfa_delete: RgwBucketMfaDelete.ENABLED
218         },
219         false,
220         false,
221         true
222       );
223       checkMfaCredentialsVisibility(
224         {
225           versioning: RgwBucketVersioning.SUSPENDED,
226           mfa_delete: RgwBucketMfaDelete.ENABLED
227         },
228         true,
229         true,
230         true
231       );
232       checkMfaCredentialsVisibility(
233         {
234           versioning: RgwBucketVersioning.ENABLED,
235           mfa_delete: RgwBucketMfaDelete.ENABLED
236         },
237         false,
238         true,
239         true
240       );
241     });
242   });
243
244   describe('object locking', () => {
245     const expectPatternLockError = (value: string) => {
246       formHelper.setValue('lock_enabled', true, true);
247       formHelper.setValue('lock_retention_period_days', value);
248       formHelper.expectError('lock_retention_period_days', 'pattern');
249     };
250
251     const expectValidLockInputs = (enabled: boolean, mode: string, days: string) => {
252       formHelper.setValue('lock_enabled', enabled);
253       formHelper.setValue('lock_mode', mode);
254       formHelper.setValue('lock_retention_period_days', days);
255       ['lock_enabled', 'lock_mode', 'lock_retention_period_days'].forEach((name) => {
256         const control = component.bucketForm.get(name);
257         expect(control.valid).toBeTruthy();
258         expect(control.errors).toBeNull();
259       });
260     };
261
262     it('should check lock enabled checkbox [mode=create]', () => {
263       component.createForm();
264       const control = component.bucketForm.get('lock_enabled');
265       expect(control.disabled).toBeFalsy();
266     });
267
268     it('should check lock enabled checkbox [mode=edit]', () => {
269       component.editing = true;
270       component.createForm();
271       const control = component.bucketForm.get('lock_enabled');
272       expect(control.disabled).toBeTruthy();
273     });
274
275     it('should not have the "lockDays" error for 10 days', () => {
276       formHelper.setValue('lock_enabled', true);
277       const control = component.bucketForm.get('lock_retention_period_days');
278       control.updateValueAndValidity();
279       expect(control.value).toBe(10);
280       expect(control.invalid).toBeFalsy();
281       formHelper.expectValid(control);
282     });
283
284     it('should have the "lockDays" error for 0 days', () => {
285       formHelper.setValue('lock_enabled', true);
286       formHelper.setValue('lock_retention_period_days', 0);
287       const control = component.bucketForm.get('lock_retention_period_days');
288       control.updateValueAndValidity();
289       expect(control.value).toBe(0);
290       expect(control.invalid).toBeTruthy();
291       formHelper.expectError(control, 'lockDays');
292     });
293
294     it('should have the "pattern" error [1]', () => {
295       expectPatternLockError('-1');
296     });
297
298     it('should have the "pattern" error [2]', () => {
299       expectPatternLockError('1.2');
300     });
301
302     it('should have valid values [1]', () => {
303       expectValidLockInputs(true, 'Governance', '1');
304     });
305
306     it('should have valid values [2]', () => {
307       expectValidLockInputs(false, 'Compliance', '2');
308     });
309   });
310 });