From ce157d8e93a160df9a880caaa1043e28bda7ce57 Mon Sep 17 00:00:00 2001 From: Mike Botsko Date: Sat, 10 Oct 2015 09:32:01 -0700 Subject: [PATCH] Migrates tests to Mocha/Chai, minor repo cleanup jasmine-node is missing some useful functionality and unfortunately it appears abandoned. This commit migrates our tests to mocha/chai, but also affords us the chance to clean up tests a bit. Also includes some minor cleanup: - Updated version of mongoose in package.json, and marked it as a peerDep - Added viveleroi as a contributor to package.json - More entries in gitignore --- .gitignore | 14 ++- package.json | 60 +++++++------ spec/index.spec.js | 218 --------------------------------------------- test/helpers.js | 48 ++++++++++ test/index.spec.js | 109 +++++++++++++++++++++++ 5 files changed, 205 insertions(+), 244 deletions(-) delete mode 100644 spec/index.spec.js create mode 100644 test/helpers.js create mode 100644 test/index.spec.js diff --git a/.gitignore b/.gitignore index 1fe1b00..699c4eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,14 @@ -.idea/ +*.sublime-workspace +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.Spotlight-V100 +.Trashes +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ node_modules/ +.tmp diff --git a/package.json b/package.json index 3d83eae..4074d4b 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,38 @@ { - "name": "mongoose-unique-validator", - "version": "0.4.1", - "description": "mongoose-unique-validator is a plugin which adds pre-save validation for unique fields within a Mongoose schema.", - "main": "index.js", - "scripts": { - "test": "./node_modules/.bin/jasmine-node spec/ --forceexit --captureExceptions" - }, - "keywords": [ - "mongoose", - "unique", - "validator" - ], - "author": { - "name": "Blake Haswell", - "email": "haswell00@gmail.com", - "url": "http://blakehaswell.com/" - }, - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/blakehaswell/mongoose-unique-validator.git" - }, - "devDependencies": { - "jasmine-node": "1.14.x", - "mongoose": "3.8.x" + "name": "mongoose-unique-validator", + "version": "0.4.1", + "description": "mongoose-unique-validator is a plugin which adds pre-save validation for unique fields within a Mongoose schema.", + "main": "index.js", + "scripts": { + "test": "mocha test" + }, + "keywords": [ + "mongoose", + "unique", + "validator" + ], + "author": { + "name": "Blake Haswell", + "email": "haswell00@gmail.com", + "url": "http://blakehaswell.com/" + }, + "contributors": [ + { + "name": "Mike Botsko", + "email": "botsko@gmail.com" } + ], + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/blakehaswell/mongoose-unique-validator.git" + }, + "devDependencies": { + "bluebird": "^2.10.2", + "chai": "^3.3.0", + "mocha": "^2.3.3" + }, + "peerDependencies": { + "mongoose": "^4.1.10" + } } diff --git a/spec/index.spec.js b/spec/index.spec.js deleted file mode 100644 index f005821..0000000 --- a/spec/index.spec.js +++ /dev/null @@ -1,218 +0,0 @@ -// TODO Fix callback hell with Q promise library. - -var mongoose = require('mongoose'); -var uniqueValidator = require('../index.js'); - -mongoose.connect('mongodb://localhost/mongoose-unique-validator'); - -describe('Mongoose Unique Validator Plugin', function () { - - describe('when no custom error message is passed', function () { - - var User = mongoose.model('User', getUserSchema().plugin(uniqueValidator)); - - describe('when a duplicate record exists in the DB', function () { - - it('a validation error is thrown for fields with a unique index', function (done) { - var user = getDuplicateUser(User); - var duplicateUser = getDuplicateUser(User); - - user.save(function () { - duplicateUser.save(function (err) { - - user.remove(function () { - duplicateUser.remove(function () { - expect(err.errors.username.message).toBe('Error, expected `username` to be unique. Value: `JohnSmith`'); - expect(err.errors.username.type).toBe('user defined'); - expect(err.errors.username.path).toBe('username'); - expect(err.errors.username.value).toBe('JohnSmith'); - - expect(err.errors.email.message).toBe('Error, expected `email` to be unique. Value: `john.smith@gmail.com`'); - expect(err.errors.email.type).toBe('user defined'); - expect(err.errors.email.path).toBe('email'); - expect(err.errors.email.value).toBe('john.smith@gmail.com'); - - done(); - }); - }); - }); - }); - }); - - it('no validation error is thrown for fields without a unique index', function (done) { - var user = getDuplicateUser(User); - var duplicateUser = getDuplicateUser(User); - - user.save(function () { - duplicateUser.save(function (err) { - - user.remove(function () { - duplicateUser.remove(function () { - expect(err.errors.password).toBeUndefined(); - done(); - }); - }); - }); - }); - }); - }); - - describe('when no duplicate record exists in the DB', function () { - - it('no validation errors are thrown for fields with a unique index', function (done) { - var user = getDuplicateUser(User); - var uniqueUser = getUniqueUser(User); - - user.save(function () { - uniqueUser.save(function (err) { - user.remove(function () { - uniqueUser.remove(function () { - expect(err).toBeNull(); - done(); - }); - }); - }); - }); - }); - }); - - describe('when a unique record exists in the DB', function () { - - it('can be saved even if validation is triggered on a field with a unique index', function (done) { - var user = getUniqueUser(User); - - user.save(function () { - - // Changing a field and then changing it back to what it was seems to change an internal Mongoose flag - // and causes validation to occur even though the value of the field hasn’t changed. - user.email = 'robert.miller@gmail.com'; - user.email = 'bob@robertmiller.com'; - - user.save(function (err) { - user.remove(function () { - expect(err).toBeNull(); - done(); - }); - }); - }); - }); - - }); - - }); - - describe('when a custom error message is passed', function () { - - var User = mongoose.model('UserErrorMessage', getUserSchema().plugin(uniqueValidator, { message: 'Path: {PATH}, value: {VALUE}, type: {TYPE}' })); - - it('a custom message error is thrown for fields with a unique index when present', function (done) { - var user = getDuplicateUser(User); - var duplicateUser = getDuplicateUser(User); - - user.save(function () { - duplicateUser.save(function (err) { - - user.remove(function () { - duplicateUser.remove(function () { - expect(err.errors.username.message).toBe('Path: username, value: JohnSmith, type: user defined'); - expect(err.errors.username.type).toBe('user defined'); - expect(err.errors.username.path).toBe('username'); - expect(err.errors.username.value).toBe('JohnSmith'); - - expect(err.errors.email.message).toBe('Path: email, value: john.smith@gmail.com, type: user defined'); - expect(err.errors.email.type).toBe('user defined'); - expect(err.errors.email.path).toBe('email'); - expect(err.errors.email.value).toBe('john.smith@gmail.com'); - - done(); - }); - }); - }); - }); - }); - - }); - - describe('when a custom error message is passed to the schema options', function(){ - - var User = mongoose.model('UserErrorCustomMessage', getUserSchemaWithCustomMessage().plugin(uniqueValidator)); - - it('a custom message error is thrown for fields with a unique index when present', function (done) { - var user = getDuplicateUser(User); - var duplicateUser = getDuplicateUser(User); - - user.save(function () { - duplicateUser.save(function (err) { - - user.remove(function () { - duplicateUser.remove(function () { - expect(err.errors.username.message).toBe('Username is already used.'); - expect(err.errors.username.type).toBe('user defined'); - expect(err.errors.username.path).toBe('username'); - expect(err.errors.username.value).toBe('JohnSmith'); - - expect(err.errors.email.message).toBe('It already exists.'); - expect(err.errors.email.type).toBe('user defined'); - expect(err.errors.email.path).toBe('email'); - expect(err.errors.email.value).toBe('john.smith@gmail.com'); - - done(); - }); - }); - }); - }); - }); - - }); - -}); - -function getUserSchema() { - return mongoose.Schema({ - username: { - type: String, - unique: true - }, - email: { - type: String, - index: true, - unique: true - }, - password: { - type: String - } - }); -} - -function getUserSchemaWithCustomMessage() { - return mongoose.Schema({ - username: { - type: String, - unique: 'Username is already used.' - }, - email: { - type: String, - index: true, - unique: 'It already exists.' - }, - password: { - type: String - } - }); -} - -function getDuplicateUser(User) { - return new User({ - username: 'JohnSmith', - email: 'john.smith@gmail.com', - password: 'j0hnNYb0i' - }); -} - -function getUniqueUser(User) { - return new User({ - username: 'Robert Miller', - email: 'bob@robertmiller.com', - password: '@b0B#b0B$b0B%' - }); -} diff --git a/test/helpers.js b/test/helpers.js new file mode 100644 index 0000000..f851d75 --- /dev/null +++ b/test/helpers.js @@ -0,0 +1,48 @@ +var mongoose = require('mongoose'); + +// Helper methods/objects for tests +module.exports = { + createUserSchema: function() { + return mongoose.Schema({ + username: { + type: String, + unique: true + }, + email: { + type: String, + index: true, + unique: true + }, + password: { + type: String + } + }); + }, + + createCustomUserSchema: function() { + return mongoose.Schema({ + username: { + type: String, + unique: 'Username is already used.' + }, + email: { + type: String, + index: true, + unique: 'It already exists.' + }, + password: { + type: String + } + }); + }, + + USERS: [{ + username: 'JohnSmith', + email: 'john.smith@gmail.com', + password: 'j0hnNYb0i' + }, { + username: 'Robert Miller', + email: 'bob@robertmiller.com', + password: '@b0B#b0B$b0B%' + }] +}; diff --git a/test/index.spec.js b/test/index.spec.js new file mode 100644 index 0000000..f0a4648 --- /dev/null +++ b/test/index.spec.js @@ -0,0 +1,109 @@ +var helpers = require('./helpers'); +var expect = require('chai').expect; +var mongoose = require('mongoose'); +var uniqueValidator = require('../index.js'); + +mongoose.Promise = require('bluebird'); + +// Connect +mongoose.connect('mongodb://localhost/mongoose-unique-validator'); +mongoose.connection.on('error', function() { + throw new Error('Unable to connect to database.'); +}); + +var models = []; + +describe('Mongoose Unique Validator', function() { + afterEach(function(done) { + var l = models.length; + + models.forEach(function(model) { + model.remove().then(function() { + l--; + + if (!l) { + done(); + } + }); + }); + }); + + describe('Default Configuration', function () { + var User = mongoose.model('User', helpers.createUserSchema().plugin(uniqueValidator)); + models.push(User); + + it('throws validation error for unique index violation', function(done) { + // Save the first user + var promise = new User(helpers.USERS[0]).save(); + promise.then(function() { + // Try saving a duplicate + new User(helpers.USERS[0]).save().catch(function(err) { + expect(err.errors.username.message).to.equal('Error, expected `username` to be unique. Value: `JohnSmith`'); + expect(err.errors.username.properties.type).to.equal('user defined'); + expect(err.errors.username.properties.path).to.equal('username'); + + expect(err.errors.email.message).to.equal('Error, expected `email` to be unique. Value: `john.smith@gmail.com`'); + expect(err.errors.email.properties.type).to.equal('user defined'); + expect(err.errors.email.properties.path).to.equal('email'); + + done(); + }); + }); + promise.catch(done); + }); + + it('allows unique records', function(done) { + // Save the first user + var promise = new User(helpers.USERS[0]).save(); + promise.then(function() { + // Try saving a unique user + new User(helpers.USERS[1]).save().catch(done).then(function() { + done(); + }); + }); + promise.catch(done); + }); + }); + + describe('Custom Configuration', function () { + var User = mongoose.model('UserErrorMessage', helpers.createUserSchema().plugin(uniqueValidator, { + message: 'Path: {PATH}, value: {VALUE}, type: {TYPE}' + })); + models.push(User); + + it('throws validation error for unique index violation', function(done) { + // Save the first user + var promise = new User(helpers.USERS[0]).save(); + promise.then(function() { + // Try saving a duplicate + new User(helpers.USERS[0]).save().catch(function(err) { + expect(err.errors.username.message).to.equal('Path: username, value: JohnSmith, type: user defined'); + expect(err.errors.email.message).to.equal('Path: email, value: john.smith@gmail.com, type: user defined'); + + done(); + }); + }); + promise.catch(done); + }); + }); + + describe('Configuration via Schema', function () { + var User = mongoose.model('UserErrorCustomMessage', helpers.createCustomUserSchema().plugin(uniqueValidator)); + models.push(User); + + it('throws validation error for unique index violation', function(done) { + // Save the first user + var promise = new User(helpers.USERS[0]).save(); + promise.then(function() { + // Try saving a duplicate + new User(helpers.USERS[0]).save().catch(function(err) { + expect(err.errors.username.message).to.equal('Username is already used.'); + expect(err.errors.email.message).to.equal('It already exists.'); + + done(); + }); + }); + promise.catch(done); + }); + }); +});