Skip to content

Commit

Permalink
Merge pull request #1976 from 4Science/main_1950_DURACOM-101
Browse files Browse the repository at this point in the history
Common Extendend Regex format for submission-forms
  • Loading branch information
tdonohue authored Dec 20, 2022
2 parents fa2dc72 + 8f91e14 commit 61f2383
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 4 deletions.
33 changes: 29 additions & 4 deletions src/app/shared/form/builder/parsers/field-parser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import {Inject, InjectionToken} from '@angular/core';
import { Inject, InjectionToken } from '@angular/core';

import uniqueId from 'lodash/uniqueId';
import {DynamicFormControlLayout, DynamicFormControlRelation, MATCH_VISIBLE, OR_OPERATOR} from '@ng-dynamic-forms/core';
import {
DynamicFormControlLayout,
DynamicFormControlRelation,
MATCH_VISIBLE,
OR_OPERATOR
} from '@ng-dynamic-forms/core';

import { hasValue, isNotEmpty, isNotNull, isNotUndefined } from '../../../empty.util';
import { FormFieldModel } from '../models/form-field.model';
Expand All @@ -22,6 +27,12 @@ export const SUBMISSION_ID: InjectionToken<string> = new InjectionToken<string>(
export const CONFIG_DATA: InjectionToken<FormFieldModel> = new InjectionToken<FormFieldModel>('configData');
export const INIT_FORM_VALUES: InjectionToken<any> = new InjectionToken<any>('initFormValues');
export const PARSER_OPTIONS: InjectionToken<ParserOptions> = new InjectionToken<ParserOptions>('parserOptions');
/**
* This pattern checks that a regex field uses the common ECMAScript format: `/{pattern}/{flags}`, in which the flags
* are part of the regex, or a simpler one with only pattern `/{pattern}/` or `{pattern}`.
* The regex itself is encapsulated inside a `RegExp` object, that will validate the pattern syntax.
*/
export const REGEX_FIELD_VALIDATOR = new RegExp('(\\/?)(.+)\\1([gimsuy]*)', 'i');

export abstract class FieldParser {

Expand All @@ -43,7 +54,7 @@ export abstract class FieldParser {
public abstract modelFactory(fieldValue?: FormFieldMetadataValueObject, label?: boolean): any;

public parse() {
if (((this.getInitValueCount() > 1 && !this.configData.repeatable) || (this.configData.repeatable))
if (((this.getInitValueCount() > 1 && !this.configData.repeatable) || (this.configData.repeatable))
&& (this.configData.input.type !== ParserType.List)
&& (this.configData.input.type !== ParserType.Tag)
) {
Expand Down Expand Up @@ -315,6 +326,7 @@ export abstract class FieldParser {
* fields in type bind, made up of a 'match' outcome (make this field visible), an 'operator'
* (OR) and a 'when' condition (the bindValues array).
* @param configuredTypeBindValues array of types from the submission definition (CONFIG_DATA)
* @param typeField
* @private
* @return DynamicFormControlRelation[] array with one relation in it, for type bind matching to show a field
*/
Expand Down Expand Up @@ -343,8 +355,21 @@ export abstract class FieldParser {
return hasValue(this.configData.input.regex);
}

/**
* Adds pattern validation to `controlModel`, it uses the encapsulated `configData` to test the regex,
* contained in the input config, against the common `ECMAScript` standard validator {@link REGEX_FIELD_VALIDATOR},
* and creates an equivalent `RegExp` object that will be used during form-validation against the user-input.
* @param controlModel
* @protected
*/
protected addPatternValidator(controlModel) {
const regex = new RegExp(this.configData.input.regex);
const validatorMatcher = this.configData.input.regex.match(REGEX_FIELD_VALIDATOR);
let regex;
if (validatorMatcher != null && validatorMatcher.length > 3) {
regex = new RegExp(validatorMatcher[2], validatorMatcher[3]);
} else {
regex = new RegExp(this.configData.input.regex);
}
controlModel.validators = Object.assign({}, controlModel.validators, { pattern: regex });
controlModel.errorMessages = Object.assign(
{},
Expand Down
48 changes: 48 additions & 0 deletions src/app/shared/form/builder/parsers/onebox-field-parser.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { DynamicQualdropModel } from '../ds-dynamic-form-ui/models/ds-dynamic-qu
import { DynamicOneboxModel } from '../ds-dynamic-form-ui/models/onebox/dynamic-onebox.model';
import { DsDynamicInputModel } from '../ds-dynamic-form-ui/models/ds-dynamic-input.model';
import { ParserOptions } from './parser-options';
import { FieldParser } from './field-parser';

describe('OneboxFieldParser test suite', () => {
let field1: FormFieldModel;
Expand Down Expand Up @@ -101,4 +102,51 @@ describe('OneboxFieldParser test suite', () => {
expect(fieldModel instanceof DynamicOneboxModel).toBe(true);
});

describe('should handle a DynamicOneboxModel with regex', () => {
let regexField: FormFieldModel;
let parser: FieldParser;
let fieldModel: any;

beforeEach(() => {
regexField = {
input: { type: 'onebox', regex: '/[a-z]+/mi' },
label: 'Title',
mandatory: 'false',
repeatable: false,
hints: 'Enter the name of the events, if any.',
selectableMetadata: [
{
metadata: 'title',
controlledVocabulary: 'EVENTAuthority',
closed: false
}
],
languageCodes: []
} as FormFieldModel;

parser = new OneboxFieldParser(submissionId, regexField, initFormValues, parserOptions);
fieldModel = parser.parse();
});

it('should have initialized pattern validator', () => {
expect(fieldModel instanceof DynamicOneboxModel).toBe(true);
expect(fieldModel.validators).not.toBeNull();
expect(fieldModel.validators.pattern).not.toBeNull();
});

it('should mark valid not case sensitive basic characters regex in multiline', () => {
let pattern = fieldModel.validators.pattern as RegExp;
expect(pattern.test('HELLO')).toBe(true);
expect(pattern.test('hello')).toBe(true);
expect(pattern.test('hello\nhello\nhello')).toBe(true);
expect(pattern.test('HeLlO')).toBe(true);
});

it('should be invalid for non-basic alphabet characters', () => {
let pattern = fieldModel.validators.pattern as RegExp;
expect(pattern.test('12345')).toBe(false);
expect(pattern.test('àèìòùáéíóú')).toBe(false);
});
});

});

0 comments on commit 61f2383

Please sign in to comment.