From 8345937dffe6f9470d5a61ddf8287afb7918f19b Mon Sep 17 00:00:00 2001 From: ashit-rath Date: Wed, 19 Apr 2023 15:11:03 +0530 Subject: [PATCH] fix: JSONForm multiselect field with invalid option crash (#22510) ## Description When invalid `Options` is passed to a multiselect field in a JSONForm, the widget crashes. Example of invalid `Options` ```js {{ [ { label: "asd", value: "zxc"}, null ] }} ``` The second option is `null` which makes the whole `Options` property as invalid. Fixes #20791 ## Type of change - Bug fix (non-breaking change which fixes an issue) ## How Has This Been Tested? - Manual - Cypress ### Test Plan > https://github.com/appsmithorg/TestSmith/issues/1466 ### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) ## Checklist: ### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag ### QA activity: - [x] Test plan has been approved by relevant developers - [x] Test plan has been peer reviewed by QA - [ ] Cypress test cases have been added and approved by either SDET or manual QA - [ ] Organized project review call with relevant stakeholders after Round 1/2 of QA - [ ] Added Test Plan Approved label after reveiwing all Cypress test --- .../JSONForm/JSONForm_FieldProperties_spec.js | 28 +++++++++++++++++-- .../fields/MultiSelectField.tsx | 10 +++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/JSONForm/JSONForm_FieldProperties_spec.js b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/JSONForm/JSONForm_FieldProperties_spec.js index d41755037d..a5db7575d1 100644 --- a/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/JSONForm/JSONForm_FieldProperties_spec.js +++ b/app/client/cypress/integration/Regression_TestSuite/ClientSideTests/Widgets/JSONForm/JSONForm_FieldProperties_spec.js @@ -277,7 +277,29 @@ describe("Text Field Property Control", () => { cy.togglebarDisable(`.t--property-control-disabled input`); }); - it("30. Radio group Field Property Control - pre condition", () => { + it("30. Invalid options should not crash the widget", () => { + // clear Options + cy.testJsonTextClearMultiline("options"); + // enter invalid options + cy.testJsontext("options", '{{[{ label: "asd", value: "zxc"}, null ]}}'); + + // wait for eval to update + cy.wait(2000); + // Check if the multiselect field exist + cy.get(`${fieldPrefix}-hobbies`).should("exist"); + + // clear Default Selected Values + cy.testJsonTextClearMultiline("defaultselectedvalues"); + // enter default value + cy.testJsontext("defaultselectedvalues", '["zxc"]'); + + // wait for eval to update + cy.wait(2000); + // Check if the multiselect field exist + cy.get(`${fieldPrefix}-hobbies`).should("exist"); + }); + + it("31. Radio group Field Property Control - pre condition", () => { const sourceData = { radio: "Y", }; @@ -288,7 +310,7 @@ describe("Text Field Property Control", () => { cy.selectDropdownValue(commonlocators.jsonFormFieldType, "Radio Group"); }); - it("31. has valid default value", () => { + it("32. has valid default value", () => { cy.get(".t--property-control-defaultselectedvalue").contains( "{{sourceData.radio}}", ); @@ -296,7 +318,7 @@ describe("Text Field Property Control", () => { cy.get(`${fieldPrefix}-radio input`).should("have.value", "Y"); }); - it("32. hides field when visible switched off", () => { + it("33. hides field when visible switched off", () => { cy.togglebarDisable(`.t--property-control-visible input`); cy.get(`${fieldPrefix}-radio`).should("not.exist"); cy.wait(500); diff --git a/app/client/src/widgets/JSONFormWidget/fields/MultiSelectField.tsx b/app/client/src/widgets/JSONFormWidget/fields/MultiSelectField.tsx index 9f771e5406..ff9f0710f2 100644 --- a/app/client/src/widgets/JSONFormWidget/fields/MultiSelectField.tsx +++ b/app/client/src/widgets/JSONFormWidget/fields/MultiSelectField.tsx @@ -100,6 +100,9 @@ function MultiSelectField({ onBlur: onBlurDynamicString, onFocus: onFocusDynamicString, } = schemaItem; + // When the options value is invalid after validation, the string value entered + // in the property pane is passed down as options here. + const options = Array.isArray(schemaItem.options) ? schemaItem.options : []; const wrapperRef = useRef(null); const { executeAction } = useContext(FormContext); @@ -154,10 +157,7 @@ function MultiSelectField({ } }, [schemaItem.defaultValue, passedDefaultValue]); - const componentValues = fieldValuesToComponentValues( - inputValue, - schemaItem.options, - ); + const componentValues = fieldValuesToComponentValues(inputValue, options); const onFilterChange = useCallback( (value: string) => { @@ -215,7 +215,7 @@ function MultiSelectField({ onChange={onOptionChange} onFilterChange={onFilterChange} onFocus={onFocusHandler} - options={schemaItem.options || []} + options={options} placeholder={schemaItem.placeholderText || ""} serverSideFiltering={schemaItem.serverSideFiltering} value={componentValues}