Code coverage report for upstream/lib/dao-validator.js

Statements: 47.76% (32 / 67)      Branches: 39.53% (17 / 43)      Functions: 61.54% (8 / 13)      Lines: 47.76% (32 / 67)     

All files » upstream/lib/ » dao-validator.js
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 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 1561     1 332 332   332 332     1                 1 332     332 332 332       332 332 332   332       332 332       332 332               1 332       332               332     1 332     332 1666       1666         332     1                                                     1                                                                                      
var Validator = require("validator")
  , Utils     = require("./utils")
 
var DaoValidator = module.exports = function(model, options) {
  options = options || {}
  options.skip = options.skip || []
 
  this.model = model
  this.options = options
}
 
DaoValidator.prototype.validate = function() {
  var errors = {}
 
  errors = Utils._.extend(errors, validateAttributes.call(this))
  errors = Utils._.extend(errors, validateModel.call(this))
 
  return errors
}
 
DaoValidator.prototype.hookValidate = function() {
  var self   = this
    , errors = {}
 
  return new Utils.CustomEventEmitter(function(emitter) {
    self.model.daoFactory.runHooks('beforeValidate', self.model.dataValues, function(err, newValues) {
      Iif (!!err) {
        return emitter.emit('error', err)
      }
 
      self.model.dataValues = newValues || self.model.dataValues
      errors = Utils._.extend(errors, validateAttributes.call(self))
      errors = Utils._.extend(errors, validateModel.call(self))
 
      Iif (Object.keys(errors).length > 0) {
        return emitter.emit('error', errors)
      }
 
      self.model.daoFactory.runHooks('afterValidate', self.model.dataValues, function(err, newValues) {
        Iif (!!err) {
          return emitter.emit('error', err)
        }
 
        self.model.dataValues = newValues || self.model.dataValues
        emitter.emit('success', self.model)
      })
    })
  }).run()
}
 
// private
 
var validateModel = function() {
  var self   = this
    , errors = {}
 
  // for each model validator for this DAO
  Utils._.each(this.model.__options.validate, function(validator, validatorType) {
    try {
      validator.apply(self.model)
    } catch (err) {
      errors[validatorType] = [err.message] // TODO: data structure needs to change for 2.0
    }
  })
 
  return errors
}
 
var validateAttributes = function() {
  var self   = this
    , errors = {}
 
  Utils._.each(this.model.rawAttributes, function(rawAttribute, field) {
    var value          = self.model.dataValues[field] || undefined
      , hasAllowedNull = ((rawAttribute === undefined || rawAttribute.allowNull === true) && ((value === null) || (value === undefined)))
      , isSkipped      = self.options.skip.length > 0 && self.options.skip.indexOf(field) === -1
 
    Iif (self.model.validators.hasOwnProperty(field) && !hasAllowedNull && !isSkipped) {
      errors = Utils._.merge(errors, validateAttribute.call(self, value, field))
    }
  })
 
  return errors
}
 
var validateAttribute = function(value, field) {
  var self   = this
    , errors = {}
 
  // for each validator
  Utils._.each(this.model.validators[field], function(details, validatorType) {
    var validator = prepareValidationOfAttribute.call(self, value, details, validatorType)
 
    try {
      validator.fn.apply(null, validator.args)
    } catch (err) {
      var msg = err.message
 
      // if we didn't provide a custom error message then augment the default one returned by the validator
      if (!validator.msg && !validator.isCustom) {
        msg += ": " + field
      }
 
      // each field can have multiple validation errors stored against it
      errors[field] = errors[field] || []
      errors[field].push(msg)
    }
  })
 
  return errors
}
 
var prepareValidationOfAttribute = function(value, details, validatorType) {
  var isCustomValidator = false // if true then it's a custom validation method
    , validatorFunction = null  // the validation function to call
    , validatorArgs     = []    // extra arguments to pass to validation function
    , errorMessage      = ""    // the error message to return if validation fails
 
  if (typeof details === 'function') {
    // it is a custom validator function?
    isCustomValidator = true
    validatorFunction = Utils._.bind(details, this.model, value)
  } else {
    // it is a validator module function?
 
    // extract extra arguments for the validator
    validatorArgs = details.hasOwnProperty("args") ? details.args : details
 
    if (!Array.isArray(validatorArgs)) {
      validatorArgs = [validatorArgs]
    }
 
    // extract the error msg
    errorMessage = details.hasOwnProperty("msg") ? details.msg : undefined
 
    // check method exists
    var validator = Validator.check(value, errorMessage)
 
    // check if Validator knows that kind of validation test
    if (!Utils._.isFunction(validator[validatorType])) {
      throw new Error("Invalid validator function: " + validatorType)
    }
 
    // bind to validator obj
    validatorFunction = Utils._.bind(validator[validatorType], validator)
  }
 
  return {
    fn:       validatorFunction,
    msg:      errorMessage,
    args:     validatorArgs,
    isCustom: isCustomValidator
  }
}