Manual Reference Source Test

src/utilities/ValidationUtility.js

import Client from '../Client';
import Clinical6Error from './Clinical6Error';

/**
 * If there is no token, a message is returned.
 * @param  {String}  msg - Message to return if validation fails
 * @return {String}      - A message if the validation fails and is blank if it passes
 */
function hasToken(msg = 'requires authToken') { return (Client.instance.authToken) ? '' : msg; }

/**
 * If the value is not a date, a message is returned.
 * @param  {any}     date - The target value to see if it is a date.
 * @param  {String}  msg  - Message to return if validation fails
 * @return {String}       - A message if the validation fails and is blank if it passes
 */
function isDate(date, msg = 'requires valid date') { return (Date.parse(date)) ? '' : msg; }

/**
 * If the required item does not exist, a message is returned.
 * @param  {any}     p   - The target value to see if it exists.
 * @param  {String}  msg - Message to return if validation fails
 * @return {String}      - A message if the validation fails and is blank if it passes
 */
function isRequired(p, msg = 'is not defined') {
  return Object.keys(p)
    .map(key => ({ key, value: p[key] }))
    .filter(obj => !obj.value)
    .map(value => `${value.key} ${msg}`)
    .join(' and ');
}

/**
 * If the parameter is not of primitive type 'type', a message is returned.
 * @param  {any}     p    - The target value in which to see if the type exists.
 * @param  {String}  type - The type, must be 'object', 'string', 'number', 'boolean', or 'symbol'.
 * @param  {String}  msg  - Message to return if validation fails
 * @return {String}       - A message if the validation fails and is blank if it passes
 */
function isA(p, type, msg = 'is not a') {
  if (isRequired(p).length > 0) { return ''; }
  return Object.keys(p)
    .map(key => ({ key, value: p[key] }))
    .filter(obj => ((typeof type !== 'function' && typeof obj.value !== type)
      || (typeof obj.value === 'object' && !(obj.value instanceof type))))
    .map(value => `${value.key} ${msg} ${type}`)
    .join(' and ');
}

/**
 * If the parameter does not have the attribute, a message is returned
 * @param  {Object}  p             - Must contain a { key: value } to be the target of validation
 * @param  {String}  attributeName - Must be a string to valide p
 * @param  {String}  msg           - Message to return if validation fails
 * @return {String}                - A message if the validation fails and blank if it passes
 */
function hasAttribute(p, attributeName, msg = 'does not have') {
  if (isRequired(p).length > 0) { return ''; }
  return Object.keys(p)
    .map(key => ({ key, value: p[key] }))
    .filter(obj => !({}.hasOwnProperty.call(obj.value, attributeName) || obj.value[attributeName]))
    .map(value => `${value.key} ${msg} ${attributeName}`)
    .join(' and ');
}

/**
 * If the boolean statement is false, return a message, otherwise return an empty string
 * @param  {Boolean} booleanStatement - Any boolean statement that should be true
 * @param  {String}  msg              - Message to return if validation fails
 * @return {String}                   - A message if the validation fails and blank if it passes
 */
function isValid(booleanStatement, msg = 'is not true') { return (booleanStatement) ? '' : msg; }

/**
 * Loops through each validation item and throws an error if something fails (a message exists)
 * @param  {String}    module  - The location that calls this method.
 * @param  {...Object} results - An array of functions to test.
 */
function validate(module, ...results) {
  const uniqueResults = results.filter(result => result);
  if (uniqueResults.length > 0) {
    const messages = uniqueResults.join(' and ');
    throw new Clinical6Error(`${module} error: ${messages}`, module);
  }
}

export {
  hasAttribute,
  hasToken,
  isA,
  isDate,
  isRequired,
  isValid,
  validate,
};