From b5b3ff6674f8258cc0b9abf57b7187abe4f72be9 Mon Sep 17 00:00:00 2001 From: MichalKinas <113341662+MichalKinas@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:13:33 +0100 Subject: [PATCH] [ACS-6812] Add new chip only when input value is valid (#9358) * [ACS-6812] Add new chip only when input value is valid * [ACS-6812] CR fixes * [ACS-6812] Expectations fixed in unit tests * [ACS-6812] Remove code duplications * [ACS-6812] Remove fdescribe * [ACS-6812] Duplications removal * [ACS-6812] Remove duplicated tests * [ACS-6812] Missing semicolon --- .../card-view-textitem.component.spec.ts | 115 ++++++++++-------- .../card-view-textitem.component.ts | 18 +-- .../src/lib/pipes/decimal-number.pipe.spec.ts | 4 + lib/core/src/lib/pipes/decimal-number.pipe.ts | 7 +- 4 files changed, 86 insertions(+), 58 deletions(-) diff --git a/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.spec.ts b/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.spec.ts index 9a05e55e86..49cf085459 100644 --- a/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.spec.ts +++ b/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.spec.ts @@ -25,9 +25,9 @@ import { CardViewItemFloatValidator } from '../../validators/card-view-item-floa import { CardViewItemIntValidator } from '../../validators/card-view-item-int.validator'; import { CardViewIntItemModel } from '../../models/card-view-intitem.model'; import { CardViewFloatItemModel } from '../../models/card-view-floatitem.model'; -import { MatChipsModule } from '@angular/material/chips'; +import { MatChipInputEvent, MatChipsModule } from '@angular/material/chips'; import { ClipboardService } from '../../../clipboard/clipboard.service'; -import { SimpleChange } from '@angular/core'; +import { DebugElement, SimpleChange } from '@angular/core'; import { TranslateModule } from '@ngx-translate/core'; import { CardViewItemValidator } from '../../interfaces/card-view-item-validator.interface'; import { HarnessLoader } from '@angular/cdk/testing'; @@ -41,23 +41,36 @@ describe('CardViewTextItemComponent', () => { const expectedErrorMessages = [{ message: 'Something went wrong' } as CardViewItemValidator]; - const updateTextField = (key, value) => { - const editInput = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-value-${key}"]`)); - editInput.nativeElement.value = value; - editInput.nativeElement.dispatchEvent(new Event('input')); + const getTextField = (key: string): HTMLInputElement => { + return fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-value-${key}"]`)).nativeElement; + }; + + const updateTextField = (key: string, value) => { + const editInput = getTextField(key); + editInput.value = value; + editInput.dispatchEvent(new Event('input')); fixture.detectChanges(); }; - const getTextFieldValue = (key): string => { - const textItemInput = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-value-${key}"]`)); + const getTextFieldValue = (key: string): string => { + const textItemInput = getTextField(key); expect(textItemInput).not.toBeNull(); - return textItemInput.nativeElement.value; + return textItemInput.value; }; - const getTextFieldError = (key): string => { - const textItemInputError = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-error-${key}"] li`)); - expect(textItemInputError).not.toBeNull(); - return textItemInputError.nativeElement.innerText; + const getErrorElements = (key: string, includeItems = false): DebugElement[] => { + return fixture.debugElement.queryAll(By.css(`[data-automation-id="card-textitem-error-${key}"]${includeItems ? ' li' : ''}`)); + }; + + const getTextFieldError = (key: string): string => { + const textItemInputErrors = getErrorElements(key, true); + expect(textItemInputErrors.length).not.toBe(0); + return textItemInputErrors[0].nativeElement.innerText; + }; + + const verifyNoErrors = (key: string) => { + const errorElement = getErrorElements(key); + expect(errorElement.length).toBe(0); }; const checkCtrlZActions = (ctrlKeyValue: boolean, codeValue: string, metaKeyValue: boolean, mockTestValue: string, flag: boolean) => { @@ -208,7 +221,7 @@ describe('CardViewTextItemComponent', () => { editable: true, multivalued: true }; - renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, 'item1', 'item2', 'item3'); + await renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, 'item1', 'item2', 'item3'); }); it('should render chips for multivalue integers when chips are enabled', async () => { @@ -219,7 +232,7 @@ describe('CardViewTextItemComponent', () => { editable: true, multivalued: true }; - renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, '1', '2', '3'); + await renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, '1', '2', '3'); }); it('should render chips for multivalue decimal numbers when chips are enabled', async () => { @@ -230,7 +243,36 @@ describe('CardViewTextItemComponent', () => { editable: true, multivalued: true }; - renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, '1.1', '2.2', '3.3'); + await renderChipsForMultiValuedProperties(cardViewTextItemObject, true, 3, '1.1', '2.2', '3.3'); + }); + + it('should only render new chip when provided value is valid for specified validators set', async () => { + const cardViewTextItemFloatObject = { + label: 'Test label', + value: [10, 20.2, 35.8], + key: 'textkey', + editable: true, + multivalued: true, + type: 'float' + }; + component.editable = true; + await renderChipsForMultiValuedProperties(cardViewTextItemFloatObject, true, 3, '10', '20.2', '35.8'); + const floatValidator: CardViewItemValidator = new CardViewItemFloatValidator(); + component.property.validators = [floatValidator]; + const inputElement = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-editchipinput-textkey"]')).nativeElement; + component.addValueToList({ value: 'abcd', chipInput: inputElement } as MatChipInputEvent); + fixture.detectChanges(); + + expect(getTextFieldError('textkey')).toBe('CORE.CARDVIEW.VALIDATORS.FLOAT_VALIDATION_ERROR'); + let valueChips = await loader.getAllHarnesses(MatChipHarness); + expect(valueChips.length).toBe(3); + + component.addValueToList({ value: '22.1', chipInput: inputElement } as MatChipInputEvent); + fixture.detectChanges(); + + verifyNoErrors('textkey'); + valueChips = await loader.getAllHarnesses(MatChipHarness); + expect(valueChips.length).toBe(4); }); it('should render string for multivalue properties when chips are disabled', async () => { @@ -697,8 +739,7 @@ describe('CardViewTextItemComponent', () => { await fixture.whenStable(); fixture.detectChanges(); - const errorElement = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-error-textkey"]')); - expect(errorElement).toBeNull(); + verifyNoErrors('textkey'); }); it('should NOT show validation error for null', async () => { @@ -706,11 +747,9 @@ describe('CardViewTextItemComponent', () => { await fixture.whenStable(); fixture.detectChanges(); - const inputElement = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-textkey"]')); - const errorElement = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-error-textkey"]')); - - expect(inputElement.nativeElement.value).toBe(''); - expect(errorElement).toBeNull(); + const inputElement = getTextField('textkey'); + expect(inputElement.value).toBe(''); + verifyNoErrors('textkey'); }); it('should show validation error for only spaces string', async () => { @@ -722,27 +761,6 @@ describe('CardViewTextItemComponent', () => { expect(errorMessage).toEqual('CORE.CARDVIEW.VALIDATORS.INT_VALIDATION_ERROR'); }); - it('should NOT show validation error for empty string', async () => { - updateTextField(component.property.key, ''); - await fixture.whenStable(); - fixture.detectChanges(); - - const errorElement = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-error-textkey"]')); - expect(errorElement).toBeNull(); - }); - - it('should NOT show validation error for null', async () => { - updateTextField(component.property.key, null); - await fixture.whenStable(); - fixture.detectChanges(); - - const inputElement = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-value-textkey"]')); - const errorElement = fixture.debugElement.query(By.css('[data-automation-id="card-textitem-error-textkey"]')); - - expect(inputElement.nativeElement.value).toBe(''); - expect(errorElement).toBeNull(); - }); - it('should show validation error for float number', async () => { updateTextField(component.property.key, 123.456); await fixture.whenStable(); @@ -768,8 +786,7 @@ describe('CardViewTextItemComponent', () => { await fixture.whenStable(); fixture.detectChanges(); - const error = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-error-${component.property.key}"] li`)); - expect(error).toBeFalsy(); + verifyNoErrors(component.property.key); expect(component.property.value).toBe('2147483647'); }); @@ -788,8 +805,7 @@ describe('CardViewTextItemComponent', () => { } }); - const error = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-error-${component.property.key}"] li`)); - expect(error).toBeFalsy(); + verifyNoErrors(component.property.key); expect(getTextFieldValue(component.property.key)).toEqual(expectedNumber.toString()); expect(component.property.value).toBe(expectedNumber.toString()); }); @@ -849,8 +865,7 @@ describe('CardViewTextItemComponent', () => { } }); - const error = fixture.debugElement.query(By.css(`[data-automation-id="card-textitem-error-${component.property.key}"] li`)); - expect(error).toBeFalsy(); + verifyNoErrors(component.property.key); expect(getTextFieldValue(component.property.key)).toEqual(expectedNumber.toString()); expect(component.property.value).toBe(expectedNumber.toString()); }); diff --git a/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.ts b/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.ts index cbcbeeaa75..2a8d3c4159 100644 --- a/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.ts +++ b/lib/core/src/lib/card-view/components/card-view-textitem/card-view-textitem.component.ts @@ -148,17 +148,21 @@ export class CardViewTextItemComponent extends BaseCardView { expect(pipe.transform(1234.567)).toBe('1,234.57'); }); + it('should properly transform array of values', () => { + expect(pipe.transform([1234.567, 22])).toEqual(['1,234.57', '22']); + }); + it('should return number with at least the minimum of digints in the integer part', () => { const decimalValues = { minIntegerDigits: 6, diff --git a/lib/core/src/lib/pipes/decimal-number.pipe.ts b/lib/core/src/lib/pipes/decimal-number.pipe.ts index 15b747294d..8a3c02ff02 100644 --- a/lib/core/src/lib/pipes/decimal-number.pipe.ts +++ b/lib/core/src/lib/pipes/decimal-number.pipe.ts @@ -74,7 +74,12 @@ export class DecimalNumberPipe implements PipeTransform, OnDestroy { const actualLocale = locale || this.defaultLocale; const decimalPipe: DecimalPipe = new DecimalPipe(actualLocale); - return decimalPipe.transform(value, actualDigitsInfo); + + if (value instanceof Array) { + return value.map((val) => decimalPipe.transform(val, actualDigitsInfo)); + } else { + return decimalPipe.transform(value, actualDigitsInfo); + } } ngOnDestroy(): void {