All files / server/api/validators generic.js

100% Statements 24/24
90% Branches 9/10
100% Functions 10/10
100% Lines 24/24
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103      1x                         1x 17x 16x 2x                               1x 22x 29x                             1x 17x   17x   17x 17x 17x   17x 2x     4x           17x 1x     2x                           1x 8x   8x   8x                
/**
 * @module server/api/validators/generic
 */
const _ = require('lodash');
 
/**
 * Returns a ValDSL validator that checks whether a value is strictly equal to a fixed value.
 *
 *     this.validate(
 *       this.json("/type"),
 *       this.equal("Point")
 *     );
 *
 * @param {*} value - The expected value.
 * @returns {function} A validator function.
 */
exports.equals = function(value) {
  return function(ctx) {
    if (ctx.get('value') !== value) {
      ctx.addError({
        validator: 'equal',
        message: `must be equal to ${JSON.stringify(value)}`
      });
    }
  };
};
 
/**
 * Returns a ValDSL condition that checks whether the current value is set and not null.
 *
 * Used when doing partial updates with PATCH, when the next validations should be run
 * only if the property is set and not null, otherwise the property should be cleared.
 *
 * @returns {function} A condition function.
 */
exports.isSetAndNotNull = function() {
  return function(ctx) {
    return ctx.get('valueSet') && ctx.get('value') !== null;
  };
};
 
/**
 * Returns a ValDSL validator that checks whether an object has exactly the expected properties.
 *
 *     this.validate(
 *       this.json("/geometry"),
 *       this.properties("type", "coordinates")
 *     )
 *
 * @param {string[]} properties - The expected properties.
 * @returns {function} A validator function.
 */
exports.properties = function(...properties) {
  return function(ctx) {
 
    const value = ctx.get('value');
 
    const actualProperties = value ? _.keys(value) : [];
    const missingProperties = _.difference(properties, actualProperties);
    const extraProperties = _.difference(actualProperties, properties);
 
    if (missingProperties.length) {
      ctx.addError({
        validator: 'properties',
        cause: 'missingProperties',
        message: `must have properties ${properties.map(property => `"${property}"`).join(', ')}`,
        expectedProperties: properties,
        missingProperties: missingProperties
      });
    }
 
    if (extraProperties.length) {
      ctx.addError({
        validator: 'properties',
        cause: 'extraProperties',
        message: `must not have other properties than ${properties.map(property => `"${property}"`).join(', ')}`,
        expectedProperties: properties,
        extraProperties: extraProperties
      });
    }
  };
};
 
/**
 * Returns a ValDSL function that changes the validated value from an Express request object to one of its query parameters.
 *
 * @param {string} param - The name of the query parameter to validate.
 * @returns {function} A validator function.
 */
exports.query = function navigateToQueryParameter(param) {
  return function(ctx) {
 
    const request = ctx.get('value');
 
    ctx.set({
      type: 'query',
      location: param,
      value: request.query[param],
      valueSet: _.has(request.query, param)
    });
  };
};