/* * Copyright (C) 2022 Das Land Schleswig-Holstein vertreten durch den * Ministerpräsidenten des Landes Schleswig-Holstein * Staatskanzlei * Abteilung Digitalisierung und zentrales IT-Management der Landesregierung * * Lizenziert unter der EUPL, Version 1.2 oder - sobald * diese von der Europäischen Kommission genehmigt wurden - * Folgeversionen der EUPL ("Lizenz"); * Sie dürfen dieses Werk ausschließlich gemäß * dieser Lizenz nutzen. * Eine Kopie der Lizenz finden Sie hier: * * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 * * Sofern nicht durch anwendbare Rechtsvorschriften * gefordert oder in schriftlicher Form vereinbart, wird * die unter der Lizenz verbreitete Software "so wie sie * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - * ausdrücklich oder stillschweigend - verbreitet. * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ import { AbstractControl, FormControl, FormGroup, UntypedFormControl, UntypedFormGroup, } from '@angular/forms'; import { faker } from '@faker-js/faker'; import { createInvalidParam, createIssue } from '../../../test/error'; import { InvalidParam, Issue } from '../tech.model'; import { getControlForInvalidParam, getControlForIssue, getFieldPath, getMessageForInvalidParam, getMessageForIssue, setInvalidParamValidationError, setIssueValidationError, } from './tech.validation.util'; describe('ValidationUtils', () => { const baseField1Control: FormControl = new UntypedFormControl(); const baseField2Control: FormControl = new UntypedFormControl(); const subGroupFieldControl: FormControl = new UntypedFormControl(); const form: FormGroup = new UntypedFormGroup({ baseField1: baseField1Control, baseField2: baseField2Control, subGroup: new UntypedFormGroup({ subGroupField1: subGroupFieldControl, }), }); describe('set issue validation error', () => { describe('get control for issue', () => { it('should return base field control', () => { const issue: Issue = { ...createIssue(), field: 'class.resource.baseField1' }; const control: AbstractControl = getControlForIssue(form, issue); expect(control).toBe(baseField1Control); }); it('should return sub group field', () => { const issue: Issue = { ...createIssue(), field: 'class.resource.subGroup.subGroupField1' }; const control: AbstractControl = getControlForIssue(form, issue, 'resource'); expect(control).toBe(subGroupFieldControl); }); it('should ignore path prefix', () => { const issue: Issue = { ...createIssue(), field: 'class.resource.baseField1' }; const control: AbstractControl = getControlForIssue(form, issue, 'resource'); expect(control).toBe(baseField1Control); }); }); describe('in base field', () => { const issue: Issue = { ...createIssue(), field: 'class.resource.baseField1' }; it('should set error in control', () => { setIssueValidationError(form, issue); expect(baseField1Control.errors).not.toBeNull(); }); it('should set message code in control', () => { setIssueValidationError(form, issue); expect(baseField1Control.hasError(issue.messageCode)).toBe(true); }); it('should set control touched', () => { setIssueValidationError(form, issue); expect(baseField1Control.touched).toBe(true); }); it('should not set error in other control', () => { setIssueValidationError(form, issue); expect(baseField2Control.errors).toBeNull(); }); }); describe('in subGroup Field', () => { const issue: Issue = { ...createIssue(), field: 'class.resource.subGroup.subGroupField1' }; it('should set error in control', () => { setIssueValidationError(form, issue, 'resource'); expect(subGroupFieldControl.errors).not.toBeNull(); }); }); }); describe('get message for issue', () => { const fieldLabel: string = 'Field Label'; it('should return message', () => { const msg: string = getMessageForIssue(fieldLabel, { ...createIssue(), messageCode: 'validation_field_size', }); expect(msg).toContain('muss mindestens'); }); it('should set field label', () => { const msg: string = getMessageForIssue(fieldLabel, { ...createIssue(), messageCode: 'validation_field_size', }); expect(msg).toContain(fieldLabel); }); it('should replace min param', () => { const msg: string = getMessageForIssue(fieldLabel, { ...createIssue(), messageCode: 'validation_field_size', parameters: [{ name: 'min', value: '3' }], }); expect(msg).toContain('3'); }); }); describe('invalid param', () => { const formPrefixes: string[] = ['', 'somePrefix']; const fieldNames: string[] = ['baseField1', 'baseField2', 'subGroup.subGroupField1']; const prefixNameCombinations: string[][] = formPrefixes .flatMap((prefix) => fieldNames.map((name) => [prefix, name])) .filter((el) => existingPrefixAndFieldCombination(el[0], el[1])); const fieldLabel: string = faker.lorem.word(); describe.each(prefixNameCombinations)( 'with prefix "%s" and fieldName "%s"', (prefix, fieldName) => { let invalidParam: InvalidParam; beforeEach(() => { form.reset(); invalidParam = { ...createInvalidParam(), name: prefix.length ? `${prefix}.${fieldName}` : fieldName, }; }); describe('get message for invalid param', () => { it('should return', () => { const msg: string = getMessageForInvalidParam(fieldLabel, invalidParam); expect(msg).toEqual(`Bitte ${fieldLabel} ausfüllen`); }); }); describe('get control for invalid param', () => { it('should find', () => { const control: AbstractControl = getControlForInvalidParam(form, invalidParam, prefix); expect(control).toBeTruthy(); }); }); describe('set invalid param validation error', () => { it('should assign invalidParam to form control error without prefix', () => { setInvalidParamValidationError(form, invalidParam, prefix); const result: InvalidParam = form.getError(invalidParam.reason, fieldName); expect(result).toBe(invalidParam); }); it('should mark form as touched', () => { setInvalidParamValidationError(form, invalidParam, prefix); expect(form.touched).toBeTruthy(); }); }); }, ); }); describe('getFieldPath', () => { const resource: string = 'resource'; const backendClassName: string = 'class'; it('should return field path ', () => { const fieldPath: string = 'field1'; const fullPath: string = `${backendClassName}.${resource}.${fieldPath}`; const result: string = getFieldPath(fullPath, resource); expect(result).toBe(fieldPath); }); it('should get all parts after the prefix', () => { const fieldPath: string = 'group.field1'; const fullPath: string = `${backendClassName}.${resource}.${fieldPath}`; const result: string = getFieldPath(fullPath, resource); expect(result).toBe(fieldPath); }); }); }); function existingPrefixAndFieldCombination(prefix: string, field: string): boolean { return !(prefix === '' && field === 'subGroup.subGroupField1'); }