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';
7 import _ from 'lodash';
8 import { ToastrModule } from 'ngx-toastr';
9 import { of as observableOf } from 'rxjs';
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';
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;
35 declarations: [RgwBucketFormComponent, RgwRateLimitComponent],
37 HttpClientTestingModule,
41 ToastrModule.forRoot(),
45 schemas: [NO_ERRORS_SCHEMA]
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);
58 it('should create', () => {
59 expect(component).toBeTruthy();
62 describe('bucketNameValidator', () => {
63 it('should validate empty name', fakeAsync(() => {
64 formHelper.expectErrorChange('bid', '', 'required', true);
68 describe('zonegroup and placement targets', () => {
69 it('should get zonegroup and placement targets', () => {
70 const payload: Record<string, any> = {
74 name: 'default-placement',
75 data_pool: 'default.rgw.buckets.data'
78 name: 'placement-target2',
79 data_pool: 'placement-target2.rgw.buckets.data'
83 getPlacementTargetsSpy.and.returnValue(observableOf(payload));
84 enumerateSpy.and.returnValue(observableOf([]));
85 fixture.detectChanges();
87 expect(component.zonegroup).toBe(payload.zonegroup);
88 const placementTargets = [];
89 for (const placementTarget of payload['placement_targets']) {
92 ] = `${placementTarget['name']} (pool: ${placementTarget['data_pool']})`;
93 placementTargets.push(placementTarget);
95 expect(component.placementTargets).toEqual(placementTargets);
99 describe('submit form', () => {
100 let notificationService: NotificationService;
103 spyOn(TestBed.inject(Router), 'navigate').and.stub();
104 notificationService = TestBed.inject(NotificationService);
105 spyOn(notificationService, 'show');
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();
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();
122 it('tests create success notification', () => {
123 spyOn(rgwBucketService, 'create').and.returnValue(observableOf([]));
124 component.editing = false;
125 component.bucketForm.markAsDirty();
127 expect(notificationService.show).toHaveBeenCalledWith(
128 NotificationType.success,
129 `Created Object Gateway bucket 'null'`
133 it('tests update success notification', () => {
134 spyOn(rgwBucketService, 'update').and.returnValue(observableOf([]));
135 component.editing = true;
136 component.bucketForm.markAsDirty();
138 expect(notificationService.show).toHaveBeenCalledWith(
139 NotificationType.success,
140 `Updated Object Gateway bucket 'null'.`
145 describe('mfa credentials', () => {
146 const checkMfaCredentialsVisibility = (
147 fakeResponse: object,
148 versioningChecked: boolean,
149 mfaDeleteChecked: boolean,
150 expectedVisibility: boolean
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
161 fixture.detectChanges();
162 fixture.whenStable().then(() => {
163 const mfaTokenSerial = fixture.debugElement.nativeElement.querySelector(
166 const mfaTokenPin = fixture.debugElement.nativeElement.querySelector('#mfa-token-pin');
167 if (expectedVisibility) {
168 expect(mfaTokenSerial).toBeTruthy();
169 expect(mfaTokenPin).toBeTruthy();
171 expect(mfaTokenSerial).toBeFalsy();
172 expect(mfaTokenPin).toBeFalsy();
177 it('inputs should be visible when required', () => {
178 checkMfaCredentialsVisibility(
180 versioning: RgwBucketVersioning.SUSPENDED,
181 mfa_delete: RgwBucketMfaDelete.DISABLED
187 checkMfaCredentialsVisibility(
189 versioning: RgwBucketVersioning.SUSPENDED,
190 mfa_delete: RgwBucketMfaDelete.DISABLED
196 checkMfaCredentialsVisibility(
198 versioning: RgwBucketVersioning.ENABLED,
199 mfa_delete: RgwBucketMfaDelete.DISABLED
205 checkMfaCredentialsVisibility(
207 versioning: RgwBucketVersioning.ENABLED,
208 mfa_delete: RgwBucketMfaDelete.ENABLED
214 checkMfaCredentialsVisibility(
216 versioning: RgwBucketVersioning.SUSPENDED,
217 mfa_delete: RgwBucketMfaDelete.DISABLED
223 checkMfaCredentialsVisibility(
225 versioning: RgwBucketVersioning.SUSPENDED,
226 mfa_delete: RgwBucketMfaDelete.ENABLED
232 checkMfaCredentialsVisibility(
234 versioning: RgwBucketVersioning.SUSPENDED,
235 mfa_delete: RgwBucketMfaDelete.ENABLED
241 checkMfaCredentialsVisibility(
243 versioning: RgwBucketVersioning.ENABLED,
244 mfa_delete: RgwBucketMfaDelete.ENABLED
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');
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();
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();
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();
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);
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');
303 it('should have the "pattern" error [1]', () => {
304 expectPatternLockError('-1');
307 it('should have the "pattern" error [2]', () => {
308 expectPatternLockError('1.2');
311 it('should have valid values [1]', () => {
312 expectValidLockInputs(true, 'Governance', '1');
315 it('should have valid values [2]', () => {
316 expectValidLockInputs(false, 'Compliance', '2');
320 describe('bucket replication', () => {
321 it('should validate replication input', () => {
322 formHelper.setValue('replication', true);
323 fixture.detectChanges();
324 formHelper.expectValid('replication');
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);
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();