Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/1502 #1691

Merged
merged 29 commits into from
Aug 11, 2017
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
95be761
Update mocha tests
taylortom Jul 31, 2017
e7f15c5
Expose logger level
taylortom Jul 31, 2017
414c5d8
Fix tenant deletion
taylortom Jul 31, 2017
551aeab
Remove old tests
taylortom Aug 1, 2017
4d1bbda
Tidy up imports
taylortom Aug 1, 2017
b17c84a
Add route to ignores
taylortom Aug 1, 2017
1948ddd
Pass result to delete function
taylortom Aug 1, 2017
2c3b85e
Refactor error handling
taylortom Aug 1, 2017
35c047c
Fix destroyRole
taylortom Aug 1, 2017
a6f37d1
Fix removeDirectory
taylortom Aug 1, 2017
70085da
Add comment
taylortom Aug 1, 2017
c32ff09
tests now allways start with a clean db
canstudios-louisem Aug 2, 2017
00c2117
fix tests, upgrade should
canstudios-louisem Aug 2, 2017
5612b98
Rename references to tenant record results for clarity
taylortom Aug 2, 2017
c53225b
Move data folder cleanup and rename various things for readability
taylortom Aug 2, 2017
5b05625
Alter tests to stop error messages
taylortom Aug 2, 2017
2ec97e8
Amend testData
taylortom Aug 2, 2017
d5954aa
Update config files
taylortom Aug 2, 2017
9593030
Remove log
taylortom Aug 2, 2017
295d0c8
Only show logger errors
taylortom Aug 3, 2017
ff15370
Switch to use grunt test task
taylortom Aug 10, 2017
b6bf953
Tidy up mocha config
taylortom Aug 10, 2017
db8e131
Update mocha
taylortom Aug 10, 2017
c81986c
Update package.json prior for next release
taylortom Aug 10, 2017
8a9fed1
Temporarily disable casperjs tests
taylortom Aug 10, 2017
5c3bd8e
Add grunt to deps
taylortom Aug 10, 2017
3f55c62
Reinstate longer timeout
taylortom Aug 10, 2017
a5a1b36
Add extended timeout to after() in addition to before()
taylortom Aug 10, 2017
e79b020
Remove test data both before and after tests
taylortom Aug 10, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions lib/filestorage.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
// LICENCE https://github.com/adaptlearning/adapt_authoring/blob/master/LICENSE
/**
* Module depencies
*/

var path = require('path'),
fs = require('fs'),
logger = require('./logger'),
EventEmitter = require('events').EventEmitter,
util = require('util'),
pluginmanager = require('./pluginmanager'),
configuration = require('./configuration');

var logger = require('./logger')
var pluginmanager = require('./pluginmanager');
/*
* CONSTANTS
*/
Expand Down
10 changes: 10 additions & 0 deletions lib/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ Log.prototype.add = function(transport, options) {
}
};

/**
* Function to change transpots log level
*/
Log.prototype.level = function(type, level) {
if(!this.logger.transports.hasOwnProperty(type)) {
return console.log("Unknown transport type", type);
}
this.logger.transports[type].level = level;
};

/**
* A wrapper for winston's clear method (removes all transports)
*
Expand Down
1 change: 1 addition & 0 deletions lib/permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var ignoreRoutes = [
/^\/\/?$/,
/^\/install\/?.*$/,
/^\/api\/login\/?$/,
/^\/api\/loginas\/?$/,
/^\/api\/logout\/?$/,
/^\/api\/authcheck\/?$/,
/^\/api\/register\/?$/,
Expand Down
21 changes: 10 additions & 11 deletions lib/rolemanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,14 @@ var RoleManager = {
var self = this;
database.getDatabase(function(err, db){
// confirm the role exists and is there is only one of them
self.retrieveRole({ _id: roleId }, function (error, results) {
self.retrieveRole({ _id: roleId }, function (error, result) {
if (error) {
return callback(error);
}

if (results && results.length === 1) {
return db.destroy('role', { _id: roleId }, callback);
if (!result) {
return callback(new Error('No matching role record found'));
}

return callback(new Error('No matching role record found'));
return db.destroy('role', { _id: result._id }, callback);
});
}, configuration.getConfig('dbName'));
},
Expand Down Expand Up @@ -559,12 +557,13 @@ function syncDefaultRoles (options, next) {
}

// Apply the latest version of the roles to the master tenant
db.update('role', {name: role.name}, { version: role.version, statement: role.statement }, function (err, rec) {
if (err || !rec) {
// Log error, but continue
logger.log('warn', '- ' + role.name + ' update failed!', err);
db.update('role', { name: role.name }, { version: role.version, statement: role.statement }, function (err, rec) {
if (err) {
logger.log('warn', '- ' + role.name + ' update failed', err);
}
if (!rec) {
logger.log('warn', '- ' + role.name + ' doesn\'t exist, cannot update', err);
}

return callback(err);
});
},
Expand Down
77 changes: 44 additions & 33 deletions lib/tenantmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
/**
* Tenant management module
*/

