Merge pull request #957 from mleanos/seeddb-enhance-testability

Seed options - logResults
This commit is contained in:
Liran Tal
2015-10-15 17:24:28 +03:00
6 changed files with 441 additions and 113 deletions

View File

@@ -66,5 +66,28 @@ module.exports = {
}
},
livereload: true,
seedDB: process.env.MONGO_SEED || false
seedDB: {
seed: process.env.MONGO_SEED === 'true' ? true : false,
options: {
logResults: process.env.MONGO_SEED_LOG_RESULTS === 'false' ? false : true,
seedUser: {
username: process.env.MONGO_SEED_USER_USERNAME || 'user',
provider: 'local',
email: process.env.MONGO_SEED_USER_EMAIL || 'user@localhost.com',
firstName: 'User',
lastName: 'Local',
displayName: 'User Local',
roles: ['user']
},
seedAdmin: {
username: process.env.MONGO_SEED_ADMIN_USERNAME || 'admin',
provider: 'local',
email: process.env.MONGO_SEED_ADMIN_EMAIL || 'admin@localhost.com',
firstName: 'Admin',
lastName: 'Local',
displayName: 'Admin Local',
roles: ['user', 'admin']
}
}
}
};

View File

@@ -66,5 +66,28 @@ module.exports = {
}
}
},
seedDB: process.env.MONGO_SEED || false
seedDB: {
seed: process.env.MONGO_SEED === 'true' ? true : false,
options: {
logResults: process.env.MONGO_SEED_LOG_RESULTS === 'false' ? false : true,
seedUser: {
username: process.env.MONGO_SEED_USER_USERNAME || 'user',
provider: 'local',
email: process.env.MONGO_SEED_USER_EMAIL || 'user@localhost.com',
firstName: 'User',
lastName: 'Local',
displayName: 'User Local',
roles: ['user']
},
seedAdmin: {
username: process.env.MONGO_SEED_ADMIN_USERNAME || 'admin',
provider: 'local',
email: process.env.MONGO_SEED_ADMIN_EMAIL || 'admin@localhost.com',
firstName: 'Admin',
lastName: 'Local',
displayName: 'Admin Local',
roles: ['user', 'admin']
}
}
}
};

25
config/env/test.js vendored
View File

@@ -57,5 +57,28 @@ module.exports = {
}
}
},
seedDB: process.env.MONGO_SEED || false
seedDB: {
seed: process.env.MONGO_SEED === 'true' ? true : false,
options: {
logResults: process.env.MONGO_SEED_LOG_RESULTS === 'false' ? false : true,
seedUser: {
username: process.env.MONGO_SEED_USER_USERNAME || 'user',
provider: 'local',
email: process.env.MONGO_SEED_USER_EMAIL || 'user@localhost.com',
firstName: 'User',
lastName: 'Local',
displayName: 'User Local',
roles: ['user']
},
seedAdmin: {
username: process.env.MONGO_SEED_ADMIN_USERNAME || 'admin',
provider: 'local',
email: process.env.MONGO_SEED_ADMIN_EMAIL || 'admin@localhost.com',
firstName: 'Admin',
lastName: 'Local',
displayName: 'Admin Local',
roles: ['user', 'admin']
}
}
}
};

View File

