From e8fa867b105426b37e0cba16c6829b7f43dee99e Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:59:34 +0100 Subject: [PATCH 1/4] [open-formulieren/open-forms#3611] Make time bounds validation inclusive --- src/formio/validators/MinMaxTimeValidator.js | 6 +++--- src/jstests/formio/components/time.spec.js | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/formio/validators/MinMaxTimeValidator.js b/src/formio/validators/MinMaxTimeValidator.js index a8ca96775..76ba2e2f1 100644 --- a/src/formio/validators/MinMaxTimeValidator.js +++ b/src/formio/validators/MinMaxTimeValidator.js @@ -14,12 +14,12 @@ const validateTimeBoundaries = (minBoundary, maxBoundary, timeValue) => { // Case 1: only one boundary is given if (!minTime || !maxTime) { if (minTime) return {isValid: parsedValue >= minTime, errorKeys: ['minTime']}; - if (maxTime) return {isValid: parsedValue < maxTime, errorKeys: ['maxTime']}; + if (maxTime) return {isValid: parsedValue <= maxTime, errorKeys: ['maxTime']}; } else { // Case 2: min boundary is smaller than max boundary if (minTime < maxTime) { const isTooEarly = parsedValue < minTime; - const isTooLate = parsedValue >= maxTime; + const isTooLate = parsedValue > maxTime; return { isValid: !isTooEarly && !isTooLate, errorKeys: [isTooEarly ? 'minTime' : 'maxTime', 'invalid_time'], @@ -27,7 +27,7 @@ const validateTimeBoundaries = (minBoundary, maxBoundary, timeValue) => { } else { // Case 3: min boundary is bigger than max boundary (it's the next day. For example min = 08:00, max = 01:00) return { - isValid: !(parsedValue >= maxTime && parsedValue < minTime), + isValid: !(parsedValue > maxTime && parsedValue < minTime), // Basically, the opposite of 01:00 < `parsedValue` < 08:00 errorKeys: ['invalid_time'], }; } diff --git a/src/jstests/formio/components/time.spec.js b/src/jstests/formio/components/time.spec.js index 0c494b300..02101c97d 100644 --- a/src/jstests/formio/components/time.spec.js +++ b/src/jstests/formio/components/time.spec.js @@ -15,9 +15,9 @@ describe('Time Component', () => { formJSON.components[0].validate.minTime = '09:00:00'; formJSON.components[0].validate.maxTime = '17:00:00'; - const validValues = ['09:00:00', '10:30:00', '11:11:11']; + const validValues = ['09:00:00', '10:30:00', '11:11:11', '17:00:00']; - const invalidValues = ['17:00:00', '17:30:00', '08:30:00']; + const invalidValues = ['17:30:00', '08:30:00']; const testValidity = (values, valid) => { values.forEach(value => { @@ -125,7 +125,7 @@ describe('Time Component', () => { let formJSON = _.cloneDeep(timeForm); formJSON.components[0].validate.maxTime = '09:00:00'; - const validValues = ['08:00:00']; + const validValues = ['08:00:00', '09:00:00']; const invalidValues = ['17:00:00']; @@ -165,7 +165,7 @@ describe('Time Component', () => { formJSON.components[0].validate.maxTime = '01:00:00'; formJSON.components[0].validate.minTime = '08:00:00'; - const validValues = ['09:00:00', '00:30:00']; + const validValues = ['09:00:00', '00:30:00', '01:00:00', '08:00:00']; const invalidValues = ['02:00:00']; From d245e80b2a4579a1fe164d564ceda44e211f3b21 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:32:07 +0100 Subject: [PATCH 2/4] [open-formulieren/open-forms#3611] Refactor tests to be parametrized --- src/jstests/formio/components/time.spec.js | 285 ++++++++------------- 1 file changed, 111 insertions(+), 174 deletions(-) diff --git a/src/jstests/formio/components/time.spec.js b/src/jstests/formio/components/time.spec.js index 02101c97d..43be61f24 100644 --- a/src/jstests/formio/components/time.spec.js +++ b/src/jstests/formio/components/time.spec.js @@ -1,5 +1,4 @@ import _ from 'lodash'; -import React from 'react'; import {Formio} from 'react-formio'; import OpenFormsModule from 'formio/module'; @@ -10,195 +9,133 @@ import {timeForm} from './fixtures/time'; Formio.use(OpenFormsModule); describe('Time Component', () => { - test('Time component with min/max time validation', done => { + it.each([ + ['09:00:00', true], + ['10:30:00', true], + ['11:11:11', true], + ['17:00:00', true], + ['17:30:00', false], + ['08:30:00', false], + ])('Time component with min/max time validation', async (value, valid) => { let formJSON = _.cloneDeep(timeForm); formJSON.components[0].validate.minTime = '09:00:00'; formJSON.components[0].validate.maxTime = '17:00:00'; - const validValues = ['09:00:00', '10:30:00', '11:11:11', '17:00:00']; - - const invalidValues = ['17:30:00', '08:30:00']; - - const testValidity = (values, valid) => { - values.forEach(value => { - const element = document.createElement('div'); - - Formio.createForm(element, formJSON) - .then(form => { - form.setPristine(false); - const component = form.getComponent('time'); - const changed = component.setValue(value); - expect(changed).toBeTruthy(); - - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - expect(component.error.message).toEqual('invalid_time'); - } - - if (value === invalidValues[2]) { - done(); - } - }, 300); - }) - .catch(done); - }); - }; - - testValidity(validValues, true); - testValidity(invalidValues, false); - }); - - test('Time component without min/max time validation', done => { - let formJSON = _.cloneDeep(timeForm); - - const validValues = ['00:00:00', '23:59:59', '11:11:11']; - - const testValidity = values => { - values.forEach(value => { - const element = document.createElement('div'); - - Formio.createForm(element, formJSON) - .then(form => { - form.setPristine(false); - const component = form.getComponent('time'); - const changed = component.setValue(value); - expect(changed).toBeTruthy(); - - setTimeout(() => { - expect(!!component.error).toBeFalsy(); - - if (value === validValues[2]) { - done(); - } - }, 300); - }) - .catch(done); - }); - }; - - testValidity(validValues); + const element = document.createElement('div'); + const form = await Formio.createForm(element, formJSON); + form.setPristine(false); + + const component = form.getComponent('time'); + const changed = component.setValue(value); + expect(changed).toBeTruthy(); + setTimeout(() => { + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } + }, 300); }); - test('Time component with only min time validation', done => { + it.each(['00:00:00', '23:59:59', '11:11:11'])( + 'Time component without min/max time validation', + async value => { + let formJSON = _.cloneDeep(timeForm); + + const element = document.createElement('div'); + const form = await Formio.createForm(element, formJSON); + form.setPristine(false); + + const component = form.getComponent('time'); + const changed = component.setValue(value); + + expect(changed).toBeTruthy(); + setTimeout(() => { + expect(!!component.error).toBeFalsy(); + }, 300); + } + ); + + it.each([ + ['17:00:00', true], + ['08:00:00', false], + ])('Time component with only min time validation', async (value, valid) => { let formJSON = _.cloneDeep(timeForm); formJSON.components[0].validate.minTime = '09:00:00'; - const validValues = ['17:00:00']; - - const invalidValues = ['08:00:00']; - - const testValidity = (values, valid) => { - values.forEach(value => { - const element = document.createElement('div'); - - Formio.createForm(element, formJSON) - .then(form => { - form.setPristine(false); - const component = form.getComponent('time'); - const changed = component.setValue(value); - expect(changed).toBeTruthy(); - - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - } - - if (value === invalidValues[0]) { - done(); - } - }, 300); - }) - .catch(done); - }); - }; - - testValidity(validValues, true); - testValidity(invalidValues, false); + const element = document.createElement('div'); + const form = await Formio.createForm(element, formJSON); + form.setPristine(false); + + const component = form.getComponent('time'); + const changed = component.setValue(value); + expect(changed).toBeTruthy(); + setTimeout(() => { + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } + }, 300); }); - test('Time component with only max time validation', done => { + it.each([ + ['08:00:00', true], + ['09:00:00', true], + ['17:00:00', false], + ])('Time component with only max time validation', async (value, valid) => { let formJSON = _.cloneDeep(timeForm); formJSON.components[0].validate.maxTime = '09:00:00'; - const validValues = ['08:00:00', '09:00:00']; - - const invalidValues = ['17:00:00']; - - const testValidity = (values, valid) => { - values.forEach(value => { - const element = document.createElement('div'); - - Formio.createForm(element, formJSON) - .then(form => { - form.setPristine(false); - const component = form.getComponent('time'); - const changed = component.setValue(value); - expect(changed).toBeTruthy(); - - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - } - - if (value === invalidValues[0]) { - done(); - } - }, 300); - }) - .catch(done); - }); - }; - - testValidity(validValues, true); - testValidity(invalidValues, false); + const element = document.createElement('div'); + const form = await Formio.createForm(element, formJSON); + form.setPristine(false); + + const component = form.getComponent('time'); + const changed = component.setValue(value); + expect(changed).toBeTruthy(); + setTimeout(() => { + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } + }, 300); }); - test('Time component with min time boundary larger than max time boundary', done => { - let formJSON = _.cloneDeep(timeForm); - formJSON.components[0].validate.maxTime = '01:00:00'; - formJSON.components[0].validate.minTime = '08:00:00'; - - const validValues = ['09:00:00', '00:30:00', '01:00:00', '08:00:00']; - - const invalidValues = ['02:00:00']; - - const testValidity = (values, valid) => { - values.forEach(value => { - const element = document.createElement('div'); - - Formio.createForm(element, formJSON) - .then(form => { - form.setPristine(false); - const component = form.getComponent('time'); - const changed = component.setValue(value); - expect(changed).toBeTruthy(); - - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - } - - if (value === invalidValues[0]) { - done(); - } - }, 300); - }) - .catch(done); - }); - }; - - testValidity(validValues, true); - testValidity(invalidValues, false); - }); + it.each([ + ['09:00:00', true], + ['00:30:00', true], + ['01:00:00', true], + ['08:00:00', true], + ['02:00:00', false], + ])( + 'Time component with min time boundary larger than max time boundary', + async (value, valid) => { + let formJSON = _.cloneDeep(timeForm); + formJSON.components[0].validate.maxTime = '01:00:00'; + formJSON.components[0].validate.minTime = '08:00:00'; + + const element = document.createElement('div'); + const form = await Formio.createForm(element, formJSON); + form.setPristine(false); + + const component = form.getComponent('time'); + const changed = component.setValue(value); + expect(changed).toBeTruthy(); + setTimeout(() => { + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } + }, 300); + } + ); test('Time component with both min/max and max > min validation and custom error', done => { let formJSON = _.cloneDeep(timeForm); From d18c7acc6584da14f505fdfb29a9bdf546eaf247 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Tue, 21 Nov 2023 15:30:14 +0100 Subject: [PATCH 3/4] [open-formulieren/open-forms#3611] Actually let jest run the expectations --- src/jstests/formio/components/time.spec.js | 62 +++++++++++----------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/jstests/formio/components/time.spec.js b/src/jstests/formio/components/time.spec.js index 43be61f24..5422a6b77 100644 --- a/src/jstests/formio/components/time.spec.js +++ b/src/jstests/formio/components/time.spec.js @@ -2,6 +2,7 @@ import _ from 'lodash'; import {Formio} from 'react-formio'; import OpenFormsModule from 'formio/module'; +import {sleep} from 'utils'; import {timeForm} from './fixtures/time'; @@ -28,14 +29,13 @@ describe('Time Component', () => { const component = form.getComponent('time'); const changed = component.setValue(value); expect(changed).toBeTruthy(); - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - expect(component.error.message).toEqual('invalid_time'); - } - }, 300); + await sleep(300); + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } }); it.each(['00:00:00', '23:59:59', '11:11:11'])( @@ -71,14 +71,13 @@ describe('Time Component', () => { const component = form.getComponent('time'); const changed = component.setValue(value); expect(changed).toBeTruthy(); - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - expect(component.error.message).toEqual('invalid_time'); - } - }, 300); + await sleep(300); + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } }); it.each([ @@ -96,14 +95,13 @@ describe('Time Component', () => { const component = form.getComponent('time'); const changed = component.setValue(value); expect(changed).toBeTruthy(); - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - expect(component.error.message).toEqual('invalid_time'); - } - }, 300); + await sleep(300); + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } }); it.each([ @@ -126,14 +124,14 @@ describe('Time Component', () => { const component = form.getComponent('time'); const changed = component.setValue(value); expect(changed).toBeTruthy(); - setTimeout(() => { - if (valid) { - expect(!!component.error).toBeFalsy(); - } else { - expect(!!component.error).toBeTruthy(); - expect(component.error.message).toEqual('invalid_time'); - } - }, 300); + + await sleep(300); + if (valid) { + expect(!!component.error).toBeFalsy(); + } else { + expect(!!component.error).toBeTruthy(); + expect(component.error.message).toEqual('invalid_time'); + } } ); From 3598e1aa877350a37563a4337886e7f34ff78818 Mon Sep 17 00:00:00 2001 From: Viicos <65306057+Viicos@users.noreply.github.com> Date: Wed, 22 Nov 2023 09:28:40 +0100 Subject: [PATCH 4/4] [open-formulieren/open-forms#3611] Add missing sleep call in test --- src/jstests/formio/components/time.spec.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/jstests/formio/components/time.spec.js b/src/jstests/formio/components/time.spec.js index 5422a6b77..384bd2477 100644 --- a/src/jstests/formio/components/time.spec.js +++ b/src/jstests/formio/components/time.spec.js @@ -49,11 +49,10 @@ describe('Time Component', () => { const component = form.getComponent('time'); const changed = component.setValue(value); + await sleep(300); expect(changed).toBeTruthy(); - setTimeout(() => { - expect(!!component.error).toBeFalsy(); - }, 300); + expect(!!component.error).toBeFalsy(); } );