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