mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
Merge pull request #6628 from ErisDS/migration-005
Data & Fixture Migrations v005
This commit is contained in:
commit
817a302885
17 changed files with 958 additions and 135 deletions
|
@ -0,0 +1,24 @@
|
||||||
|
var commands = require('../../schema').commands,
|
||||||
|
db = require('../../db'),
|
||||||
|
|
||||||
|
table = 'tags',
|
||||||
|
column = 'hidden',
|
||||||
|
message = 'Removing column: ' + table + '.' + column;
|
||||||
|
|
||||||
|
module.exports = function dropHiddenColumnFromTags(logger) {
|
||||||
|
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||||
|
if (exists) {
|
||||||
|
return db.knex.schema.hasColumn(table, column).then(function (exists) {
|
||||||
|
if (exists) {
|
||||||
|
logger.info(message);
|
||||||
|
return commands.dropColumn(table, column);
|
||||||
|
} else {
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// @TODO: this should probably be an error
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
var Promise = require('bluebird'),
|
||||||
|
commands = require('../../schema').commands,
|
||||||
|
db = require('../../db'),
|
||||||
|
|
||||||
|
tables = ['posts', 'tags', 'users'],
|
||||||
|
column = 'visibility';
|
||||||
|
|
||||||
|
module.exports = function addVisibilityColumnToKeyTables(logger) {
|
||||||
|
return Promise.mapSeries(tables, function (table) {
|
||||||
|
var message = 'Adding column: ' + table + '.' + column;
|
||||||
|
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||||
|
if (exists) {
|
||||||
|
return db.knex.schema.hasColumn(table, column).then(function (exists) {
|
||||||
|
if (!exists) {
|
||||||
|
logger.info(message);
|
||||||
|
return commands.addColumn(table, column);
|
||||||
|
} else {
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// @TODO: this should probably be an error
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
var commands = require('../../schema').commands,
|
||||||
|
db = require('../../db'),
|
||||||
|
|
||||||
|
table = 'posts',
|
||||||
|
column = 'mobiledoc',
|
||||||
|
message = 'Adding column: ' + table + '.' + column;
|
||||||
|
|
||||||
|
module.exports = function addMobiledocColumnToPosts(logger) {
|
||||||
|
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||||
|
if (exists) {
|
||||||
|
return db.knex.schema.hasColumn(table, column).then(function (exists) {
|
||||||
|
if (!exists) {
|
||||||
|
logger.info(message);
|
||||||
|
return commands.addColumn(table, column);
|
||||||
|
} else {
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// @TODO: this should probably be an error
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
var Promise = require('bluebird'),
|
||||||
|
commands = require('../../schema').commands,
|
||||||
|
db = require('../../db'),
|
||||||
|
|
||||||
|
table = 'users',
|
||||||
|
columns = ['facebook', 'twitter'];
|
||||||
|
|
||||||
|
module.exports = function addSocialMediaColumnsToUsers(logger) {
|
||||||
|
return db.knex.schema.hasTable(table).then(function (exists) {
|
||||||
|
if (exists) {
|
||||||
|
return Promise.mapSeries(columns, function (column) {
|
||||||
|
var message = 'Adding column: ' + table + '.' + column;
|
||||||
|
return db.knex.schema.hasColumn(table, column).then(function (exists) {
|
||||||
|
if (!exists) {
|
||||||
|
logger.info(message);
|
||||||
|
return commands.addColumn(table, column);
|
||||||
|
} else {
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// @TODO: this should probably be an error
|
||||||
|
logger.warn('Adding columns to table: ' + table);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
11
core/server/data/migration/005/index.js
Normal file
11
core/server/data/migration/005/index.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module.exports = [
|
||||||
|
// Drop hidden column from tags table
|
||||||
|
require('./01-drop-hidden-column-from-tags'),
|
||||||
|
// Add visibility column to posts, tags, and users tables
|
||||||
|
require('./02-add-visibility-column-to-key-tables'),
|
||||||
|
// Add mobiledoc column to posts
|
||||||
|
require('./03-add-mobiledoc-column-to-posts'),
|
||||||
|
// Add social media columns to isers
|
||||||
|
require('./04-add-social-media-columns-to-users')
|
||||||
|
|
||||||
|
];
|
|
@ -0,0 +1,26 @@
|
||||||
|
// Update the `ghost-*` clients so that they definitely have a proper secret
|
||||||
|
var models = require('../../../../models'),
|
||||||
|
_ = require('lodash'),
|
||||||
|
Promise = require('bluebird'),
|
||||||
|
crypto = require('crypto'),
|
||||||
|
|
||||||
|
message = 'Updating client secret';
|
||||||
|
|
||||||
|
module.exports = function updateGhostClientsSecrets(options, logger) {
|
||||||
|
return models.Clients.forge().query('where', 'secret', '=', 'not_available').fetch().then(function (results) {
|
||||||
|
if (results.models.length === 0) {
|
||||||
|
logger.warn(message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.map(results.models, function mapper(client) {
|
||||||
|
logger.info(message + ' (' + client.slug + ')');
|
||||||
|
client.secret = crypto.randomBytes(6).toString('hex');
|
||||||
|
|
||||||
|
return models.Client.edit(
|
||||||
|
_.extend({}, client, {secret: crypto.randomBytes(6).toString('hex')},
|
||||||
|
_.extend({}, options, {id: client.id}))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Create a new `ghost-scheduler` client for use in themes
|
||||||
|
var models = require('../../../../models'),
|
||||||
|
|
||||||
|
schedulerClient = require('../utils').findModelFixtureEntry('Client', {slug: 'ghost-scheduler'}),
|
||||||
|
message = 'Add ghost-scheduler client fixture';
|
||||||
|
|
||||||
|
module.exports = function addGhostFrontendClient(options, logger) {
|
||||||
|
return models.Client.findOne({slug: schedulerClient.slug}).then(function (client) {
|
||||||
|
if (!client) {
|
||||||
|
logger.info(message);
|
||||||
|
return models.Client.add(schedulerClient, options);
|
||||||
|
} else {
|
||||||
|
logger.warn(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Update the permissions & permissions_roles tables to get the new entries
|
||||||
|
var utils = require('../utils');
|
||||||
|
|
||||||
|
function getClientPermissions() {
|
||||||
|
return utils.findModelFixtures('Permission', {object_type: 'client'});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClientRelations() {
|
||||||
|
return utils.findPermissionRelationsForObject('client');
|
||||||
|
}
|
||||||
|
|
||||||
|
function printResult(logger, result, message) {
|
||||||
|
if (result.done === result.expected) {
|
||||||
|
logger.info(message);
|
||||||
|
} else {
|
||||||
|
logger.warn('(' + result.done + '/' + result.expected + ') ' + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function addClientPermissions(options, logger) {
|
||||||
|
var modelToAdd = getClientPermissions(),
|
||||||
|
relationToAdd = getClientRelations();
|
||||||
|
|
||||||
|
return utils.addFixturesForModel(modelToAdd).then(function (result) {
|
||||||
|
printResult(logger, result, 'Adding permissions fixtures for clients');
|
||||||
|
return utils.addFixturesForRelation(relationToAdd);
|
||||||
|
}).then(function (result) {
|
||||||
|
printResult(logger, result, 'Adding permissions_roles fixtures for clients');
|
||||||
|
});
|
||||||
|
};
|
8
core/server/data/migration/fixtures/005/index.js
Normal file
8
core/server/data/migration/fixtures/005/index.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = [
|
||||||
|
// add jquery setting and privacy info
|
||||||
|
require('./01-update-ghost-client-secrets'),
|
||||||
|
// add ghost-scheduler client
|
||||||
|
require('./02-add-ghost-scheduler-client'),
|
||||||
|
// add client permissions and permission_role relations
|
||||||
|
require('./03-add-client-permissions')
|
||||||
|
];
|
|
@ -42,6 +42,12 @@
|
||||||
"name": "Ghost Frontend",
|
"name": "Ghost Frontend",
|
||||||
"slug": "ghost-frontend",
|
"slug": "ghost-frontend",
|
||||||
"status": "enabled"
|
"status": "enabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Ghost Scheduler",
|
||||||
|
"slug": "ghost-scheduler",
|
||||||
|
"status": "enabled",
|
||||||
|
"type": "web"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -218,6 +224,31 @@
|
||||||
"name": "Browse roles",
|
"name": "Browse roles",
|
||||||
"action_type": "browse",
|
"action_type": "browse",
|
||||||
"object_type": "role"
|
"object_type": "role"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Browse clients",
|
||||||
|
"action_type": "browse",
|
||||||
|
"object_type": "client"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Read clients",
|
||||||
|
"action_type": "read",
|
||||||
|
"object_type": "client"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Edit clients",
|
||||||
|
"action_type": "edit",
|
||||||
|
"object_type": "client"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Add clients",
|
||||||
|
"action_type": "add",
|
||||||
|
"object_type": "client"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Delete clients",
|
||||||
|
"action_type": "destroy",
|
||||||
|
"object_type": "client"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -245,7 +276,8 @@
|
||||||
"tag": "all",
|
"tag": "all",
|
||||||
"theme": "all",
|
"theme": "all",
|
||||||
"user": "all",
|
"user": "all",
|
||||||
"role": "all"
|
"role": "all",
|
||||||
|
"client": "all"
|
||||||
},
|
},
|
||||||
"Editor": {
|
"Editor": {
|
||||||
"post": "all",
|
"post": "all",
|
||||||
|
@ -253,7 +285,8 @@
|
||||||
"slug": "all",
|
"slug": "all",
|
||||||
"tag": "all",
|
"tag": "all",
|
||||||
"user": "all",
|
"user": "all",
|
||||||
"role": "all"
|
"role": "all",
|
||||||
|
"client": "all"
|
||||||
},
|
},
|
||||||
"Author": {
|
"Author": {
|
||||||
"post": ["browse", "read", "add"],
|
"post": ["browse", "read", "add"],
|
||||||
|
@ -261,7 +294,8 @@
|
||||||
"slug": "all",
|
"slug": "all",
|
||||||
"tag": ["browse", "read", "add"],
|
"tag": ["browse", "read", "add"],
|
||||||
"user": ["browse", "read"],
|
"user": ["browse", "read"],
|
||||||
"role": ["browse"]
|
"role": ["browse"],
|
||||||
|
"client": "all"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
var Promise = require('bluebird'),
|
var versioning = require('../schema').versioning,
|
||||||
crypto = require('crypto'),
|
|
||||||
versioning = require('../schema').versioning,
|
|
||||||
errors = require('../../errors'),
|
errors = require('../../errors'),
|
||||||
models = require('../../models'),
|
|
||||||
|
|
||||||
// private
|
// private
|
||||||
logger,
|
logger,
|
||||||
fixClientSecret,
|
|
||||||
populate = require('./populate'),
|
populate = require('./populate'),
|
||||||
update = require('./update'),
|
update = require('./update'),
|
||||||
|
|
||||||
|
@ -28,21 +24,8 @@ logger = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: move to migration.to005() for next DB version
|
|
||||||
fixClientSecret = function () {
|
|
||||||
return models.Clients.forge().query('where', 'secret', '=', 'not_available').fetch().then(function updateClients(results) {
|
|
||||||
return Promise.map(results.models, function mapper(client) {
|
|
||||||
if (process.env.NODE_ENV.indexOf('testing') !== 0) {
|
|
||||||
logger.info('Updating client secret');
|
|
||||||
client.secret = crypto.randomBytes(6).toString('hex');
|
|
||||||
}
|
|
||||||
return models.Client.edit(client, {context: {internal: true}, id: client.id});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check for whether data is needed to be bootstrapped or not
|
// Check for whether data is needed to be bootstrapped or not
|
||||||
init = function (tablesOnly) {
|
init = function init(tablesOnly) {
|
||||||
tablesOnly = tablesOnly || false;
|
tablesOnly = tablesOnly || false;
|
||||||
|
|
||||||
// There are 4 possibilities:
|
// There are 4 possibilities:
|
||||||
|
@ -63,8 +46,7 @@ init = function (tablesOnly) {
|
||||||
// 1. The database exists and is up-to-date
|
// 1. The database exists and is up-to-date
|
||||||
} else if (databaseVersion === defaultVersion) {
|
} else if (databaseVersion === defaultVersion) {
|
||||||
logger.info('Up-to-date at version ' + databaseVersion);
|
logger.info('Up-to-date at version ' + databaseVersion);
|
||||||
// TODO: temporary fix for missing client.secret
|
return;
|
||||||
return fixClientSecret();
|
|
||||||
|
|
||||||
// 3. The database exists but the currentVersion setting does not or cannot be understood
|
// 3. The database exists but the currentVersion setting does not or cannot be understood
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"core": {
|
"core": {
|
||||||
"databaseVersion": {
|
"databaseVersion": {
|
||||||
"defaultValue": "004"
|
"defaultValue": "005"
|
||||||
},
|
},
|
||||||
"dbHash": {
|
"dbHash": {
|
||||||
"defaultValue": null
|
"defaultValue": null
|
||||||
|
|
|
@ -5,12 +5,14 @@ module.exports = {
|
||||||
title: {type: 'string', maxlength: 150, nullable: false},
|
title: {type: 'string', maxlength: 150, nullable: false},
|
||||||
slug: {type: 'string', maxlength: 150, nullable: false, unique: true},
|
slug: {type: 'string', maxlength: 150, nullable: false, unique: true},
|
||||||
markdown: {type: 'text', maxlength: 16777215, fieldtype: 'medium', nullable: true},
|
markdown: {type: 'text', maxlength: 16777215, fieldtype: 'medium', nullable: true},
|
||||||
|
mobiledoc: {type: 'text', maxlength: 1000000000, fieldtype: 'long', nullable: true},
|
||||||
html: {type: 'text', maxlength: 16777215, fieldtype: 'medium', nullable: true},
|
html: {type: 'text', maxlength: 16777215, fieldtype: 'medium', nullable: true},
|
||||||
image: {type: 'text', maxlength: 2000, nullable: true},
|
image: {type: 'text', maxlength: 2000, nullable: true},
|
||||||
featured: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
|
featured: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
|
||||||
page: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
|
page: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
|
||||||
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'draft'},
|
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'draft'},
|
||||||
language: {type: 'string', maxlength: 6, nullable: false, defaultTo: 'en_US'},
|
language: {type: 'string', maxlength: 6, nullable: false, defaultTo: 'en_US'},
|
||||||
|
visibility: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'public', validations: {isIn: [['public']]}},
|
||||||
meta_title: {type: 'string', maxlength: 150, nullable: true},
|
meta_title: {type: 'string', maxlength: 150, nullable: true},
|
||||||
meta_description: {type: 'string', maxlength: 200, nullable: true},
|
meta_description: {type: 'string', maxlength: 200, nullable: true},
|
||||||
author_id: {type: 'integer', nullable: false},
|
author_id: {type: 'integer', nullable: false},
|
||||||
|
@ -33,9 +35,12 @@ module.exports = {
|
||||||
bio: {type: 'string', maxlength: 200, nullable: true},
|
bio: {type: 'string', maxlength: 200, nullable: true},
|
||||||
website: {type: 'text', maxlength: 2000, nullable: true, validations: {isEmptyOrURL: true}},
|
website: {type: 'text', maxlength: 2000, nullable: true, validations: {isEmptyOrURL: true}},
|
||||||
location: {type: 'text', maxlength: 65535, nullable: true},
|
location: {type: 'text', maxlength: 65535, nullable: true},
|
||||||
|
facebook: {type: 'text', maxlength: 2000, nullable: true, validations: {isEmptyOrURL: true}},
|
||||||
|
twitter: {type: 'text', maxlength: 2000, nullable: true, validations: {isEmptyOrURL: true}},
|
||||||
accessibility: {type: 'text', maxlength: 65535, nullable: true},
|
accessibility: {type: 'text', maxlength: 65535, nullable: true},
|
||||||
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'active'},
|
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'active'},
|
||||||
language: {type: 'string', maxlength: 6, nullable: false, defaultTo: 'en_US'},
|
language: {type: 'string', maxlength: 6, nullable: false, defaultTo: 'en_US'},
|
||||||
|
visibility: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'public', validations: {isIn: [['public']]}},
|
||||||
meta_title: {type: 'string', maxlength: 150, nullable: true},
|
meta_title: {type: 'string', maxlength: 150, nullable: true},
|
||||||
meta_description: {type: 'string', maxlength: 200, nullable: true},
|
meta_description: {type: 'string', maxlength: 200, nullable: true},
|
||||||
tour: {type: 'text', maxlength: 65535, nullable: true},
|
tour: {type: 'text', maxlength: 65535, nullable: true},
|
||||||
|
@ -105,8 +110,8 @@ module.exports = {
|
||||||
slug: {type: 'string', maxlength: 150, nullable: false, unique: true},
|
slug: {type: 'string', maxlength: 150, nullable: false, unique: true},
|
||||||
description: {type: 'string', maxlength: 200, nullable: true},
|
description: {type: 'string', maxlength: 200, nullable: true},
|
||||||
image: {type: 'text', maxlength: 2000, nullable: true},
|
image: {type: 'text', maxlength: 2000, nullable: true},
|
||||||
hidden: {type: 'bool', nullable: false, defaultTo: false, validations: {isIn: [[0, 1, false, true]]}},
|
|
||||||
parent_id: {type: 'integer', nullable: true},
|
parent_id: {type: 'integer', nullable: true},
|
||||||
|
visibility: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'public', validations: {isIn: [['public', 'internal']]}},
|
||||||
meta_title: {type: 'string', maxlength: 150, nullable: true},
|
meta_title: {type: 'string', maxlength: 150, nullable: true},
|
||||||
meta_description: {type: 'string', maxlength: 200, nullable: true},
|
meta_description: {type: 'string', maxlength: 200, nullable: true},
|
||||||
created_at: {type: 'dateTime', nullable: false},
|
created_at: {type: 'dateTime', nullable: false},
|
||||||
|
@ -167,7 +172,7 @@ module.exports = {
|
||||||
redirection_uri: {type: 'string', maxlength: 2000, nullable: true},
|
redirection_uri: {type: 'string', maxlength: 2000, nullable: true},
|
||||||
logo: {type: 'string', maxlength: 2000, nullable: true},
|
logo: {type: 'string', maxlength: 2000, nullable: true},
|
||||||
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'development'},
|
status: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'development'},
|
||||||
type: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'ua'},
|
type: {type: 'string', maxlength: 150, nullable: false, defaultTo: 'ua', validations: {isIn: [['ua', 'web', 'native']]}},
|
||||||
description: {type: 'string', maxlength: 200, nullable: true},
|
description: {type: 'string', maxlength: 200, nullable: true},
|
||||||
created_at: {type: 'dateTime', nullable: false},
|
created_at: {type: 'dateTime', nullable: false},
|
||||||
created_by: {type: 'integer', nullable: false},
|
created_by: {type: 'integer', nullable: false},
|
||||||
|
|
|
@ -6,6 +6,7 @@ var testUtils = require('../utils'),
|
||||||
Promise = require('bluebird'),
|
Promise = require('bluebird'),
|
||||||
|
|
||||||
fixtures = require('../../server/data/migration/fixtures'),
|
fixtures = require('../../server/data/migration/fixtures'),
|
||||||
|
fixtures005 = require('../../server/data/migration/fixtures/005'),
|
||||||
Models = require('../../server/models'),
|
Models = require('../../server/models'),
|
||||||
|
|
||||||
sandbox = sinon.sandbox.create();
|
sandbox = sinon.sandbox.create();
|
||||||
|
@ -122,6 +123,18 @@ describe('Database Migration (special functions)', function () {
|
||||||
permissions[28].should.be.AssignedToRoles(['Administrator', 'Editor']);
|
permissions[28].should.be.AssignedToRoles(['Administrator', 'Editor']);
|
||||||
permissions[29].name.should.eql('Browse roles');
|
permissions[29].name.should.eql('Browse roles');
|
||||||
permissions[29].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
permissions[29].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
|
||||||
|
// Clients
|
||||||
|
permissions[30].name.should.eql('Browse clients');
|
||||||
|
permissions[30].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[31].name.should.eql('Read clients');
|
||||||
|
permissions[31].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[32].name.should.eql('Edit clients');
|
||||||
|
permissions[32].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[33].name.should.eql('Add clients');
|
||||||
|
permissions[33].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[34].name.should.eql('Delete clients');
|
||||||
|
permissions[34].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Populate', function () {
|
describe('Populate', function () {
|
||||||
|
@ -159,9 +172,10 @@ describe('Database Migration (special functions)', function () {
|
||||||
|
|
||||||
// Clients
|
// Clients
|
||||||
should.exist(result.clients);
|
should.exist(result.clients);
|
||||||
result.clients.length.should.eql(2);
|
result.clients.length.should.eql(3);
|
||||||
result.clients.at(0).get('name').should.eql('Ghost Admin');
|
result.clients.at(0).get('name').should.eql('Ghost Admin');
|
||||||
result.clients.at(1).get('name').should.eql('Ghost Frontend');
|
result.clients.at(1).get('name').should.eql('Ghost Frontend');
|
||||||
|
result.clients.at(2).get('name').should.eql('Ghost Scheduler');
|
||||||
|
|
||||||
// User (Owner)
|
// User (Owner)
|
||||||
should.exist(result.users);
|
should.exist(result.users);
|
||||||
|
@ -179,7 +193,7 @@ describe('Database Migration (special functions)', function () {
|
||||||
result.roles.at(3).get('name').should.eql('Owner');
|
result.roles.at(3).get('name').should.eql('Owner');
|
||||||
|
|
||||||
// Permissions
|
// Permissions
|
||||||
result.permissions.length.should.eql(30);
|
result.permissions.length.should.eql(35);
|
||||||
result.permissions.toJSON().should.be.CompletePermissions();
|
result.permissions.toJSON().should.be.CompletePermissions();
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
@ -187,6 +201,60 @@ describe('Database Migration (special functions)', function () {
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Update', function () {
|
||||||
|
// We need the roles, and lets add some other perms to simulate the "Update" environment
|
||||||
|
beforeEach(testUtils.setup('users:roles', 'perms:db', 'perms:init'));
|
||||||
|
|
||||||
|
it('should update client permissions correctly', function (done) {
|
||||||
|
fixtures005[2]({}, loggerStub).then(function () {
|
||||||
|
var props = {
|
||||||
|
roles: Models.Role.findAll(),
|
||||||
|
permissions: Models.Permission.findAll({include: ['roles']})
|
||||||
|
}, permissions;
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
|
return Promise.props(props).then(function (result) {
|
||||||
|
should.exist(result);
|
||||||
|
|
||||||
|
should.exist(result.roles);
|
||||||
|
result.roles.length.should.eql(4);
|
||||||
|
result.roles.at(0).get('name').should.eql('Administrator');
|
||||||
|
result.roles.at(1).get('name').should.eql('Editor');
|
||||||
|
result.roles.at(2).get('name').should.eql('Author');
|
||||||
|
result.roles.at(3).get('name').should.eql('Owner');
|
||||||
|
|
||||||
|
// Permissions
|
||||||
|
result.permissions.length.should.eql(8);
|
||||||
|
permissions = result.permissions.toJSON();
|
||||||
|
|
||||||
|
// DB Perms
|
||||||
|
permissions[0].name.should.eql('Export database');
|
||||||
|
permissions[0].should.be.AssignedToRoles(['Administrator']);
|
||||||
|
permissions[1].name.should.eql('Import database');
|
||||||
|
permissions[1].should.be.AssignedToRoles(['Administrator']);
|
||||||
|
permissions[2].name.should.eql('Delete all content');
|
||||||
|
permissions[2].should.be.AssignedToRoles(['Administrator']);
|
||||||
|
|
||||||
|
// Client Perms
|
||||||
|
permissions[3].name.should.eql('Browse clients');
|
||||||
|
permissions[3].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[4].name.should.eql('Read clients');
|
||||||
|
permissions[4].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[5].name.should.eql('Edit clients');
|
||||||
|
permissions[5].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[6].name.should.eql('Add clients');
|
||||||
|
permissions[6].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
permissions[7].name.should.eql('Delete clients');
|
||||||
|
permissions[7].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,9 @@ var should = require('should'),
|
||||||
versioning = require('../../server/data/schema/versioning'),
|
versioning = require('../../server/data/schema/versioning'),
|
||||||
update = rewire('../../server/data/migration/fixtures/update'),
|
update = rewire('../../server/data/migration/fixtures/update'),
|
||||||
populate = rewire('../../server/data/migration/fixtures/populate'),
|
populate = rewire('../../server/data/migration/fixtures/populate'),
|
||||||
|
fixtureUtils = require('../../server/data/migration/fixtures/utils'),
|
||||||
fixtures004 = require('../../server/data/migration/fixtures/004'),
|
fixtures004 = require('../../server/data/migration/fixtures/004'),
|
||||||
|
fixtures005 = require('../../server/data/migration/fixtures/005'),
|
||||||
ensureDefaultSettings = require('../../server/data/migration/fixtures/settings'),
|
ensureDefaultSettings = require('../../server/data/migration/fixtures/settings'),
|
||||||
|
|
||||||
sandbox = sinon.sandbox.create();
|
sandbox = sinon.sandbox.create();
|
||||||
|
@ -124,6 +126,11 @@ describe('Fixtures', function () {
|
||||||
clientEditStub = sandbox.stub(models.Client, 'edit').returns(Promise.resolve());
|
clientEditStub = sandbox.stub(models.Client, 'edit').returns(Promise.resolve());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have tasks for 004', function () {
|
||||||
|
should.exist(fixtures004);
|
||||||
|
fixtures004.should.be.an.Array().with.lengthOf(8);
|
||||||
|
});
|
||||||
|
|
||||||
describe('01-move-jquery-with-alert', function () {
|
describe('01-move-jquery-with-alert', function () {
|
||||||
it('tries to move jQuery to ghost_foot', function (done) {
|
it('tries to move jQuery to ghost_foot', function (done) {
|
||||||
getObjStub.get.returns('');
|
getObjStub.get.returns('');
|
||||||
|
@ -685,6 +692,187 @@ describe('Fixtures', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Update to 005', function () {
|
||||||
|
it('should call all the 005 fixture upgrades', function (done) {
|
||||||
|
// Setup
|
||||||
|
// Create a new stub, this will replace sequence, so that db calls don't actually get run
|
||||||
|
var sequenceStub = sandbox.stub(),
|
||||||
|
sequenceReset = update.__set__('sequence', sequenceStub);
|
||||||
|
|
||||||
|
// The first time we call sequence, it should be to execute a top level version, e.g 005
|
||||||
|
// yieldsTo('0') means this stub will execute the function at index 0 of the array passed as the
|
||||||
|
// first argument. In short the `runVersionTasks` function gets executed, and sequence gets called
|
||||||
|
// again with the array of tasks to execute for 005, which is what we want to check
|
||||||
|
sequenceStub.onFirstCall().yieldsTo('0').returns(Promise.resolve([]));
|
||||||
|
|
||||||
|
update(['005'], loggerStub).then(function (result) {
|
||||||
|
should.exist(result);
|
||||||
|
|
||||||
|
loggerStub.info.calledTwice.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
|
sequenceStub.calledTwice.should.be.true();
|
||||||
|
|
||||||
|
sequenceStub.firstCall.calledWith(sinon.match.array, sinon.match.object, loggerStub).should.be.true();
|
||||||
|
sequenceStub.firstCall.args[0].should.be.an.Array().with.lengthOf(1);
|
||||||
|
sequenceStub.firstCall.args[0][0].should.be.a.Function().with.property('name', 'runVersionTasks');
|
||||||
|
|
||||||
|
sequenceStub.secondCall.calledWith(sinon.match.array, sinon.match.object, loggerStub).should.be.true();
|
||||||
|
sequenceStub.secondCall.args[0].should.be.an.Array().with.lengthOf(3);
|
||||||
|
sequenceStub.secondCall.args[0][0].should.be.a.Function().with.property('name', 'updateGhostClientsSecrets');
|
||||||
|
sequenceStub.secondCall.args[0][1].should.be.a.Function().with.property('name', 'addGhostFrontendClient');
|
||||||
|
sequenceStub.secondCall.args[0][2].should.be.a.Function().with.property('name', 'addClientPermissions');
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
sequenceReset();
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Tasks:', function () {
|
||||||
|
it('should have tasks for 005', function () {
|
||||||
|
should.exist(fixtures005);
|
||||||
|
fixtures005.should.be.an.Array().with.lengthOf(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('01-update-ghost-client-secrets', function () {
|
||||||
|
var queryStub, clientForgeStub, clientEditStub;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
queryStub = {
|
||||||
|
query: sandbox.stub().returnsThis(),
|
||||||
|
fetch: sandbox.stub()
|
||||||
|
};
|
||||||
|
|
||||||
|
clientForgeStub = sandbox.stub(models.Clients, 'forge').returns(queryStub);
|
||||||
|
clientEditStub = sandbox.stub(models.Client, 'edit');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if there are no incorrect secrets', function (done) {
|
||||||
|
// Setup
|
||||||
|
queryStub.fetch.returns(new Promise.resolve({models: []}));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
fixtures005[0]({}, loggerStub).then(function () {
|
||||||
|
clientForgeStub.calledOnce.should.be.true();
|
||||||
|
clientEditStub.called.should.be.false();
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should try to fix any incorrect secrets', function (done) {
|
||||||
|
// Setup
|
||||||
|
queryStub.fetch.returns(new Promise.resolve({models: [{id: 1}]}));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
fixtures005[0]({}, loggerStub).then(function () {
|
||||||
|
clientForgeStub.calledOnce.should.be.true();
|
||||||
|
clientEditStub.called.should.be.true();
|
||||||
|
loggerStub.info.calledOnce.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('02-add-ghost-scheduler-client', function () {
|
||||||
|
var clientOneStub;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
clientOneStub = sandbox.stub(models.Client, 'findOne').returns(Promise.resolve({}));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tries to add client correctly', function (done) {
|
||||||
|
var clientAddStub = sandbox.stub(models.Client, 'add').returns(Promise.resolve());
|
||||||
|
clientOneStub.returns(Promise.resolve());
|
||||||
|
|
||||||
|
fixtures005[1]({}, loggerStub).then(function () {
|
||||||
|
clientOneStub.calledOnce.should.be.true();
|
||||||
|
clientOneStub.calledWith({slug: 'ghost-scheduler'}).should.be.true();
|
||||||
|
clientAddStub.calledOnce.should.be.true();
|
||||||
|
loggerStub.info.calledOnce.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
sinon.assert.callOrder(clientOneStub, loggerStub.info, clientAddStub);
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not try to add client if it already exists', function (done) {
|
||||||
|
var clientAddStub = sandbox.stub(models.Client, 'add').returns(Promise.resolve());
|
||||||
|
|
||||||
|
fixtures005[1]({}, loggerStub).then(function () {
|
||||||
|
clientOneStub.calledOnce.should.be.true();
|
||||||
|
clientOneStub.calledWith({slug: 'ghost-scheduler'}).should.be.true();
|
||||||
|
clientAddStub.called.should.be.false();
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('03-add-client-permissions', function () {
|
||||||
|
var modelResult, addModelStub, relationResult, addRelationStub;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
modelResult = {expected: 1, done: 1};
|
||||||
|
addModelStub = sandbox.stub(fixtureUtils, 'addFixturesForModel')
|
||||||
|
.returns(Promise.resolve(modelResult));
|
||||||
|
|
||||||
|
relationResult = {expected: 1, done: 1};
|
||||||
|
addRelationStub = sandbox.stub(fixtureUtils, 'addFixturesForRelation')
|
||||||
|
.returns(Promise.resolve(relationResult));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should find the correct model & relation to add', function (done) {
|
||||||
|
// Execute
|
||||||
|
fixtures005[2]({}, loggerStub).then(function () {
|
||||||
|
addModelStub.calledOnce.should.be.true();
|
||||||
|
addModelStub.calledWith(
|
||||||
|
fixtureUtils.findModelFixtures('Permission', {object_type: 'client'})
|
||||||
|
).should.be.true();
|
||||||
|
|
||||||
|
addRelationStub.calledOnce.should.be.true();
|
||||||
|
addRelationStub.calledWith(
|
||||||
|
fixtureUtils.findPermissionRelationsForObject('client')
|
||||||
|
).should.be.true();
|
||||||
|
|
||||||
|
loggerStub.info.calledTwice.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should warn the result shows less work was done than expected', function (done) {
|
||||||
|
// Setup
|
||||||
|
modelResult.expected = 3;
|
||||||
|
// Execute
|
||||||
|
fixtures005[2]({}, loggerStub).then(function () {
|
||||||
|
addModelStub.calledOnce.should.be.true();
|
||||||
|
addModelStub.calledWith(
|
||||||
|
fixtureUtils.findModelFixtures('Permission', {object_type: 'client'})
|
||||||
|
).should.be.true();
|
||||||
|
|
||||||
|
addRelationStub.calledOnce.should.be.true();
|
||||||
|
addRelationStub.calledWith(
|
||||||
|
fixtureUtils.findPermissionRelationsForObject('client')
|
||||||
|
).should.be.true();
|
||||||
|
|
||||||
|
loggerStub.info.calledOnce.should.be.true();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Populate fixtures', function () {
|
describe('Populate fixtures', function () {
|
||||||
|
@ -730,12 +918,12 @@ describe('Fixtures', function () {
|
||||||
tagAddStub.calledOnce.should.be.true();
|
tagAddStub.calledOnce.should.be.true();
|
||||||
roleOneStub.callCount.should.be.aboveOrEqual(4);
|
roleOneStub.callCount.should.be.aboveOrEqual(4);
|
||||||
roleAddStub.callCount.should.eql(4);
|
roleAddStub.callCount.should.eql(4);
|
||||||
clientOneStub.calledTwice.should.be.true();
|
clientOneStub.calledThrice.should.be.true();
|
||||||
clientAddStub.calledTwice.should.be.true();
|
clientAddStub.calledThrice.should.be.true();
|
||||||
|
|
||||||
permOneStub.callCount.should.eql(30);
|
permOneStub.callCount.should.eql(35);
|
||||||
permsAddStub.called.should.be.true();
|
permsAddStub.called.should.be.true();
|
||||||
permsAddStub.callCount.should.eql(30);
|
permsAddStub.callCount.should.eql(35);
|
||||||
|
|
||||||
permsAllStub.calledOnce.should.be.true();
|
permsAllStub.calledOnce.should.be.true();
|
||||||
rolesAllStub.calledOnce.should.be.true();
|
rolesAllStub.calledOnce.should.be.true();
|
||||||
|
@ -744,8 +932,8 @@ describe('Fixtures', function () {
|
||||||
|
|
||||||
// Relations
|
// Relations
|
||||||
modelMethodStub.filter.called.should.be.true();
|
modelMethodStub.filter.called.should.be.true();
|
||||||
// 22 permissions, 1 tag
|
// 25 permissions, 1 tag
|
||||||
modelMethodStub.filter.callCount.should.eql(22 + 1);
|
modelMethodStub.filter.callCount.should.eql(25 + 1);
|
||||||
modelMethodStub.find.called.should.be.true();
|
modelMethodStub.find.called.should.be.true();
|
||||||
// 3 roles, 1 post
|
// 3 roles, 1 post
|
||||||
modelMethodStub.find.callCount.should.eql(3 + 1);
|
modelMethodStub.find.callCount.should.eql(3 + 1);
|
||||||
|
|
|
@ -152,21 +152,21 @@ describe('Utils', function () {
|
||||||
fixtureUtils.addFixturesForRelation(fixtures.relations[0]).then(function (result) {
|
fixtureUtils.addFixturesForRelation(fixtures.relations[0]).then(function (result) {
|
||||||
should.exist(result);
|
should.exist(result);
|
||||||
result.should.be.an.Object();
|
result.should.be.an.Object();
|
||||||
result.should.have.property('expected', 22);
|
result.should.have.property('expected', 25);
|
||||||
result.should.have.property('done', 22);
|
result.should.have.property('done', 25);
|
||||||
|
|
||||||
// Permissions & Roles
|
// Permissions & Roles
|
||||||
permsAllStub.calledOnce.should.be.true();
|
permsAllStub.calledOnce.should.be.true();
|
||||||
rolesAllStub.calledOnce.should.be.true();
|
rolesAllStub.calledOnce.should.be.true();
|
||||||
dataMethodStub.filter.callCount.should.eql(22);
|
dataMethodStub.filter.callCount.should.eql(25);
|
||||||
dataMethodStub.find.callCount.should.eql(3);
|
dataMethodStub.find.callCount.should.eql(3);
|
||||||
|
|
||||||
fromItem.related.callCount.should.eql(22);
|
fromItem.related.callCount.should.eql(25);
|
||||||
fromItem.findWhere.callCount.should.eql(22);
|
fromItem.findWhere.callCount.should.eql(25);
|
||||||
toItem[0].get.callCount.should.eql(44);
|
toItem[0].get.callCount.should.eql(50);
|
||||||
|
|
||||||
fromItem.permissions.callCount.should.eql(22);
|
fromItem.permissions.callCount.should.eql(25);
|
||||||
fromItem.attach.callCount.should.eql(22);
|
fromItem.attach.callCount.should.eql(25);
|
||||||
fromItem.attach.calledWith(toItem).should.be.true();
|
fromItem.attach.calledWith(toItem).should.be.true();
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
|
@ -13,14 +13,12 @@ var should = require('should'),
|
||||||
exporter = require('../../server/data/export'),
|
exporter = require('../../server/data/export'),
|
||||||
schema = require('../../server/data/schema'),
|
schema = require('../../server/data/schema'),
|
||||||
|
|
||||||
// TODO: can go when fixClientSecret is moved
|
|
||||||
models = require('../../server/models'),
|
|
||||||
|
|
||||||
migration = rewire('../../server/data/migration'),
|
migration = rewire('../../server/data/migration'),
|
||||||
fixtures = require('../../server/data/migration/fixtures'),
|
fixtures = require('../../server/data/migration/fixtures'),
|
||||||
populate = require('../../server/data/migration/populate'),
|
populate = require('../../server/data/migration/populate'),
|
||||||
update = rewire('../../server/data/migration/update'),
|
update = rewire('../../server/data/migration/update'),
|
||||||
updates004 = require('../../server/data/migration/004'),
|
updates004 = require('../../server/data/migration/004'),
|
||||||
|
updates005 = require('../../server/data/migration/005'),
|
||||||
|
|
||||||
defaultSettings = schema.defaultSettings,
|
defaultSettings = schema.defaultSettings,
|
||||||
schemaTables = Object.keys(schema.tables),
|
schemaTables = Object.keys(schema.tables),
|
||||||
|
@ -33,9 +31,9 @@ var should = require('should'),
|
||||||
// both of which are required for migrations to work properly.
|
// both of which are required for migrations to work properly.
|
||||||
describe('DB version integrity', function () {
|
describe('DB version integrity', function () {
|
||||||
// Only these variables should need updating
|
// Only these variables should need updating
|
||||||
var currentDbVersion = '004',
|
var currentDbVersion = '005',
|
||||||
currentSchemaHash = 'a195562bf4915e3f3f610f6d178aba01',
|
currentSchemaHash = 'be706cdbeb06103d90703ee733efc556',
|
||||||
currentFixturesHash = '77ebb081539f9e0c49f487faf7fd929e';
|
currentFixturesHash = 'ba195b645386b019a69c4b79e6854138';
|
||||||
|
|
||||||
// If this test is failing, then it is likely a change has been made that requires a DB version bump,
|
// If this test is failing, then it is likely a change has been made that requires a DB version bump,
|
||||||
// and the values above will need updating as confirmation
|
// and the values above will need updating as confirmation
|
||||||
|
@ -343,7 +341,7 @@ describe('Migrations', function () {
|
||||||
// yieldsTo('0') means this stub will execute the function at index 0 of the array passed as the
|
// yieldsTo('0') means this stub will execute the function at index 0 of the array passed as the
|
||||||
// first argument. In short the `runVersionTasks` function gets executed, and sequence gets called
|
// first argument. In short the `runVersionTasks` function gets executed, and sequence gets called
|
||||||
// again with the array of tasks to execute for 004, which is what we want to check
|
// again with the array of tasks to execute for 004, which is what we want to check
|
||||||
sequenceStub.onFirstCall().yieldsTo('0');
|
sequenceStub.onFirstCall().yieldsTo('0').returns(Promise.resolve([]));
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
update('003', '004', loggerStub).then(function () {
|
update('003', '004', loggerStub).then(function () {
|
||||||
|
@ -359,14 +357,13 @@ describe('Migrations', function () {
|
||||||
tasksSpy.firstCall.returnValue.should.be.an.Array().with.lengthOf(5);
|
tasksSpy.firstCall.returnValue.should.be.an.Array().with.lengthOf(5);
|
||||||
|
|
||||||
sequenceStub.calledTwice.should.be.true();
|
sequenceStub.calledTwice.should.be.true();
|
||||||
|
|
||||||
sequenceStub.firstCall.calledWith(sinon.match.array, loggerStub).should.be.true();
|
sequenceStub.firstCall.calledWith(sinon.match.array, loggerStub).should.be.true();
|
||||||
sequenceStub.secondCall.calledWith(sinon.match.array, loggerStub).should.be.true();
|
|
||||||
|
|
||||||
sequenceStub.firstCall.args[0].should.be.an.Array().with.lengthOf(1);
|
sequenceStub.firstCall.args[0].should.be.an.Array().with.lengthOf(1);
|
||||||
sequenceStub.secondCall.args[0].should.be.an.Array().with.lengthOf(5);
|
|
||||||
|
|
||||||
sequenceStub.firstCall.args[0][0].should.be.a.Function().with.property('name', 'runVersionTasks');
|
sequenceStub.firstCall.args[0][0].should.be.a.Function().with.property('name', 'runVersionTasks');
|
||||||
|
|
||||||
|
sequenceStub.secondCall.calledWith(sinon.match.array, loggerStub).should.be.true();
|
||||||
|
sequenceStub.secondCall.args[0].should.be.an.Array().with.lengthOf(5);
|
||||||
sequenceStub.secondCall.args[0][0].should.be.a.Function().with.property('name', 'addTourColumnToUsers');
|
sequenceStub.secondCall.args[0][0].should.be.a.Function().with.property('name', 'addTourColumnToUsers');
|
||||||
sequenceStub.secondCall.args[0][1].should.be.a.Function().with.property('name', 'addSortOrderColumnToPostsTags');
|
sequenceStub.secondCall.args[0][1].should.be.a.Function().with.property('name', 'addSortOrderColumnToPostsTags');
|
||||||
sequenceStub.secondCall.args[0][2].should.be.a.Function().with.property('name', 'addManyColumnsToClients');
|
sequenceStub.secondCall.args[0][2].should.be.a.Function().with.property('name', 'addManyColumnsToClients');
|
||||||
|
@ -402,6 +399,11 @@ describe('Migrations', function () {
|
||||||
knexStub.restore();
|
knexStub.restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have tasks for 004', function () {
|
||||||
|
should.exist(updates004);
|
||||||
|
updates004.should.be.an.Array().with.lengthOf(5);
|
||||||
|
});
|
||||||
|
|
||||||
describe('01-add-tour-column-to-users', function () {
|
describe('01-add-tour-column-to-users', function () {
|
||||||
it('does not try to add a new column if the table does not exist', function (done) {
|
it('does not try to add a new column if the table does not exist', function (done) {
|
||||||
// Setup
|
// Setup
|
||||||
|
@ -771,6 +773,435 @@ describe('Migrations', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Update to 005', function () {
|
||||||
|
it('should call all the 005 database upgrade tasks', function (done) {
|
||||||
|
// Setup
|
||||||
|
// Create a new stub, this will replace sequence, so that db calls don't actually get run
|
||||||
|
var sequenceStub = sandbox.stub(),
|
||||||
|
sequenceReset = update.__set__('sequence', sequenceStub);
|
||||||
|
|
||||||
|
// The first time we call sequence, it should be to execute a top level version, e.g 005
|
||||||
|
// yieldsTo('0') means this stub will execute the function at index 0 of the array passed as the
|
||||||
|
// first argument. In short the `runVersionTasks` function gets executed, and sequence gets called
|
||||||
|
// again with the array of tasks to execute for 005, which is what we want to check
|
||||||
|
sequenceStub.onFirstCall().yieldsTo('0').returns(Promise.resolve([]));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
update('004', '005', loggerStub).then(function () {
|
||||||
|
errorStub.called.should.be.false();
|
||||||
|
loggerStub.info.calledTwice.should.be.true();
|
||||||
|
|
||||||
|
versionsSpy.calledOnce.should.be.true();
|
||||||
|
versionsSpy.calledWith('004', '005').should.be.true();
|
||||||
|
versionsSpy.returned(['004', '005']).should.be.true();
|
||||||
|
|
||||||
|
tasksSpy.calledOnce.should.be.true();
|
||||||
|
tasksSpy.calledWith('005', loggerStub).should.be.true();
|
||||||
|
tasksSpy.firstCall.returnValue.should.be.an.Array().with.lengthOf(4);
|
||||||
|
|
||||||
|
sequenceStub.calledTwice.should.be.true();
|
||||||
|
|
||||||
|
sequenceStub.firstCall.calledWith(sinon.match.array, loggerStub).should.be.true();
|
||||||
|
sequenceStub.firstCall.args[0].should.be.an.Array().with.lengthOf(1);
|
||||||
|
sequenceStub.firstCall.args[0][0].should.be.a.Function().with.property('name', 'runVersionTasks');
|
||||||
|
|
||||||
|
sequenceStub.secondCall.calledWith(sinon.match.array, loggerStub).should.be.true();
|
||||||
|
sequenceStub.secondCall.args[0].should.be.an.Array().with.lengthOf(4);
|
||||||
|
sequenceStub.secondCall.args[0][0].should.be.a.Function().with.property('name', 'dropHiddenColumnFromTags');
|
||||||
|
sequenceStub.secondCall.args[0][1].should.be.a.Function().with.property('name', 'addVisibilityColumnToKeyTables');
|
||||||
|
sequenceStub.secondCall.args[0][2].should.be.a.Function().with.property('name', 'addMobiledocColumnToPosts');
|
||||||
|
sequenceStub.secondCall.args[0][3].should.be.a.Function().with.property('name', 'addSocialMediaColumnsToUsers');
|
||||||
|
|
||||||
|
// Reset sequence
|
||||||
|
sequenceReset();
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Tasks:', function () {
|
||||||
|
var dropColumnStub, addColumnStub,
|
||||||
|
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; }});
|
||||||
|
|
||||||
|
dropColumnStub = sandbox.stub(schema.commands, 'dropColumn');
|
||||||
|
addColumnStub = sandbox.stub(schema.commands, 'addColumn');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function () {
|
||||||
|
knexStub.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have tasks for 005', function () {
|
||||||
|
should.exist(updates005);
|
||||||
|
updates005.should.be.an.Array().with.lengthOf(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('01-drop-hidden-column-from-tags', function () {
|
||||||
|
it('does not try to drop column if the table does not exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('tags').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[0](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('tags').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.called.should.be.false();
|
||||||
|
|
||||||
|
dropColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not try to drop column if the column does not exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('tags').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('tags', 'hidden').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[0](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('tags').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('tags', 'hidden').should.be.true();
|
||||||
|
|
||||||
|
dropColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tries to add drop column if table and column are both present', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('tags').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('tags', 'hidden').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[0](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('tags').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('tags', 'hidden').should.be.true();
|
||||||
|
|
||||||
|
dropColumnStub.calledOnce.should.be.true();
|
||||||
|
dropColumnStub.calledWith('tags', 'hidden').should.be.true();
|
||||||
|
|
||||||
|
loggerStub.info.calledOnce.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('02-add-visibility-column-to-key-tables', function () {
|
||||||
|
it('does not try to add new column if the table does not exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('posts').returns(Promise.resolve(false));
|
||||||
|
knexMock.schema.hasTable.withArgs('tags').returns(Promise.resolve(false));
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[1](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledThrice.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('posts').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('tags').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.called.should.be.false();
|
||||||
|
|
||||||
|
addColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledThrice.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not try to add new columns if the columns already exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('posts').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasTable.withArgs('tags').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.withArgs('posts', 'visibility').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('tags', 'visibility').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'visibility').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[1](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledThrice.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('posts').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('tags').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledThrice.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('posts', 'visibility').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('tags', 'visibility').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'visibility').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledThrice.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tries to add new columns if table is present but columns are not', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('posts').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasTable.withArgs('tags').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.withArgs('posts', 'visibility').returns(Promise.resolve(false));
|
||||||
|
knexMock.schema.hasColumn.withArgs('tags', 'visibility').returns(Promise.resolve(false));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'visibility').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[1](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledThrice.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('posts').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('tags').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledThrice.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('posts', 'visibility').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('tags', 'visibility').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'visibility').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.calledThrice.should.be.true();
|
||||||
|
addColumnStub.calledWith('posts', 'visibility').should.be.true();
|
||||||
|
addColumnStub.calledWith('tags', 'visibility').should.be.true();
|
||||||
|
addColumnStub.calledWith('users', 'visibility').should.be.true();
|
||||||
|
|
||||||
|
loggerStub.info.calledThrice.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will only try to add columns that do not exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('posts').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasTable.withArgs('tags').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.withArgs('posts', 'visibility').returns(Promise.resolve(false));
|
||||||
|
knexMock.schema.hasColumn.withArgs('tags', 'visibility').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'visibility').returns(Promise.resolve(false));
|
||||||
|
// Execute
|
||||||
|
updates005[1](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledThrice.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('posts').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('tags').should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledThrice.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('posts', 'visibility').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('tags', 'visibility').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'visibility').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.calledTwice.should.be.true();
|
||||||
|
addColumnStub.calledWith('posts', 'visibility').should.be.true();
|
||||||
|
addColumnStub.calledWith('tags', 'visibility').should.be.false();
|
||||||
|
addColumnStub.calledWith('users', 'visibility').should.be.true();
|
||||||
|
|
||||||
|
loggerStub.info.calledTwice.should.be.true();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('03-add-mobiledoc-column-to-posts', function () {
|
||||||
|
it('does not try to add a new column if the table does not exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('posts').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[2](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('posts').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.called.should.be.false();
|
||||||
|
|
||||||
|
addColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not try to add a new column if the column already exists', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('posts').returns(new Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('posts', 'mobiledoc').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[2](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('posts').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('posts', 'mobiledoc').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tries to add a new column if table is present but column is not', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('posts').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('posts', 'mobiledoc').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[2](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('posts').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('posts', 'mobiledoc').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.calledOnce.should.be.true();
|
||||||
|
addColumnStub.calledWith('posts', 'mobiledoc').should.be.true();
|
||||||
|
|
||||||
|
loggerStub.info.calledOnce.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('04-add-social-media-columns-to-users', function () {
|
||||||
|
it('does not try to add new columns if the table does not exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[3](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.called.should.be.false();
|
||||||
|
|
||||||
|
addColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not try to add new columns if the columns already exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'facebook').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'twitter').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[3](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledTwice.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'facebook').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'twitter').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.called.should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.called.should.be.false();
|
||||||
|
loggerStub.warn.calledTwice.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tries to add new columns if table is present but columns are not', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'facebook').returns(Promise.resolve(false));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'twitter').returns(Promise.resolve(false));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[3](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledTwice.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'facebook').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'twitter').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.calledTwice.should.be.true();
|
||||||
|
addColumnStub.calledWith('users', 'facebook').should.be.true();
|
||||||
|
addColumnStub.calledWith('users', 'twitter').should.be.true();
|
||||||
|
|
||||||
|
loggerStub.info.calledTwice.should.be.true();
|
||||||
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('will only try to add columns that do not exist', function (done) {
|
||||||
|
// Setup
|
||||||
|
knexMock.schema.hasTable.withArgs('users').returns(Promise.resolve(true));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'facebook').returns(Promise.resolve(false));
|
||||||
|
knexMock.schema.hasColumn.withArgs('users', 'twitter').returns(Promise.resolve(true));
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
updates005[3](loggerStub).then(function () {
|
||||||
|
knexMock.schema.hasTable.calledOnce.should.be.true();
|
||||||
|
knexMock.schema.hasTable.calledWith('users').should.be.true();
|
||||||
|
|
||||||
|
knexMock.schema.hasColumn.calledTwice.should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'facebook').should.be.true();
|
||||||
|
knexMock.schema.hasColumn.calledWith('users', 'twitter').should.be.true();
|
||||||
|
|
||||||
|
addColumnStub.callCount.should.eql(1);
|
||||||
|
addColumnStub.calledWith('users', 'facebook').should.be.true();
|
||||||
|
addColumnStub.calledWith('users', 'twitter').should.be.false();
|
||||||
|
|
||||||
|
loggerStub.info.calledOnce.should.be.true();
|
||||||
|
loggerStub.warn.calledOnce.should.be.true();
|
||||||
|
|
||||||
|
done();
|
||||||
|
}).catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Update Database Schema', function () {
|
describe('Update Database Schema', function () {
|
||||||
|
@ -813,8 +1244,8 @@ describe('Migrations', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Init', function () {
|
describe('Init', function () {
|
||||||
var defaultVersionStub, databaseVersionStub, errorStub, updateStub, populateStub, fixSecretStub,
|
var defaultVersionStub, databaseVersionStub, errorStub, updateStub, populateStub,
|
||||||
resetLog, resetUpdate, resetPopulate, resetFixSecret;
|
resetLog, resetUpdate, resetPopulate;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
defaultVersionStub = sandbox.stub(schema.versioning, 'getDefaultDatabaseVersion');
|
defaultVersionStub = sandbox.stub(schema.versioning, 'getDefaultDatabaseVersion');
|
||||||
|
@ -822,19 +1253,16 @@ describe('Migrations', function () {
|
||||||
errorStub = sandbox.stub(errors, 'logErrorAndExit');
|
errorStub = sandbox.stub(errors, 'logErrorAndExit');
|
||||||
updateStub = sandbox.stub();
|
updateStub = sandbox.stub();
|
||||||
populateStub = sandbox.stub();
|
populateStub = sandbox.stub();
|
||||||
fixSecretStub = sandbox.stub();
|
|
||||||
|
|
||||||
resetLog = migration.__set__('logger', loggerStub);
|
resetLog = migration.__set__('logger', loggerStub);
|
||||||
resetUpdate = migration.__set__('update', updateStub);
|
resetUpdate = migration.__set__('update', updateStub);
|
||||||
resetPopulate = migration.__set__('populate', populateStub);
|
resetPopulate = migration.__set__('populate', populateStub);
|
||||||
resetFixSecret = migration.__set__('fixClientSecret', fixSecretStub);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
resetLog();
|
resetLog();
|
||||||
resetUpdate();
|
resetUpdate();
|
||||||
resetPopulate();
|
resetPopulate();
|
||||||
resetFixSecret();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do an UPDATE if default version is higher', function (done) {
|
it('should do an UPDATE if default version is higher', function (done) {
|
||||||
|
@ -854,7 +1282,6 @@ describe('Migrations', function () {
|
||||||
|
|
||||||
errorStub.called.should.be.false();
|
errorStub.called.should.be.false();
|
||||||
populateStub.called.should.be.false();
|
populateStub.called.should.be.false();
|
||||||
fixSecretStub.called.should.be.false();
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
@ -877,13 +1304,12 @@ describe('Migrations', function () {
|
||||||
|
|
||||||
errorStub.called.should.be.false();
|
errorStub.called.should.be.false();
|
||||||
populateStub.called.should.be.false();
|
populateStub.called.should.be.false();
|
||||||
fixSecretStub.called.should.be.false();
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should do FIX SECRET if versions are the same', function (done) {
|
it('should just return if versions are the same', function (done) {
|
||||||
// Setup
|
// Setup
|
||||||
defaultVersionStub.returns('004');
|
defaultVersionStub.returns('004');
|
||||||
databaseVersionStub.returns(new Promise.resolve('004'));
|
databaseVersionStub.returns(new Promise.resolve('004'));
|
||||||
|
@ -895,8 +1321,6 @@ describe('Migrations', function () {
|
||||||
loggerStub.info.calledOnce.should.be.true();
|
loggerStub.info.calledOnce.should.be.true();
|
||||||
loggerStub.warn.called.should.be.false();
|
loggerStub.warn.called.should.be.false();
|
||||||
|
|
||||||
fixSecretStub.called.should.be.true();
|
|
||||||
|
|
||||||
errorStub.called.should.be.false();
|
errorStub.called.should.be.false();
|
||||||
updateStub.called.should.be.false();
|
updateStub.called.should.be.false();
|
||||||
populateStub.called.should.be.false();
|
populateStub.called.should.be.false();
|
||||||
|
@ -923,7 +1347,6 @@ describe('Migrations', function () {
|
||||||
|
|
||||||
errorStub.called.should.be.false();
|
errorStub.called.should.be.false();
|
||||||
populateStub.called.should.be.false();
|
populateStub.called.should.be.false();
|
||||||
fixSecretStub.called.should.be.false();
|
|
||||||
|
|
||||||
delete process.env.FORCE_MIGRATION;
|
delete process.env.FORCE_MIGRATION;
|
||||||
done();
|
done();
|
||||||
|
@ -947,7 +1370,6 @@ describe('Migrations', function () {
|
||||||
|
|
||||||
errorStub.called.should.be.false();
|
errorStub.called.should.be.false();
|
||||||
updateStub.called.should.be.false();
|
updateStub.called.should.be.false();
|
||||||
fixSecretStub.called.should.be.false();
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
@ -970,7 +1392,6 @@ describe('Migrations', function () {
|
||||||
|
|
||||||
errorStub.called.should.be.false();
|
errorStub.called.should.be.false();
|
||||||
updateStub.called.should.be.false();
|
updateStub.called.should.be.false();
|
||||||
fixSecretStub.called.should.be.false();
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
@ -991,7 +1412,6 @@ describe('Migrations', function () {
|
||||||
|
|
||||||
populateStub.called.should.be.false();
|
populateStub.called.should.be.false();
|
||||||
updateStub.called.should.be.false();
|
updateStub.called.should.be.false();
|
||||||
fixSecretStub.called.should.be.false();
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
@ -1012,7 +1432,6 @@ describe('Migrations', function () {
|
||||||
defaultVersionStub.calledOnce.should.be.false();
|
defaultVersionStub.calledOnce.should.be.false();
|
||||||
populateStub.called.should.be.false();
|
populateStub.called.should.be.false();
|
||||||
updateStub.called.should.be.false();
|
updateStub.called.should.be.false();
|
||||||
fixSecretStub.called.should.be.false();
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).catch(done);
|
}).catch(done);
|
||||||
|
@ -1044,70 +1463,4 @@ describe('Migrations', function () {
|
||||||
errorsInfoStub.called.should.be.false();
|
errorsInfoStub.called.should.be.false();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: move this to 005!!
|
|
||||||
describe('FixClientSecret', function () {
|
|
||||||
var fixClientSecret, queryStub, clientForgeStub, clientEditStub, toStringStub, cryptoStub;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
fixClientSecret = migration.__get__('fixClientSecret');
|
|
||||||
queryStub = {
|
|
||||||
query: sandbox.stub().returnsThis(),
|
|
||||||
fetch: sandbox.stub()
|
|
||||||
};
|
|
||||||
|
|
||||||
models.init();
|
|
||||||
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');
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue