AAE-23116 Dropdown should not display errors / call apis when it's in readOnly state [without refactor] (#9800)

* AAE-23116 Add tests for dropdown widget

* AAE-23116 Update form-field.model

* AAE-23116 Final

* AAE-23116 Restore formatting

* AAE-23116 Align with comments

* AAE-23116 Update

* AAE-23116 Fix process-services-cloud unit tests

* AAE-23116 Fix process services unit tests

* AAE-23116 Fix for core unit tests
This commit is contained in:
Wiktor Danielewski
2024-06-21 08:50:55 +02:00
committed by GitHub
parent 328d233b05
commit 4d2c489508
7 changed files with 395 additions and 344 deletions

View File

@@ -52,20 +52,20 @@ describe('FormFieldValidator', () => {
}); });
field.required = false; field.required = false;
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
field.required = true; field.required = true;
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should skip unsupported type', () => { it('should skip unsupported type', () => {
const field = new FormFieldModel(new FormModel(), { type: 'wrong-type' }); const field = new FormFieldModel(new FormModel(), { type: 'wrong-type' });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for dropdown with empty value', () => { it('should fail (display error) for dropdown with empty value', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
value: '<empty>', value: '<empty>',
@@ -75,29 +75,34 @@ describe('FormFieldValidator', () => {
}); });
field.emptyOption = { id: '<empty>' } as FormFieldOption; field.emptyOption = { id: '<empty>' } as FormFieldOption;
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
field.value = '<non-empty>'; field.value = '<non-empty>';
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for dropdown with zero selection', () => { it('should fail (display error) for multiple type dropdown with zero selection', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
value: [], value: [{ id: 'id_cat', name: 'Cat' }],
hasEmptyValue: true,
required: true, required: true,
selectionType: 'multiple' selectionType: 'multiple',
hasEmptyValue: false,
options: [
{ id: 'id_cat', name: 'Cat' },
{ id: 'id_dog', name: 'Dog' }
]
}); });
field.emptyOption = { id: 'empty' } as FormFieldOption; const validateBeforeUnselect = validator.validate(field);
expect(validator.validate(field)).toBeFalsy();
field.value = []; field.value = [];
expect(validator.validate(field)).toBe(false); const validateAfterUnselect = validator.validate(field);
expect(validateBeforeUnselect).toBe(true);
expect(validateAfterUnselect).toBe(false);
}); });
it('should fail for dropdown with null value', () => { it('should fail (display error) for dropdown with null value', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
value: null, value: null,
@@ -109,7 +114,7 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBe(false); expect(validator.validate(field)).toBe(false);
}); });
it('should fail for dropdown with empty object', () => { it('should fail (display error) for dropdown with empty object', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
value: {}, value: {},
@@ -121,7 +126,7 @@ describe('FormFieldValidator', () => {
expect(validator.validate(field)).toBe(false); expect(validator.validate(field)).toBe(false);
}); });
it('should fail for radio buttons', () => { it('should fail (display error) for radio buttons', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.RADIO_BUTTONS, type: FormFieldTypes.RADIO_BUTTONS,
required: true, required: true,
@@ -129,7 +134,7 @@ describe('FormFieldValidator', () => {
}); });
field.value = 'one'; field.value = 'one';
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
}); });
it('should succeed for radio buttons', () => { it('should succeed for radio buttons', () => {
@@ -140,10 +145,10 @@ describe('FormFieldValidator', () => {
options: [{ id: 'two', name: 'two' }] options: [{ id: 'two', name: 'two' }]
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for upload', () => { it('should fail (display error) for upload', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.UPLOAD, type: FormFieldTypes.UPLOAD,
value: null, value: null,
@@ -151,10 +156,10 @@ describe('FormFieldValidator', () => {
}); });
field.value = null; field.value = null;
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
field.value = []; field.value = [];
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
}); });
it('should succeed for upload', () => { it('should succeed for upload', () => {
@@ -164,10 +169,10 @@ describe('FormFieldValidator', () => {
required: true required: true
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for text', () => { it('should fail (display error) for text', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TEXT, type: FormFieldTypes.TEXT,
value: null, value: null,
@@ -175,10 +180,10 @@ describe('FormFieldValidator', () => {
}); });
field.value = null; field.value = null;
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
field.value = ''; field.value = '';
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
}); });
it('should succeed for date', () => { it('should succeed for date', () => {
@@ -188,10 +193,10 @@ describe('FormFieldValidator', () => {
required: true required: true
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for date', () => { it('should fail (display error) for date', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATE, type: FormFieldTypes.DATE,
value: null, value: null,
@@ -199,10 +204,10 @@ describe('FormFieldValidator', () => {
}); });
field.value = null; field.value = null;
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
field.value = ''; field.value = '';
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
}); });
it('should succeed for text', () => { it('should succeed for text', () => {
@@ -212,7 +217,7 @@ describe('FormFieldValidator', () => {
required: true required: true
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for check box', () => { it('should succeed for check box', () => {
@@ -223,10 +228,10 @@ describe('FormFieldValidator', () => {
options: [{ id: 'two', name: 'two' }] options: [{ id: 'two', name: 'two' }]
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for check box', () => { it('should fail (display error) for check box', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.BOOLEAN, type: FormFieldTypes.BOOLEAN,
required: true, required: true,
@@ -235,7 +240,7 @@ describe('FormFieldValidator', () => {
}); });
field.value = false; field.value = false;
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
}); });
}); });
@@ -247,20 +252,20 @@ describe('FormFieldValidator', () => {
}); });
it('should verify number', () => { it('should verify number', () => {
expect(NumberFieldValidator.isNumber('1')).toBeTruthy(); expect(NumberFieldValidator.isNumber('1')).toBe(true);
expect(NumberFieldValidator.isNumber('1.0')).toBeTruthy(); expect(NumberFieldValidator.isNumber('1.0')).toBe(true);
expect(NumberFieldValidator.isNumber('-1')).toBeTruthy(); expect(NumberFieldValidator.isNumber('-1')).toBe(true);
expect(NumberFieldValidator.isNumber(1)).toBeTruthy(); expect(NumberFieldValidator.isNumber(1)).toBe(true);
expect(NumberFieldValidator.isNumber(0)).toBeTruthy(); expect(NumberFieldValidator.isNumber(0)).toBe(true);
expect(NumberFieldValidator.isNumber(-1)).toBeTruthy(); expect(NumberFieldValidator.isNumber(-1)).toBe(true);
}); });
it('should not verify number', () => { it('should not verify number', () => {
expect(NumberFieldValidator.isNumber(null)).toBeFalsy(); expect(NumberFieldValidator.isNumber(null)).toBe(false);
expect(NumberFieldValidator.isNumber(undefined)).toBeFalsy(); expect(NumberFieldValidator.isNumber(undefined)).toBe(false);
expect(NumberFieldValidator.isNumber('')).toBeFalsy(); expect(NumberFieldValidator.isNumber('')).toBe(false);
expect(NumberFieldValidator.isNumber('one')).toBeFalsy(); expect(NumberFieldValidator.isNumber('one')).toBe(false);
expect(NumberFieldValidator.isNumber('1q')).toBeFalsy(); expect(NumberFieldValidator.isNumber('1q')).toBe(false);
}); });
it('should allow empty number value', () => { it('should allow empty number value', () => {
@@ -269,7 +274,7 @@ describe('FormFieldValidator', () => {
value: null value: null
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should allow number value', () => { it('should allow number value', () => {
@@ -278,7 +283,7 @@ describe('FormFieldValidator', () => {
value: 44 value: 44
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should allow zero number value', () => { it('should allow zero number value', () => {
@@ -287,17 +292,17 @@ describe('FormFieldValidator', () => {
value: 0 value: 0
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for wrong number value', () => { it('should fail (display error) for wrong number value', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.NUMBER, type: FormFieldTypes.NUMBER,
value: '<value>' value: '<value>'
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -314,10 +319,10 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.minLength = 10; field.minLength = 10;
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -327,7 +332,7 @@ describe('FormFieldValidator', () => {
value: null value: null
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed text validation', () => { it('should succeed text validation', () => {
@@ -337,10 +342,10 @@ describe('FormFieldValidator', () => {
value: '1234' value: '1234'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail text validation', () => { it('should fail (display error) text validation', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TEXT, type: FormFieldTypes.TEXT,
minLength: 3, minLength: 3,
@@ -348,7 +353,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -365,10 +370,10 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.maxLength = 10; field.maxLength = 10;
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -378,7 +383,7 @@ describe('FormFieldValidator', () => {
value: null value: null
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed text validation', () => { it('should succeed text validation', () => {
@@ -388,10 +393,10 @@ describe('FormFieldValidator', () => {
value: '123' value: '123'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail text validation', () => { it('should fail (display error) text validation', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TEXT, type: FormFieldTypes.TEXT,
maxLength: 3, maxLength: 3,
@@ -399,7 +404,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -415,10 +420,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.NUMBER type: FormFieldTypes.NUMBER
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.minValue = '1'; field.minValue = '1';
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should support numeric widgets only', () => { it('should support numeric widgets only', () => {
@@ -427,10 +432,10 @@ describe('FormFieldValidator', () => {
minValue: '1' minValue: '1'
}); });
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
field.type = FormFieldTypes.TEXT; field.type = FormFieldTypes.TEXT;
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -440,7 +445,7 @@ describe('FormFieldValidator', () => {
minValue: '1' minValue: '1'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for unsupported types', () => { it('should succeed for unsupported types', () => {
@@ -448,7 +453,7 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed validating value', () => { it('should succeed validating value', () => {
@@ -458,10 +463,10 @@ describe('FormFieldValidator', () => {
minValue: '10' minValue: '10'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating value', () => { it('should fail (display error) validating value', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.NUMBER, type: FormFieldTypes.NUMBER,
value: '9', value: '9',
@@ -469,7 +474,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -485,10 +490,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.NUMBER type: FormFieldTypes.NUMBER
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.maxValue = '1'; field.maxValue = '1';
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should support numeric widgets only', () => { it('should support numeric widgets only', () => {
@@ -497,10 +502,10 @@ describe('FormFieldValidator', () => {
maxValue: '1' maxValue: '1'
}); });
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
field.type = FormFieldTypes.TEXT; field.type = FormFieldTypes.TEXT;
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -510,7 +515,7 @@ describe('FormFieldValidator', () => {
maxValue: '1' maxValue: '1'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for unsupported types', () => { it('should succeed for unsupported types', () => {
@@ -518,7 +523,7 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed validating value', () => { it('should succeed validating value', () => {
@@ -528,10 +533,10 @@ describe('FormFieldValidator', () => {
maxValue: '10' maxValue: '10'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating value', () => { it('should fail (display error) validating value', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.NUMBER, type: FormFieldTypes.NUMBER,
value: '11', value: '11',
@@ -539,7 +544,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -555,10 +560,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.regexPattern = '<pattern>'; field.regexPattern = '<pattern>';
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -568,7 +573,7 @@ describe('FormFieldValidator', () => {
regexPattern: 'pattern' regexPattern: 'pattern'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should allow empty string values', () => { it('should allow empty string values', () => {
@@ -578,7 +583,7 @@ describe('FormFieldValidator', () => {
regexPattern: 'pattern' regexPattern: 'pattern'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed validating regex', () => { it('should succeed validating regex', () => {
@@ -588,17 +593,17 @@ describe('FormFieldValidator', () => {
regexPattern: 'pattern' regexPattern: 'pattern'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating regex', () => { it('should fail (display error) validating regex', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TEXT, type: FormFieldTypes.TEXT,
value: 'some value', value: 'some value',
regexPattern: 'pattern' regexPattern: 'pattern'
}); });
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
}); });
}); });
@@ -613,13 +618,13 @@ describe('FormFieldValidator', () => {
let field = new FormFieldModel(new FormModel(), { let field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field = new FormFieldModel(new FormModel(), { field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TYPEAHEAD type: FormFieldTypes.TYPEAHEAD
}); });
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -629,7 +634,7 @@ describe('FormFieldValidator', () => {
regexPattern: 'pattern' regexPattern: 'pattern'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for a valid input value in options', () => { it('should succeed for a valid input value in options', () => {
@@ -642,10 +647,10 @@ describe('FormFieldValidator', () => {
] ]
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail for an invalid input value in options', () => { it('should fail (display error) for an invalid input value in options', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.TYPEAHEAD, type: FormFieldTypes.TYPEAHEAD,
value: 'Lean', value: 'Lean',
@@ -655,7 +660,7 @@ describe('FormFieldValidator', () => {
] ]
}); });
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
}); });
}); });
@@ -670,10 +675,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATETIME type: FormFieldTypes.DATETIME
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.maxValue = '9999-02-08 10:10 AM'; field.maxValue = '9999-02-08 10:10 AM';
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should support date time widgets only', () => { it('should support date time widgets only', () => {
@@ -682,10 +687,10 @@ describe('FormFieldValidator', () => {
maxValue: '9999-02-08 10:10 AM' maxValue: '9999-02-08 10:10 AM'
}); });
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
field.type = FormFieldTypes.TEXT; field.type = FormFieldTypes.TEXT;
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -695,7 +700,7 @@ describe('FormFieldValidator', () => {
maxValue: '9999-02-08 10:10 AM' maxValue: '9999-02-08 10:10 AM'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for unsupported types', () => { it('should succeed for unsupported types', () => {
@@ -703,10 +708,10 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should take into account that max value is in UTC and NOT fail validating value checking the time', () => { it('should take into account that max value is in UTC and NOT fail (display error) validating value checking the time', () => {
const localValidValue = '2018-03-30T22:59:00.000Z'; const localValidValue = '2018-03-30T22:59:00.000Z';
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
@@ -715,10 +720,10 @@ describe('FormFieldValidator', () => {
maxValue: '2018-03-31T23:00:00.000Z' maxValue: '2018-03-31T23:00:00.000Z'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should take into account that max value is in UTC and fail validating value checking the time', () => { it('should take into account that max value is in UTC and fail (display error) validating value checking the time', () => {
const localInvalidValue = '2018-03-30T23:01:00.000Z'; const localInvalidValue = '2018-03-30T23:01:00.000Z';
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
@@ -728,7 +733,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
expect(field.validationSummary.message).toBe('FORM.FIELD.VALIDATOR.NOT_GREATER_THAN'); expect(field.validationSummary.message).toBe('FORM.FIELD.VALIDATOR.NOT_GREATER_THAN');
}); });
@@ -740,10 +745,10 @@ describe('FormFieldValidator', () => {
maxValue: '9999-02-08T10:10:00.000Z' maxValue: '9999-02-08T10:10:00.000Z'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating value checking the time', () => { it('should fail (display error) validating value checking the time', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATETIME, type: FormFieldTypes.DATETIME,
value: '9999-02-08T11:10:00.000Z', value: '9999-02-08T11:10:00.000Z',
@@ -751,7 +756,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
@@ -762,10 +767,10 @@ describe('FormFieldValidator', () => {
maxValue: '9999-02-08T10:10:00.000Z' maxValue: '9999-02-08T10:10:00.000Z'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating value checking the date', () => { it('should fail (display error) validating value checking the date', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATETIME, type: FormFieldTypes.DATETIME,
value: '08-02-9999 12:10 AM', value: '08-02-9999 12:10 AM',
@@ -773,7 +778,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -789,10 +794,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATETIME type: FormFieldTypes.DATETIME
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.minValue = '9999-02-08 09:10 AM'; field.minValue = '9999-02-08 09:10 AM';
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should support date time widgets only', () => { it('should support date time widgets only', () => {
@@ -801,10 +806,10 @@ describe('FormFieldValidator', () => {
minValue: '9999-02-08 09:10 AM' minValue: '9999-02-08 09:10 AM'
}); });
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
field.type = FormFieldTypes.TEXT; field.type = FormFieldTypes.TEXT;
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -814,7 +819,7 @@ describe('FormFieldValidator', () => {
minValue: '9999-02-08 09:10 AM' minValue: '9999-02-08 09:10 AM'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for unsupported types', () => { it('should succeed for unsupported types', () => {
@@ -822,10 +827,10 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should take into account that min value is in UTC and NOT fail validating value checking the time', () => { it('should take into account that min value is in UTC and NOT fail (display error) validating value checking the time', () => {
const localValidValue = '2018-03-02T06:01:00.000Z'; const localValidValue = '2018-03-02T06:01:00.000Z';
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
@@ -834,10 +839,10 @@ describe('FormFieldValidator', () => {
minValue: '2018-03-02T06:00:00.000Z' minValue: '2018-03-02T06:00:00.000Z'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should take into account that min value is in UTC and fail validating value checking the time', () => { it('should take into account that min value is in UTC and fail (display error) validating value checking the time', () => {
const localInvalidValue = '2018-3-02 05:59 AM'; const localInvalidValue = '2018-3-02 05:59 AM';
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
@@ -847,7 +852,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
expect(field.validationSummary.message).toBe('FORM.FIELD.VALIDATOR.NOT_LESS_THAN'); expect(field.validationSummary.message).toBe('FORM.FIELD.VALIDATOR.NOT_LESS_THAN');
}); });
@@ -859,7 +864,7 @@ describe('FormFieldValidator', () => {
minValue: '9999-02-08 09:00 AM' minValue: '9999-02-08 09:00 AM'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed validating value by date', () => { it('should succeed validating value by date', () => {
@@ -869,10 +874,10 @@ describe('FormFieldValidator', () => {
minValue: '9999-02-08 09:10 AM' minValue: '9999-02-08 09:10 AM'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating value by time', () => { it('should fail (display error) validating value by time', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATETIME, type: FormFieldTypes.DATETIME,
value: '9999-08-02T08:10:00.000Z', value: '9999-08-02T08:10:00.000Z',
@@ -880,11 +885,11 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
it('should fail validating value by date', () => { it('should fail (display error) validating value by date', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATETIME, type: FormFieldTypes.DATETIME,
value: '9999-02-07T09:10:00.000Z', value: '9999-02-07T09:10:00.000Z',
@@ -892,7 +897,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -908,10 +913,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATE type: FormFieldTypes.DATE
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.maxValue = '9999-02-08'; field.maxValue = '9999-02-08';
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should support date widgets only', () => { it('should support date widgets only', () => {
@@ -920,10 +925,10 @@ describe('FormFieldValidator', () => {
maxValue: '9999-02-08' maxValue: '9999-02-08'
}); });
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
field.type = FormFieldTypes.TEXT; field.type = FormFieldTypes.TEXT;
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -933,7 +938,7 @@ describe('FormFieldValidator', () => {
maxValue: '9999-02-08' maxValue: '9999-02-08'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for unsupported types', () => { it('should succeed for unsupported types', () => {
@@ -941,7 +946,7 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed validating value checking the date', () => { it('should succeed validating value checking the date', () => {
@@ -951,10 +956,10 @@ describe('FormFieldValidator', () => {
maxValue: '9999-02-09' maxValue: '9999-02-09'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating value checking the date', () => { it('should fail (display error) validating value checking the date', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATE, type: FormFieldTypes.DATE,
value: '9999-02-08T00:00:00', value: '9999-02-08T00:00:00',
@@ -962,7 +967,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
@@ -973,10 +978,10 @@ describe('FormFieldValidator', () => {
maxValue: '09-02-9999' maxValue: '09-02-9999'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating with APS1 format', () => { it('should fail (display error) validating with APS1 format', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATE, type: FormFieldTypes.DATE,
value: '9999-02-08T00:00:00', value: '9999-02-08T00:00:00',
@@ -984,7 +989,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -1000,10 +1005,10 @@ describe('FormFieldValidator', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATE type: FormFieldTypes.DATE
}); });
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
field.minValue = '9999-02-08'; field.minValue = '9999-02-08';
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
}); });
it('should support date widgets only', () => { it('should support date widgets only', () => {
@@ -1012,10 +1017,10 @@ describe('FormFieldValidator', () => {
minValue: '9999-02-08' minValue: '9999-02-08'
}); });
expect(validator.isSupported(field)).toBeTruthy(); expect(validator.isSupported(field)).toBe(true);
field.type = FormFieldTypes.TEXT; field.type = FormFieldTypes.TEXT;
expect(validator.isSupported(field)).toBeFalsy(); expect(validator.isSupported(field)).toBe(false);
}); });
it('should allow empty values', () => { it('should allow empty values', () => {
@@ -1025,7 +1030,7 @@ describe('FormFieldValidator', () => {
minValue: '9999-02-08' minValue: '9999-02-08'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed for unsupported types', () => { it('should succeed for unsupported types', () => {
@@ -1033,7 +1038,7 @@ describe('FormFieldValidator', () => {
type: FormFieldTypes.TEXT type: FormFieldTypes.TEXT
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should succeed validating value checking the date', () => { it('should succeed validating value checking the date', () => {
@@ -1043,10 +1048,10 @@ describe('FormFieldValidator', () => {
minValue: '9999-02-07' minValue: '9999-02-07'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating value checking the date', () => { it('should fail (display error) validating value checking the date', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATE, type: FormFieldTypes.DATE,
value: '9999-02-08T00:00:00', value: '9999-02-08T00:00:00',
@@ -1054,7 +1059,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
@@ -1065,10 +1070,10 @@ describe('FormFieldValidator', () => {
minValue: '07-02-9999' minValue: '07-02-9999'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should fail validating with APS1 format', () => { it('should fail (display error) validating with APS1 format', () => {
const field = new FormFieldModel(new FormModel(), { const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DATE, type: FormFieldTypes.DATE,
value: '9999-02-08T00:00:00', value: '9999-02-08T00:00:00',
@@ -1076,7 +1081,7 @@ describe('FormFieldValidator', () => {
}); });
field.validationSummary = new ErrorMessageModel(); field.validationSummary = new ErrorMessageModel();
expect(validator.validate(field)).toBeFalsy(); expect(validator.validate(field)).toBe(false);
expect(field.validationSummary).not.toBeNull(); expect(field.validationSummary).not.toBeNull();
}); });
}); });
@@ -1095,7 +1100,7 @@ describe('FormFieldValidator', () => {
dateDisplayFormat: 'YYYY-MM-DD HH:mm' dateDisplayFormat: 'YYYY-MM-DD HH:mm'
}); });
expect(validator.validate(field)).toBeTruthy(); expect(validator.validate(field)).toBe(true);
}); });
it('should validate dateTime format with default format', () => { it('should validate dateTime format with default format', () => {
@@ -1105,7 +1110,7 @@ describe('FormFieldValidator', () => {
}); });
expect(field.value).toBe('9-6-2021 11:10 AM'); expect(field.value).toBe('9-6-2021 11:10 AM');
expect(field.dateDisplayFormat).toBe('D-M-YYYY hh:mm A'); expect(field.dateDisplayFormat).toBe('D-M-YYYY hh:mm A');
expect(validator.validate(field)).toBeTrue(); expect(validator.validate(field)).toBe(true);
}); });
it('should not validate dateTime format with default format', () => { it('should not validate dateTime format with default format', () => {
@@ -1115,7 +1120,7 @@ describe('FormFieldValidator', () => {
}); });
expect(field.value).toBe('2021-06-09 14:10 AM'); expect(field.value).toBe('2021-06-09 14:10 AM');
expect(field.dateDisplayFormat).toBe('D-M-YYYY hh:mm A'); expect(field.dateDisplayFormat).toBe('D-M-YYYY hh:mm A');
expect(validator.validate(field)).toBeFalse(); expect(validator.validate(field)).toBe(false);
}); });
}); });
@@ -1133,7 +1138,7 @@ describe('FormFieldValidator', () => {
precision: 2 precision: 2
}); });
expect(decimalValidator.validate(field)).toBeTrue(); expect(decimalValidator.validate(field)).toBe(true);
}); });
it('should return true when value is of lower precision', () => { it('should return true when value is of lower precision', () => {
@@ -1143,7 +1148,7 @@ describe('FormFieldValidator', () => {
precision: 2 precision: 2
}); });
expect(decimalValidator.validate(field)).toBeTrue(); expect(decimalValidator.validate(field)).toBe(true);
}); });
it('should return false when value is of higher precision', () => { it('should return false when value is of higher precision', () => {
@@ -1153,7 +1158,7 @@ describe('FormFieldValidator', () => {
precision: 1 precision: 1
}); });
expect(decimalValidator.validate(field)).toBeFalse(); expect(decimalValidator.validate(field)).toBe(false);
}); });
it('should validate decimal of wrong precision when value is of type string', () => { it('should validate decimal of wrong precision when value is of type string', () => {
@@ -1163,7 +1168,7 @@ describe('FormFieldValidator', () => {
precision: 1 precision: 1
}); });
expect(decimalValidator.validate(field)).toBeFalse(); expect(decimalValidator.validate(field)).toBe(false);
}); });
it('should return false, when value is a negative number and of correct precission', () => { it('should return false, when value is a negative number and of correct precission', () => {
@@ -1173,7 +1178,7 @@ describe('FormFieldValidator', () => {
precision: 1 precision: 1
}); });
expect(decimalValidator.validate(field)).toBeFalse(); expect(decimalValidator.validate(field)).toBe(false);
}); });
it('should return true, when value is a positive number and of correct precission', () => { it('should return true, when value is a positive number and of correct precission', () => {
@@ -1183,8 +1188,7 @@ describe('FormFieldValidator', () => {
precision: 3 precision: 3
}); });
expect(decimalValidator.validate(field)).toBeTrue(); expect(decimalValidator.validate(field)).toBe(true);
}); });
}); });
}); });

View File

@@ -24,15 +24,11 @@ import { DateFnsUtils } from '../../../../common/utils/date-fns-utils';
import { isValid as isDateValid, isBefore, isAfter } from 'date-fns'; import { isValid as isDateValid, isBefore, isAfter } from 'date-fns';
export interface FormFieldValidator { export interface FormFieldValidator {
isSupported(field: FormFieldModel): boolean; isSupported(field: FormFieldModel): boolean;
validate(field: FormFieldModel): boolean; validate(field: FormFieldModel): boolean;
} }
export class RequiredFieldValidator implements FormFieldValidator { export class RequiredFieldValidator implements FormFieldValidator {
private supportedTypes = [ private supportedTypes = [
FormFieldTypes.TEXT, FormFieldTypes.TEXT,
FormFieldTypes.MULTILINE_TEXT, FormFieldTypes.MULTILINE_TEXT,
@@ -54,14 +50,11 @@ export class RequiredFieldValidator implements FormFieldValidator {
]; ];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && field.required;
this.supportedTypes.indexOf(field.type) > -1 &&
field.required;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
if (this.isSupported(field) && field.isVisible) { if (this.isSupported(field) && field.isVisible) {
if (field.type === FormFieldTypes.DROPDOWN) { if (field.type === FormFieldTypes.DROPDOWN) {
if (field.hasMultipleValues) { if (field.hasMultipleValues) {
return Array.isArray(field.value) && !!field.value.length; return Array.isArray(field.value) && !!field.value.length;
@@ -73,7 +66,7 @@ export class RequiredFieldValidator implements FormFieldValidator {
} }
} }
if (field.required && typeof field.value === 'object' && field.value && !Object.keys(field.value).length) { if (field.required && field.value && typeof field.value === 'object' && !Object.keys(field.value).length) {
return false; return false;
} }
} }
@@ -84,11 +77,11 @@ export class RequiredFieldValidator implements FormFieldValidator {
} }
if (field.type === FormFieldTypes.UPLOAD) { if (field.type === FormFieldTypes.UPLOAD) {
return field.value && field.value.length > 0; return !!field.value && field.value.length > 0;
} }
if (field.type === FormFieldTypes.DYNAMIC_TABLE) { if (field.type === FormFieldTypes.DYNAMIC_TABLE) {
return field.value && field.value instanceof Array && field.value.length > 0; return !!field.value && field.value instanceof Array && field.value.length > 0;
} }
if (field.type === FormFieldTypes.BOOLEAN) { if (field.type === FormFieldTypes.BOOLEAN) {
@@ -101,15 +94,10 @@ export class RequiredFieldValidator implements FormFieldValidator {
} }
return true; return true;
} }
} }
export class NumberFieldValidator implements FormFieldValidator { export class NumberFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.AMOUNT];
private supportedTypes = [
FormFieldTypes.NUMBER,
FormFieldTypes.AMOUNT
];
static isNumber(value: any): boolean { static isNumber(value: any): boolean {
return isNumberValue(value); return isNumberValue(value);
@@ -121,9 +109,7 @@ export class NumberFieldValidator implements FormFieldValidator {
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
if (this.isSupported(field) && field.isVisible) { if (this.isSupported(field) && field.isVisible) {
if (field.value === null || if (field.value === null || field.value === undefined || field.value === '') {
field.value === undefined ||
field.value === '') {
return true; return true;
} }
const valueStr = '' + field.value; const valueStr = '' + field.value;
@@ -142,10 +128,7 @@ export class NumberFieldValidator implements FormFieldValidator {
} }
export class DateFieldValidator implements FormFieldValidator { export class DateFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.DATE];
private supportedTypes = [
FormFieldTypes.DATE
];
// Validates that the input string is a valid date formatted as <dateFormat> (default D-M-YYYY) // Validates that the input string is a valid date formatted as <dateFormat> (default D-M-YYYY)
static isValidDate(inputDate: string, dateFormat: string = 'D-M-YYYY'): boolean { static isValidDate(inputDate: string, dateFormat: string = 'D-M-YYYY'): boolean {
@@ -169,10 +152,7 @@ export class DateFieldValidator implements FormFieldValidator {
} }
export class DateTimeFieldValidator implements FormFieldValidator { export class DateTimeFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.DATETIME];
private supportedTypes = [
FormFieldTypes.DATETIME
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && this.supportedTypes.indexOf(field.type) > -1; return field && this.supportedTypes.indexOf(field.type) > -1;
@@ -196,13 +176,10 @@ export class DateTimeFieldValidator implements FormFieldValidator {
} }
export abstract class BoundaryDateFieldValidator implements FormFieldValidator { export abstract class BoundaryDateFieldValidator implements FormFieldValidator {
DATE_FORMAT_CLOUD = 'YYYY-MM-DD'; DATE_FORMAT_CLOUD = 'YYYY-MM-DD';
DATE_FORMAT = 'DD-MM-YYYY'; DATE_FORMAT = 'DD-MM-YYYY';
supportedTypes = [ supportedTypes = [FormFieldTypes.DATE];
FormFieldTypes.DATE
];
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
let isValid = true; let isValid = true;
@@ -226,11 +203,9 @@ export abstract class BoundaryDateFieldValidator implements FormFieldValidator {
abstract checkDate(field: FormFieldModel, dateFormat: string); abstract checkDate(field: FormFieldModel, dateFormat: string);
abstract isSupported(field: FormFieldModel); abstract isSupported(field: FormFieldModel);
} }
export class MinDateFieldValidator extends BoundaryDateFieldValidator { export class MinDateFieldValidator extends BoundaryDateFieldValidator {
checkDate(field: FormFieldModel, dateFormat: string): boolean { checkDate(field: FormFieldModel, dateFormat: string): boolean {
let isValid = true; let isValid = true;
const fieldValueData = DateFnsUtils.parseDate(field.value, dateFormat, { dateOnly: true }); const fieldValueData = DateFnsUtils.parseDate(field.value, dateFormat, { dateOnly: true });
@@ -239,23 +214,18 @@ export class MinDateFieldValidator extends BoundaryDateFieldValidator {
if (DateFnsUtils.isBeforeDate(fieldValueData, min)) { if (DateFnsUtils.isBeforeDate(fieldValueData, min)) {
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`; field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`;
field.validationSummary.attributes.set( field.validationSummary.attributes.set('minValue', DateFnsUtils.formatDate(min, field.dateDisplayFormat).toLocaleUpperCase());
'minValue',
DateFnsUtils.formatDate(min, field.dateDisplayFormat).toLocaleUpperCase()
);
isValid = false; isValid = false;
} }
return isValid; return isValid;
} }
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.minValue;
this.supportedTypes.indexOf(field.type) > -1 && !!field.minValue;
} }
} }
export class MaxDateFieldValidator extends BoundaryDateFieldValidator { export class MaxDateFieldValidator extends BoundaryDateFieldValidator {
checkDate(field: FormFieldModel, dateFormat: string): boolean { checkDate(field: FormFieldModel, dateFormat: string): boolean {
let isValid = true; let isValid = true;
const fieldValueData = DateFnsUtils.parseDate(field.value, dateFormat, { dateOnly: true }); const fieldValueData = DateFnsUtils.parseDate(field.value, dateFormat, { dateOnly: true });
@@ -264,18 +234,14 @@ export class MaxDateFieldValidator extends BoundaryDateFieldValidator {
if (DateFnsUtils.isAfterDate(fieldValueData, max)) { if (DateFnsUtils.isAfterDate(fieldValueData, max)) {
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`; field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`;
field.validationSummary.attributes.set( field.validationSummary.attributes.set('maxValue', DateFnsUtils.formatDate(max, field.dateDisplayFormat).toLocaleUpperCase());
'maxValue',
DateFnsUtils.formatDate(max, field.dateDisplayFormat).toLocaleUpperCase()
);
isValid = false; isValid = false;
} }
return isValid; return isValid;
} }
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.maxValue;
this.supportedTypes.indexOf(field.type) > -1 && !!field.maxValue;
} }
} }
@@ -288,14 +254,10 @@ export class MaxDateFieldValidator extends BoundaryDateFieldValidator {
* *
*/ */
export class MinDateTimeFieldValidator implements FormFieldValidator { export class MinDateTimeFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.DATETIME];
private supportedTypes = [
FormFieldTypes.DATETIME
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.minValue;
this.supportedTypes.indexOf(field.type) > -1 && !!field.minValue;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -318,10 +280,7 @@ export class MinDateTimeFieldValidator implements FormFieldValidator {
if (isBefore(fieldValueDate, min)) { if (isBefore(fieldValueDate, min)) {
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`; field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_LESS_THAN`;
field.validationSummary.attributes.set( field.validationSummary.attributes.set('minValue', DateFnsUtils.formatDate(min, field.dateDisplayFormat).replace(':', '-'));
'minValue',
DateFnsUtils.formatDate(min, field.dateDisplayFormat).replace(':', '-')
);
isValid = false; isValid = false;
} }
return isValid; return isValid;
@@ -337,14 +296,10 @@ export class MinDateTimeFieldValidator implements FormFieldValidator {
* *
*/ */
export class MaxDateTimeFieldValidator implements FormFieldValidator { export class MaxDateTimeFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.DATETIME];
private supportedTypes = [
FormFieldTypes.DATETIME
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.maxValue;
this.supportedTypes.indexOf(field.type) > -1 && !!field.maxValue;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -367,10 +322,7 @@ export class MaxDateTimeFieldValidator implements FormFieldValidator {
if (isAfter(fieldValueDate, max)) { if (isAfter(fieldValueDate, max)) {
field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`; field.validationSummary.message = `FORM.FIELD.VALIDATOR.NOT_GREATER_THAN`;
field.validationSummary.attributes.set( field.validationSummary.attributes.set('maxValue', DateFnsUtils.formatDate(max, field.dateDisplayFormat).replace(':', '-'));
'maxValue',
DateFnsUtils.formatDate(max, field.dateDisplayFormat).replace(':', '-')
);
isValid = false; isValid = false;
} }
return isValid; return isValid;
@@ -378,16 +330,10 @@ export class MaxDateTimeFieldValidator implements FormFieldValidator {
} }
export class MinLengthFieldValidator implements FormFieldValidator { export class MinLengthFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT];
private supportedTypes = [
FormFieldTypes.TEXT,
FormFieldTypes.MULTILINE_TEXT
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && field.minLength > 0;
this.supportedTypes.indexOf(field.type) > -1 &&
field.minLength > 0;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -404,16 +350,10 @@ export class MinLengthFieldValidator implements FormFieldValidator {
} }
export class MaxLengthFieldValidator implements FormFieldValidator { export class MaxLengthFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT];
private supportedTypes = [
FormFieldTypes.TEXT,
FormFieldTypes.MULTILINE_TEXT
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && field.maxLength > 0;
this.supportedTypes.indexOf(field.type) > -1 &&
field.maxLength > 0;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -430,17 +370,10 @@ export class MaxLengthFieldValidator implements FormFieldValidator {
} }
export class MinValueFieldValidator implements FormFieldValidator { export class MinValueFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.DECIMAL, FormFieldTypes.AMOUNT];
private supportedTypes = [
FormFieldTypes.NUMBER,
FormFieldTypes.DECIMAL,
FormFieldTypes.AMOUNT
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && NumberFieldValidator.isNumber(field.minValue);
this.supportedTypes.indexOf(field.type) > -1 &&
NumberFieldValidator.isNumber(field.minValue);
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -461,17 +394,10 @@ export class MinValueFieldValidator implements FormFieldValidator {
} }
export class MaxValueFieldValidator implements FormFieldValidator { export class MaxValueFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.NUMBER, FormFieldTypes.DECIMAL, FormFieldTypes.AMOUNT];
private supportedTypes = [
FormFieldTypes.NUMBER,
FormFieldTypes.DECIMAL,
FormFieldTypes.AMOUNT
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && NumberFieldValidator.isNumber(field.maxValue);
this.supportedTypes.indexOf(field.type) > -1 &&
NumberFieldValidator.isNumber(field.maxValue);
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -492,15 +418,10 @@ export class MaxValueFieldValidator implements FormFieldValidator {
} }
export class RegExFieldValidator implements FormFieldValidator { export class RegExFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.TEXT, FormFieldTypes.MULTILINE_TEXT];
private supportedTypes = [
FormFieldTypes.TEXT,
FormFieldTypes.MULTILINE_TEXT
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.regexPattern;
this.supportedTypes.indexOf(field.type) > -1 && !!field.regexPattern;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -513,14 +434,10 @@ export class RegExFieldValidator implements FormFieldValidator {
} }
return true; return true;
} }
} }
export class FixedValueFieldValidator implements FormFieldValidator { export class FixedValueFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.TYPEAHEAD];
private supportedTypes = [
FormFieldTypes.TYPEAHEAD
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && this.supportedTypes.indexOf(field.type) > -1; return field && this.supportedTypes.indexOf(field.type) > -1;
@@ -558,10 +475,7 @@ export class FixedValueFieldValidator implements FormFieldValidator {
} }
export class DecimalFieldValidator implements FormFieldValidator { export class DecimalFieldValidator implements FormFieldValidator {
private supportedTypes = [FormFieldTypes.DECIMAL];
private supportedTypes = [
FormFieldTypes.DECIMAL
];
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.value; return field && this.supportedTypes.indexOf(field.type) > -1 && !!field.value;

View File

@@ -60,7 +60,7 @@ describe('FormFieldModel', () => {
}; };
const field = new FormFieldModel(new FormModel(), json); const field = new FormFieldModel(new FormModel(), json);
Object.keys(json).forEach((key) => { Object.keys(json).forEach((key) => {
expect(field[key]).toBe(json[key]); expect(field[key]).toEqual(json[key]);
}); });
}); });
@@ -122,6 +122,59 @@ describe('FormFieldModel', () => {
expect(field.value).toBe('deferred'); expect(field.value).toBe('deferred');
}); });
it('should add value to field options if NOT present', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN,
options: [],
value: { id: 'id_one', name: 'One' }
});
expect(field.options).toEqual([{ id: 'id_one', name: 'One' }]);
expect(field.value).toEqual('id_one');
});
it('should assign "empty" option as value if value is null and "empty" option is present in options', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN,
options: [
{ id: 'empty', name: 'Chose one...' },
{ id: 'one', name: 'One' }
],
value: null
});
expect(field.hasEmptyValue).toBe(true);
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Chose one...' });
expect(field.value).toEqual('empty');
});
it('should set hasEmptyValue to true if "empty" option is present in options', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN,
options: [{ id: 'empty', name: 'Choose one...' }],
value: null
});
expect(field.hasEmptyValue).toBe(true);
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Choose one...' });
});
it('should add default "empty" option to the options if hasEmptyValue is true but "empty" option is not present', () => {
const field = new FormFieldModel(new FormModel(), {
type: FormFieldTypes.DROPDOWN,
options: [{ id: 'one', name: 'One' }],
value: null,
hasEmptyValue: true
});
expect(field.hasEmptyValue).toBe(true);
expect(field.emptyOption).toEqual({ id: 'empty', name: 'Choose one...' });
expect(field.options).toEqual([
{ id: 'empty', name: 'Choose one...' },
{ id: 'one', name: 'One' }
]);
});
it('should parse the date with the default format (D-M-YYYY) if the display format is missing', () => { it('should parse the date with the default format (D-M-YYYY) if the display format is missing', () => {
const form = new FormModel(); const form = new FormModel();
const field = new FormFieldModel(form, { const field = new FormFieldModel(form, {

View File

@@ -40,6 +40,8 @@ export class FormFieldModel extends FormWidgetModel {
readonly defaultDateFormat: string = 'D-M-YYYY'; readonly defaultDateFormat: string = 'D-M-YYYY';
readonly defaultDateTimeFormat: string = 'D-M-YYYY hh:mm A'; readonly defaultDateTimeFormat: string = 'D-M-YYYY hh:mm A';
private readonly defaultEmptyOptionId = 'empty';
private readonly defaultEmptyOptionName = 'Choose one...';
// model members // model members
fieldType: string; fieldType: string;
@@ -187,8 +189,9 @@ export class FormFieldModel extends FormWidgetModel {
this.maxDateRangeValue = json.maxDateRangeValue; this.maxDateRangeValue = json.maxDateRangeValue;
this.dynamicDateRangeSelection = json.dynamicDateRangeSelection; this.dynamicDateRangeSelection = json.dynamicDateRangeSelection;
this.regexPattern = json.regexPattern; this.regexPattern = json.regexPattern;
this.options = json.options || []; this.options = this.parseValidOptions(json.options);
this.hasEmptyValue = json.hasEmptyValue; this.emptyOption = this.getEmptyOption(this.options);
this.hasEmptyValue = json?.hasEmptyValue ?? !!this.emptyOption;
this.className = json.className; this.className = json.className;
this.optionType = json.optionType; this.optionType = json.optionType;
this.params = json.params || {}; this.params = json.params || {};
@@ -198,7 +201,6 @@ export class FormFieldModel extends FormWidgetModel {
this.enableFractions = json.enableFractions; this.enableFractions = json.enableFractions;
this.currency = json.currency; this.currency = json.currency;
this.dateDisplayFormat = json.dateDisplayFormat || this.getDefaultDateFormat(json); this.dateDisplayFormat = json.dateDisplayFormat || this.getDefaultDateFormat(json);
this._value = this.parseValue(json);
this.validationSummary = new ErrorMessageModel(); this.validationSummary = new ErrorMessageModel();
this.tooltip = json.tooltip; this.tooltip = json.tooltip;
this.selectionType = json.selectionType; this.selectionType = json.selectionType;
@@ -210,6 +212,7 @@ export class FormFieldModel extends FormWidgetModel {
this.schemaDefinition = json.schemaDefinition; this.schemaDefinition = json.schemaDefinition;
this.precision = json.precision; this.precision = json.precision;
this.externalProperty = json.externalProperty; this.externalProperty = json.externalProperty;
this._value = this.parseValue(json);
if (json.placeholder && json.placeholder !== '' && json.placeholder !== 'null') { if (json.placeholder && json.placeholder !== '' && json.placeholder !== 'null') {
this.placeholder = json.placeholder; this.placeholder = json.placeholder;
@@ -230,18 +233,13 @@ export class FormFieldModel extends FormWidgetModel {
this.leftLabels = form.json.leftLabels || false; this.leftLabels = form.json.leftLabels || false;
} }
const emptyOption = Array.isArray(this.options) ? this.options.find(({ id }) => id === 'empty') : undefined;
if (this.hasEmptyValue === undefined) {
this.hasEmptyValue = json?.hasEmptyValue ?? !!emptyOption;
}
if (this.options && this.options.length > 0 && this.hasEmptyValue) {
this.emptyOption = emptyOption;
}
this.updateForm(); this.updateForm();
} }
private getEmptyOption(options: FormFieldOption[]): FormFieldOption {
return options.find((option) => option?.id === this.defaultEmptyOptionId);
}
private setValueForReadonlyType(form: any) { private setValueForReadonlyType(form: any) {
const value = this.getProcessVariableValue(this.params.field, form); const value = this.getProcessVariableValue(this.params.field, form);
if (value) { if (value) {
@@ -308,22 +306,34 @@ export class FormFieldModel extends FormWidgetModel {
but saving back as object: { id: <id>, name: <name> } but saving back as object: { id: <id>, name: <name> }
*/ */
if (json.type === FormFieldTypes.DROPDOWN) { if (json.type === FormFieldTypes.DROPDOWN) {
if (json.options) { if (this.hasEmptyValue) {
if (json.hasEmptyValue) { if (!this.emptyOption) {
const emptyOption = json.options[0]; this.emptyOption = {
if (value === '' || value === emptyOption.id || value === emptyOption.name) { id: this.defaultEmptyOptionId,
value = emptyOption.id; name: this.defaultEmptyOptionName
} };
} else { this.options.unshift(this.emptyOption);
if (value?.id && value?.name) { }
value = value.id;
} const isEmptyValue = !value || [this.emptyOption.id, this.emptyOption.name].includes(value);
if (isEmptyValue) {
return this.emptyOption.id;
} }
} }
if (this.hasMultipleValues) { if (this.isValidOption(value)) {
value = Array.isArray(json.value) ? json.value : []; this.addOption(value);
return value.id;
} }
if (this.hasMultipleValues) {
const validSelectedOptions = (Array.isArray(json.value) ? json.value : []).filter((option) => this.isValidOption(option));
this.addOptions(validSelectedOptions);
return validSelectedOptions;
}
return value;
} }
/* /*
@@ -337,9 +347,8 @@ export class FormFieldModel extends FormWidgetModel {
const entry: FormFieldOption[] = this.options.filter( const entry: FormFieldOption[] = this.options.filter(
(opt) => opt.id === value || opt.name === value || (value && (opt.id === value.id || opt.name === value.name)) (opt) => opt.id === value || opt.name === value || (value && (opt.id === value.id || opt.name === value.name))
); );
if (entry.length > 0) {
value = entry[0].id; return entry.length > 0 ? entry[0].id : value;
}
} }
/* /*
@@ -359,13 +368,15 @@ export class FormFieldModel extends FormWidgetModel {
} }
if (isValidDate(dateValue)) { if (isValidDate(dateValue)) {
value = DateFnsUtils.formatDate(dateValue, this.dateDisplayFormat); return DateFnsUtils.formatDate(dateValue, this.dateDisplayFormat);
} }
} }
return value;
} }
if (this.isCheckboxField(json)) { if (this.isCheckboxField(json)) {
value = json.value === 'true' || json.value === true; return json.value === 'true' || json.value === true;
} }
return value; return value;
@@ -511,6 +522,29 @@ export class FormFieldModel extends FormWidgetModel {
return this.options?.length > 0; return this.options?.length > 0;
} }
isEmptyValueOption(option: FormFieldOption): boolean {
return this.hasEmptyValue && option?.id === this.defaultEmptyOptionId;
}
private addOptions(options: FormFieldOption[]) {
options.forEach((option) => this.addOption(option));
}
private addOption(option: FormFieldOption) {
const alreadyExists = this.options.find((opt) => opt?.id === option?.id);
if (!alreadyExists) {
this.options.push(option);
}
}
private parseValidOptions(options: any): FormFieldOption[] {
return Array.isArray(options) ? options.filter((option) => this.isValidOption(option)) : [];
}
private isValidOption(option: any): boolean {
return typeof option === 'object' && !Array.isArray(option) && option?.id && option?.name;
}
private isDateField(json: any) { private isDateField(json: any) {
return json.params?.field?.type === FormFieldTypes.DATE || json.type === FormFieldTypes.DATE; return json.params?.field?.type === FormFieldTypes.DATE || json.type === FormFieldTypes.DATE;
} }

View File

@@ -64,11 +64,10 @@ describe('DropdownCloudWidgetComponent', () => {
describe('Simple Dropdown', () => { describe('Simple Dropdown', () => {
beforeEach(() => { beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'date-name', name: 'date-name',
type: 'dropdown', type: 'dropdown',
readOnly: false,
restUrl: 'https://fake-rest-url', restUrl: 'https://fake-rest-url',
options: [{ id: 'empty', name: 'Choose one...' }] options: [{ id: 'empty', name: 'Choose one...' }]
}); });
@@ -120,6 +119,18 @@ describe('DropdownCloudWidgetComponent', () => {
expect(await allOptions[2].getText()).toEqual('option_3'); expect(await allOptions[2].getText()).toEqual('option_3');
}); });
it('should NOT load data from restUrl when field is readonly', () => {
spyOn(formCloudService, 'getRestWidgetData');
widget.field.readOnly = true;
widget.field.restUrl = 'https://fake-rest-url';
widget.field.optionType = 'rest';
widget.field.restIdProperty = 'name';
widget.ngOnInit();
expect(formCloudService.getRestWidgetData).not.toHaveBeenCalled();
});
it('should show error message if the restUrl failed to fetch options', async () => { 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')); const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(throwError('Failed to fetch options'));
const errorIcon: string = 'error_outline'; const errorIcon: string = 'error_outline';
@@ -315,15 +326,30 @@ describe('DropdownCloudWidgetComponent', () => {
const requiredErrorElement = fixture.debugElement.query(By.css('.adf-dropdown-required-message .adf-error-text')); const requiredErrorElement = fixture.debugElement.query(By.css('.adf-dropdown-required-message .adf-error-text'));
expect(requiredErrorElement.nativeElement.innerText).toEqual('FORM.FIELD.REQUIRED'); expect(requiredErrorElement.nativeElement.innerText).toEqual('FORM.FIELD.REQUIRED');
}); });
it('should NOT display a required error when dropdown is readonly', async () => {
widget.field.readOnly = true;
fixture.detectChanges();
await fixture.whenStable();
expect(element.querySelector('.adf-invalid')).toBeFalsy();
const dropdownSelect = element.querySelector('.adf-select');
dropdownSelect.dispatchEvent(new Event('blur'));
fixture.detectChanges();
await fixture.whenStable();
expect(element.querySelector('.adf-invalid')).toBeFalsy();
});
}); });
describe('filter', () => { describe('filter', () => {
beforeEach(() => { beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'option list', name: 'option list',
type: 'dropdown', type: 'dropdown',
readOnly: false,
options: filterOptionList options: filterOptionList
}); });
widget.ngOnInit(); widget.ngOnInit();
@@ -370,11 +396,10 @@ describe('DropdownCloudWidgetComponent', () => {
describe('multiple selection', () => { describe('multiple selection', () => {
it('should show preselected option', async () => { it('should show preselected option', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'date-name', name: 'date-name',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
options: fakeOptionList, options: fakeOptionList,
selectionType: 'multiple', selectionType: 'multiple',
value: [ value: [
@@ -389,11 +414,10 @@ describe('DropdownCloudWidgetComponent', () => {
}); });
it('should support multiple options', async () => { it('should support multiple options', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'date-name', name: 'date-name',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
selectionType: 'multiple', selectionType: 'multiple',
options: fakeOptionList options: fakeOptionList
}); });
@@ -408,11 +432,10 @@ describe('DropdownCloudWidgetComponent', () => {
}); });
it('should show preselected option for rest options', async () => { it('should show preselected option for rest options', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'date-name', name: 'date-name',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
restUrl: 'https://fake-rest-url', restUrl: 'https://fake-rest-url',
optionType: 'rest', optionType: 'rest',
selectionType: 'multiple', selectionType: 'multiple',
@@ -448,11 +471,10 @@ describe('DropdownCloudWidgetComponent', () => {
}); });
it('should support multiple options for rest options', async () => { it('should support multiple options for rest options', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'date-name', name: 'date-name',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
restUrl: 'https://fake-rest-url', restUrl: 'https://fake-rest-url',
optionType: 'rest', optionType: 'rest',
selectionType: 'multiple' selectionType: 'multiple'
@@ -498,11 +520,10 @@ describe('DropdownCloudWidgetComponent', () => {
validate: () => true validate: () => true
}); });
beforeEach(() => { beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'child-dropdown-id', id: 'child-dropdown-id',
name: 'child-dropdown', name: 'child-dropdown',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
optionType: 'rest', optionType: 'rest',
restUrl: 'myFakeDomain.com/cities?country=${parentDropdown}', restUrl: 'myFakeDomain.com/cities?country=${parentDropdown}',
rule: { rule: {
@@ -605,11 +626,10 @@ describe('DropdownCloudWidgetComponent', () => {
const parentDropdown = new FormFieldModel(new FormModel(), { id: 'parentDropdown', type: 'dropdown' }); const parentDropdown = new FormFieldModel(new FormModel(), { id: 'parentDropdown', type: 'dropdown' });
beforeEach(() => { beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'child-dropdown-id', id: 'child-dropdown-id',
name: 'child-dropdown', name: 'child-dropdown',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
optionType: 'manual', optionType: 'manual',
rule: { rule: {
ruleOn: 'parentDropdown', ruleOn: 'parentDropdown',
@@ -694,11 +714,10 @@ describe('DropdownCloudWidgetComponent', () => {
describe('Load selection for linked dropdown (i.e. saved, completed forms)', () => { describe('Load selection for linked dropdown (i.e. saved, completed forms)', () => {
it('should load the selection of a manual type linked dropdown', () => { it('should load the selection of a manual type linked dropdown', () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'child-dropdown-id', id: 'child-dropdown-id',
name: 'child-dropdown', name: 'child-dropdown',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
optionType: 'manual', optionType: 'manual',
rule: { rule: {
ruleOn: 'parentDropdown', ruleOn: 'parentDropdown',
@@ -718,11 +737,10 @@ describe('DropdownCloudWidgetComponent', () => {
it('should load the selection of a rest type linked dropdown', () => { it('should load the selection of a rest type linked dropdown', () => {
const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(mockRestDropdownOptions)); const jsonDataSpy = spyOn(formCloudService, 'getRestWidgetData').and.returnValue(of(mockRestDropdownOptions));
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false' }), {
id: 'child-dropdown-id', id: 'child-dropdown-id',
name: 'child-dropdown', name: 'child-dropdown',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
restUrl: 'mock-url.com/country=${country}', restUrl: 'mock-url.com/country=${country}',
optionType: 'rest', optionType: 'rest',
rule: { rule: {
@@ -744,11 +762,10 @@ describe('DropdownCloudWidgetComponent', () => {
describe('when form model has left labels', () => { describe('when form model has left labels', () => {
it('should have left labels classes on leftLabels true', async () => { it('should have left labels classes on leftLabels true', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: true }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false, leftLabels: true }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'option list', name: 'option list',
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
readOnly: false,
options: filterOptionList options: filterOptionList
}); });
@@ -763,11 +780,10 @@ describe('DropdownCloudWidgetComponent', () => {
}); });
it('should not have left labels classes on leftLabels false', async () => { it('should not have left labels classes on leftLabels false', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', leftLabels: false }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false, leftLabels: false }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'option list', name: 'option list',
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
readOnly: false,
options: filterOptionList options: filterOptionList
}); });
@@ -782,11 +798,10 @@ describe('DropdownCloudWidgetComponent', () => {
}); });
it('should not have left labels classes on leftLabels not present', async () => { it('should not have left labels classes on leftLabels not present', async () => {
widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id' }), { widget.field = new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: false }), {
id: 'dropdown-id', id: 'dropdown-id',
name: 'option list', name: 'option list',
type: FormFieldTypes.DROPDOWN, type: FormFieldTypes.DROPDOWN,
readOnly: false,
options: filterOptionList options: filterOptionList
}); });
@@ -813,11 +828,10 @@ describe('DropdownCloudWidgetComponent', () => {
processVariables?: TaskVariableCloud[], processVariables?: TaskVariableCloud[],
variables?: TaskVariableCloud[] variables?: TaskVariableCloud[]
) => ) =>
new FormFieldModel(new FormModel({ taskId: 'fake-task-id', processVariables, variables }), { new FormFieldModel(new FormModel({ taskId: 'fake-task-id', readOnly: 'false', processVariables, variables }), {
id: 'variable-dropdown-id', id: 'variable-dropdown-id',
name: 'variable-options-dropdown', name: 'variable-options-dropdown',
type: 'dropdown', type: 'dropdown',
readOnly: 'false',
optionType: 'variable', optionType: 'variable',
variableConfig: { variableConfig: {
variableName, variableName,
@@ -961,5 +975,20 @@ describe('DropdownCloudWidgetComponent', () => {
const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message')); const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
expect(failedErrorMsgElement).toBeNull(); expect(failedErrorMsgElement).toBeNull();
}); });
it('should NOT display errors if field is readonly', () => {
widget.field = getVariableDropdownWidget(
'variables.wrong-variable-id',
'response.wrongPath.players',
'wrongId',
'wrongFullName',
mockProcessVariablesWithJson
);
widget.field.readOnly = true;
fixture.detectChanges();
const failedErrorMsgElement = fixture.debugElement.query(By.css('.adf-dropdown-failed-message'));
expect(failedErrorMsgElement).toBeNull();
});
}); });
}); });

View File

@@ -84,7 +84,9 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
private checkFieldOptionsSource(): void { private checkFieldOptionsSource(): void {
switch (true) { switch (true) {
case this.field.restUrl && !this.isLinkedWidget(): case this.isReadOnly():
break;
case this.hasRestUrl() && !this.isLinkedWidget():
this.persistFieldOptionsFromRestApi(); this.persistFieldOptionsFromRestApi();
break; break;
@@ -377,7 +379,7 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
} }
private isValidRestType(): boolean { private isValidRestType(): boolean {
return this.field.optionType === 'rest' && !!this.field.restUrl; return this.field.optionType === 'rest' && this.hasRestUrl();
} }
private setPreviewState(): void { private setPreviewState(): void {
@@ -390,6 +392,14 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
} }
} }
private isReadOnly(): boolean {
return this.field.readOnly;
}
private hasRestUrl(): boolean {
return !!this.field.restUrl;
}
isReadOnlyType(): boolean { isReadOnlyType(): boolean {
return this.field.type === 'readonly'; return this.field.type === 'readonly';
} }
@@ -400,6 +410,10 @@ export class DropdownCloudWidgetComponent extends WidgetComponent implements OnI
} }
updateOptions(): void { updateOptions(): void {
if (this.isReadOnly()) {
this.list$ = of(this.field.options);
}
this.showInputFilter = this.field.options.length > this.appConfig.get<number>('form.dropDownFilterLimit', HIDE_FILTER_LIMIT); this.showInputFilter = this.field.options.length > this.appConfig.get<number>('form.dropDownFilterLimit', HIDE_FILTER_LIMIT);
this.list$ = combineLatest([of(this.field.options), this.filter$]).pipe( this.list$ = combineLatest([of(this.field.options), this.filter$]).pipe(
map(([items, search]) => { map(([items, search]) => {

View File

@@ -944,10 +944,13 @@ describe('FormComponent', () => {
const formValues: any = {}; const formValues: any = {};
formValues.dropdownId = { formValues.dropdownId = {
id: 'option_2', id: 'dropdown_option_2',
name: 'test2' name: 'Dropdown option 2'
};
formValues.radio = {
id: 'radio_option_3',
name: 'Radio option 3'
}; };
formValues.radio = { id: 'option_2', name: 'Option 2' };
const change = new SimpleChange(null, formValues, false); const change = new SimpleChange(null, formValues, false);
formComponent.data = formValues; formComponent.data = formValues;
formComponent.ngOnChanges({ data: change }); formComponent.ngOnChanges({ data: change });
@@ -956,9 +959,9 @@ describe('FormComponent', () => {
dropdownField = formFields.find((field) => field.id === 'dropdownId'); dropdownField = formFields.find((field) => field.id === 'dropdownId');
radioField = formFields.find((field) => field.id === 'radio'); radioField = formFields.find((field) => field.id === 'radio');
expect(dropdownField.value.id).toBe('option_2'); expect(dropdownField.value).toBe('dropdown_option_2');
expect(dropdownField.value.name).toBe('test2'); expect(radioField.value.id).toBe('radio_option_3');
expect(radioField.value).toBe('option_2'); expect(radioField.value.name).toBe('Radio option 3');
}); });
it('should refresh radio buttons value when id is given to data', () => { it('should refresh radio buttons value when id is given to data', () => {