fix: resolve linting issues in validation rules editor component

This commit is contained in:
Dhruwang
2026-01-08 14:08:13 +05:30
parent 942cb0f8d0
commit a296ad189a
2 changed files with 676 additions and 0 deletions

View File

@@ -0,0 +1,190 @@
import { describe, expect, test } from "vitest";
import { TValidationRuleType } from "@formbricks/types/surveys/validation-rules";
import { RULE_TYPE_CONFIG } from "./validation-rules-config";
describe("RULE_TYPE_CONFIG", () => {
test("should have config for all validation rule types", () => {
const allRuleTypes: TValidationRuleType[] = [
"required",
"minLength",
"maxLength",
"pattern",
"email",
"url",
"phone",
"minValue",
"maxValue",
"minSelections",
"maxSelections",
];
allRuleTypes.forEach((ruleType) => {
expect(RULE_TYPE_CONFIG[ruleType]).toBeDefined();
expect(RULE_TYPE_CONFIG[ruleType].labelKey).toBeDefined();
expect(typeof RULE_TYPE_CONFIG[ruleType].labelKey).toBe("string");
expect(typeof RULE_TYPE_CONFIG[ruleType].needsValue).toBe("boolean");
});
});
describe("required rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.required;
expect(config.labelKey).toBe("required");
expect(config.needsValue).toBe(false);
expect(config.valueType).toBeUndefined();
expect(config.valuePlaceholder).toBeUndefined();
expect(config.unitOptions).toBeUndefined();
});
});
describe("minLength rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.minLength;
expect(config.labelKey).toBe("min_length");
expect(config.needsValue).toBe(true);
expect(config.valueType).toBe("number");
expect(config.valuePlaceholder).toBe("100");
expect(config.unitOptions).toEqual([{ value: "characters", labelKey: "characters" }]);
});
});
describe("maxLength rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.maxLength;
expect(config.labelKey).toBe("max_length");
expect(config.needsValue).toBe(true);
expect(config.valueType).toBe("number");
expect(config.valuePlaceholder).toBe("500");
expect(config.unitOptions).toEqual([{ value: "characters", labelKey: "characters" }]);
});
});
describe("pattern rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.pattern;
expect(config.labelKey).toBe("pattern");
expect(config.needsValue).toBe(true);
expect(config.valueType).toBe("text");
expect(config.valuePlaceholder).toBe("^[A-Z].*");
expect(config.unitOptions).toBeUndefined();
});
});
describe("email rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.email;
expect(config.labelKey).toBe("email");
expect(config.needsValue).toBe(false);
expect(config.valueType).toBeUndefined();
expect(config.valuePlaceholder).toBeUndefined();
expect(config.unitOptions).toBeUndefined();
});
});
describe("url rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.url;
expect(config.labelKey).toBe("url");
expect(config.needsValue).toBe(false);
expect(config.valueType).toBeUndefined();
expect(config.valuePlaceholder).toBeUndefined();
expect(config.unitOptions).toBeUndefined();
});
});
describe("phone rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.phone;
expect(config.labelKey).toBe("phone");
expect(config.needsValue).toBe(false);
expect(config.valueType).toBeUndefined();
expect(config.valuePlaceholder).toBeUndefined();
expect(config.unitOptions).toBeUndefined();
});
});
describe("minValue rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.minValue;
expect(config.labelKey).toBe("min_value");
expect(config.needsValue).toBe(true);
expect(config.valueType).toBe("number");
expect(config.valuePlaceholder).toBe("0");
expect(config.unitOptions).toBeUndefined();
});
});
describe("maxValue rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.maxValue;
expect(config.labelKey).toBe("max_value");
expect(config.needsValue).toBe(true);
expect(config.valueType).toBe("number");
expect(config.valuePlaceholder).toBe("100");
expect(config.unitOptions).toBeUndefined();
});
});
describe("minSelections rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.minSelections;
expect(config.labelKey).toBe("min_selections");
expect(config.needsValue).toBe(true);
expect(config.valueType).toBe("number");
expect(config.valuePlaceholder).toBe("1");
expect(config.unitOptions).toEqual([{ value: "options", labelKey: "options_selected" }]);
});
});
describe("maxSelections rule", () => {
test("should have correct config", () => {
const config = RULE_TYPE_CONFIG.maxSelections;
expect(config.labelKey).toBe("max_selections");
expect(config.needsValue).toBe(true);
expect(config.valueType).toBe("number");
expect(config.valuePlaceholder).toBe("3");
expect(config.unitOptions).toEqual([{ value: "options", labelKey: "options_selected" }]);
});
});
describe("valueType validation", () => {
test("should have valueType 'number' for numeric rules", () => {
expect(RULE_TYPE_CONFIG.minLength.valueType).toBe("number");
expect(RULE_TYPE_CONFIG.maxLength.valueType).toBe("number");
expect(RULE_TYPE_CONFIG.minValue.valueType).toBe("number");
expect(RULE_TYPE_CONFIG.maxValue.valueType).toBe("number");
expect(RULE_TYPE_CONFIG.minSelections.valueType).toBe("number");
expect(RULE_TYPE_CONFIG.maxSelections.valueType).toBe("number");
});
test("should have valueType 'text' for text rules", () => {
expect(RULE_TYPE_CONFIG.pattern.valueType).toBe("text");
});
test("should not have valueType for rules that don't need values", () => {
expect(RULE_TYPE_CONFIG.required.valueType).toBeUndefined();
expect(RULE_TYPE_CONFIG.email.valueType).toBeUndefined();
expect(RULE_TYPE_CONFIG.url.valueType).toBeUndefined();
expect(RULE_TYPE_CONFIG.phone.valueType).toBeUndefined();
});
});
describe("unitOptions validation", () => {
test("should have unitOptions for length and selection rules", () => {
expect(RULE_TYPE_CONFIG.minLength.unitOptions).toBeDefined();
expect(RULE_TYPE_CONFIG.maxLength.unitOptions).toBeDefined();
expect(RULE_TYPE_CONFIG.minSelections.unitOptions).toBeDefined();
expect(RULE_TYPE_CONFIG.maxSelections.unitOptions).toBeDefined();
});
test("should not have unitOptions for other rules", () => {
expect(RULE_TYPE_CONFIG.required.unitOptions).toBeUndefined();
expect(RULE_TYPE_CONFIG.pattern.unitOptions).toBeUndefined();
expect(RULE_TYPE_CONFIG.email.unitOptions).toBeUndefined();
expect(RULE_TYPE_CONFIG.url.unitOptions).toBeUndefined();
expect(RULE_TYPE_CONFIG.phone.unitOptions).toBeUndefined();
expect(RULE_TYPE_CONFIG.minValue.unitOptions).toBeUndefined();
expect(RULE_TYPE_CONFIG.maxValue.unitOptions).toBeUndefined();
});
});
});