@@ -10,7 +10,7 @@ var config = require('../config'),
seed = require('./seed');
function seedDB() {
if (config.seedDB) {
if (config.seedDB.seed) {
console.log(chalk.bold.red('Warning: Database seeding is turned on'));
seed.start();
}

View File

@@ -1,15 +1,20 @@
'use strict';
var mongoose = require('mongoose'),
var _ = require('lodash'),
config = require('../config'),
mongoose = require('mongoose'),
chalk = require('chalk'),
crypto = require('crypto');
// global seed options object
var seedOptions = {};
function removeUser (user) {
return new Promise(function (resolve, reject) {
var User = mongoose.model('User');
User.find({username: user.username}).remove(function (err) {
if (err) {
reject(new Error('Database Seeding:\t\t\tFailed to remove local ' + user.username));
reject(new Error('Failed to remove local ' + user.username));
}
resolve();
});
@@ -22,7 +27,7 @@ function saveUser (user) {
// Then save the user
user.save(function (err, theuser) {
if (err) {
reject(new Error('Database Seeding:\t\t\tFailed to add local ' + user.username));
reject(new Error('Failed to add local ' + user.username));
} else {
resolve(theuser);
}
@@ -36,13 +41,13 @@ function checkUserNotExists (user) {
var User = mongoose.model('User');
User.find({username: user.username}, function (err, users) {
if (err) {
reject(new Error('Database Seeding:\t\t\tFailed to find local account ' + user.username));
reject(new Error('Failed to find local account ' + user.username));
}
if (users.length === 0) {
resolve();
} else {
reject(new Error('Database Seeding:\t\t\tFailed due to local account already exists: ' + user.username));
reject(new Error('Failed due to local account already exists: ' + user.username));
}
});
});
@@ -51,7 +56,9 @@ function checkUserNotExists (user) {
function reportSuccess (password) {
return function (user) {
return new Promise(function (resolve, reject) {
console.log(chalk.bold.red('Database Seeding:\t\t\tLocal ' + user.username + ' added with password set to ' + password));
if (seedOptions.logResults) {
console.log(chalk.bold.red('Database Seeding:\t\t\tLocal ' + user.username + ' added with password set to ' + password));
}
resolve();
});
};
@@ -66,82 +73,86 @@ function seedTheUser (user) {
// set the new password
user.password = password;
if (user.username === 'admin' && process.env.NODE_ENV === 'production') {
if (user.username === seedOptions.seedAdmin.username && process.env.NODE_ENV === 'production') {
checkUserNotExists(user)
.then(saveUser(user))
.then(reportSuccess(password))
.then(function () {
resolve();
})
.catch(reportError);
.then(saveUser(user))
.then(reportSuccess(password))
.then(function () {
resolve();
})
.catch(function (err) {
reject(err);
});
} else {
removeUser(user)
.then(saveUser(user))
.then(reportSuccess(password))
.then(function () {
resolve();
})
.catch(reportError);
.then(saveUser(user))
.then(reportSuccess(password))
.then(function () {
resolve();
})
.catch(function (err) {
reject(err);
});
}
});
};
}
// report the error
function reportError (err) {
console.log();
console.log(err);
console.log();
function reportError (reject) {
return function (err) {
if (seedOptions.logResults) {
console.log();
console.log('Database Seeding:\t\t\t' + err);
console.log();
}
reject(err);
};
}
module.exports.start = function start() {
module.exports.start = function start(options) {
// Initialize the default seed options
seedOptions = _.clone(config.seedDB.options, true);
// Check for provided options
if (_.has(options, 'logResults')) {
seedOptions.logResults = options.logResults;
}
if (_.has(options, 'seedUser')) {
seedOptions.seedUser = options.seedUser;
}
if (_.has(options, 'seedAdmin')) {
seedOptions.seedAdmin = options.seedAdmin;
}
var User = mongoose.model('User');
return new Promise(function (resolve, reject) {
var seedUser = {
username: 'user',
password: 'User_Password1!',
provider: 'local',
email: 'user@localhost.com',
firstName: 'User',
lastName: 'Local',
displayName: 'User Local',
roles: ['user']
};
var seedAdmin = {
username: 'admin',
password: 'Admin_Password1!',
provider: 'local',
email: 'admin@localhost.com',
firstName: 'Admin',
lastName: 'Local',
displayName: 'Admin Local',
roles: ['user', 'admin']
};
var user = null;
var adminAccount = new User(seedAdmin);
var userAccount = new User(seedUser);
var adminAccount = new User(seedOptions.seedAdmin);
var userAccount = new User(seedOptions.seedUser);
//If production only seed admin if it does not exist
if (process.env.NODE_ENV === 'production') {
User.generateRandomPassphrase()
.then(seedTheUser(adminAccount))
.then(function () {
.then(seedTheUser(adminAccount))
.then(function () {
resolve();
})
.catch(reportError);
.catch(reportError(reject));
} else {
// Add both Admin and User account
User.generateRandomPassphrase()
.then(seedTheUser(userAccount))
.then(User.generateRandomPassphrase)
.then(seedTheUser(adminAccount))
.then(function () {
.then(seedTheUser(userAccount))
.then(User.generateRandomPassphrase)
.then(seedTheUser(adminAccount))
.then(function () {
resolve();
})
.catch(reportError);
.catch(reportError(reject));
}
});
};

View File

@@ -10,13 +10,43 @@ var should = require('should'),
config = require(path.resolve('./config/config')),
seed = require(path.resolve('./config/lib/seed'));
/**
* Globals
*/
var user1, admin1, userFromSeedConfig, adminFromSeedConfig;
describe('Configuration Tests:', function () {
describe('Testing default seedDB', function () {
before(function(done) {
User.remove(function(err) {
should.not.exist(err);
user1 = {
username: 'user_config_test',
provider: 'local',
email: 'user_config_test_@localhost.com',
firstName: 'User',
lastName: 'Local',
displayName: 'User Local',
roles: ['user']
};
admin1 = {
username: 'admin_config_test',
provider: 'local',
email: 'admin_config_test_@localhost.com',
firstName: 'Admin',
lastName: 'Local',
displayName: 'Admin Local',
roles: ['user', 'admin']
};
userFromSeedConfig = config.seedDB.options.seedUser;
adminFromSeedConfig = config.seedDB.options.seedAdmin;
return done();
});
});
@@ -27,6 +57,18 @@ describe('Configuration Tests:', function () {
});
});
it('should have seedDB configuration set for "regular" user', function() {
(typeof userFromSeedConfig).should.not.equal('undefined');
should.exist(userFromSeedConfig.username);
should.exist(userFromSeedConfig.email);
});
it('should have seedDB configuration set for admin user', function() {
(typeof adminFromSeedConfig).should.not.equal('undefined');
should.exist(adminFromSeedConfig.username);
should.exist(adminFromSeedConfig.email);
});
it('should not be an admin user to begin with', function(done) {
User.find({username: 'admin'}, function(err, users) {
should.not.exist(err);
@@ -43,67 +85,28 @@ describe('Configuration Tests:', function () {
});
});
it('should set NODE_ENV to production and seedDB turned on so admin account must exist', function(done) {
it('should seed ONLY the admin user account when NODE_ENV is set to "production"', function(done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'production';
User.find({username: 'admin'}, function(err, users) {
User.find({username: adminFromSeedConfig.username}, function(err, users) {
// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);
seed.start().then(function() {
User.find({username: 'admin'}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var admin = users.pop();
admin.username.should.equal('admin');
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
User.remove(function(err) {
should.not.exist(err);
return done();
});
});
});
});
});
it('should set NODE_ENV to test and seedDB turned on so admin, and user accounts must exist', function(done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'test';
User.find({username: 'admin'}, function(err, users) {
// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);
seed.start().then(function() {
User.find({username: 'admin'}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var admin = users.pop();
admin.username.should.equal('admin');
User.find({username: 'user'}, function(err, users) {
seed
.start({ logResults: false })
.then(function() {
User.find({username: adminFromSeedConfig.username}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var user = users.pop();
user.username.should.equal('user');
var _admin = users.pop();
_admin.username.should.equal(adminFromSeedConfig.username);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
@@ -114,9 +117,257 @@ describe('Configuration Tests:', function () {
});
});
});
});
});
it('should seed admin, and "regular" user accounts when NODE_ENV is set to "test"', function(done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'test';
User.find({username: adminFromSeedConfig.username}, function(err, users) {
// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);
seed
.start({ logResults: false })
.then(function() {
User.find({username: adminFromSeedConfig.username}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var _admin = users.pop();
_admin.username.should.equal(adminFromSeedConfig.username);
User.find({username: userFromSeedConfig.username}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var _user = users.pop();
_user.username.should.equal(userFromSeedConfig.username);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
User.remove(function(err) {
should.not.exist(err);
return done();
});
});
});
});
});
});
it('should seed admin, and "regular" user accounts when NODE_ENV is set to "test" when they already exist', function (done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'test';
var _user = new User(userFromSeedConfig);
var _admin = new User(adminFromSeedConfig);
_admin.save(function (err) {
// There shouldn't be any errors
should.not.exist(err);
_user.save(function (err) {
// There shouldn't be any errors
should.not.exist(err);
User.find({ username: { $in: [adminFromSeedConfig.username, userFromSeedConfig.username] } }, function (err, users) {
// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(2);
seed
.start({ logResults: false })
.then(function () {
User.find({ username: { $in: [adminFromSeedConfig.username, userFromSeedConfig.username] } }, function (err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(2);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
User.remove(function (err) {
should.not.exist(err);
return done();
});
});
});
});
});
});
});
it('should ONLY seed admin user account when NODE_ENV is set to "production" with custom admin', function(done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'production';
User.find({username: admin1.username}, function(err, users) {
// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);
seed
.start({ logResults: false, seedAdmin: admin1 })
.then(function() {
User.find({username: admin1.username}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var _admin = users.pop();
_admin.username.should.equal(admin1.username);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
User.remove(function(err) {
should.not.exist(err);
return done();
});
});
});
});
});
it('should seed admin, and "regular" user accounts when NODE_ENV is set to "test" with custom options', function(done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'test';
User.find({username: admin1.username}, function(err, users) {
// There shouldn't be any errors
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(0);
seed
.start({ logResults: false, seedAdmin: admin1, seedUser: user1 })
.then(function() {
User.find({username: admin1.username}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var _admin = users.pop();
_admin.username.should.equal(admin1.username);
User.find({username: user1.username}, function(err, users) {
should.not.exist(err);
users.should.be.instanceof(Array).and.have.lengthOf(1);
var _user = users.pop();
_user.username.should.equal(user1.username);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
User.remove(function(err) {
should.not.exist(err);
return done();
});
});
});
});
});
});
it('should NOT seed admin user account if it already exists when NODE_ENV is set to "production"', function(done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro production environment
process.env.NODE_ENV = 'production';
var _admin = new User(adminFromSeedConfig);
_admin.save(function(err, user) {
// There shouldn't be any errors
should.not.exist(err);
user.username.should.equal(adminFromSeedConfig.username);
seed
.start({ logResults: false })
.then(function () {
// we don't ever expect to make it here but we don't want to timeout
User.remove(function(err) {
should.not.exist(err);
// force this test to fail since we should never be here
should.exist(undefined);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
return done();
});
})
.catch(function (err) {
should.exist(err);
err.message.should.equal('Failed due to local account already exists: ' + adminFromSeedConfig.username);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
User.remove(function(removeErr) {
should.not.exist(removeErr);
return done();
});
});
});
});
it('should NOT seed "regular" user account if missing email when NODE_ENV set to "test"', function (done) {
// Save original value
var nodeEnv = process.env.NODE_ENV;
// Set node env ro test environment
process.env.NODE_ENV = 'test';
var _user = new User(user1);
_user.email = '';
seed
.start({ logResults: false, seedUser: _user })
.then(function () {
// we don't ever expect to make it here but we don't want to timeout
User.remove(function(err) {
// force this test to fail since we should never be here
should.exist(undefined);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
return done();
});
})
.catch(function (err) {
should.exist(err);
err.message.should.equal('Failed to add local ' + user1.username);
// Restore original NODE_ENV environment variable
process.env.NODE_ENV = nodeEnv;
User.remove(function(removeErr) {
should.not.exist(removeErr);
return done();
});
});
});
});
describe('Testing Session Secret Configuration', function () {
@@ -130,30 +381,27 @@ describe('Configuration Tests:', function () {
return done();
});
it('should accept non-default session secret when running in production', function (done) {
it('should accept non-default session secret when running in production', function () {
var conf = { sessionSecret: 'super amazing secret' };
// set env to production for this test
process.env.NODE_ENV = 'production';
config.utils.validateSessionSecret(conf, true).should.equal(true);
// set env back to test
process.env.NODE_ENV = 'test';
return done();
});
it('should accept default session secret when running in development', function (done) {
it('should accept default session secret when running in development', function () {
var conf = { sessionSecret: 'MEAN' };
// set env to development for this test
process.env.NODE_ENV = 'development';
config.utils.validateSessionSecret(conf, true).should.equal(true);
// set env back to test
process.env.NODE_ENV = 'test';
return done();
});
it('should accept default session secret when running in test', function (done) {
it('should accept default session secret when running in test', function () {
var conf = { sessionSecret: 'MEAN' };
config.utils.validateSessionSecret(conf, true).should.equal(true);
return done();
});
});
});