From c3629633de9d7517de5ca71cc6bf8b3c932542aa Mon Sep 17 00:00:00 2001 From: Bram Borggreve Date: Mon, 21 Dec 2015 12:38:11 +0000 Subject: [PATCH] Add caseInsensitive opt to validatesUniquenessOf --- lib/validations.js | 16 ++++++- test/validations.test.js | 96 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 1 deletion(-) diff --git a/lib/validations.js b/lib/validations.js index 7c8ed722..6a99f1db 100644 --- a/lib/validations.js +++ b/lib/validations.js @@ -240,6 +240,7 @@ Validatable.validateAsync = getConfigurator('custom', {async: true}); * @property {Array.} scopedTo List of properties defining the scope. * @property {String} message Optional error message if property is not valid. Default error message: "is not unique". * @property {Boolean} allowNull Whether null values are allowed. + * @property {String} ignoreCase Make the validation case insensitive */ Validatable.validatesUniquenessOf = getConfigurator('uniqueness', {async: true}); @@ -344,6 +345,14 @@ function validateCustom(attr, conf, err, options, done) { conf.customValidator.call(this, err, done); } +function escapeStringRegexp(str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + return str.replace(matchOperatorsRe, '\\$&'); +} + /*! * Uniqueness validator */ @@ -356,7 +365,12 @@ function validateUniqueness(attr, conf, err, options, done) { return process.nextTick(done); } var cond = {where: {}}; - cond.where[attr] = this[attr]; + + if (conf && conf.ignoreCase) { + cond.where[attr] = new RegExp('^' + escapeStringRegexp(this[attr]) + '$', 'i'); + } else { + cond.where[attr] = this[attr]; + } if (conf && conf.scopedTo) { conf.scopedTo.forEach(function(k) { diff --git a/test/validations.test.js b/test/validations.test.js index f551ac1e..e54bb49c 100644 --- a/test/validations.test.js +++ b/test/validations.test.js @@ -517,6 +517,102 @@ describe('validations', function() { })).should.be.false; }); }); + + it('passes case insensitive validation', function(done) { + User.validatesUniquenessOf('email', {ignoreCase: true}); + var u = new User({email: 'hey'}); + Boolean(u.isValid(function(valid) { + valid.should.be.true(); + u.save(function(err) { + if (err) return done(err); + var u2 = new User({email: 'HEY'}); + u2.isValid(function(valid) { + valid.should.be.false(); + done(); + }); + }); + })).should.be.false(); + }); + + it('passed case sensitive validation', function(done) { + User.validatesUniquenessOf('email', {ignoreCase: false}); + var u = new User({email: 'hey'}); + Boolean(u.isValid(function(valid) { + valid.should.be.true(); + u.save(function(err) { + if (err) return done(err); + var u2 = new User({email: 'HEY'}); + u2.isValid(function(valid) { + valid.should.be.true(); + done(); + }); + }); + })).should.be.false(); + }); + + it('passes case insensitive validation with string that needs escaping', function(done) { + User.validatesUniquenessOf('email', {ignoreCase: true}); + var u = new User({email: 'me+me@my.com'}); + Boolean(u.isValid(function(valid) { + valid.should.be.true(); + u.save(function(err) { + if (err) return done(err); + var u2 = new User({email: 'ME+ME@MY.COM'}); + u2.isValid(function(valid) { + valid.should.be.false(); + done(); + }); + }); + })).should.be.false(); + }); + + it('passed case sensitive validation with string that needs escaping', function(done) { + User.validatesUniquenessOf('email', {ignoreCase: false}); + var u = new User({email: 'me+me@my.com'}); + Boolean(u.isValid(function(valid) { + valid.should.be.true(); + u.save(function(err) { + if (err) return done(err); + var u2 = new User({email: 'ME+ME@MY.COM'}); + u2.isValid(function(valid) { + valid.should.be.true(); + done(); + }); + }); + })).should.be.false(); + }); + + it('passes partial case insensitive validation with string that needs escaping', function(done) { + User.validatesUniquenessOf('email', {ignoreCase: true}); + var u = new User({email: 'also+me@my.com'}); + Boolean(u.isValid(function(valid) { + valid.should.be.true(); + u.save(function(err) { + if (err) return done(err); + var u2 = new User({email: 'Me@My.com'}); + u2.isValid(function(valid) { + valid.should.be.true(); + done(); + }); + }); + })).should.be.false(); + }); + + it('passes partial case sensitive validation with string that needs escaping', function(done) { + User.validatesUniquenessOf('email', {ignoreCase: false}); + var u = new User({email: 'also+me@my.com'}); + Boolean(u.isValid(function(valid) { + valid.should.be.true(); + u.save(function(err) { + if (err) return done(err); + var u2 = new User({email: 'Me@My.com'}); + u2.isValid(function(valid) { + valid.should.be.true(); + done(); + }); + }); + })).should.be.false(); + }); }); describe('format', function() {