var util = require('util'),
database = require('./database'),
logger = require('./logger'),
fs = require('fs'),
path = require('path'),
ncp = require('ncp'),
mkdirp = require('mkdirp'),
frameworkhelper = require('./frameworkhelper'),
configuration = require('./configuration');
var async = require('async');
var fs = require('fs-extra');
var mkdirp = require('mkdirp');
var ncp = require('ncp');
var path = require('path');
var util = require('util');

var configuration = require('./configuration');
var database = require('./database');
var frameworkhelper = require('./frameworkhelper');
var logger = require('./logger');

// Constants
var MODNAME = 'tenantmanager';
Expand Down Expand Up @@ -442,12 +443,12 @@ exports = module.exports = {
}

// only execute if we have a single matching record
self.retrieveTenant(search, function (error, result) {
self.retrieveTenant(search, function (error, tenantRec) {
if (error) {
return callback(error);
}

if (result) {
if (tenantRec) {
if (!update.updatedAt) {
update.updatedAt = new Date();
}
Expand All @@ -458,12 +459,12 @@ exports = module.exports = {
}

// Re-fetch the tenant
self.retrieveTenant(search, function(error, result) {
self.retrieveTenant(search, function(error, tenantRec) {
if (error) {
return callback(error);
}

return callback(null, result);
return callback(null, tenantRec);
});

});
Expand All @@ -489,18 +490,15 @@ exports = module.exports = {
logger.log('error', err);
return callback(err);
}

// confirm the tenant exists and is there is only one of them
self.retrieveTenant({ _id: tenantId }, function (error, results) {
// confirm the tenant exists
self.retrieveTenant({ _id: tenantId }, function (error, tenantRec) {
if (error) {
return callback(error);
}

if (results && results.length === 1) {
return self.updateTenant({ '_id': results[0]._id }, { _isDeleted: true }, callback);
if (!result) {
return callback(new Error('No matching tenant record found'));
}

return callback(new Error('No matching tenant record found'));
return self.updateTenant({ '_id': tenantRec._id }, { _isDeleted: true }, callback);
});
}, configuration.getConfig('dbName'));
},
Expand All @@ -515,27 +513,40 @@ exports = module.exports = {

deleteTenant: function (tenant, callback) {
var self = this;
database.getDatabase(function(err, db){
database.getDatabase(function(err, db) {
if (err) {
logger.log('error', err);
return callback(err);
}

// confirm the tenant exists and is there is only one of them
self.retrieveTenant(tenant, function (error, result) {
// confirm the tenant exists
self.retrieveTenant(tenant, function (error, tenantRec) {
if (error) {
return callback(error);
}

if (result) {
return db.destroy('tenant', tenant, callback);
if (!tenantRec) {
return callback(new Error('No matching tenant record found'));
}

return callback(new Error('No matching tenant record found'));
async.parallel([
function cleanDB(done) {
db.destroy('tenant', tenant, done);
},
function removeTemp(done) {
self.deleteTenantFilesystem(tenantRec, done);
}
], callback);
});
}, configuration.getConfig('dbName'));
},

/**
* Removes the tenant's working folders
* @param {object} tenant - a fully defined tenant object
* @param {function} callback - function of the form function (error)
*/
deleteTenantFilesystem: function(tenant, callback) {
fs.remove(path.join(configuration.tempDir, tenant._id.toString()), callback);
},

/**
* returns the database object for a named tenant
*
Expand All @@ -544,7 +555,7 @@ exports = module.exports = {
*/
getDatabaseConfig: function (tenantId, next) {
// just fetch up the tenant from the master db
this.retrieveTenant({ _id: tenantId }, function (err, tenant) {
this.retrieveTenant({ _id: tenantId }, function (err, tenantRec) {
if (err) {
return next(err);
}
Expand All @@ -554,7 +565,7 @@ exports = module.exports = {
}

// if database is not defined, the caller is expected to deal with item
return next(null, tenant.database);
return next(null, tenantRec.database);
});
}
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@
},
"devDependencies": {
"mocha": "~1.13.0",
"mongodb": "^2.2.30",
"phantom": "^0.6.5",
"should": "~1.3.0",
"should": "~11.2.1",
"supertest": "~0.8.1"
}
}
4 changes: 2 additions & 2 deletions plugins/filestorage/localfs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
var async = require('async');
var ffmpeg = require('fluent-ffmpeg');
var fs = require('fs');
var fs = require('fs-extra');
var mkdirp = require('mkdirp');
var ncp = require('ncp').ncp;
var path = require('path');
Expand Down Expand Up @@ -265,7 +265,7 @@ LocalFileStorage.prototype.createDirectory = function (filePath, callback) {
*/

LocalFileStorage.prototype.removeDirectory = function (filePath, callback) {
fs.rmdir(this.resolvePath(filePath), callback);
fs.remove(this.resolvePath(filePath), callback);
};

/**
Expand Down
135 changes: 135 additions & 0 deletions test/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
var async = require('async');
var fs = require('fs-extra');
var path = require('path');
var mongodb = require('mongodb');

var origin = require('../');
var auth = require('../lib/auth');
var logger = require('../lib/logger');
var permissions = require('../lib/permissions');
var usermanager = require('../lib/usermanager');
var tenantmanager = require('../lib/tenantmanager');

var testData = require('./testData.json');
var testConfig = require('./testConfig.json');

var app = origin();

before(function(done) {
this.timeout(600000);

async.series([
function dumpOldDb(cb) {
var MongoClient = mongodb.MongoClient;
var connStr = 'mongodb://' + testConfig.dbHost + ':' + testConfig.dbPort + '/' + testConfig.dbName;
MongoClient.connect(connStr, function(error, db) {
if(error){
return cb(error);
}
db.dropDatabase(function(error, result) {
if(error){
return cb(error);
}
db.close();
return cb();
});
});
},
function removeData(cb) {
fs.remove(testConfig.dataRoot, cb);
},
function initApp(cb) {
// only show errors
logger.level('console','error');
// bootstrapping!
app.use({ configFile: path.join('test', 'testConfig.json') });
// add some test entities ...
app.on('serverStarted', function(server) {
createTestTenant(testData.testTenant, function(error, tenant) {
if(error) {
return cb(error);
}
testData.testTenant = tenant;
testData.testUser._tenantId = tenant._id;

app.configuration.setConfig('masterTenantID', tenant._id);
app.configuration.setConfig('masterTenantName', tenant.name);

createTestUser(testData.testUser, function(error, user) {
if(error) {
return cb(error);
}
testData.testUser._id = user._id;
app.rolemanager.assignRoleByName('Super Admin', user._id, cb);
});
});
});
app.run();
}
], done);
});

after(function(done) {
async.parallel([
function removePolicies(cb) {
permissions.clearPolicies(testData.testUser._id, cb);
},
function removeUser(cb) {
usermanager.deleteUser({ _id: testData.testUser._id }, cb);
},
function removeTenant(cb) {
tenantmanager.deleteTenant({ _id: testData.testTenant._id }, cb);
},
function removeRoles(cb) {
app.rolemanager.retrieveRoles({}, {}, function(error, roles) {
async.each(roles, function(role, cb2) {
app.rolemanager.destroyRole(role._id, cb2);
}, cb);
});
}
], done);
});

function createTestTenant (tenantDetails, cb) {
tenantmanager.createTenant(tenantDetails, function(error, tenant) {
if(error && error instanceof tenantmanager.errors.DuplicateTenantError) {
return tenantmanager.retrieveTenant({name: tenantDetails.name}, cb);
}
return cb(error, tenant);
});
}

function createTestUser (userDetails, cb) {
auth.hashPassword(userDetails.plainPassword, function(error, hash) {
if(error) return done(error);
userDetails.password = hash;
usermanager.createUser(userDetails, function(error, user) {
if(error && error instanceof usermanager.errors.DuplicateUserError) {
return usermanager.retrieveUser({email: userDetails.email}, cb);
}
return cb(error, user);
});
});
}

// Assumes any .js file in this folder is a test script
// Skips this file, non-recursive
function testLoader() {
var contents = fs.readdirSync(__dirname);

for(var i = 0, count = contents.length; i < count; i++) {
var item = contents[i];
if(path.join(__dirname, item) === __filename) continue;

var parts = item.split('.');
if(parts.pop() !== 'js') continue;

describe(parts.pop(), function() { require('./' + item) });
}
}

/**
* Entry point
*/
console.log('\n\nRunning mocha test suite');
testLoader();
Loading