utils/validation.js

/* eslint-disable sonarjs/cognitive-complexity */
import React from 'react';
import { VALIDATION_RULES } from '../constants';
/**
 * @namespace utils/validation
 */
/**
 * Validate one field for passed rule
 *
 * @memberof utils/validation
 * @async
 * @param {object} validationObj
 * @param {Array} params
 * @param {number} paramsIndex
 * @returns {void}
 */
const checkRules = (validationObj, params, paramsIndex) =>
  new Promise((resolve) => {
    let errorMsg = null;
    if (validationObj.rules?.includes(VALIDATION_RULES.MANDATORY) && !validationObj.value) {
      errorMsg = `${validationObj.label} is required !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.MANDATORY_NEW) &&
      (validationObj.value === null || validationObj.value === undefined || validationObj.value === '')
    ) {
      errorMsg = `${validationObj.label} is required !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.EQUAL) &&
      validationObj.value !== params[validationObj.equalToIndex].value
    ) {
      errorMsg = `${validationObj.label} does not match !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.REG_EXP) &&
      !RegExp(validationObj.expression).test(validationObj.value)
    ) {
      errorMsg = `${validationObj.label} does not match requirements !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.GREATER_THAN) &&
      validationObj.value <= validationObj.comparatorValue
    ) {
      errorMsg = `${validationObj.label} should be greater than ${validationObj.comparatorValue} !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.LESS_THAN) &&
      validationObj.value >= validationObj.comparatorValue
    ) {
      errorMsg = `${validationObj.label} should  be less than ${validationObj.comparatorValue} !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.NOT_LESS_THAN) &&
      validationObj.value < validationObj.comparatorValue
    ) {
      errorMsg = `${validationObj.label} should not be less than ${validationObj.comparatorValue} !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.BETWEEN) &&
      (validationObj.value < validationObj.minValue || validationObj.value > validationObj.comparatorMaxValue)
    ) {
      errorMsg = `${validationObj.label} does not match requirements !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.BETWEEN_X_AND_Y) &&
      (validationObj.value < validationObj.minValue || validationObj.value > validationObj.comparatorMaxValue)
    ) {
      errorMsg = `${validationObj.label} should be between ${validationObj.minValue} and ${validationObj.comparatorMaxValue} !`;
    } else if (
      validationObj.rules?.includes(VALIDATION_RULES.GREATER_THAN_MIN) &&
      validationObj.value < validationObj.minValue
    ) {
      errorMsg = `${validationObj.label} should not be less than ${validationObj.minValue} !`;
    } else if (validationObj.rules?.includes(VALIDATION_RULES.NOT_EMPTY_ARRAY) && validationObj.value?.length === 0) {
      errorMsg = `${validationObj.label} cannot be empty !`;
    } else if (validationObj.rules?.includes(VALIDATION_RULES.CUSTOM)) {
      const isValid = validationObj.customValidation(validationObj.value, params[paramsIndex].formValues);
      if (!isValid) {
        errorMsg = validationObj.customErrorMessage || `${validationObj.label} is invalid !`;
      }
    }
    if (errorMsg) {
      const error = {
        [validationObj.fieldName]: <div className="error-txt mt-2">{errorMsg}</div>,
      };
      resolve(error);
    } else {
      resolve(null);
    }
  });

/**
 * Validate all fields
 *
 * @memberof utils/validation
 * @async
 * @param {Array} validationParams
 * @returns {void}
 */
const validateFields = (validationParams) =>
  new Promise((resolve, reject) => {
    const values = validationParams.map((validationObj, index) => checkRules(validationObj, validationParams, index));
    Promise.all(values).then((val) => {
      const errors = val.filter((e) => !!e);
      if (errors.length > 0) {
        reject(errors);
      } else {
        resolve();
      }
    });
  }).catch((err) => {
    let error = {};
    err.map((e) => {
      error = {
        ...error,
        ...e,
      };
    });
    throw error;
  });

export default validateFields;