mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
[AAE-6660] FE - [ADF] Linked dropdown still contains old options when the rest api does not return results (#7454)
* [AAE-6660] FE - [ADF] Linked dropdown still contains old options when the rest api does not return results * * Added unit tests to the recent changes done on dropdown. * * Improved error message * My empty commit to kick start travis * * Fixed lint errors * * Fixed css lint error * * Fixed failing unit test
This commit is contained in:
@@ -29,4 +29,6 @@
|
||||
<error-widget [error]="field.validationSummary"></error-widget>
|
||||
<error-widget class="adf-dropdown-required-message" *ngIf="isInvalidFieldRequired()"
|
||||
required="{{ 'FORM.FIELD.REQUIRED' | translate }}"></error-widget>
|
||||
<error-widget class="adf-dropdown-failed-message" *ngIf="isRestApiFailed"
|
||||
required="{{ 'FORM.FIELD.REST_API_FAILED' | translate: { hostname: restApiHostName } }}"></error-widget>
|
||||
</div>
|
||||
|
@@ -19,5 +19,9 @@
|
||||
&-dropdown-required-message .adf-error-text-container {
|
||||
margin-top: 1px !important;
|
||||
}
|
||||
|
||||
&-dropdown-failed-message .adf-error-text-container {
|
||||
margin-top: 1px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { of } from 'rxjs';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { DropdownCloudWidgetComponent } from './dropdown-cloud.widget';
|
||||
import { FormFieldModel, FormModel, FormService, setupTestBed } from '@alfresco/adf-core';
|
||||
import { FormCloudService } from '../../../services/form-cloud.service';
|
||||
@@ -27,7 +27,8 @@ import {
|
||||
fakeOptionList,
|
||||
filterOptionList,
|
||||
mockConditionalEntries,
|
||||
mockRestDropdownOptions
|
||||
mockRestDropdownOptions,
|
||||
mockSecondRestDropdownOptions
|
||||
} from '../../../mocks/dropdown.mock';
|
||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
|
||||
@@ -78,7 +79,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
name: 'date-name',
|
||||
type: 'dropdown',
|
||||
readOnly: false,
|
||||
restUrl: 'fake-rest-url'
|
||||
restUrl: 'https://fake-rest-url'
|
||||
});
|
||||
widget.field.emptyOption = { id: 'empty', name: 'Choose one...' };
|
||||
widget.field.isVisible = true;
|
||||
@@ -134,7 +135,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
|
||||
it('should load data from restUrl and populate options', async () => {
|
||||
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(fakeOptionList));
|
||||
widget.field.restUrl = 'fake-rest-url';
|
||||
widget.field.restUrl = 'https://fake-rest-url';
|
||||
widget.field.optionType = 'rest';
|
||||
widget.field.restIdProperty = 'name';
|
||||
|
||||
@@ -159,8 +160,30 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
expect(optThree.nativeElement.innerText).toEqual('option_3');
|
||||
});
|
||||
|
||||
it('should show error message if the restUrl failed to fetch options', async () => {
|
||||
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(throwError('Failed to fetch options'));
|
||||
widget.field.restUrl = 'https://fake-rest-url';
|
||||
widget.field.optionType = 'rest';
|
||||
widget.field.restIdProperty = 'name';
|
||||
|
||||
widget.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const dropdown = fixture.debugElement.query(By.css('mat-select'));
|
||||
dropdown.nativeElement.click();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
|
||||
|
||||
expect(jsonDataSpy).toHaveBeenCalled();
|
||||
expect(widget.isRestApiFailed).toBe(true);
|
||||
expect(widget.field.options.length).toEqual(0);
|
||||
expect(failedErrorMsgElement.nativeElement.innerText.trim()).toBe('FORM.FIELD.REST_API_FAILED');
|
||||
});
|
||||
|
||||
it('should preselect dropdown widget value when Json (rest call) passed', async () => {
|
||||
widget.field.restUrl = 'fake-rest-url';
|
||||
widget.field.restUrl = 'https://fake-rest-url';
|
||||
widget.field.optionType = 'rest';
|
||||
widget.field.value = {
|
||||
id: 'opt1',
|
||||
@@ -188,7 +211,7 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
});
|
||||
|
||||
it('should preselect dropdown widget value when String (defined value) passed ', async () => {
|
||||
widget.field.restUrl = 'fake-rest-url';
|
||||
widget.field.restUrl = 'https://fake-rest-url';
|
||||
widget.field.optionType = 'rest';
|
||||
widget.field.value = 'opt1';
|
||||
|
||||
@@ -367,6 +390,44 @@ describe('DropdownCloudWidgetComponent', () => {
|
||||
expect(optTwo.context.value).toBe('MA');
|
||||
expect(optTwo.context.viewValue).toBe('MANCHESTER');
|
||||
});
|
||||
|
||||
it('should reset previous child options if the rest url failed for a linked dropdown', async () => {
|
||||
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(mockRestDropdownOptions));
|
||||
const mockParentDropdown = { id: 'parentDropdown', value: 'mock-value', validate: () => true };
|
||||
spyOn(widget.field.form, 'getFormFields').and.returnValue([mockParentDropdown]);
|
||||
|
||||
function selectParentOption(parentOptionName: string) {
|
||||
parentDropdown.value = parentOptionName;
|
||||
widget.selectionChangedForField(parentDropdown);
|
||||
fixture.detectChanges();
|
||||
}
|
||||
|
||||
selectParentOption('UK');
|
||||
await openSelect('child-dropdown-id');
|
||||
const failedErrorMsgElement1 = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
|
||||
|
||||
expect(widget.isRestApiFailed).toBe(false);
|
||||
expect(widget.field.options.length).toBe(2);
|
||||
expect(failedErrorMsgElement1).toBeNull();
|
||||
|
||||
jsonDataSpy.and.returnValue(throwError('Failed to fetch options'));
|
||||
selectParentOption('GR');
|
||||
await openSelect('child-dropdown-id');
|
||||
const failedErrorMsgElement2 = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
|
||||
|
||||
expect(widget.isRestApiFailed).toBe(true);
|
||||
expect(widget.field.options.length).toBe(0);
|
||||
expect(failedErrorMsgElement2.nativeElement.innerText.trim()).toBe('FORM.FIELD.REST_API_FAILED');
|
||||
|
||||
jsonDataSpy.and.returnValue(of(mockSecondRestDropdownOptions));
|
||||
selectParentOption('IT');
|
||||
await openSelect('child-dropdown-id');
|
||||
const failedErrorMsgElement3 = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
|
||||
|
||||
expect(widget.isRestApiFailed).toBe(false);
|
||||
expect(widget.field.options.length).toBe(2);
|
||||
expect(failedErrorMsgElement3).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Manual options', () => {
|
||||
|
@@ -59,6 +59,8 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
typeId = 'DropdownCloudWidgetComponent';
|
||||
HIDE_FILTER_LIMIT = 5;
|
||||
showInputFilter = false;
|
||||
isRestApiFailed = false;
|
||||
restApiHostName: string;
|
||||
list$: Observable<FormFieldOption[]>;
|
||||
filter$ = new BehaviorSubject<string>('');
|
||||
|
||||
@@ -93,14 +95,19 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
|
||||
private persistFieldOptionsFromRestApi() {
|
||||
if (this.isValidRestType()) {
|
||||
this.resetRestApiErrorMessage();
|
||||
const bodyParam = this.buildBodyParam();
|
||||
this.formCloudService.getRestWidgetData(this.field.form.id, this.field.id, bodyParam)
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe((result: FormFieldOption[]) => {
|
||||
this.resetRestApiErrorMessage();
|
||||
this.field.options = result;
|
||||
this.updateOptions();
|
||||
this.field.updateForm();
|
||||
}, (err) => this.handleError(err));
|
||||
}, (err) => {
|
||||
this.resetRestApiOptions();
|
||||
this.handleError(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,6 +136,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
if (this.isValidValue(value)) {
|
||||
this.isValidRestType() ? this.persistFieldOptionsFromRestApi() : this.persistFieldOptionsFromManualList(value);
|
||||
} else if (this.isDefaultValue(value)) {
|
||||
this.resetRestApiErrorMessage();
|
||||
this.addDefaultOption();
|
||||
}
|
||||
}
|
||||
@@ -253,4 +261,25 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
|
||||
takeUntil(this.onDestroy$)
|
||||
);
|
||||
}
|
||||
|
||||
resetRestApiErrorMessage() {
|
||||
this.isRestApiFailed = false;
|
||||
this.restApiHostName = '';
|
||||
}
|
||||
|
||||
resetRestApiOptions() {
|
||||
this.field.options = [];
|
||||
this.isRestApiFailed = true;
|
||||
this.restApiHostName = this.getRestUrlHostName();
|
||||
this.updateOptions();
|
||||
this.field.updateForm();
|
||||
}
|
||||
|
||||
private getRestUrlHostName(): string {
|
||||
try {
|
||||
return new URL(this.field?.restUrl).hostname;
|
||||
} catch {
|
||||
return this.field?.restUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -84,6 +84,11 @@ export const mockRestDropdownOptions: FormFieldOption[] = [
|
||||
{ id: 'MA', name: 'MANCHESTER' }
|
||||
];
|
||||
|
||||
export const mockSecondRestDropdownOptions: FormFieldOption[] = [
|
||||
{ id: 'MI', name: 'MILAN' },
|
||||
{ id: 'RM', name: 'ROME' }
|
||||
];
|
||||
|
||||
export const fakeOptionList: FormFieldOption[] = [
|
||||
{ id: 'opt_1', name: 'option_1' },
|
||||
{ id: 'opt_2', name: 'option_2' },
|
||||
|
Reference in New Issue
Block a user