diff --git a/app/client/src/widgets/JSONFormWidget/schemaParser.ts b/app/client/src/widgets/JSONFormWidget/schemaParser.ts index d21943a9de..42c4724f9e 100644 --- a/app/client/src/widgets/JSONFormWidget/schemaParser.ts +++ b/app/client/src/widgets/JSONFormWidget/schemaParser.ts @@ -226,9 +226,7 @@ export const normalizeArrayValue = (data: any[]) => { return data[0]; }; -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const fieldTypeFor = (value: any): FieldType => { +export const fieldTypeFor = (value: unknown): FieldType => { const dataType = dataTypeFor(value); const potentialFieldType = DATA_TYPE_POTENTIAL_FIELD[dataType]; const subDataType = subDataTypeFor(value); diff --git a/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.test.ts b/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.test.ts index 05a4dd0983..56aaa2967a 100644 --- a/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.test.ts +++ b/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.test.ts @@ -4,98 +4,120 @@ import type { JSONFormWidgetProps } from "../.."; import { defaultOptionValueValidation } from "./select"; describe(".defaultOptionValueValidation", () => { - it("return undefined when input is undefined", () => { - const input = undefined; - const expectedOutput = { - isValid: true, - parsed: undefined, - messages: [{ name: "", message: "" }], - }; + describe("handling falsey values", () => { + it("return undefined when input is undefined", () => { + const input = undefined; + const expectedOutput = { + isValid: true, + parsed: undefined, + messages: [{ name: "", message: "" }], + }; - const response = defaultOptionValueValidation( - input, - {} as JSONFormWidgetProps, - _, - ); + const response = defaultOptionValueValidation( + input, + {} as JSONFormWidgetProps, + _, + ); - expect(response).toEqual(expectedOutput); + expect(response).toEqual(expectedOutput); + }); + + it("return null when input is null", () => { + const input = null; + const expectedOutput = { + isValid: true, + parsed: null, + messages: [{ name: "", message: "" }], + }; + + const response = defaultOptionValueValidation( + input, + {} as JSONFormWidgetProps, + _, + ); + + expect(response).toEqual(expectedOutput); + }); + + it("return empty string with empty string", () => { + const input = ""; + const expectedOutput = { + isValid: true, + parsed: "", + messages: [{ name: "", message: "" }], + }; + + const response = defaultOptionValueValidation( + input, + {} as JSONFormWidgetProps, + _, + ); + + expect(response).toEqual(expectedOutput); + }); }); - it("return null when input is null", () => { - const input = null; - const expectedOutput = { - isValid: true, - parsed: null, - messages: [{ name: "", message: "" }], - }; + describe("handling truthy values", () => { + it("return value with string", () => { + const input = "green"; + const expectedOutput = { + isValid: true, + parsed: "green", + messages: [{ name: "", message: "" }], + }; - const response = defaultOptionValueValidation( - input, - {} as JSONFormWidgetProps, - _, - ); + const response = defaultOptionValueValidation( + input, + {} as JSONFormWidgetProps, + _, + ); - expect(response).toEqual(expectedOutput); - }); + expect(response).toEqual(expectedOutput); + }); - it("return empty string with empty string", () => { - const input = ""; - const expectedOutput = { - isValid: true, - parsed: "", - messages: [{ name: "", message: "" }], - }; - - const response = defaultOptionValueValidation( - input, - {} as JSONFormWidgetProps, - _, - ); - - expect(response).toEqual(expectedOutput); - }); - - it("return value with string", () => { - const input = "green"; - const expectedOutput = { - isValid: true, - parsed: "green", - messages: [{ name: "", message: "" }], - }; - - const response = defaultOptionValueValidation( - input, - {} as JSONFormWidgetProps, - _, - ); - - expect(response).toEqual(expectedOutput); - }); - - it("return value with stringified json", () => { - const input = ` + it("return value with stringified json", () => { + const input = ` { "label": "green", "value": "green" } `; - const expectedOutput = { - isValid: true, - parsed: { - label: "green", - value: "green", - }, - messages: [{ name: "", message: "" }], - }; + const expectedOutput = { + isValid: true, + parsed: { + label: "green", + value: "green", + }, + messages: [{ name: "", message: "" }], + }; - const response = defaultOptionValueValidation( - input, - {} as JSONFormWidgetProps, - _, - ); + const response = defaultOptionValueValidation( + input, + {} as JSONFormWidgetProps, + _, + ); - expect(response).toEqual(expectedOutput); + expect(response).toEqual(expectedOutput); + }); + + it("Edge Case: For very long numbers passed as string, don't parse it as number", () => { + const input = + "123456789012345678901234567890123456789012345678901234567890"; + const expectedOutput = { + isValid: true, + parsed: "123456789012345678901234567890123456789012345678901234567890", + messages: [{ name: "", message: "" }], + }; + + const response = defaultOptionValueValidation( + input, + {} as JSONFormWidgetProps, + _, + ); + + expect(response).toEqual(expectedOutput); + }); }); it("should return isValid false with invalid values", () => { diff --git a/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.ts b/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.ts index 3da96ecd95..d1c7285c7a 100644 --- a/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.ts +++ b/app/client/src/widgets/JSONFormWidget/widget/propertyConfig/properties/select.ts @@ -7,21 +7,13 @@ import type { ValidationResponse } from "constants/WidgetValidation"; import { ValidationTypes } from "constants/WidgetValidation"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType"; +import type { LoDashStatic } from "lodash"; export function defaultOptionValueValidation( - inputValue: unknown, + value: unknown, props: JSONFormWidgetProps, - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - _: any, + _: LoDashStatic, ): ValidationResponse { - const DEFAULT_ERROR_MESSAGE = { - name: "TypeError", - message: - 'value should match: string | { "label": "label1", "value": "value1" }', - }; - let value = inputValue; - const hasLabelValueProperties = ( // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -38,22 +30,7 @@ export function defaultOptionValueValidation( // If input value is empty string then we can fairly assume that the input // was cleared out and can be treated as undefined. - if (inputValue === undefined || inputValue === null || inputValue === "") { - return { - isValid: true, - parsed: inputValue, - messages: [{ name: "", message: "" }], - }; - } - - if (typeof inputValue === "string") { - try { - value = JSON.parse(inputValue); - } catch (e) {} - } - - if (_.isString(value) || _.isFinite(value)) { - // When value is "", "green", 444 + if (value === undefined || value === null || value === "") { return { isValid: true, parsed: value, @@ -61,8 +38,22 @@ export function defaultOptionValueValidation( }; } - if (hasLabelValueProperties(value)) { - // When value is {label: "green", value: "green"} + if (typeof value === "string") { + try { + const parsedValue = JSON.parse(value); + + if (_.isObject(parsedValue)) { + value = parsedValue; + } + } catch (e) {} + } + + if ( + _.isString(value) || + _.isFinite(value) || + hasLabelValueProperties(value) + ) { + // When value is "", "green", 444 return { isValid: true, parsed: value, @@ -73,7 +64,13 @@ export function defaultOptionValueValidation( return { isValid: false, parsed: {}, - messages: [DEFAULT_ERROR_MESSAGE], + messages: [ + { + name: "TypeError", + message: + 'value should match: string | { "label": "label1", "value": "value1" }', + }, + ], }; }