From 08b10574e3330dda22f5073f499f80348131ede9 Mon Sep 17 00:00:00 2001 From: alexandraRamanenka Date: Thu, 22 Feb 2024 10:06:27 -0500 Subject: [PATCH 1/4] FIO-7847: Highlight components that have API keys consisting only from numeric characters --- src/WebformBuilder.js | 8 +++++++ src/WebformBuilder.unit.js | 12 ++++++++++- test/formtest/formWithNumericKeys.json | 30 ++++++++++++++++++++++++++ test/formtest/index.d.ts | 2 +- test/formtest/index.js | 4 +++- 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 test/formtest/formWithNumericKeys.json diff --git a/src/WebformBuilder.js b/src/WebformBuilder.js index 184c717486..07919b68d0 100644 --- a/src/WebformBuilder.js +++ b/src/WebformBuilder.js @@ -1265,6 +1265,7 @@ export default class WebformBuilder extends Component { highlightInvalidComponents() { const repeatablePaths = this.findRepeatablePaths(); let hasInvalidComponents = false; + const badCharacters = /^[^A-Za-z_]+|[^A-Za-z0-9\-._]+/g; this.webform.everyComponent((comp) => { const path = comp.path; @@ -1275,6 +1276,13 @@ export default class WebformBuilder extends Component { else if (comp.error?.message?.startsWith('API Key is not unique')) { comp.setCustomValidity(''); } + + if (comp.key.replace(badCharacters, '') === '') { + comp.setCustomValidity(`API Key is not valid: ${comp.key}`); + } + else if (comp.error?.message?.startsWith('API Key is not valid')) { + comp.setCustomValidity(''); + } }); this.emit('builderFormValidityChange', hasInvalidComponents); diff --git a/src/WebformBuilder.unit.js b/src/WebformBuilder.unit.js index 5b3979ac16..8556b3d905 100644 --- a/src/WebformBuilder.unit.js +++ b/src/WebformBuilder.unit.js @@ -2,7 +2,7 @@ import assert from 'power-assert'; import Harness from '../test/harness'; import WebformBuilder from './WebformBuilder'; import Builders from './builders'; -import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCase } from '../test/formtest'; +import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCas, formWithNumericKeys } from '../test/formtest'; import sameApiKeysLayoutComps from '../test/forms/sameApiKeysLayoutComps'; import testApiKeysUniquifying from '../test/forms/testApiKeysUniquifying'; import formBasedOnWizard from '../test/forms/formBasedOnWizard'; @@ -42,6 +42,16 @@ describe('WebformBuilder tests', function() { }).catch(done); }); + it('Should show API error when componentshave invalid API keys', (done) => { + const builder = Harness.getBuilder(); + builder.webform.setForm(formWithNumericKeys).then(() => { + builder.highlightInvalidComponents(); + const component = builder.webform.components[1]; + assert.equal(component.errors.length, 1); + done(); + }).catch(done); + }); + it('Should show unique API error when components inside and outside of the Layout component have same keys', (done) => { const builder = Harness.getBuilder(); builder.webform.setForm(uniqueApiKeysLayout).then(() => { diff --git a/test/formtest/formWithNumericKeys.json b/test/formtest/formWithNumericKeys.json new file mode 100644 index 0000000000..7d4476156b --- /dev/null +++ b/test/formtest/formWithNumericKeys.json @@ -0,0 +1,30 @@ +{ + "type": "form", + "display": "form", + "components": [ + { + "label": "Text Field", + "applyMaskOn": "change", + "tableView": true, + "key": "test", + "type": "textfield", + "input": true + }, + { + "label": "Text Field", + "applyMaskOn": "change", + "tableView": true, + "key": "1234", + "type": "textfield", + "input": true + }, + { + "type": "button", + "label": "Submit", + "key": "submit", + "disableOnInvalid": true, + "input": true, + "tableView": false + } + ] +} diff --git a/test/formtest/index.d.ts b/test/formtest/index.d.ts index dfd6d0a3d1..b6763d9406 100644 --- a/test/formtest/index.d.ts +++ b/test/formtest/index.d.ts @@ -1 +1 @@ -export { advanced, basic, data, defaults, layout, premium, settingErrors, clearOnHide, manualOverride, uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, validationOnBlur, calculateValueWithManualOverride, calculateValueWithSubmissionMetadata, displayAsModalEditGrid, formWithAdvancedLogic, formWithPatternValidation, calculatedSelectboxes, columnsForm, calculateZeroValue, formWithConditionalLogic, formWithCalculatedValueWithoutOverriding, formWithTimeComponent, formWithEditGridModalDrafts, formWithBlurValidationInsidePanel, modalEditComponents, calculatedNotPersistentValue, calculateValueInEditingMode, initiallyCollapsedPanel, multipleTextareaInsideConditionalComponent, formComponentWithConditionalRenderingForm, disabledNestedForm, propertyActions, formWithEditGridAndNestedDraftModalRow, formWithDateTimeComponents, formWithCollapsedPanel, formWithCustomFormatDate, wizardWithHiddenPanel, wizardWithSimpleConditionalPage, wizardWithTooltip, resourceKeyCamelCase, tooltipActivateCheckbox }; +export { advanced, basic, data, defaults, layout, premium, settingErrors, clearOnHide, manualOverride, uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, validationOnBlur, calculateValueWithManualOverride, calculateValueWithSubmissionMetadata, displayAsModalEditGrid, formWithAdvancedLogic, formWithPatternValidation, calculatedSelectboxes, columnsForm, calculateZeroValue, formWithConditionalLogic, formWithCalculatedValueWithoutOverriding, formWithTimeComponent, formWithEditGridModalDrafts, formWithBlurValidationInsidePanel, modalEditComponents, calculatedNotPersistentValue, calculateValueInEditingMode, initiallyCollapsedPanel, multipleTextareaInsideConditionalComponent, formComponentWithConditionalRenderingForm, disabledNestedForm, propertyActions, formWithEditGridAndNestedDraftModalRow, formWithDateTimeComponents, formWithCollapsedPanel, formWithCustomFormatDate, wizardWithHiddenPanel, wizardWithSimpleConditionalPage, wizardWithTooltip, resourceKeyCamelCase, formWithNumericKeys, tooltipActivateCheckbox }; diff --git a/test/formtest/index.js b/test/formtest/index.js index 4b21cb8e25..6a388d6e78 100644 --- a/test/formtest/index.js +++ b/test/formtest/index.js @@ -42,6 +42,7 @@ const wizardWithTooltip = require('./wizardWithTooltip.json'); const resourceKeyCamelCase = require('./resourceKeyCamelCase.json'); const tooltipActivateCheckbox = require('./tooltipActivateCheckbox.json'); const formWithObjectValueSelect = require('./formWithObjectValueSelect.json'); +const formWithNumericKeys = require('./formWithNumericKeys.json'); module.exports = { advanced, @@ -87,5 +88,6 @@ module.exports = { wizardWithTooltip, resourceKeyCamelCase, tooltipActivateCheckbox, - formWithObjectValueSelect + formWithObjectValueSelect, + formWithNumericKeys, }; From 944e706556baee2d4fcb91cba2073851783c4e44 Mon Sep 17 00:00:00 2001 From: lane-formio Date: Thu, 22 Feb 2024 16:27:29 -0600 Subject: [PATCH 2/4] FIO-7857 fix typo --- src/WebformBuilder.unit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebformBuilder.unit.js b/src/WebformBuilder.unit.js index 8556b3d905..db159a2c43 100644 --- a/src/WebformBuilder.unit.js +++ b/src/WebformBuilder.unit.js @@ -2,7 +2,7 @@ import assert from 'power-assert'; import Harness from '../test/harness'; import WebformBuilder from './WebformBuilder'; import Builders from './builders'; -import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCas, formWithNumericKeys } from '../test/formtest'; +import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCase, formWithNumericKeys } from '../test/formtest'; import sameApiKeysLayoutComps from '../test/forms/sameApiKeysLayoutComps'; import testApiKeysUniquifying from '../test/forms/testApiKeysUniquifying'; import formBasedOnWizard from '../test/forms/formBasedOnWizard'; From b9b3432b2db44cc2abeab0ec8c08abc5d7e698a6 Mon Sep 17 00:00:00 2001 From: alexandraRamanenka Date: Mon, 4 Mar 2024 14:40:33 +0200 Subject: [PATCH 3/4] Fixed tests --- src/WebformBuilder.unit.js | 5 +++-- test/forms/formWithNumericKeys.js | 30 ++++++++++++++++++++++++++ test/formtest/formWithNumericKeys.json | 30 -------------------------- test/formtest/index.js | 2 -- 4 files changed, 33 insertions(+), 34 deletions(-) create mode 100644 test/forms/formWithNumericKeys.js delete mode 100644 test/formtest/formWithNumericKeys.json diff --git a/src/WebformBuilder.unit.js b/src/WebformBuilder.unit.js index 8556b3d905..ac2bb11a1e 100644 --- a/src/WebformBuilder.unit.js +++ b/src/WebformBuilder.unit.js @@ -2,7 +2,8 @@ import assert from 'power-assert'; import Harness from '../test/harness'; import WebformBuilder from './WebformBuilder'; import Builders from './builders'; -import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCas, formWithNumericKeys } from '../test/formtest'; +import { uniqueApiKeys, uniqueApiKeysLayout, uniqueApiKeysSameLevel, columnsForm, resourceKeyCamelCas } from '../test/formtest'; +import formWithNumericKeys from '../test/forms/formWithNumericKeys'; import sameApiKeysLayoutComps from '../test/forms/sameApiKeysLayoutComps'; import testApiKeysUniquifying from '../test/forms/testApiKeysUniquifying'; import formBasedOnWizard from '../test/forms/formBasedOnWizard'; @@ -42,7 +43,7 @@ describe('WebformBuilder tests', function() { }).catch(done); }); - it('Should show API error when componentshave invalid API keys', (done) => { + it('Should show API error when components have invalid API keys', (done) => { const builder = Harness.getBuilder(); builder.webform.setForm(formWithNumericKeys).then(() => { builder.highlightInvalidComponents(); diff --git a/test/forms/formWithNumericKeys.js b/test/forms/formWithNumericKeys.js new file mode 100644 index 0000000000..3e76bea557 --- /dev/null +++ b/test/forms/formWithNumericKeys.js @@ -0,0 +1,30 @@ +export default { + type: 'form', + display: 'form', + components: [ + { + label: 'Text Field', + applyMaskOn: 'change', + tableView: true, + key: 'test', + type: 'textfield', + input: true, + }, + { + label: 'Text Field', + applyMaskOn: 'change', + tableView: true, + key: '1234', + type: 'textfield', + input: true, + }, + { + type: 'button', + label: 'Submit', + key: 'submit', + disableOnInvalid: true, + input: true, + tableView: false, + }, + ], +}; diff --git a/test/formtest/formWithNumericKeys.json b/test/formtest/formWithNumericKeys.json deleted file mode 100644 index 7d4476156b..0000000000 --- a/test/formtest/formWithNumericKeys.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "type": "form", - "display": "form", - "components": [ - { - "label": "Text Field", - "applyMaskOn": "change", - "tableView": true, - "key": "test", - "type": "textfield", - "input": true - }, - { - "label": "Text Field", - "applyMaskOn": "change", - "tableView": true, - "key": "1234", - "type": "textfield", - "input": true - }, - { - "type": "button", - "label": "Submit", - "key": "submit", - "disableOnInvalid": true, - "input": true, - "tableView": false - } - ] -} diff --git a/test/formtest/index.js b/test/formtest/index.js index 6a388d6e78..1592a47297 100644 --- a/test/formtest/index.js +++ b/test/formtest/index.js @@ -42,7 +42,6 @@ const wizardWithTooltip = require('./wizardWithTooltip.json'); const resourceKeyCamelCase = require('./resourceKeyCamelCase.json'); const tooltipActivateCheckbox = require('./tooltipActivateCheckbox.json'); const formWithObjectValueSelect = require('./formWithObjectValueSelect.json'); -const formWithNumericKeys = require('./formWithNumericKeys.json'); module.exports = { advanced, @@ -89,5 +88,4 @@ module.exports = { resourceKeyCamelCase, tooltipActivateCheckbox, formWithObjectValueSelect, - formWithNumericKeys, }; From cd3efea567497e17d9a2aec73fe03c85570e7f48 Mon Sep 17 00:00:00 2001 From: alexandraRamanenka <60643585+alexandraRamanenka@users.noreply.github.com> Date: Mon, 20 May 2024 13:58:19 +0300 Subject: [PATCH 4/4] Added RexExp description --- src/WebformBuilder.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/WebformBuilder.js b/src/WebformBuilder.js index 07919b68d0..615c156fec 100644 --- a/src/WebformBuilder.js +++ b/src/WebformBuilder.js @@ -1265,6 +1265,7 @@ export default class WebformBuilder extends Component { highlightInvalidComponents() { const repeatablePaths = this.findRepeatablePaths(); let hasInvalidComponents = false; + // Matches anything expect letters and '_' at the begginnig of the key and anything except of letters, numbers, '-', '.' and '_' in the rest of the key const badCharacters = /^[^A-Za-z_]+|[^A-Za-z0-9\-._]+/g; this.webform.everyComponent((comp) => {