Skip to content

Commit

Permalink
Refactor requiredWhen validation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Codycody31 committed Mar 16, 2024
1 parent ea7b454 commit 6836265
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 16 deletions.
68 changes: 68 additions & 0 deletions __tests__/validator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,74 @@ describe("Validator - Required When Validation", () => {
);
expect(validator.validate({ age: 18 })).resolves.toBe(false);
});

it("should validate requiredWhen fields with multiple fields", () => {
const validator = new Validator(
{
name: {
type: "string",
requiredWhen: [
{ field: "age", value: 18 },
{ field: "age", value: 20 },
],
},
age: { type: "number" },
},
{
name: {
type: "Name must be a string",
requiredWhen: "Name is required",
},
age: {
type: "Age must be a number",
},
}
);

expect(validator.validate({ name: "John Doe", age: 18 })).resolves.toBe(
true
);
expect(validator.validate({ name: "John Doe", age: 20 })).resolves.toBe(
true
);
expect(validator.validate({ age: 18 })).resolves.toBe(false);
});

it("should validate requiredWhen fields with multiple fields and values", () => {
const validator = new Validator(
{
name: {
type: "string",
requiredWhen: [
{ field: "age", value: [18, 20] },
{ field: "active", value: true },
],
},
age: { type: "number" },
active: { type: "boolean" },
},
{
name: {
type: "Name must be a string",
requiredWhen: "Name is required",
},
age: {
type: "Age must be a number",
},
active: {
type: "Active must be a boolean",
},
}
);

expect(
validator.validate({ name: "John Doe", age: 18, active: true })
).resolves.toBe(true);
expect(
validator.validate({ name: "John Doe", age: 20, active: true })
).resolves.toBe(true);
expect(validator.validate({ age: 18, active: true })).resolves.toBe(false);
});
});

describe("Validator - Min/Max Validation", () => {
Expand Down
40 changes: 24 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ interface Rule {
/**
* Field is required when another field matches a specific value.
*/
requiredWhen?: { field: string; value: any | any[] };
requiredWhen?:
| { field: string; value: any | any[] }
| Array<{ field: string; value: any | any[] }>;
}

/**
Expand Down Expand Up @@ -265,27 +267,33 @@ class Validator {

// Handle requiredWhen condition
if (rule.requiredWhen) {
const conditionField = rule.requiredWhen.field;
const conditionValue = rule.requiredWhen.value;
let conditionMet = false;

// Check if conditionValue is an array and if it includes the input value
if (Array.isArray(conditionValue)) {
conditionMet = conditionValue.includes(input[conditionField]);
} else {
// If conditionValue is not an array, proceed with the normal equality check
conditionMet = input[conditionField] === conditionValue;
// Convert single condition to array for unified processing
const conditions = Array.isArray(rule.requiredWhen)
? rule.requiredWhen
: [rule.requiredWhen];

for (const condition of conditions) {
const conditionField = condition.field;
const conditionValue = condition.value;
const inputValue = input[conditionField];

// Check if the condition is met (supports value being an array)
if (Array.isArray(conditionValue)) {
conditionMet = conditionValue.includes(inputValue);
} else {
conditionMet = inputValue === conditionValue;
}

if (conditionMet) break; // Stop checking further conditions if one is met
}

// If the condition is met and the field is required but not present or empty
// If any condition is met and the field is required but not present or empty
if (conditionMet && (value === "" || value === undefined)) {
this.errors[key] =
this.messages[key].required ??
`"${key}" is required when "${conditionField}" is set to ${
Array.isArray(conditionValue)
? conditionValue.join(" or ")
: conditionValue
}.`;
this.messages[key].requiredWhen ??
`"${key}" is required based on the current conditions.`;
isValid = false;
continue; // Skip further checks for this field
}
Expand Down

0 comments on commit 6836265

Please sign in to comment.