fix: chartWidget fix for "TypeError: r.palettecolors.split" (#7717)
* adding validation for fusion chart's paletteColors Attribute * restructuring as params for TEXT type * removing unnecessary space * addressing review comments * adding validations to ignore case
This commit is contained in:
parent
f0325c11c6
commit
fb7143cef2
|
|
@ -88,6 +88,8 @@ type ValidationConfigParams = {
|
||||||
) => ValidationResponse; // Function in a FUNCTION type
|
) => ValidationResponse; // Function in a FUNCTION type
|
||||||
fnString?: string; // AUTO GENERATED, SHOULD NOT BE SET BY WIDGET DEVELOPER
|
fnString?: string; // AUTO GENERATED, SHOULD NOT BE SET BY WIDGET DEVELOPER
|
||||||
expected?: CodeEditorExpected; // FUNCTION type expected type and example
|
expected?: CodeEditorExpected; // FUNCTION type expected type and example
|
||||||
|
strict?: boolean; //for strict string validation of TEXT type
|
||||||
|
ignoreCase?: boolean; //to ignore the case of key
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ValidationConfig = {
|
export type ValidationConfig = {
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,16 @@ export default [
|
||||||
name: "chart",
|
name: "chart",
|
||||||
type: ValidationTypes.OBJECT,
|
type: ValidationTypes.OBJECT,
|
||||||
params: {
|
params: {
|
||||||
|
allowedKeys: [
|
||||||
|
{
|
||||||
|
name: "paletteColors",
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
strict: true,
|
||||||
|
ignoreCase: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,39 @@ describe("Validate Validators", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("correctly validates strict text", () => {
|
||||||
|
const validation = {
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
required: true,
|
||||||
|
default: "abc",
|
||||||
|
allowedValues: ["abc", "123", "mno", "test"],
|
||||||
|
strict: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const inputs = ["abc", "xyz", 123];
|
||||||
|
const expected = [
|
||||||
|
{
|
||||||
|
isValid: true,
|
||||||
|
parsed: "abc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isValid: false,
|
||||||
|
parsed: "abc",
|
||||||
|
message: "Value is not allowed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
isValid: false,
|
||||||
|
parsed: "abc",
|
||||||
|
message: `${WIDGET_TYPE_VALIDATION_ERROR} string ( abc | 123 | mno | test )`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
inputs.forEach((input, index) => {
|
||||||
|
const result = validate(validation, input, DUMMY_WIDGET);
|
||||||
|
expect(result).toStrictEqual(expected[index]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("correctly validates image url", () => {
|
it("correctly validates image url", () => {
|
||||||
const config = {
|
const config = {
|
||||||
type: ValidationTypes.IMAGE_URL,
|
type: ValidationTypes.IMAGE_URL,
|
||||||
|
|
@ -939,6 +972,10 @@ describe("Validate Validators", () => {
|
||||||
label: true,
|
label: true,
|
||||||
value: "true",
|
value: "true",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
paletteColors1: "#ffffff",
|
||||||
|
palettecolors2: "#ffffff",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const config = [
|
const config = [
|
||||||
{
|
{
|
||||||
|
|
@ -987,6 +1024,28 @@ describe("Validate Validators", () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: ValidationTypes.OBJECT,
|
||||||
|
params: {
|
||||||
|
allowedKeys: [
|
||||||
|
{
|
||||||
|
name: "paletteColors1",
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
strict: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "paletteColors2",
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
strict: true,
|
||||||
|
ignoreCase: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const expected = [
|
const expected = [
|
||||||
{
|
{
|
||||||
|
|
@ -1000,6 +1059,13 @@ describe("Validate Validators", () => {
|
||||||
isValid: true,
|
isValid: true,
|
||||||
parsed: { label: true, value: "true" },
|
parsed: { label: true, value: "true" },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
isValid: true,
|
||||||
|
parsed: {
|
||||||
|
paletteColors1: "#ffffff",
|
||||||
|
palettecolors2: "#ffffff",
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
inputs.forEach((input, index) => {
|
inputs.forEach((input, index) => {
|
||||||
const result = validate(config[index], input, DUMMY_WIDGET);
|
const result = validate(config[index], input, DUMMY_WIDGET);
|
||||||
|
|
@ -1015,6 +1081,10 @@ describe("Validate Validators", () => {
|
||||||
{
|
{
|
||||||
label: true,
|
label: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
paletteColors1: "#ffffff",
|
||||||
|
palettecolors2: 3,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const config = [
|
const config = [
|
||||||
{
|
{
|
||||||
|
|
@ -1063,6 +1133,28 @@ describe("Validate Validators", () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: ValidationTypes.OBJECT,
|
||||||
|
params: {
|
||||||
|
allowedKeys: [
|
||||||
|
{
|
||||||
|
name: "paletteColors1",
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
strict: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "paletteColors2",
|
||||||
|
type: ValidationTypes.TEXT,
|
||||||
|
params: {
|
||||||
|
strict: true,
|
||||||
|
ignoreCase: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
const expected = [
|
const expected = [
|
||||||
{
|
{
|
||||||
|
|
@ -1078,6 +1170,15 @@ describe("Validate Validators", () => {
|
||||||
message: "Missing required key: value",
|
message: "Missing required key: value",
|
||||||
parsed: { label: true },
|
parsed: { label: true },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
isValid: false,
|
||||||
|
message:
|
||||||
|
"Value of key: palettecolors2 is invalid: This value does not evaluate to type string",
|
||||||
|
parsed: {
|
||||||
|
paletteColors1: "#ffffff",
|
||||||
|
palettecolors2: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
];
|
];
|
||||||
inputs.forEach((input, index) => {
|
inputs.forEach((input, index) => {
|
||||||
const result = validate(config[index], input, DUMMY_WIDGET);
|
const result = validate(config[index], input, DUMMY_WIDGET);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,20 @@ const flat = (array: Record<string, any>[], uniqueParam: string) => {
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function getPropertyEntry(
|
||||||
|
obj: Record<string, unknown>,
|
||||||
|
name: string,
|
||||||
|
ignoreCase = false,
|
||||||
|
) {
|
||||||
|
if (!ignoreCase) {
|
||||||
|
return name;
|
||||||
|
} else {
|
||||||
|
const keys = Object.getOwnPropertyNames(obj);
|
||||||
|
return keys.find((key) => key.toLowerCase() === name.toLowerCase()) || name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function validatePlainObject(
|
function validatePlainObject(
|
||||||
config: ValidationConfig,
|
config: ValidationConfig,
|
||||||
value: Record<string, unknown>,
|
value: Record<string, unknown>,
|
||||||
|
|
@ -42,24 +56,25 @@ function validatePlainObject(
|
||||||
const _messages: string[] = [];
|
const _messages: string[] = [];
|
||||||
const parsedValue: Record<string, unknown> = value;
|
const parsedValue: Record<string, unknown> = value;
|
||||||
config.params.allowedKeys.forEach((entry) => {
|
config.params.allowedKeys.forEach((entry) => {
|
||||||
if (value.hasOwnProperty(entry.name)) {
|
const ignoreCase = !!entry.params?.ignoreCase;
|
||||||
|
const entryName = getPropertyEntry(value, entry.name, ignoreCase);
|
||||||
|
|
||||||
|
if (value.hasOwnProperty(entryName)) {
|
||||||
const { isValid, message, parsed } = validate(
|
const { isValid, message, parsed } = validate(
|
||||||
entry,
|
entry,
|
||||||
value[entry.name],
|
value[entryName],
|
||||||
props,
|
props,
|
||||||
);
|
);
|
||||||
parsedValue[entry.name] = parsed;
|
parsedValue[entryName] = parsed;
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
value[entry.name] = parsed;
|
value[entryName] = parsed;
|
||||||
_valid = isValid;
|
_valid = isValid;
|
||||||
message &&
|
message &&
|
||||||
_messages.push(
|
_messages.push(`Value of key: ${entryName} is invalid: ${message}`);
|
||||||
`Value of key: ${entry.name} is invalid: ${message}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else if (entry.params?.required) {
|
} else if (entry.params?.required) {
|
||||||
_valid = false;
|
_valid = false;
|
||||||
_messages.push(`Missing required key: ${entry.name}`);
|
_messages.push(`Missing required key: ${entryName}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (_valid) {
|
if (_valid) {
|
||||||
|
|
@ -303,15 +318,17 @@ export const VALIDATORS: Record<ValidationTypes, Validator> = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const isValid = isString(parsed);
|
const isValid = isString(parsed);
|
||||||
|
const stringValidationError = {
|
||||||
|
isValid: false,
|
||||||
|
parsed: config.params?.default || "",
|
||||||
|
message: `${WIDGET_TYPE_VALIDATION_ERROR} ${getExpectedType(config)}`,
|
||||||
|
};
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
try {
|
try {
|
||||||
parsed = toString(parsed);
|
if (!config.params?.strict) parsed = toString(parsed);
|
||||||
|
else return stringValidationError;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return {
|
return stringValidationError;
|
||||||
isValid: false,
|
|
||||||
parsed: config.params?.default || "",
|
|
||||||
message: `${WIDGET_TYPE_VALIDATION_ERROR} ${getExpectedType(config)}`,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the value is an empty string we skip
|
// If the value is an empty string we skip
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user