From 88ab336d05daed173139cd57d71ef1e55495c4e3 Mon Sep 17 00:00:00 2001 From: Wojciech Duda <69160975+wojd0@users.noreply.github.com> Date: Tue, 5 Dec 2023 18:20:26 +0100 Subject: [PATCH] [AAE-18450] fixed form value not updating instantly on radio change (#9141) * [AAE-18450] fixed form value not updating instantly on radio change * [AAE-18450] added tests, removed material references * [AAE-18450] test enhancements * [AAE-18450] added label to filter --- .../radio-buttons-cloud.widget.spec.ts | 78 +++++++++++-------- .../radio-buttons-cloud.widget.ts | 2 +- 2 files changed, 45 insertions(+), 35 deletions(-) diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts index 073f96b1075..a783446a0c5 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.spec.ts @@ -22,13 +22,17 @@ import { FormCloudService } from '../../../services/form-cloud.service'; import { RadioButtonsCloudWidgetComponent } from './radio-buttons-cloud.widget'; import { ProcessServiceCloudTestingModule } from '../../../../testing/process-service-cloud.testing.module'; import { of, throwError } from 'rxjs'; -import { By } from '@angular/platform-browser'; +import { HarnessLoader } from '@angular/cdk/testing'; +import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'; +import { MatRadioButtonHarness, MatRadioGroupHarness } from '@angular/material/radio/testing'; +import { MatTooltipHarness } from '@angular/material/tooltip/testing'; describe('RadioButtonsCloudWidgetComponent', () => { let fixture: ComponentFixture; let widget: RadioButtonsCloudWidgetComponent; let formCloudService: FormCloudService; let element: HTMLElement; + let loader: HarnessLoader; const restOption: FormFieldOption[] = [ { id: 'opt-1', @@ -51,6 +55,7 @@ describe('RadioButtonsCloudWidgetComponent', () => { fixture = TestBed.createComponent(RadioButtonsCloudWidgetComponent); widget = fixture.componentInstance; element = fixture.nativeElement; + loader = TestbedHarnessEnvironment.loader(fixture); widget.field = new FormFieldModel(new FormModel(), { restUrl: '' }); }); @@ -124,18 +129,14 @@ describe('RadioButtonsCloudWidgetComponent', () => { expect(widgetLabel.innerText).toBe('radio-name-label*'); expect(widget.field.isValid).toBe(false); - const option = element.querySelector('#radio-id-opt-1 label'); - option.click(); + const option = await loader.getHarness(MatRadioButtonHarness.with({ label: 'opt-name-1' })); + await option.check(); - fixture.detectChanges(); - await fixture.whenStable(); - fixture.detectChanges(); - const selectedOption = element.querySelector('[class*="mat-radio-checked"]'); - expect(selectedOption.innerText).toBe('opt-name-1'); + await loader.getHarness(MatRadioButtonHarness.with({ checked: true, label: 'opt-name-1'})); expect(widget.field.isValid).toBe(true); }); - it('should set Radio Button as valid when required and not empty', () => { + it('should set Radio Button as valid when required and not empty', async () => { widget.field = new FormFieldModel(new FormModel({}), { id: 'radio-id', name: 'radio-name-label', @@ -149,8 +150,7 @@ describe('RadioButtonsCloudWidgetComponent', () => { }); fixture.detectChanges(); - const selectedOption = element.querySelector('[class*="mat-radio-checked"]'); - expect(selectedOption.innerText).toBe('opt-name-2'); + await loader.getHarness(MatRadioButtonHarness.with({ checked: true, label: 'opt-name-2' })); expect(widget.field.isValid).toBe(true); }); @@ -167,22 +167,22 @@ describe('RadioButtonsCloudWidgetComponent', () => { restUrl: 'http://mocky.com/mocky-12344', value: { id: 'opt-1' } }); - fixture.detectChanges(); - const selectedOption = element.querySelector('[class*="mat-radio-checked"]'); - expect(selectedOption.innerText).toBe('opt-name-1'); + + expect(widget.isChecked(widget.field.options[0])).toBeTrue(); expect(widget.field.isValid).toBe(true); }); - it('should show error message if the restUrl failed to fetch options', () => { + it('should show error message if the restUrl failed to fetch options', async () => { 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'; fixture.detectChanges(); - const radioButtons = element.querySelector('mat-radio-group'); - radioButtons.click(); + const radioButtons = await loader.getHarness(MatRadioGroupHarness); + await (await radioButtons.host()).click(); + fixture.detectChanges(); const errorMessage = element.querySelector('.adf-radio-group-error-message .adf-error-text'); @@ -192,6 +192,23 @@ describe('RadioButtonsCloudWidgetComponent', () => { expect(errorMessage.textContent).toBe('FORM.FIELD.REST_API_FAILED'); }); + it('should change the value of the form when an option is clicked', async () => { + const form = new FormModel({}); + widget.field = new FormFieldModel(form, { + id: 'radio-id', + name: 'radio-name-label', + type: FormFieldTypes.RADIO_BUTTONS, + options: restOption + }); + fixture.detectChanges(); + const formValueSpy = spyOn(widget.formService.formRulesEvent, 'next'); + const radioButton = await loader.getHarness(MatRadioButtonHarness.with({ label: 'opt-name-1' })); + await radioButton.check(); + + expect(widget.field.value).toEqual('opt-1'); + expect(formValueSpy).toHaveBeenCalled(); + }); + describe('when tooltip is set', () => { beforeEach(() => { @@ -205,28 +222,21 @@ describe('RadioButtonsCloudWidgetComponent', () => { }); it('should show tooltip', async () => { - const radioButtonsInput = element.querySelector('mat-radio-button'); - radioButtonsInput.dispatchEvent(new Event('mouseenter')); - await fixture.whenStable(); - fixture.detectChanges(); - - const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')).nativeElement; - expect(tooltipElement).toBeTruthy(); - expect(tooltipElement.textContent.trim()).toBe('my custom tooltip'); + const radioButton = await loader.getHarness(MatRadioButtonHarness); + await (await radioButton.host()).hover(); + const tooltip = await loader.getHarness(MatTooltipHarness); + expect(await tooltip.getTooltipText()).toBe('my custom tooltip'); }); it('should hide tooltip', async () => { - const radioButtonsInput = element.querySelector('mat-radio-button'); - radioButtonsInput.dispatchEvent(new Event('mouseenter')); - await fixture.whenStable(); - fixture.detectChanges(); + const radioButton = await loader.getHarness(MatRadioButtonHarness); + const tooltipElement = await loader.getHarness(MatTooltipHarness); - radioButtonsInput.dispatchEvent(new Event('mouseleave')); - await fixture.whenStable(); - fixture.detectChanges(); + await (await radioButton.host()).hover(); + expect(await tooltipElement.isOpen()).toBeTrue(); - const tooltipElement = fixture.debugElement.query(By.css('.mat-tooltip')); - expect(tooltipElement).toBeFalsy(); + await (await radioButton.host()).mouseAway(); + expect(await tooltipElement.isOpen()).toBeFalse(); }); }); }); diff --git a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts index 3b507b0f2e7..a99d4525ca5 100644 --- a/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts +++ b/lib/process-services-cloud/src/lib/form/components/widgets/radio-buttons/radio-buttons-cloud.widget.ts @@ -80,7 +80,7 @@ export class RadioButtonsCloudWidgetComponent extends WidgetComponent implements onOptionClick(optionSelected: any) { this.field.value = optionSelected; - this.fieldChanged.emit(this.field); + this.onFieldChanged(this.field); } handleError(error: any) {