View File

@@ -0,0 +1,486 @@
import { describe, expect, test } from "vitest";
import { TSurveyElementTypeEnum } from "@formbricks/types/surveys/elements";
import { TValidationRule } from "@formbricks/types/surveys/validation-rules";
import { createRuleParams, getAvailableRuleTypes, getRuleValue } from "./validation-rules-utils";
describe("getAvailableRuleTypes", () => {
test("should return all applicable rules for openText element when no rules exist", () => {
const elementType = TSurveyElementTypeEnum.OpenText;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toContain("required");
expect(available).toContain("minLength");
expect(available).toContain("maxLength");
expect(available).toContain("pattern");
expect(available).toContain("email");
expect(available).toContain("url");
expect(available).toContain("phone");
expect(available).toContain("minValue");
expect(available).toContain("maxValue");
});
test("should filter out already added rules", () => {
const elementType = TSurveyElementTypeEnum.OpenText;
const existingRules: TValidationRule[] = [
{
id: "rule1",
type: "required",
params: {},
},
{
id: "rule2",
type: "minLength",
params: { min: 10 },
},
];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).not.toContain("required");
expect(available).not.toContain("minLength");
expect(available).toContain("maxLength");
expect(available).toContain("pattern");
});
test("should return only required rule for multipleChoiceSingle element", () => {
const elementType = TSurveyElementTypeEnum.MultipleChoiceSingle;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return empty array for multipleChoiceSingle when required is already added", () => {
const elementType = TSurveyElementTypeEnum.MultipleChoiceSingle;
const existingRules: TValidationRule[] = [
{
id: "rule1",
type: "required",
params: {},
},
];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual([]);
});
test("should return required, minSelections, maxSelections for multipleChoiceMulti element", () => {
const elementType = TSurveyElementTypeEnum.MultipleChoiceMulti;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toContain("required");
expect(available).toContain("minSelections");
expect(available).toContain("maxSelections");
expect(available.length).toBe(3);
});
test("should return only required rule for rating element", () => {
const elementType = TSurveyElementTypeEnum.Rating;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for nps element", () => {
const elementType = TSurveyElementTypeEnum.NPS;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for date element", () => {
const elementType = TSurveyElementTypeEnum.Date;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for consent element", () => {
const elementType = TSurveyElementTypeEnum.Consent;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for matrix element", () => {
const elementType = TSurveyElementTypeEnum.Matrix;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for ranking element", () => {
const elementType = TSurveyElementTypeEnum.Ranking;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for fileUpload element", () => {
const elementType = TSurveyElementTypeEnum.FileUpload;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return required, minSelections, maxSelections for pictureSelection element", () => {
const elementType = TSurveyElementTypeEnum.PictureSelection;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toContain("required");
expect(available).toContain("minSelections");
expect(available).toContain("maxSelections");
expect(available.length).toBe(3);
});
test("should return only required rule for address element", () => {
const elementType = TSurveyElementTypeEnum.Address;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for contactInfo element", () => {
const elementType = TSurveyElementTypeEnum.ContactInfo;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return only required rule for cal element", () => {
const elementType = TSurveyElementTypeEnum.Cal;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual(["required"]);
});
test("should return empty array for cta element", () => {
const elementType = TSurveyElementTypeEnum.CTA;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual([]);
});
test("should handle unknown element type gracefully", () => {
const elementType = "unknown" as TSurveyElementTypeEnum;
const existingRules: TValidationRule[] = [];
const available = getAvailableRuleTypes(elementType, existingRules);
expect(available).toEqual([]);
});
});
describe("getRuleValue", () => {
test("should return min value for minLength rule", () => {
const rule: TValidationRule = {
id: "rule1",
type: "minLength",
params: { min: 10 },
};
expect(getRuleValue(rule)).toBe(10);
});
test("should return max value for maxLength rule", () => {
const rule: TValidationRule = {
id: "rule2",
type: "maxLength",
params: { max: 100 },
};
expect(getRuleValue(rule)).toBe(100);
});
test("should return pattern string for pattern rule", () => {
const rule: TValidationRule = {
id: "rule3",
type: "pattern",
params: { pattern: "^[A-Z].*" },
};
expect(getRuleValue(rule)).toBe("^[A-Z].*");
});
test("should return pattern string with flags for pattern rule", () => {
const rule: TValidationRule = {
id: "rule3",
type: "pattern",
params: { pattern: "^[A-Z].*", flags: "i" },
};
expect(getRuleValue(rule)).toBe("^[A-Z].*");
});
test("should return min value for minValue rule", () => {
const rule: TValidationRule = {
id: "rule4",
type: "minValue",
params: { min: 5 },
};
expect(getRuleValue(rule)).toBe(5);
});
test("should return max value for maxValue rule", () => {
const rule: TValidationRule = {
id: "rule5",
type: "maxValue",
params: { max: 50 },
};
expect(getRuleValue(rule)).toBe(50);
});
test("should return min value for minSelections rule", () => {
const rule: TValidationRule = {
id: "rule6",
type: "minSelections",
params: { min: 2 },
};
expect(getRuleValue(rule)).toBe(2);
});
test("should return max value for maxSelections rule", () => {
const rule: TValidationRule = {
id: "rule7",
type: "maxSelections",
params: { max: 5 },
};
expect(getRuleValue(rule)).toBe(5);
});
test("should return undefined for required rule", () => {
const rule: TValidationRule = {
id: "rule8",
type: "required",
params: {},
};
expect(getRuleValue(rule)).toBeUndefined();
});
test("should return undefined for email rule", () => {
const rule: TValidationRule = {
id: "rule9",
type: "email",
params: {},
};
expect(getRuleValue(rule)).toBeUndefined();
});
test("should return undefined for url rule", () => {
const rule: TValidationRule = {
id: "rule10",
type: "url",
params: {},
};
expect(getRuleValue(rule)).toBeUndefined();
});
test("should return undefined for phone rule", () => {
const rule: TValidationRule = {
id: "rule11",
type: "phone",
params: {},
};
expect(getRuleValue(rule)).toBeUndefined();
});
test("should return empty string for pattern rule with empty pattern", () => {
const rule: TValidationRule = {
id: "rule12",
type: "pattern",
params: { pattern: "" },
};
expect(getRuleValue(rule)).toBe("");
});
});
describe("createRuleParams", () => {
test("should create empty params for required rule", () => {
const params = createRuleParams("required");
expect(params).toEqual({});
});
test("should create params for minLength rule with value", () => {
const params = createRuleParams("minLength", 10);
expect(params).toEqual({ min: 10 });
});
test("should create params for minLength rule without value (defaults to 0)", () => {
const params = createRuleParams("minLength");
expect(params).toEqual({ min: 0 });
});
test("should create params for maxLength rule with value", () => {
const params = createRuleParams("maxLength", 100);
expect(params).toEqual({ max: 100 });
});
test("should create params for maxLength rule without value (defaults to 100)", () => {
const params = createRuleParams("maxLength");
expect(params).toEqual({ max: 100 });
});
test("should create params for pattern rule with string value", () => {
const params = createRuleParams("pattern", "^[A-Z].*");
expect(params).toEqual({ pattern: "^[A-Z].*" });
});
test("should create params for pattern rule without value (defaults to empty string)", () => {
const params = createRuleParams("pattern");
expect(params).toEqual({ pattern: "" });
});
test("should create empty params for email rule", () => {
const params = createRuleParams("email");
expect(params).toEqual({});
});
test("should create empty params for url rule", () => {
const params = createRuleParams("url");
expect(params).toEqual({});
});
test("should create empty params for phone rule", () => {
const params = createRuleParams("phone");
expect(params).toEqual({});
});
test("should create params for minValue rule with value", () => {
const params = createRuleParams("minValue", 5);
expect(params).toEqual({ min: 5 });
});
test("should create params for minValue rule without value (defaults to 0)", () => {
const params = createRuleParams("minValue");
expect(params).toEqual({ min: 0 });
});
test("should create params for maxValue rule with value", () => {
const params = createRuleParams("maxValue", 50);
expect(params).toEqual({ max: 50 });
});
test("should create params for maxValue rule without value (defaults to 100)", () => {
const params = createRuleParams("maxValue");
expect(params).toEqual({ max: 100 });
});
test("should create params for minSelections rule with value", () => {
const params = createRuleParams("minSelections", 2);
expect(params).toEqual({ min: 2 });
});
test("should create params for minSelections rule without value (defaults to 1)", () => {
const params = createRuleParams("minSelections");
expect(params).toEqual({ min: 1 });
});
test("should create params for maxSelections rule with value", () => {
const params = createRuleParams("maxSelections", 5);
expect(params).toEqual({ max: 5 });
});
test("should create params for maxSelections rule without value (defaults to 3)", () => {
const params = createRuleParams("maxSelections");
expect(params).toEqual({ max: 3 });
});
test("should convert string number to number for minLength", () => {
const params = createRuleParams("minLength", "10");
expect(params).toEqual({ min: 10 });
});
test("should convert string number to number for maxLength", () => {
const params = createRuleParams("maxLength", "100");
expect(params).toEqual({ max: 100 });
});
test("should convert string number to number for minValue", () => {
const params = createRuleParams("minValue", "5");
expect(params).toEqual({ min: 5 });
});
test("should convert string number to number for maxValue", () => {
const params = createRuleParams("maxValue", "50");
expect(params).toEqual({ max: 50 });
});
test("should convert string number to number for minSelections", () => {
const params = createRuleParams("minSelections", "2");
expect(params).toEqual({ min: 2 });
});
test("should convert string number to number for maxSelections", () => {
const params = createRuleParams("maxSelections", "5");
expect(params).toEqual({ max: 5 });
});
test("should handle invalid string number (defaults to 0 for minLength)", () => {
const params = createRuleParams("minLength", "invalid");
expect(params).toEqual({ min: 0 });
});
test("should handle invalid string number (defaults to 100 for maxLength)", () => {
const params = createRuleParams("maxLength", "invalid");
expect(params).toEqual({ max: 100 });
});
test("should handle invalid string number (defaults to 0 for minValue)", () => {
const params = createRuleParams("minValue", "invalid");
expect(params).toEqual({ min: 0 });
});
test("should handle invalid string number (defaults to 100 for maxValue)", () => {
const params = createRuleParams("maxValue", "invalid");
expect(params).toEqual({ max: 100 });
});
test("should handle invalid string number (defaults to 1 for minSelections)", () => {
const params = createRuleParams("minSelections", "invalid");
expect(params).toEqual({ min: 1 });
});
test("should handle invalid string number (defaults to 3 for maxSelections)", () => {
const params = createRuleParams("maxSelections", "invalid");
expect(params).toEqual({ max: 3 });
});
});