diff --git a/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.spec.ts b/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.spec.ts index 9f14dd72c25..b83549a406e 100644 --- a/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.spec.ts +++ b/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.spec.ts @@ -18,6 +18,7 @@ import { DialogService } from 'app/modules/dialog/dialog.service'; import { CloudCredentialsSelectComponent, } from 'app/modules/forms/custom-selects/cloud-credentials-select/cloud-credentials-select.component'; +import { IxInputHarness } from 'app/modules/forms/ix-forms/components/ix-input/ix-input.harness'; import { IxSelectHarness } from 'app/modules/forms/ix-forms/components/ix-select/ix-select.harness'; import { SlideIn } from 'app/modules/slide-ins/slide-in'; import { SlideInRef } from 'app/modules/slide-ins/slide-in-ref'; @@ -335,7 +336,29 @@ describe('CloudSyncFormComponent', () => { }]); expect(slideInRef.close).toHaveBeenCalledWith({ response: existingTask, error: null }); }); + + it('checks payload when use invalid s3 credentials', async () => { + spectator.component.isCredentialInvalid$.next(true); + spectator.detectChanges(); + + const bucketInput = await loader.getHarness(IxInputHarness.with({ label: 'Bucket' })); + await bucketInput.setValue('selected'); + + expect(spectator.component.getPayload()).toEqual(expect.objectContaining({ + attributes: expect.objectContaining({ + bucket: 'selected', + }), + })); + + await bucketInput.setValue('test-bucket'); + expect(spectator.component.getPayload()).toEqual(expect.objectContaining({ + attributes: expect.objectContaining({ + bucket: 'test-bucket', + }), + })); + }); }); + describe('doesnt load buckets when user doesnt has roles', () => { beforeEach(() => { spectator = createComponent({ diff --git a/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.ts b/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.ts index e09b137826b..a64da89273e 100644 --- a/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.ts +++ b/src/app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component.ts @@ -12,6 +12,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy'; import { TranslateService, TranslateModule } from '@ngx-translate/core'; import { find, findIndex, isArray } from 'lodash-es'; import { + BehaviorSubject, EMPTY, Observable, forkJoin, of, } from 'rxjs'; @@ -164,6 +165,7 @@ export class CloudSyncFormComponent implements OnInit { bwlimit: [[] as string[]], }); + isCredentialInvalid$ = new BehaviorSubject(false); isLoading = false; bucketPlaceholder: string = helptextCloudSync.bucket_placeholder; bucketTooltip: string = helptextCloudSync.bucket_tooltip; @@ -268,6 +270,16 @@ export class CloudSyncFormComponent implements OnInit { ngOnInit(): void { this.getInitialData(); + + this.isCredentialInvalid$.pipe(untilDestroyed(this)).subscribe((value) => { + if (value) { + this.form.controls.bucket_input.enable(); + this.form.controls.bucket.disable(); + } else { + this.form.controls.bucket_input.disable(); + this.form.controls.bucket.enable(); + } + }); } setupForm(): void { @@ -427,14 +439,12 @@ export class CloudSyncFormComponent implements OnInit { } this.bucketOptions$ = of(bucketOptions); this.isLoading = false; - this.form.controls.bucket.enable(); - this.form.controls.bucket_input.disable(); + this.isCredentialInvalid$.next(false); this.cdr.markForCheck(); }, error: (error: unknown) => { this.isLoading = false; - this.form.controls.bucket.disable(); - this.form.controls.bucket_input.enable(); + this.isCredentialInvalid$.next(true); this.dialogService.closeAllDialogs(); this.cdr.markForCheck(); const apiError = extractApiError(error); @@ -637,7 +647,8 @@ export class CloudSyncFormComponent implements OnInit { } } - prepareData(formValue: FormValue): CloudSyncTaskUpdate { + getPayload(): CloudSyncTaskUpdate { + const formValue = this.form.value; const attributes: CloudSyncTaskUpdate['attributes'] = {}; const value: CloudSyncTaskUpdate = { @@ -709,6 +720,8 @@ export class CloudSyncFormComponent implements OnInit { if (formValue[name] !== undefined && formValue[name] !== null && formValue[name] !== '') { if (name === 'task_encryption') { attributes[name] = formValue[name] === '' ? null : formValue[name]; + } else if (name === 'bucket_input') { + attributes.bucket = formValue[name]; } else { attributes[name] = formValue[name]; } @@ -721,7 +734,7 @@ export class CloudSyncFormComponent implements OnInit { } onDryRun(): void { - const payload = this.prepareData(this.form.value); + const payload = this.getPayload(); this.dialogService.jobDialog( this.api.job('cloudsync.sync_onetime', [payload, { dry_run: true }]), { title: this.translate.instant(helptextCloudSync.job_dialog_title_dry_run) }, @@ -734,7 +747,7 @@ export class CloudSyncFormComponent implements OnInit { } onSubmit(): void { - const payload = this.prepareData(this.form.value); + const payload = this.getPayload(); this.isLoading = true; let request$: Observable; diff --git a/src/app/pages/data-protection/cloudsync/cloudsync-wizard/steps/cloudsync-what-and-when/cloudsync-what-and-when.component.ts b/src/app/pages/data-protection/cloudsync/cloudsync-wizard/steps/cloudsync-what-and-when/cloudsync-what-and-when.component.ts index 42aa731bfbd..f33eb454757 100644 --- a/src/app/pages/data-protection/cloudsync/cloudsync-wizard/steps/cloudsync-what-and-when/cloudsync-what-and-when.component.ts +++ b/src/app/pages/data-protection/cloudsync/cloudsync-wizard/steps/cloudsync-what-and-when/cloudsync-what-and-when.component.ts @@ -279,7 +279,7 @@ export class CloudSyncWhatAndWhenComponent implements OnInit, OnChanges { if (name === 'task_encryption') { attributes[name] = formValue[name] === '' ? null : formValue[name]; } else if (name === 'bucket_input') { - attributes['bucket'] = formValue[name]; + attributes.bucket = formValue[name]; } else { attributes[name] = formValue[name]; }