mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
Merge pull request #6609 from ErisDS/new-db-upgrade
Rewrite DB update to be explicit
This commit is contained in:
commit
ea9c8235fa
14 changed files with 1288 additions and 441 deletions
|
@ -0,0 +1,18 @@
|
|||
var commands = require('../../schema').commands,
|
||||
db = require('../../db'),
|
||||
|
||||
table = 'users',
|
||||
column = 'tour';
|
||||
|
||||
module.exports = function addTourColumnToUsers(logInfo) {
|
||||
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||
if (exists) {
|
||||
return db.knex.schema.hasColumn(table, column).then(function (exists) {
|
||||
if (!exists) {
|
||||
logInfo('Adding column: ' + table + '.' + column);
|
||||
return commands.addColumn(table, column);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
var commands = require('../../schema').commands,
|
||||
db = require('../../db'),
|
||||
|
||||
table = 'posts_tags',
|
||||
column = 'sort_order';
|
||||
|
||||
module.exports = function addSortOrderColumnToPostsTags(logInfo) {
|
||||
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||
if (exists) {
|
||||
return db.knex.schema.hasColumn(table, column).then(function (exists) {
|
||||
if (!exists) {
|
||||
logInfo('Adding column: ' + table + '.' + column);
|
||||
return commands.addColumn(table, column);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
|
@ -0,0 +1,21 @@
|
|||
var Promise = require('bluebird'),
|
||||
commands = require('../../schema').commands,
|
||||
db = require('../../db'),
|
||||
|
||||
table = 'clients',
|
||||
columns = ['redirection_uri', 'logo', 'status', 'type', 'description'];
|
||||
|
||||
module.exports = function addManyColumnsToClients(logInfo) {
|
||||
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||
if (exists) {
|
||||
return Promise.mapSeries(columns, function (column) {
|
||||
return db.knex.schema.hasColumn(table, column).then(function (exists) {
|
||||
if (!exists) {
|
||||
logInfo('Adding column: ' + table + '.' + column);
|
||||
return commands.addColumn(table, column);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
var commands = require('../../schema').commands,
|
||||
db = require('../../db'),
|
||||
|
||||
table = 'client_trusted_domains';
|
||||
|
||||
module.exports = function addClientTrustedDomainsTable(logInfo) {
|
||||
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||
if (!exists) {
|
||||
logInfo('Creating table: ' + table);
|
||||
return commands.createTable(table);
|
||||
}
|
||||
});
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
var commands = require('../../schema').commands,
|
||||
db = require('../../db'),
|
||||
|
||||
table = 'clients',
|
||||
column = 'secret';
|
||||
|
||||
module.exports = function dropUniqueOnClientsSecret(logInfo) {
|
||||
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||
if (exists) {
|
||||
return commands.getIndexes(table).then(function (indexes) {
|
||||
if (indexes.indexOf(table + '_' + column + '_unique') > -1) {
|
||||
logInfo('Dropping unique on: ' + table + '.' + column);
|
||||
return commands.dropUnique(table, column);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
12
core/server/data/migration/004/index.js
Normal file
12
core/server/data/migration/004/index.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
module.exports = [
|
||||
// Added tour column to users
|
||||
require('./01-add-tour-column-to-users'),
|
||||
// Added sort_order to posts_tags
|
||||
require('./02-add-sortorder-column-to-poststags'),
|
||||
// Added redirection_uri, logo, status, type & description columns to clients
|
||||
require('./03-add-many-columns-to-clients'),
|
||||
// Added client_trusted_domains table
|
||||
require('./04-add-clienttrusteddomains-table'),
|
||||
// Dropped unique index on client secret
|
||||
require('./05-drop-unique-on-clients-secret')
|
||||
];
|
|
@ -1,91 +0,0 @@
|
|||
var _ = require('lodash'),
|
||||
errors = require('../../errors'),
|
||||
commands = require('../schema').commands,
|
||||
schema = require('../schema').tables,
|
||||
|
||||
// private
|
||||
logInfo,
|
||||
|
||||
// public
|
||||
getDeleteCommands,
|
||||
getAddCommands,
|
||||
addColumnCommands,
|
||||
dropColumnCommands,
|
||||
modifyUniqueCommands;
|
||||
|
||||
logInfo = function logInfo(message) {
|
||||
errors.logInfo('Migrations', message);
|
||||
};
|
||||
|
||||
getDeleteCommands = function getDeleteCommands(oldTables, newTables) {
|
||||
var deleteTables = _.difference(oldTables, newTables);
|
||||
return _.map(deleteTables, function (table) {
|
||||
return function () {
|
||||
logInfo('Deleting table: ' + table);
|
||||
return commands.deleteTable(table);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
getAddCommands = function getAddCommands(oldTables, newTables) {
|
||||
var addTables = _.difference(newTables, oldTables);
|
||||
return _.map(addTables, function (table) {
|
||||
return function () {
|
||||
logInfo('Creating table: ' + table);
|
||||
return commands.createTable(table);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
addColumnCommands = function addColumnCommands(table, columns) {
|
||||
var columnKeys = _.keys(schema[table]),
|
||||
addColumns = _.difference(columnKeys, columns);
|
||||
|
||||
return _.map(addColumns, function (column) {
|
||||
return function () {
|
||||
logInfo('Adding column: ' + table + '.' + column);
|
||||
return commands.addColumn(table, column);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
dropColumnCommands = function dropColumnCommands(table, columns) {
|
||||
var columnKeys = _.keys(schema[table]),
|
||||
dropColumns = _.difference(columns, columnKeys);
|
||||
|
||||
return _.map(dropColumns, function (column) {
|
||||
return function () {
|
||||
logInfo('Dropping column: ' + table + '.' + column);
|
||||
return commands.dropColumn(table, column);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
modifyUniqueCommands = function modifyUniqueCommands(table, indexes) {
|
||||
var columnKeys = _.keys(schema[table]);
|
||||
return _.map(columnKeys, function (column) {
|
||||
if (schema[table][column].unique === true) {
|
||||
if (!_.contains(indexes, table + '_' + column + '_unique')) {
|
||||
return function () {
|
||||
logInfo('Adding unique on: ' + table + '.' + column);
|
||||
return commands.addUnique(table, column);
|
||||
};
|
||||
}
|
||||
} else if (!schema[table][column].unique) {
|
||||
if (_.contains(indexes, table + '_' + column + '_unique')) {
|
||||
return function () {
|
||||
logInfo('Dropping unique on: ' + table + '.' + column);
|
||||
return commands.dropUnique(table, column);
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
getDeleteCommands: getDeleteCommands,
|
||||
getAddCommands: getAddCommands,
|
||||
addColumnCommands: addColumnCommands,
|
||||
dropColumnCommands: dropColumnCommands,
|
||||
modifyUniqueCommands: modifyUniqueCommands
|
||||
};
|
|
@ -4,36 +4,14 @@
|
|||
// E.g. if we update to version 004, all the tasks in /004/ are executed
|
||||
|
||||
var sequence = require('../../../utils/sequence'),
|
||||
versioning = require('../../schema').versioning,
|
||||
|
||||
// Private
|
||||
getVersionTasks,
|
||||
modelOptions = {context: {internal: true}},
|
||||
|
||||
// Public
|
||||
update;
|
||||
|
||||
/**
|
||||
* ### Get Version Tasks
|
||||
* Tries to require a directory matching the version number
|
||||
*
|
||||
* This was split from update to make testing easier
|
||||
*
|
||||
* @param {String} version
|
||||
* @param {Function} logInfo
|
||||
* @returns {Array}
|
||||
*/
|
||||
getVersionTasks = function getVersionTasks(version, logInfo) {
|
||||
var tasks = [];
|
||||
|
||||
try {
|
||||
tasks = require('./' + version);
|
||||
} catch (e) {
|
||||
logInfo('No fixture updates found for version', version);
|
||||
}
|
||||
|
||||
return tasks;
|
||||
};
|
||||
|
||||
/**
|
||||
* ## Update
|
||||
* Handles doing subsequent updates for versions
|
||||
|
@ -43,20 +21,20 @@ getVersionTasks = function getVersionTasks(version, logInfo) {
|
|||
* @returns {Promise<*>}
|
||||
*/
|
||||
update = function update(versions, logInfo) {
|
||||
var ops = [];
|
||||
|
||||
logInfo('Updating fixtures');
|
||||
|
||||
versions.forEach(function (version) {
|
||||
var tasks = getVersionTasks(version, logInfo);
|
||||
var ops = versions.reduce(function updateToVersion(ops, version) {
|
||||
var tasks = versioning.getUpdateFixturesTasks(version, logInfo);
|
||||
|
||||
if (tasks && tasks.length > 0) {
|
||||
ops.push(function () {
|
||||
logInfo('Updating fixtures to', version);
|
||||
return sequence(require('./' + version), modelOptions, logInfo);
|
||||
ops.push(function runVersionTasks() {
|
||||
logInfo('Updating fixtures to ', version);
|
||||
return sequence(tasks, modelOptions, logInfo);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return ops;
|
||||
}, []);
|
||||
|
||||
return sequence(ops, modelOptions, logInfo);
|
||||
};
|
||||
|
|
|
@ -44,22 +44,21 @@ init = function (tablesOnly) {
|
|||
return versioning.getDatabaseVersion().then(function (databaseVersion) {
|
||||
var defaultVersion = versioning.getDefaultDatabaseVersion();
|
||||
|
||||
// Update goes first, to allow for FORCE_MIGRATION
|
||||
// 2. The database exists but is out of date
|
||||
if (databaseVersion < defaultVersion || process.env.FORCE_MIGRATION) {
|
||||
// 2. The database exists but is out of date
|
||||
// Migrate to latest version
|
||||
logInfo('Database upgrade required from version ' + databaseVersion + ' to ' + defaultVersion);
|
||||
return update(databaseVersion, defaultVersion, logInfo);
|
||||
}
|
||||
|
||||
if (databaseVersion === defaultVersion) {
|
||||
// 1. The database exists and is up-to-date
|
||||
} else if (databaseVersion === defaultVersion) {
|
||||
logInfo('Up to date at version ' + databaseVersion);
|
||||
// TODO: temporary fix for missing client.secret
|
||||
return fixClientSecret();
|
||||
}
|
||||
|
||||
if (databaseVersion > defaultVersion) {
|
||||
// 3. The database exists but the currentVersion setting does not or cannot be understood
|
||||
} else {
|
||||
// In this case we don't understand the version because it is too high
|
||||
errors.logErrorAndExit(
|
||||
'Your database is not compatible with this version of Ghost',
|
||||
|
@ -75,7 +74,7 @@ init = function (tablesOnly) {
|
|||
}
|
||||
// 3. The database exists but the currentVersion setting does not or cannot be understood
|
||||
// In this case the setting was missing or there was some other problem
|
||||
errors.logErrorAndExit('There is a problem with the database', err.message || err);
|
||||
errors.logErrorAndExit('There is a problem with the database', err.message);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1,67 +1,44 @@
|
|||
// # Update Database
|
||||
// Handles migrating a database between two different database versions
|
||||
var _ = require('lodash'),
|
||||
Promise = require('bluebird'),
|
||||
backup = require('./backup'),
|
||||
builder = require('./builder'),
|
||||
commands = require('../schema').commands,
|
||||
fixtures = require('./fixtures'),
|
||||
schema = require('../schema').tables,
|
||||
sequence = require('../../utils/sequence'),
|
||||
versioning = require('../schema').versioning,
|
||||
|
||||
schemaTables = Object.keys(schema),
|
||||
|
||||
updateDatabaseSchema,
|
||||
|
||||
// Public
|
||||
update;
|
||||
|
||||
/**
|
||||
* ### Update Database Schema
|
||||
* Automatically detect differences between the current DB and the schema, and fix them
|
||||
* TODO refactor to use explicit instructions, as this has the potential to destroy data
|
||||
* Fetch the update tasks for each version, and iterate through them in order
|
||||
*
|
||||
* @param {Array} versions
|
||||
* @param {Function} logInfo
|
||||
* @returns {Promise<*>}
|
||||
*/
|
||||
updateDatabaseSchema = function updateDatabaseSchema(logInfo) {
|
||||
var oldTables,
|
||||
modifyUniCommands = [],
|
||||
migrateOps = [];
|
||||
updateDatabaseSchema = function updateDatabaseSchema(versions, logInfo) {
|
||||
var migrateOps = versions.reduce(function updateToVersion(migrateOps, version) {
|
||||
var tasks = versioning.getUpdateDatabaseTasks(version, logInfo);
|
||||
|
||||
return commands.getTables().then(function (tables) {
|
||||
oldTables = tables;
|
||||
if (!_.isEmpty(oldTables)) {
|
||||
return commands.checkTables();
|
||||
if (tasks && tasks.length > 0) {
|
||||
migrateOps.push(function runVersionTasks() {
|
||||
logInfo('Updating database to ', version);
|
||||
return sequence(tasks, logInfo);
|
||||
});
|
||||
}
|
||||
}).then(function () {
|
||||
migrateOps = migrateOps.concat(builder.getDeleteCommands(oldTables, schemaTables));
|
||||
migrateOps = migrateOps.concat(builder.getAddCommands(oldTables, schemaTables));
|
||||
return Promise.all(
|
||||
_.map(oldTables, function (table) {
|
||||
return commands.getIndexes(table).then(function (indexes) {
|
||||
modifyUniCommands = modifyUniCommands.concat(builder.modifyUniqueCommands(table, indexes));
|
||||
});
|
||||
})
|
||||
);
|
||||
}).then(function () {
|
||||
return Promise.all(
|
||||
_.map(oldTables, function (table) {
|
||||
return commands.getColumns(table).then(function (columns) {
|
||||
migrateOps = migrateOps.concat(builder.dropColumnCommands(table, columns));
|
||||
migrateOps = migrateOps.concat(builder.addColumnCommands(table, columns));
|
||||
});
|
||||
})
|
||||
);
|
||||
}).then(function () {
|
||||
migrateOps = migrateOps.concat(_.compact(modifyUniCommands));
|
||||
|
||||
// execute the commands in sequence
|
||||
if (!_.isEmpty(migrateOps)) {
|
||||
logInfo('Running migrations');
|
||||
return migrateOps;
|
||||
}, []);
|
||||
|
||||
return sequence(migrateOps);
|
||||
}
|
||||
});
|
||||
// execute the commands in sequence
|
||||
if (!_.isEmpty(migrateOps)) {
|
||||
logInfo('Running migrations');
|
||||
}
|
||||
|
||||
return sequence(migrateOps, logInfo);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -80,19 +57,22 @@ update = function update(fromVersion, toVersion, logInfo) {
|
|||
return versioning.showCannotMigrateError();
|
||||
}
|
||||
|
||||
fromVersion = process.env.FORCE_MIGRATION ? versioning.canMigrateFromVersion : fromVersion;
|
||||
|
||||
// Figure out which versions we're updating through.
|
||||
// This shouldn't include the from/current version (which we're already on)
|
||||
var versionsToUpdate = versioning.getMigrationVersions(fromVersion, toVersion).slice(1);
|
||||
|
||||
return backup(logInfo).then(function () {
|
||||
return updateDatabaseSchema(logInfo);
|
||||
return updateDatabaseSchema(versionsToUpdate, logInfo);
|
||||
}).then(function () {
|
||||
// Ensure all of the current default settings are created (these are fixtures, so should be inserted first)
|
||||
return fixtures.ensureDefaultSettings(logInfo);
|
||||
}).then(function () {
|
||||
fromVersion = process.env.FORCE_MIGRATION ? versioning.canMigrateFromVersion : fromVersion;
|
||||
var versions = versioning.getMigrationVersions(fromVersion, toVersion);
|
||||
// Finally, run any updates to the fixtures, including default settings, that are required
|
||||
// for anything other than the from/current version (which we're already on)
|
||||
return fixtures.update(versions.slice(1), logInfo);
|
||||
// Next, run any updates to the fixtures, including default settings, that are required
|
||||
return fixtures.update(versionsToUpdate, logInfo);
|
||||
}).then(function () {
|
||||
// Finally update the databases current version
|
||||
// Finally update the database's current version
|
||||
return versioning.setDatabaseVersion();
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
var db = require('../db'),
|
||||
var path = require('path'),
|
||||
db = require('../db'),
|
||||
errors = require('../../errors'),
|
||||
i18n = require('../../i18n'),
|
||||
defaultSettings = require('./default-settings'),
|
||||
|
@ -72,11 +73,44 @@ function showCannotMigrateError() {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ### Get Version Tasks
|
||||
* Tries to require a directory matching the version number
|
||||
*
|
||||
* This was split from update to make testing easier
|
||||
*
|
||||
* @param {String} version
|
||||
* @param {String} relPath
|
||||
* @param {Function} logInfo
|
||||
* @returns {Array}
|
||||
*/
|
||||
function getVersionTasks(version, relPath, logInfo) {
|
||||
var tasks = [];
|
||||
|
||||
try {
|
||||
tasks = require(path.join(relPath, version));
|
||||
} catch (e) {
|
||||
logInfo('No tasks found for version', version);
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
function getUpdateDatabaseTasks(version, logInfo) {
|
||||
return getVersionTasks(version, '../migration/', logInfo);
|
||||
}
|
||||
|
||||
function getUpdateFixturesTasks(version, logInfo) {
|
||||
return getVersionTasks(version, '../migration/fixtures/', logInfo);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
canMigrateFromVersion: '003',
|
||||
showCannotMigrateError: showCannotMigrateError,
|
||||
getDefaultDatabaseVersion: getDefaultDatabaseVersion,
|
||||
getDatabaseVersion: getDatabaseVersion,
|
||||
setDatabaseVersion: setDatabaseVersion,
|
||||
getMigrationVersions: getMigrationVersions
|
||||
getMigrationVersions: getMigrationVersions,
|
||||
getUpdateDatabaseTasks: getUpdateDatabaseTasks,
|
||||
getUpdateFixturesTasks: getUpdateFixturesTasks
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@ var should = require('should'),
|
|||
configUtils = require('../utils/configUtils'),
|
||||
models = require('../../server/models'),
|
||||
notifications = require('../../server/api/notifications'),
|
||||
versioning = require('../../server/data/schema/versioning'),
|
||||
update = rewire('../../server/data/migration/fixtures/update'),
|
||||
populate = rewire('../../server/data/migration/fixtures/populate'),
|
||||
fixtures004 = require('../../server/data/migration/fixtures/004'),
|
||||
|
@ -28,37 +29,41 @@ describe('Fixtures', function () {
|
|||
});
|
||||
|
||||
describe('Update fixtures', function () {
|
||||
it('should call `getVersionTasks` when upgrading from 003 -> 004', function (done) {
|
||||
it('should call `getUpdateFixturesTasks` when upgrading from 003 -> 004', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
getVersionTasksStub = sandbox.stub().returns([]),
|
||||
reset = update.__set__('getVersionTasks', getVersionTasksStub);
|
||||
getVersionTasksStub = sandbox.stub(versioning, 'getUpdateFixturesTasks').returns([]);
|
||||
|
||||
update(['004'], logStub).then(function () {
|
||||
logStub.calledOnce.should.be.true();
|
||||
getVersionTasksStub.calledOnce.should.be.true();
|
||||
reset();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should NOT call `getVersionTasks` when upgrading from 004 -> 004', function (done) {
|
||||
it('should NOT call `getUpdateFixturesTasks` when upgrading from 004 -> 004', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
getVersionTasksStub = sandbox.stub().returns(Promise.resolve()),
|
||||
reset = update.__set__('getVersionTasks', getVersionTasksStub);
|
||||
getVersionTasksStub = sandbox.stub(versioning, 'getUpdateFixturesTasks').returns([]);
|
||||
|
||||
update([], logStub).then(function () {
|
||||
logStub.calledOnce.should.be.true();
|
||||
getVersionTasksStub.calledOnce.should.be.false();
|
||||
reset();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('`getVersionTasks` returns empty array if no tasks are found', function () {
|
||||
var logStub = sandbox.stub();
|
||||
it('should call tasks in correct order if provided', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
task1Stub = sandbox.stub().returns(Promise.resolve()),
|
||||
task2Stub = sandbox.stub().returns(Promise.resolve()),
|
||||
getVersionTasksStub = sandbox.stub(versioning, 'getUpdateFixturesTasks').returns([task1Stub, task2Stub]);
|
||||
|
||||
update.__get__('getVersionTasks')('999', logStub).should.eql([]);
|
||||
logStub.calledOnce.should.be.true();
|
||||
update(['000'], logStub).then(function () {
|
||||
logStub.calledTwice.should.be.true();
|
||||
getVersionTasksStub.calledOnce.should.be.true();
|
||||
task1Stub.calledOnce.should.be.true();
|
||||
task2Stub.calledOnce.should.be.true();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
describe('Update to 004', function () {
|
||||
|
@ -101,275 +106,277 @@ describe('Fixtures', function () {
|
|||
}).catch(done);
|
||||
});
|
||||
|
||||
describe('01-move-jquery-with-alert', function () {
|
||||
it('tries to move jQuery to ghost_foot', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({
|
||||
attributes: {value: ''}
|
||||
})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
describe('Tasks:', function () {
|
||||
describe('01-move-jquery-with-alert', function () {
|
||||
it('tries to move jQuery to ghost_foot', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({
|
||||
attributes: {value: ''}
|
||||
})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[0]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('ghost_foot').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
fixtures004[0]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('ghost_foot').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
done();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not move jQuery to ghost_foot if it is already there', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({
|
||||
attributes: {
|
||||
value: '<!-- You can safely delete this line if your theme does not require jQuery -->\n'
|
||||
+ '<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>\n\n'
|
||||
}
|
||||
})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[0]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('ghost_foot').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.false();
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('tried to move jQuery AND add a privacy message if any privacy settings are on', function (done) {
|
||||
configUtils.set({privacy: {useGoogleFonts: false}});
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({
|
||||
attributes: {value: ''}
|
||||
})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve()),
|
||||
notificationsAddStub = sandbox.stub(notifications, 'add').returns(Promise.resolve());
|
||||
|
||||
fixtures004[0]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('ghost_foot').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
notificationsAddStub.calledOnce.should.be.true();
|
||||
logStub.calledTwice.should.be.true();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not move jQuery to ghost_foot if it is already there', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({
|
||||
attributes: {
|
||||
value: '<!-- You can safely delete this line if your theme does not require jQuery -->\n'
|
||||
+ '<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>\n\n'
|
||||
}
|
||||
})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
describe('02-update-private-setting-type', function () {
|
||||
it('tries to update setting type correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[0]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('ghost_foot').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.false();
|
||||
logStub.called.should.be.false();
|
||||
fixtures004[1]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('isPrivate').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
settingsEditStub.calledWith({key: 'isPrivate', type: 'private'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(settingsOneStub, logStub, settingsEditStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tried to move jQuery AND add a privacy message if any privacy settings are on', function (done) {
|
||||
configUtils.set({privacy: {useGoogleFonts: false}});
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({
|
||||
attributes: {value: ''}
|
||||
})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve()),
|
||||
notificationsAddStub = sandbox.stub(notifications, 'add').returns(Promise.resolve());
|
||||
describe('03-update-password-setting-type', function () {
|
||||
it('tries to update setting type correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[0]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('ghost_foot').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
notificationsAddStub.calledOnce.should.be.true();
|
||||
logStub.calledTwice.should.be.true();
|
||||
fixtures004[2]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('password').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
settingsEditStub.calledWith({key: 'password', type: 'private'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(settingsOneStub, logStub, settingsEditStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('02-update-private-setting-type', function () {
|
||||
it('tries to update setting type correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[1]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('isPrivate').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
settingsEditStub.calledWith({key: 'isPrivate', type: 'private'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(settingsOneStub, logStub, settingsEditStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('03-update-password-setting-type', function () {
|
||||
it('tries to update setting type correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
settingsOneStub = sandbox.stub(models.Settings, 'findOne').returns(Promise.resolve({})),
|
||||
settingsEditStub = sandbox.stub(models.Settings, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[2]({}, logStub).then(function () {
|
||||
settingsOneStub.calledOnce.should.be.true();
|
||||
settingsOneStub.calledWith('password').should.be.true();
|
||||
settingsEditStub.calledOnce.should.be.true();
|
||||
settingsEditStub.calledWith({key: 'password', type: 'private'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(settingsOneStub, logStub, settingsEditStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('04-update-ghost-admin-client', function () {
|
||||
it('tries to update client correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
clientOneStub = sandbox.stub(models.Client, 'findOne').returns(Promise.resolve({})),
|
||||
clientEditStub = sandbox.stub(models.Client, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[3]({}, logStub).then(function () {
|
||||
clientOneStub.calledOnce.should.be.true();
|
||||
clientOneStub.calledWith({slug: 'ghost-admin'}).should.be.true();
|
||||
clientEditStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(clientOneStub, logStub, clientEditStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('05-add-ghost-frontend-client', function () {
|
||||
it('tries to add client correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
clientOneStub = sandbox.stub(models.Client, 'findOne').returns(Promise.resolve()),
|
||||
clientAddStub = sandbox.stub(models.Client, 'add').returns(Promise.resolve());
|
||||
|
||||
fixtures004[4]({}, logStub).then(function () {
|
||||
clientOneStub.calledOnce.should.be.true();
|
||||
clientOneStub.calledWith({slug: 'ghost-frontend'}).should.be.true();
|
||||
clientAddStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(clientOneStub, logStub, clientAddStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('06-clean-broken-tags', function () {
|
||||
it('tries to clean broken tags correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
tagObjStub = {
|
||||
get: sandbox.stub().returns(',hello'),
|
||||
save: sandbox.stub().returns(Promise.resolve)
|
||||
},
|
||||
tagCollStub = {each: sandbox.stub().callsArgWith(0, tagObjStub)},
|
||||
tagAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(tagCollStub));
|
||||
|
||||
fixtures004[5]({}, logStub).then(function () {
|
||||
tagAllStub.calledOnce.should.be.true();
|
||||
tagCollStub.each.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledWith('name').should.be.true();
|
||||
tagObjStub.save.calledOnce.should.be.true();
|
||||
tagObjStub.save.calledWith({name: 'hello'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(tagAllStub, tagCollStub.each, tagObjStub.get, tagObjStub.save, logStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tries can handle tags which end up empty', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
tagObjStub = {
|
||||
get: sandbox.stub().returns(','),
|
||||
save: sandbox.stub().returns(Promise.resolve)
|
||||
},
|
||||
tagCollStub = {each: sandbox.stub().callsArgWith(0, tagObjStub)},
|
||||
tagAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(tagCollStub));
|
||||
describe('04-update-ghost-admin-client', function () {
|
||||
it('tries to update client correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
clientOneStub = sandbox.stub(models.Client, 'findOne').returns(Promise.resolve({})),
|
||||
clientEditStub = sandbox.stub(models.Client, 'edit').returns(Promise.resolve());
|
||||
|
||||
fixtures004[5]({}, logStub).then(function () {
|
||||
tagAllStub.calledOnce.should.be.true();
|
||||
tagCollStub.each.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledWith('name').should.be.true();
|
||||
tagObjStub.save.calledOnce.should.be.true();
|
||||
tagObjStub.save.calledWith({name: 'tag'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(tagAllStub, tagCollStub.each, tagObjStub.get, tagObjStub.save, logStub);
|
||||
fixtures004[3]({}, logStub).then(function () {
|
||||
clientOneStub.calledOnce.should.be.true();
|
||||
clientOneStub.calledWith({slug: 'ghost-admin'}).should.be.true();
|
||||
clientEditStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(clientOneStub, logStub, clientEditStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tries only changes a tag if necessary', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
tagObjStub = {
|
||||
get: sandbox.stub().returns('hello'),
|
||||
save: sandbox.stub().returns(Promise.resolve)
|
||||
},
|
||||
tagCollStub = {each: sandbox.stub().callsArgWith(0, tagObjStub)},
|
||||
tagAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(tagCollStub));
|
||||
describe('05-add-ghost-frontend-client', function () {
|
||||
it('tries to add client correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
clientOneStub = sandbox.stub(models.Client, 'findOne').returns(Promise.resolve()),
|
||||
clientAddStub = sandbox.stub(models.Client, 'add').returns(Promise.resolve());
|
||||
|
||||
fixtures004[5]({}, logStub).then(function () {
|
||||
tagAllStub.calledOnce.should.be.true();
|
||||
tagCollStub.each.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledWith('name').should.be.true();
|
||||
tagObjStub.save.called.should.be.false();
|
||||
logStub.calledOnce.should.be.false();
|
||||
sinon.assert.callOrder(tagAllStub, tagCollStub.each, tagObjStub.get);
|
||||
fixtures004[4]({}, logStub).then(function () {
|
||||
clientOneStub.calledOnce.should.be.true();
|
||||
clientOneStub.calledWith({slug: 'ghost-frontend'}).should.be.true();
|
||||
clientAddStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(clientOneStub, logStub, clientAddStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('07-add-post-tag-order', function () {
|
||||
it('calls load on each post', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
postObjStub = {
|
||||
load: sandbox.stub().returnsThis()
|
||||
},
|
||||
postCollStub = {mapThen: sandbox.stub().callsArgWith(0, postObjStub)},
|
||||
postAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(postCollStub));
|
||||
|
||||
fixtures004[6]({}, logStub).then(function () {
|
||||
postAllStub.calledOnce.should.be.true();
|
||||
postCollStub.mapThen.calledOnce.should.be.true();
|
||||
postObjStub.load.calledOnce.should.be.true();
|
||||
postObjStub.load.calledWith(['tags']).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(logStub, postAllStub, postCollStub.mapThen, postObjStub.load);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
it('tries to add order to posts_tags', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
postObjStub = {
|
||||
load: sandbox.stub().returnsThis(),
|
||||
related: sandbox.stub().returnsThis(),
|
||||
tags: sandbox.stub().returnsThis(),
|
||||
each: sandbox.stub().callsArgWith(0, {id: 5}),
|
||||
updatePivot: sandbox.stub().returns(Promise.resolve())
|
||||
},
|
||||
postCollStub = {mapThen: sandbox.stub().returns([postObjStub])},
|
||||
postAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(postCollStub));
|
||||
describe('06-clean-broken-tags', function () {
|
||||
it('tries to clean broken tags correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
tagObjStub = {
|
||||
get: sandbox.stub().returns(',hello'),
|
||||
save: sandbox.stub().returns(Promise.resolve)
|
||||
},
|
||||
tagCollStub = {each: sandbox.stub().callsArgWith(0, tagObjStub)},
|
||||
tagAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(tagCollStub));
|
||||
|
||||
fixtures004[6]({}, logStub).then(function () {
|
||||
postAllStub.calledOnce.should.be.true();
|
||||
postCollStub.mapThen.calledOnce.should.be.true();
|
||||
postObjStub.load.called.should.be.false();
|
||||
postObjStub.related.calledOnce.should.be.true();
|
||||
postObjStub.each.calledOnce.should.be.true();
|
||||
postObjStub.tags.calledOnce.should.be.true();
|
||||
postObjStub.updatePivot.calledOnce.should.be.true();
|
||||
logStub.calledThrice.should.be.true();
|
||||
sinon.assert.callOrder(
|
||||
logStub, postAllStub, postCollStub.mapThen, postObjStub.related, postObjStub.each,
|
||||
logStub, postObjStub.tags, postObjStub.updatePivot, logStub
|
||||
);
|
||||
fixtures004[5]({}, logStub).then(function () {
|
||||
tagAllStub.calledOnce.should.be.true();
|
||||
tagCollStub.each.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledWith('name').should.be.true();
|
||||
tagObjStub.save.calledOnce.should.be.true();
|
||||
tagObjStub.save.calledWith({name: 'hello'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(tagAllStub, tagCollStub.each, tagObjStub.get, tagObjStub.save, logStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('tries can handle tags which end up empty', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
tagObjStub = {
|
||||
get: sandbox.stub().returns(','),
|
||||
save: sandbox.stub().returns(Promise.resolve)
|
||||
},
|
||||
tagCollStub = {each: sandbox.stub().callsArgWith(0, tagObjStub)},
|
||||
tagAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(tagCollStub));
|
||||
|
||||
fixtures004[5]({}, logStub).then(function () {
|
||||
tagAllStub.calledOnce.should.be.true();
|
||||
tagCollStub.each.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledWith('name').should.be.true();
|
||||
tagObjStub.save.calledOnce.should.be.true();
|
||||
tagObjStub.save.calledWith({name: 'tag'}).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(tagAllStub, tagCollStub.each, tagObjStub.get, tagObjStub.save, logStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('tries only changes a tag if necessary', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
tagObjStub = {
|
||||
get: sandbox.stub().returns('hello'),
|
||||
save: sandbox.stub().returns(Promise.resolve)
|
||||
},
|
||||
tagCollStub = {each: sandbox.stub().callsArgWith(0, tagObjStub)},
|
||||
tagAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(tagCollStub));
|
||||
|
||||
fixtures004[5]({}, logStub).then(function () {
|
||||
tagAllStub.calledOnce.should.be.true();
|
||||
tagCollStub.each.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledOnce.should.be.true();
|
||||
tagObjStub.get.calledWith('name').should.be.true();
|
||||
tagObjStub.save.called.should.be.false();
|
||||
logStub.calledOnce.should.be.false();
|
||||
sinon.assert.callOrder(tagAllStub, tagCollStub.each, tagObjStub.get);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('08-add-post-fixture', function () {
|
||||
it('tries to add a new post fixture correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
postOneStub = sandbox.stub(models.Post, 'findOne').returns(Promise.resolve()),
|
||||
postAddStub = sandbox.stub(models.Post, 'add').returns(Promise.resolve());
|
||||
describe('07-add-post-tag-order', function () {
|
||||
it('calls load on each post', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
postObjStub = {
|
||||
load: sandbox.stub().returnsThis()
|
||||
},
|
||||
postCollStub = {mapThen: sandbox.stub().callsArgWith(0, postObjStub)},
|
||||
postAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(postCollStub));
|
||||
|
||||
fixtures004[7]({}, logStub).then(function () {
|
||||
postOneStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
postAddStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(postOneStub, logStub, postAddStub);
|
||||
fixtures004[6]({}, logStub).then(function () {
|
||||
postAllStub.calledOnce.should.be.true();
|
||||
postCollStub.mapThen.calledOnce.should.be.true();
|
||||
postObjStub.load.calledOnce.should.be.true();
|
||||
postObjStub.load.calledWith(['tags']).should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(logStub, postAllStub, postCollStub.mapThen, postObjStub.load);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('tries to add order to posts_tags', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
postObjStub = {
|
||||
load: sandbox.stub().returnsThis(),
|
||||
related: sandbox.stub().returnsThis(),
|
||||
tags: sandbox.stub().returnsThis(),
|
||||
each: sandbox.stub().callsArgWith(0, {id: 5}),
|
||||
updatePivot: sandbox.stub().returns(Promise.resolve())
|
||||
},
|
||||
postCollStub = {mapThen: sandbox.stub().returns([postObjStub])},
|
||||
postAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(postCollStub));
|
||||
|
||||
fixtures004[6]({}, logStub).then(function () {
|
||||
postAllStub.calledOnce.should.be.true();
|
||||
postCollStub.mapThen.calledOnce.should.be.true();
|
||||
postObjStub.load.called.should.be.false();
|
||||
postObjStub.related.calledOnce.should.be.true();
|
||||
postObjStub.each.calledOnce.should.be.true();
|
||||
postObjStub.tags.calledOnce.should.be.true();
|
||||
postObjStub.updatePivot.calledOnce.should.be.true();
|
||||
logStub.calledThrice.should.be.true();
|
||||
sinon.assert.callOrder(
|
||||
logStub, postAllStub, postCollStub.mapThen, postObjStub.related, postObjStub.each,
|
||||
logStub, postObjStub.tags, postObjStub.updatePivot, logStub
|
||||
);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('08-add-post-fixture', function () {
|
||||
it('tries to add a new post fixture correctly', function (done) {
|
||||
var logStub = sandbox.stub(),
|
||||
postOneStub = sandbox.stub(models.Post, 'findOne').returns(Promise.resolve()),
|
||||
postAddStub = sandbox.stub(models.Post, 'add').returns(Promise.resolve());
|
||||
|
||||
fixtures004[7]({}, logStub).then(function () {
|
||||
postOneStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
postAddStub.calledOnce.should.be.true();
|
||||
sinon.assert.callOrder(postOneStub, logStub, postAddStub);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +1,27 @@
|
|||
/*globals describe, it, afterEach*/
|
||||
/*globals describe, it, afterEach, beforeEach*/
|
||||
var should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
rewire = require('rewire'),
|
||||
_ = require('lodash'),
|
||||
Promise = require('bluebird'),
|
||||
crypto = require('crypto'),
|
||||
fs = require('fs'),
|
||||
|
||||
// Stuff we are testing
|
||||
db = require('../../server/data/db'),
|
||||
errors = require('../../server/errors/'),
|
||||
exporter = require('../../server/data/export'),
|
||||
fixtures = require('../../server/data/migration/fixtures'),
|
||||
migration = require('../../server/data/migration'),
|
||||
populate = require('../../server/data/migration/populate'),
|
||||
schema = require('../../server/data/schema'),
|
||||
|
||||
// TODO: can go when fixClientSecret is moved
|
||||
models = require('../../server/models'),
|
||||
|
||||
migration = rewire('../../server/data/migration'),
|
||||
fixtures = require('../../server/data/migration/fixtures'),
|
||||
populate = require('../../server/data/migration/populate'),
|
||||
update = rewire('../../server/data/migration/update'),
|
||||
updates004 = require('../../server/data/migration/004'),
|
||||
|
||||
defaultSettings = schema.defaultSettings,
|
||||
schemaTables = Object.keys(schema.tables),
|
||||
|
||||
|
@ -167,7 +176,7 @@ describe('Migrations', function () {
|
|||
settingsStub.calledOnce.should.be.true();
|
||||
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should should only create tables, with tablesOnly setting', function (done) {
|
||||
|
@ -190,11 +199,812 @@ describe('Migrations', function () {
|
|||
settingsStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
});
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update', function () {
|
||||
it('should be tested!');
|
||||
describe('Update function', function () {
|
||||
var reset, backupStub, settingsStub, fixturesStub, setDbStub, errorStub, logStub, versionsSpy;
|
||||
|
||||
beforeEach(function () {
|
||||
// Stubs
|
||||
backupStub = sandbox.stub().returns(new Promise.resolve());
|
||||
settingsStub = sandbox.stub(fixtures, 'ensureDefaultSettings').returns(new Promise.resolve());
|
||||
fixturesStub = sandbox.stub(fixtures, 'update').returns(new Promise.resolve());
|
||||
setDbStub = sandbox.stub(schema.versioning, 'setDatabaseVersion').returns(new Promise.resolve());
|
||||
errorStub = sandbox.stub(schema.versioning, 'showCannotMigrateError').returns(new Promise.resolve());
|
||||
logStub = sandbox.stub();
|
||||
|
||||
// Spys
|
||||
versionsSpy = sandbox.spy(schema.versioning, 'getMigrationVersions');
|
||||
|
||||
// Internal overrides
|
||||
reset = update.__set__('backup', backupStub);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
reset();
|
||||
});
|
||||
|
||||
describe('Pre & post update process', function () {
|
||||
var updateStub, updateReset;
|
||||
|
||||
beforeEach(function () {
|
||||
// For these tests, stub out the actual update task
|
||||
updateStub = sandbox.stub().returns(new Promise.resolve());
|
||||
updateReset = update.__set__('updateDatabaseSchema', updateStub);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
updateReset();
|
||||
});
|
||||
|
||||
it('should attempt to run the pre & post update tasks correctly', function (done) {
|
||||
// Execute
|
||||
update('100', '102', logStub).then(function () {
|
||||
// Before the update, it does some tasks...
|
||||
// It should not show an error for these versions
|
||||
errorStub.called.should.be.false();
|
||||
// getMigrationVersions should be called with the correct versions
|
||||
versionsSpy.calledOnce.should.be.true();
|
||||
versionsSpy.calledWith('100', '102').should.be.true();
|
||||
// It should attempt to do a backup
|
||||
backupStub.calledOnce.should.be.true();
|
||||
|
||||
// Now it's going to try to actually do the update...
|
||||
updateStub.calledOnce.should.be.true();
|
||||
updateStub.calledWith(['101', '102'], logStub).should.be.true();
|
||||
|
||||
// And now there are some final tasks to wrap up...
|
||||
// First, the ensure default settings task
|
||||
settingsStub.calledOnce.should.be.true();
|
||||
// Then fixture updates
|
||||
fixturesStub.calledOnce.should.be.true();
|
||||
// And finally, set the new DB version
|
||||
setDbStub.calledOnce.should.be.true();
|
||||
|
||||
// Because we stubbed everything, logStub didn't get called
|
||||
logStub.called.should.be.false();
|
||||
|
||||
// Just to be sure, lets assert the call order
|
||||
sinon.assert.callOrder(
|
||||
versionsSpy, backupStub, updateStub, settingsStub, fixturesStub, setDbStub
|
||||
);
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should throw error if versions are too old', function (done) {
|
||||
// Execute
|
||||
update('000', '002', logStub).then(function () {
|
||||
// It should show an error for these versions
|
||||
errorStub.called.should.be.true();
|
||||
|
||||
// And so should not do the update...
|
||||
updateStub.calledOnce.should.be.false();
|
||||
|
||||
// Because we stubbed everything, logStub didn't get called
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should upgrade from minimum version, if FORCE_MIGRATION is set', function (done) {
|
||||
// Setup
|
||||
process.env.FORCE_MIGRATION = true;
|
||||
|
||||
// Execute
|
||||
update('005', '006', logStub).then(function () {
|
||||
// It should not show an error for these versions
|
||||
errorStub.called.should.be.false();
|
||||
|
||||
// getMigrationVersions should be called with the correct versions
|
||||
versionsSpy.calledOnce.should.be.true();
|
||||
versionsSpy.calledWith('003', '006').should.be.true();
|
||||
versionsSpy.returned(['003', '004', '005', '006']).should.be.true();
|
||||
|
||||
// It should try to do the update
|
||||
updateStub.calledOnce.should.be.true();
|
||||
updateStub.calledWith(['004', '005', '006']).should.be.true();
|
||||
|
||||
// Because we stubbed everything, logStub didn't get called
|
||||
logStub.called.should.be.false();
|
||||
|
||||
// Restore
|
||||
delete process.env.FORCE_MIGRATION;
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update to 004', function () {
|
||||
var knexStub, knexMock;
|
||||
|
||||
beforeEach(function () {
|
||||
knexMock = sandbox.stub().returns({});
|
||||
knexMock.schema = {
|
||||
hasTable: sandbox.stub(),
|
||||
hasColumn: sandbox.stub()
|
||||
};
|
||||
// this MUST use sinon, not sandbox, see sinonjs/sinon#781
|
||||
knexStub = sinon.stub(db, 'knex', {get: function () { return knexMock; }});
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
knexStub.restore();
|
||||
});
|
||||
|
||||
it('should call all the 004 database upgrades', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub();
|
||||
// stub has table, so that the next action won't happen
|
||||
knexMock.schema.hasTable.withArgs('users').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasTable.withArgs('posts_tags').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasTable.withArgs('clients').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasTable.withArgs('client_trusted_domains').returns(new Promise.resolve(true));
|
||||
|
||||
// Execute
|
||||
update('003', '004', logStub).then(function () {
|
||||
errorStub.called.should.be.false();
|
||||
logStub.calledTwice.should.be.true();
|
||||
|
||||
versionsSpy.calledOnce.should.be.true();
|
||||
versionsSpy.calledWith('003', '004').should.be.true();
|
||||
versionsSpy.returned(['003', '004']).should.be.true();
|
||||
|
||||
knexStub.get.callCount.should.eql(5);
|
||||
knexMock.schema.hasTable.callCount.should.eql(5);
|
||||
knexMock.schema.hasColumn.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
describe('Tasks:', function () {
|
||||
describe('01-add-tour-column-to-users', function () {
|
||||
it('does not try to add a new column if the column already exists', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||
knexMock.schema.hasTable.withArgs('users').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('users', 'tour').returns(new Promise.resolve(true));
|
||||
|
||||
// Execute
|
||||
updates004[0](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||
|
||||
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('users', 'tour').should.be.true();
|
||||
|
||||
addColumnStub.called.should.be.false();
|
||||
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tries to add a new column if table is present but column is not', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||
knexMock.schema.hasTable.withArgs('users').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('users', 'tour').returns(new Promise.resolve(false));
|
||||
|
||||
// Execute
|
||||
updates004[0](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||
|
||||
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('users', 'tour').should.be.true();
|
||||
|
||||
addColumnStub.calledOnce.should.be.true();
|
||||
addColumnStub.calledWith('users', 'tour').should.be.true();
|
||||
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('02-add-sortorder-column-to-poststags', function () {
|
||||
it('does not try to add a new column if the column already exists', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||
knexMock.schema.hasTable.withArgs('posts_tags').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('posts_tags', 'sort_order').returns(new Promise.resolve(true));
|
||||
|
||||
// Execute
|
||||
updates004[1](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('posts_tags').should.be.true();
|
||||
|
||||
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('posts_tags', 'sort_order').should.be.true();
|
||||
|
||||
addColumnStub.called.should.be.false();
|
||||
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tries to add a new column if table is present but column is not', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||
knexMock.schema.hasTable.withArgs('posts_tags').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('posts_tags', 'sort_order').returns(new Promise.resolve(false));
|
||||
|
||||
// Execute
|
||||
updates004[1](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('posts_tags').should.be.true();
|
||||
|
||||
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('posts_tags', 'sort_order').should.be.true();
|
||||
|
||||
addColumnStub.calledOnce.should.be.true();
|
||||
addColumnStub.calledWith('posts_tags', 'sort_order').should.be.true();
|
||||
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('03-add-many-columns-to-clients', function () {
|
||||
it('does not try to add new columns if the columns already exist', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||
knexMock.schema.hasTable.withArgs('clients').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'redirection_uri').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'logo').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'status').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'type').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'description').returns(new Promise.resolve(true));
|
||||
|
||||
// Execute
|
||||
updates004[2](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('clients').should.be.true();
|
||||
|
||||
knexMock.schema.hasColumn.callCount.should.eql(5);
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'redirection_uri').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'logo').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'status').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'type').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'description').should.be.true();
|
||||
|
||||
addColumnStub.called.should.be.false();
|
||||
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tries to add new columns if table is present but columns are not', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||
knexMock.schema.hasTable.withArgs('clients').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'redirection_uri').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'logo').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'status').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'type').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'description').returns(new Promise.resolve(false));
|
||||
|
||||
// Execute
|
||||
updates004[2](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('clients').should.be.true();
|
||||
|
||||
knexMock.schema.hasColumn.callCount.should.eql(5);
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'redirection_uri').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'logo').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'status').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'type').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'description').should.be.true();
|
||||
|
||||
addColumnStub.callCount.should.eql(5);
|
||||
addColumnStub.calledWith('clients', 'redirection_uri').should.be.true();
|
||||
addColumnStub.calledWith('clients', 'logo').should.be.true();
|
||||
addColumnStub.calledWith('clients', 'status').should.be.true();
|
||||
addColumnStub.calledWith('clients', 'type').should.be.true();
|
||||
addColumnStub.calledWith('clients', 'description').should.be.true();
|
||||
|
||||
logStub.callCount.should.eql(5);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('will only try to add columns that do not exist', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||
knexMock.schema.hasTable.withArgs('clients').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'redirection_uri').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'logo').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'status').returns(new Promise.resolve(true));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'type').returns(new Promise.resolve(false));
|
||||
knexMock.schema.hasColumn.withArgs('clients', 'description').returns(new Promise.resolve(true));
|
||||
|
||||
// Execute
|
||||
updates004[2](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('clients').should.be.true();
|
||||
|
||||
knexMock.schema.hasColumn.callCount.should.eql(5);
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'redirection_uri').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'logo').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'status').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'type').should.be.true();
|
||||
knexMock.schema.hasColumn.calledWith('clients', 'description').should.be.true();
|
||||
|
||||
addColumnStub.callCount.should.eql(2);
|
||||
addColumnStub.calledWith('clients', 'logo').should.be.true();
|
||||
addColumnStub.calledWith('clients', 'type').should.be.true();
|
||||
|
||||
logStub.callCount.should.eql(2);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('04-add-clienttrusteddomains-table', function () {
|
||||
it('does not try to add a new table if the table already exists', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
createTableStub = sandbox.stub(schema.commands, 'createTable');
|
||||
|
||||
knexMock.schema.hasTable.withArgs('client_trusted_domains').returns(new Promise.resolve(true));
|
||||
|
||||
// Execute
|
||||
updates004[3](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('client_trusted_domains').should.be.true();
|
||||
|
||||
createTableStub.called.should.be.false();
|
||||
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tries to add a new table if the table does not exist', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
createTableStub = sandbox.stub(schema.commands, 'createTable');
|
||||
|
||||
knexMock.schema.hasTable.withArgs('client_trusted_domains').returns(new Promise.resolve(false));
|
||||
|
||||
// Execute
|
||||
updates004[3](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('client_trusted_domains').should.be.true();
|
||||
|
||||
createTableStub.calledOnce.should.be.true();
|
||||
createTableStub.calledWith('client_trusted_domains').should.be.true();
|
||||
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('05-drop-unique-on-clients-secret', function () {
|
||||
it('does not try to drop unique if the table does not exist', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
getIndexesStub = sandbox.stub(schema.commands, 'getIndexes'),
|
||||
dropUniqueStub = sandbox.stub(schema.commands, 'dropUnique');
|
||||
|
||||
getIndexesStub.withArgs('clients').returns(new Promise.resolve(
|
||||
['clients_slug_unique', 'clients_name_unique', 'clients_secret_unique'])
|
||||
);
|
||||
knexMock.schema.hasTable.withArgs('clients').returns(new Promise.resolve(false));
|
||||
|
||||
// Execute
|
||||
updates004[4](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('clients').should.be.true();
|
||||
|
||||
getIndexesStub.called.should.be.false();
|
||||
|
||||
dropUniqueStub.called.should.be.false();
|
||||
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not try to drop unique if the index does not exist', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
getIndexesStub = sandbox.stub(schema.commands, 'getIndexes'),
|
||||
dropUniqueStub = sandbox.stub(schema.commands, 'dropUnique');
|
||||
|
||||
knexMock.schema.hasTable.withArgs('clients').returns(new Promise.resolve(true));
|
||||
|
||||
getIndexesStub.withArgs('clients').returns(new Promise.resolve(
|
||||
['clients_slug_unique', 'clients_name_unique'])
|
||||
);
|
||||
|
||||
// Execute
|
||||
updates004[4](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('clients').should.be.true();
|
||||
|
||||
getIndexesStub.calledOnce.should.be.true();
|
||||
getIndexesStub.calledWith('clients').should.be.true();
|
||||
|
||||
dropUniqueStub.called.should.be.false();
|
||||
|
||||
logStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('tries to add a drop unique if table and index both exist', function (done) {
|
||||
// Setup
|
||||
var logStub = sandbox.stub(),
|
||||
getIndexesStub = sandbox.stub(schema.commands, 'getIndexes'),
|
||||
dropUniqueStub = sandbox.stub(schema.commands, 'dropUnique');
|
||||
|
||||
knexMock.schema.hasTable.withArgs('clients').returns(new Promise.resolve(true));
|
||||
|
||||
getIndexesStub.withArgs('clients').returns(new Promise.resolve(
|
||||
['clients_slug_unique', 'clients_name_unique', 'clients_secret_unique'])
|
||||
);
|
||||
|
||||
// Execute
|
||||
updates004[4](logStub).then(function () {
|
||||
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||
knexMock.schema.hasTable.calledWith('clients').should.be.true();
|
||||
|
||||
getIndexesStub.calledOnce.should.be.true();
|
||||
getIndexesStub.calledWith('clients').should.be.true();
|
||||
|
||||
dropUniqueStub.calledOnce.should.be.true();
|
||||
dropUniqueStub.calledWith('clients', 'secret').should.be.true();
|
||||
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Update Database Schema', function () {
|
||||
it('should not do anything if there are no tasks', function (done) {
|
||||
var updateDatabaseSchema = update.__get__('updateDatabaseSchema'),
|
||||
getVersionTasksStub = sandbox.stub(schema.versioning, 'getUpdateDatabaseTasks').returns([]),
|
||||
logStub = sandbox.stub();
|
||||
|
||||
updateDatabaseSchema(['001'], logStub).then(function () {
|
||||
getVersionTasksStub.calledOnce.should.be.true();
|
||||
logStub.called.should.be.false();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should call the tasks if they are provided', function (done) {
|
||||
var updateDatabaseSchema = update.__get__('updateDatabaseSchema'),
|
||||
task1Stub = sandbox.stub().returns(new Promise.resolve()),
|
||||
task2Stub = sandbox.stub().returns(new Promise.resolve()),
|
||||
getVersionTasksStub = sandbox.stub(schema.versioning, 'getUpdateDatabaseTasks').returns([task1Stub, task2Stub]),
|
||||
logStub = sandbox.stub();
|
||||
|
||||
updateDatabaseSchema(['001'], logStub).then(function () {
|
||||
getVersionTasksStub.calledOnce.should.be.true();
|
||||
task1Stub.calledOnce.should.be.true();
|
||||
task2Stub.calledOnce.should.be.true();
|
||||
logStub.calledTwice.should.be.true();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Init', function () {
|
||||
var defaultVersionStub, databaseVersionStub, logStub, errorStub, updateStub, populateStub, fixSecretStub,
|
||||
resetLog, resetUpdate, resetPopulate, resetFixSecret;
|
||||
|
||||
beforeEach(function () {
|
||||
defaultVersionStub = sandbox.stub(schema.versioning, 'getDefaultDatabaseVersion');
|
||||
databaseVersionStub = sandbox.stub(schema.versioning, 'getDatabaseVersion');
|
||||
errorStub = sandbox.stub(errors, 'logErrorAndExit');
|
||||
updateStub = sandbox.stub();
|
||||
populateStub = sandbox.stub();
|
||||
fixSecretStub = sandbox.stub();
|
||||
logStub = sandbox.stub();
|
||||
|
||||
resetLog = migration.__set__('logInfo', logStub);
|
||||
resetUpdate = migration.__set__('update', updateStub);
|
||||
resetPopulate = migration.__set__('populate', populateStub);
|
||||
resetFixSecret = migration.__set__('fixClientSecret', fixSecretStub);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
resetLog();
|
||||
resetUpdate();
|
||||
resetPopulate();
|
||||
resetFixSecret();
|
||||
});
|
||||
|
||||
it('should do an UPDATE if default version is higher', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('005');
|
||||
databaseVersionStub.returns(new Promise.resolve('004'));
|
||||
|
||||
// Execute
|
||||
migration.init().then(function () {
|
||||
defaultVersionStub.calledOnce.should.be.true();
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
updateStub.calledOnce.should.be.true();
|
||||
updateStub.calledWith('004', '005', logStub).should.be.true();
|
||||
|
||||
errorStub.called.should.be.false();
|
||||
populateStub.called.should.be.false();
|
||||
fixSecretStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should do an UPDATE if default version is significantly higher', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('010');
|
||||
databaseVersionStub.returns(new Promise.resolve('004'));
|
||||
|
||||
// Execute
|
||||
migration.init().then(function () {
|
||||
defaultVersionStub.calledOnce.should.be.true();
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
updateStub.calledOnce.should.be.true();
|
||||
updateStub.calledWith('004', '010', logStub).should.be.true();
|
||||
|
||||
errorStub.called.should.be.false();
|
||||
populateStub.called.should.be.false();
|
||||
fixSecretStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should do FIX SECRET if versions are the same', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('004');
|
||||
databaseVersionStub.returns(new Promise.resolve('004'));
|
||||
|
||||
// Execute
|
||||
migration.init().then(function () {
|
||||
defaultVersionStub.calledOnce.should.be.true();
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
fixSecretStub.called.should.be.true();
|
||||
|
||||
errorStub.called.should.be.false();
|
||||
updateStub.called.should.be.false();
|
||||
populateStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should do an UPDATE even if versions are the same, when FORCE_MIGRATION set', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('004');
|
||||
databaseVersionStub.returns(new Promise.resolve('004'));
|
||||
process.env.FORCE_MIGRATION = true;
|
||||
|
||||
// Execute
|
||||
migration.init().then(function () {
|
||||
defaultVersionStub.calledOnce.should.be.true();
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
updateStub.calledOnce.should.be.true();
|
||||
updateStub.calledWith('004', '004', logStub).should.be.true();
|
||||
|
||||
errorStub.called.should.be.false();
|
||||
populateStub.called.should.be.false();
|
||||
fixSecretStub.called.should.be.false();
|
||||
|
||||
delete process.env.FORCE_MIGRATION;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should do a POPULATE if settings table does not exist', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('004');
|
||||
databaseVersionStub.returns(new Promise.reject(new Error('Settings table does not exist')));
|
||||
|
||||
// Execute
|
||||
migration.init().then(function () {
|
||||
defaultVersionStub.calledOnce.should.be.true();
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
populateStub.called.should.be.true();
|
||||
populateStub.calledWith(logStub, false).should.be.true();
|
||||
|
||||
errorStub.called.should.be.false();
|
||||
updateStub.called.should.be.false();
|
||||
fixSecretStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should do a POPULATE with TABLES ONLY if settings table does not exist & tablesOnly is set', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('004');
|
||||
databaseVersionStub.returns(new Promise.reject(new Error('Settings table does not exist')));
|
||||
|
||||
// Execute
|
||||
migration.init(true).then(function () {
|
||||
defaultVersionStub.calledOnce.should.be.true();
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.true();
|
||||
|
||||
populateStub.called.should.be.true();
|
||||
populateStub.calledWith(logStub, true).should.be.true();
|
||||
|
||||
errorStub.called.should.be.false();
|
||||
updateStub.called.should.be.false();
|
||||
fixSecretStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should throw an error if the database version is higher than the default', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('004');
|
||||
databaseVersionStub.returns(new Promise.resolve('010'));
|
||||
|
||||
// Execute
|
||||
migration.init().then(function () {
|
||||
defaultVersionStub.calledOnce.should.be.true();
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.false();
|
||||
errorStub.calledOnce.should.be.true();
|
||||
|
||||
populateStub.called.should.be.false();
|
||||
updateStub.called.should.be.false();
|
||||
fixSecretStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should throw an error if the database version returns an error other than settings not existing', function (done) {
|
||||
// Setup
|
||||
defaultVersionStub.returns('004');
|
||||
databaseVersionStub.returns(new Promise.reject(new Error('Something went wrong')));
|
||||
|
||||
// Execute
|
||||
migration.init().then(function () {
|
||||
databaseVersionStub.calledOnce.should.be.true();
|
||||
logStub.calledOnce.should.be.false();
|
||||
errorStub.calledOnce.should.be.true();
|
||||
|
||||
defaultVersionStub.calledOnce.should.be.false();
|
||||
populateStub.called.should.be.false();
|
||||
updateStub.called.should.be.false();
|
||||
fixSecretStub.called.should.be.false();
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('LogInfo', function () {
|
||||
it('should output an info message prefixed with "Migrations"', function () {
|
||||
var logInfo = migration.__get__('logInfo'),
|
||||
errorsStub = sandbox.stub(errors, 'logInfo');
|
||||
|
||||
logInfo('Stuff');
|
||||
|
||||
errorsStub.calledOnce.should.be.true();
|
||||
errorsStub.calledWith('Migrations', 'Stuff').should.be.true();
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: move this to 005!!
|
||||
describe('FixClientSecret', function () {
|
||||
var fixClientSecret, queryStub, clientForgeStub, clientEditStub, toStringStub, cryptoStub;
|
||||
|
||||
beforeEach(function (done) {
|
||||
fixClientSecret = migration.__get__('fixClientSecret');
|
||||
queryStub = {
|
||||
query: sandbox.stub().returnsThis(),
|
||||
fetch: sandbox.stub()
|
||||
};
|
||||
|
||||
models.init().then(function () {
|
||||
toStringStub = {toString: sandbox.stub().returns('TEST')};
|
||||
cryptoStub = sandbox.stub(crypto, 'randomBytes').returns(toStringStub);
|
||||
clientForgeStub = sandbox.stub(models.Clients, 'forge').returns(queryStub);
|
||||
clientEditStub = sandbox.stub(models.Client, 'edit');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should do nothing if there are no incorrect secrets', function (done) {
|
||||
// Setup
|
||||
queryStub.fetch.returns(new Promise.resolve({models: []}));
|
||||
|
||||
// Execute
|
||||
fixClientSecret().then(function () {
|
||||
clientForgeStub.calledOnce.should.be.true();
|
||||
clientEditStub.called.should.be.false();
|
||||
toStringStub.toString.called.should.be.false();
|
||||
cryptoStub.called.should.be.false();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should try to fix any incorrect secrets', function (done) {
|
||||
// Setup
|
||||
queryStub.fetch.returns(new Promise.resolve({models: [{id: 1}]}));
|
||||
|
||||
// Execute
|
||||
fixClientSecret().then(function () {
|
||||
clientForgeStub.calledOnce.should.be.true();
|
||||
clientEditStub.called.should.be.true();
|
||||
toStringStub.toString.called.should.be.false();
|
||||
cryptoStub.called.should.be.false();
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should try to create a new secret, if the mode is not testing', function (done) {
|
||||
// Setup
|
||||
var envTemp = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = 'development';
|
||||
queryStub.fetch.returns(new Promise.resolve({models: [{id: 1}]}));
|
||||
|
||||
// Execute
|
||||
fixClientSecret().then(function () {
|
||||
clientForgeStub.calledOnce.should.be.true();
|
||||
clientEditStub.called.should.be.true();
|
||||
toStringStub.toString.called.should.be.true();
|
||||
cryptoStub.calledOnce.should.be.true();
|
||||
|
||||
// reset
|
||||
process.env.NODE_ENV = envTemp;
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -200,4 +200,34 @@ describe('Versioning', function () {
|
|||
).should.be.true();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUpdateTasks', function () {
|
||||
it('`getUpdateFixturesTasks` returns empty array if no tasks are found', function () {
|
||||
var logStub = sandbox.stub();
|
||||
|
||||
versioning.getUpdateFixturesTasks('999', logStub).should.eql([]);
|
||||
logStub.calledOnce.should.be.true();
|
||||
});
|
||||
|
||||
it('`getUpdateFixturesTasks` returns 8 items for 004', function () {
|
||||
var logStub = sandbox.stub();
|
||||
|
||||
versioning.getUpdateFixturesTasks('004', logStub).should.be.an.Array().with.lengthOf(8);
|
||||
logStub.calledOnce.should.be.false();
|
||||
});
|
||||
|
||||
it('`getUpdateDatabaseTasks` returns empty array if no tasks are found', function () {
|
||||
var logStub = sandbox.stub();
|
||||
|
||||
versioning.getUpdateDatabaseTasks('999', logStub).should.eql([]);
|
||||
logStub.calledOnce.should.be.true();
|
||||
});
|
||||
|
||||
it('`getUpdateDatabaseTasks` returns 5 items for 004', function () {
|
||||
var logStub = sandbox.stub();
|
||||
|
||||
versioning.getUpdateDatabaseTasks('004', logStub).should.be.an.Array().with.lengthOf(5);
|
||||
logStub.calledOnce.should.be.false();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue