mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-05 18:34:39 +03:00
commit
2200a65954
@ -1,24 +1,10 @@
|
||||
var when = require('when'),
|
||||
_ = require('lodash'),
|
||||
models = require('../../models'),
|
||||
Importer000,
|
||||
updatedSettingKeys,
|
||||
areEmpty,
|
||||
internal = {context: {internal: true}};
|
||||
utils = require('./utils'),
|
||||
|
||||
areEmpty = function (object) {
|
||||
var fields = _.toArray(arguments).slice(1),
|
||||
areEmpty = _.all(fields, function (field) {
|
||||
return _.isEmpty(object[field]);
|
||||
});
|
||||
Importer000;
|
||||
|
||||
return areEmpty;
|
||||
};
|
||||
|
||||
updatedSettingKeys = {
|
||||
activePlugins: 'activeApps',
|
||||
installedPlugins: 'installedApps'
|
||||
};
|
||||
|
||||
Importer000 = function () {
|
||||
_.bindAll(this, 'basicImport');
|
||||
@ -50,169 +36,6 @@ Importer000.prototype.canImport = function (data) {
|
||||
return when.reject('Unsupported version of data: ' + data.meta.version);
|
||||
};
|
||||
|
||||
|
||||
function stripProperties(properties, data) {
|
||||
data = _.clone(data, true);
|
||||
_.each(data, function (obj) {
|
||||
_.each(properties, function (property) {
|
||||
delete obj[property];
|
||||
});
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
function preProcessPostTags(tableData) {
|
||||
var postTags,
|
||||
postsWithTags = {};
|
||||
|
||||
|
||||
postTags = tableData.posts_tags;
|
||||
_.each(postTags, function (post_tag) {
|
||||
if (!postsWithTags.hasOwnProperty(post_tag.post_id)) {
|
||||
postsWithTags[post_tag.post_id] = [];
|
||||
}
|
||||
postsWithTags[post_tag.post_id].push(post_tag.tag_id);
|
||||
});
|
||||
|
||||
_.each(postsWithTags, function (tag_ids, post_id) {
|
||||
var post, tags;
|
||||
post = _.find(tableData.posts, function (post) {
|
||||
return post.id === parseInt(post_id, 10);
|
||||
});
|
||||
if (post) {
|
||||
tags = _.filter(tableData.tags, function (tag) {
|
||||
return _.indexOf(tag_ids, tag.id) !== -1;
|
||||
});
|
||||
post.tags = [];
|
||||
_.each(tags, function (tag) {
|
||||
// Only add valid tags
|
||||
if (!_.isEmpty(tag.uuid)) {
|
||||
// names are unique.. this should get the right tags added
|
||||
// as long as tags are added first;
|
||||
post.tags.push({name: tag.name});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return tableData;
|
||||
}
|
||||
|
||||
function importTags(ops, tableData, transaction) {
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
_.each(tableData, function (tag) {
|
||||
// Validate minimum tag fields
|
||||
if (areEmpty(tag, 'name', 'slug')) {
|
||||
return;
|
||||
}
|
||||
|
||||
ops.push(models.Tag.findOne({name: tag.name}, {transacting: transaction}).then(function (_tag) {
|
||||
if (!_tag) {
|
||||
return models.Tag.add(tag, _.extend(internal, {transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'tag', data: tag});
|
||||
});
|
||||
}
|
||||
return when.resolve(_tag);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function importPosts(ops, tableData, transaction) {
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
_.each(tableData, function (post) {
|
||||
// Validate minimum post fields
|
||||
if (areEmpty(post, 'title', 'slug', 'markdown')) {
|
||||
return;
|
||||
}
|
||||
|
||||
ops.push(models.Post.add(post, _.extend(internal, {transacting: transaction, importing: true}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'post', data: post});
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function importUsers(ops, tableData, transaction) {
|
||||
// don't override the users credentials
|
||||
tableData = stripProperties(['id', 'email', 'password'], tableData);
|
||||
tableData[0].id = 1;
|
||||
|
||||
ops.push(models.User.edit(tableData[0], _.extend(internal, {id: 1, transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'user', data: tableData[0]});
|
||||
}));
|
||||
}
|
||||
|
||||
function importSettings(ops, tableData, transaction) {
|
||||
// for settings we need to update individual settings, and insert any missing ones
|
||||
// settings we MUST NOT update are 'core' and 'theme' settings
|
||||
// as all of these will cause side effects which don't make sense for an import
|
||||
var blackList = ['core', 'theme'];
|
||||
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
tableData = _.filter(tableData, function (data) {
|
||||
return blackList.indexOf(data.type) === -1;
|
||||
});
|
||||
|
||||
// Clean up legacy plugin setting references
|
||||
_.each(tableData, function (datum) {
|
||||
datum.key = updatedSettingKeys[datum.key] || datum.key;
|
||||
});
|
||||
|
||||
ops.push(models.Settings.edit(tableData, _.extend(internal, {transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'setting', data: tableData});
|
||||
}));
|
||||
}
|
||||
|
||||
function importApps(ops, tableData, transaction) {
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
_.each(tableData, function (app) {
|
||||
// Avoid duplicates
|
||||
ops.push(models.App.findOne({name: app.name}, {transacting: transaction}).then(function (_app) {
|
||||
if (!_app) {
|
||||
return models.App.add(app, _.extend(internal, {transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'app', data: app});
|
||||
});
|
||||
}
|
||||
return when.resolve(_app);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
// function importAppSettings(ops, tableData, transaction) {
|
||||
// var appsData = tableData.apps,
|
||||
// appSettingsData = tableData.app_settings,
|
||||
// appName;
|
||||
//
|
||||
// appSettingsData = stripProperties(['id'], appSettingsData);
|
||||
//
|
||||
// _.each(appSettingsData, function (appSetting) {
|
||||
// // Find app to attach settings to
|
||||
// appName = _.find(appsData, function (app) {
|
||||
// return app.id === appSetting.app_id;
|
||||
// }).name;
|
||||
// ops.push(models.App.findOne({name: appName}, {transacting: transaction}).then(function (_app) {
|
||||
// if (_app) {
|
||||
// // Fix app_id
|
||||
// appSetting.app_id = _app.id;
|
||||
// return models.AppSetting.add(appSetting, {transacting: transaction})
|
||||
// // add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
// .catch(function (error) { return when.reject(error); });
|
||||
// }
|
||||
// // Gracefully ignore missing apps
|
||||
// return when.resolve(_app);
|
||||
// }));
|
||||
// });
|
||||
// }
|
||||
|
||||
// No data needs modifying, we just import whatever tables are available
|
||||
Importer000.prototype.basicImport = function (data) {
|
||||
var ops = [],
|
||||
@ -221,39 +44,34 @@ Importer000.prototype.basicImport = function (data) {
|
||||
|
||||
// Do any pre-processing of relationships (we can't depend on ids)
|
||||
if (tableData.posts_tags && tableData.posts && tableData.tags) {
|
||||
tableData = preProcessPostTags(tableData);
|
||||
tableData = utils.preProcessPostTags(tableData);
|
||||
}
|
||||
|
||||
// Import things in the right order:
|
||||
if (tableData.tags && tableData.tags.length) {
|
||||
importTags(ops, tableData.tags, t);
|
||||
utils.importTags(ops, tableData.tags, t);
|
||||
}
|
||||
|
||||
if (tableData.posts && tableData.posts.length) {
|
||||
importPosts(ops, tableData.posts, t);
|
||||
utils.importPosts(ops, tableData.posts, t);
|
||||
}
|
||||
|
||||
if (tableData.users && tableData.users.length) {
|
||||
importUsers(ops, tableData.users, t);
|
||||
// If we only have 1 user, behave as we always have done, overwriting properties,
|
||||
// Else attempt to import users like any other resource, failing if there are clashes
|
||||
if (tableData.users && tableData.users.length && tableData.users.length > 1) {
|
||||
if (tableData.roles_users && tableData.roles_users.length) {
|
||||
tableData = utils.preProcessRolesUsers(tableData);
|
||||
}
|
||||
|
||||
utils.importUsers(ops, tableData.users, t);
|
||||
} else if (tableData.users && tableData.users.length) {
|
||||
utils.importSingleUser(ops, tableData.users, t);
|
||||
}
|
||||
|
||||
if (tableData.settings && tableData.settings.length) {
|
||||
importSettings(ops, tableData.settings, t);
|
||||
utils.importSettings(ops, tableData.settings, t);
|
||||
}
|
||||
|
||||
if (tableData.apps && tableData.apps.length) {
|
||||
importApps(ops, tableData.apps, t);
|
||||
|
||||
// ToDo: This is rather complicated
|
||||
// Only import settings if there are apps defined
|
||||
//if (tableData.app_settings && tableData.app_settings.length) {
|
||||
// importAppSettings(ops, _.pick(tableData, 'apps', 'app_settings'), t);
|
||||
//}
|
||||
|
||||
//if (tableData.app_fields && tableData.app_fields.length) {
|
||||
// importAppFields(ops, _.pick(tableData, 'apps', 'posts', 'app_fields'), t);
|
||||
//}
|
||||
}
|
||||
|
||||
/** do nothing with these tables, the data shouldn't have changed from the fixtures
|
||||
* permissions
|
||||
|
@ -0,0 +1,189 @@
|
||||
var when = require('when'),
|
||||
_ = require('lodash'),
|
||||
models = require('../../models'),
|
||||
|
||||
internal = {context: {internal: true}},
|
||||
utils,
|
||||
areEmpty,
|
||||
updatedSettingKeys,
|
||||
stripProperties;
|
||||
|
||||
updatedSettingKeys = {
|
||||
activePlugins: 'activeApps',
|
||||
installedPlugins: 'installedApps'
|
||||
};
|
||||
|
||||
areEmpty = function (object) {
|
||||
var fields = _.toArray(arguments).slice(1),
|
||||
areEmpty = _.all(fields, function (field) {
|
||||
return _.isEmpty(object[field]);
|
||||
});
|
||||
|
||||
return areEmpty;
|
||||
};
|
||||
|
||||
stripProperties = function stripProperties(properties, data) {
|
||||
data = _.clone(data, true);
|
||||
_.each(data, function (obj) {
|
||||
_.each(properties, function (property) {
|
||||
delete obj[property];
|
||||
});
|
||||
});
|
||||
return data;
|
||||
};
|
||||
|
||||
utils = {
|
||||
preProcessPostTags: function preProcessPostTags(tableData) {
|
||||
var postTags,
|
||||
postsWithTags = {};
|
||||
|
||||
|
||||
postTags = tableData.posts_tags;
|
||||
_.each(postTags, function (post_tag) {
|
||||
if (!postsWithTags.hasOwnProperty(post_tag.post_id)) {
|
||||
postsWithTags[post_tag.post_id] = [];
|
||||
}
|
||||
postsWithTags[post_tag.post_id].push(post_tag.tag_id);
|
||||
});
|
||||
|
||||
_.each(postsWithTags, function (tag_ids, post_id) {
|
||||
var post, tags;
|
||||
post = _.find(tableData.posts, function (post) {
|
||||
return post.id === parseInt(post_id, 10);
|
||||
});
|
||||
if (post) {
|
||||
tags = _.filter(tableData.tags, function (tag) {
|
||||
return _.indexOf(tag_ids, tag.id) !== -1;
|
||||
});
|
||||
post.tags = [];
|
||||
_.each(tags, function (tag) {
|
||||
// names are unique.. this should get the right tags added
|
||||
// as long as tags are added first;
|
||||
post.tags.push({name: tag.name});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return tableData;
|
||||
},
|
||||
|
||||
preProcessRolesUsers: function preProcessRolesUsers(tableData) {
|
||||
_.each(tableData.roles_users, function (role_user) {
|
||||
var user = _.find(tableData.users, function (user) {
|
||||
return user.id === parseInt(role_user.user_id, 10);
|
||||
});
|
||||
// just the one role for now
|
||||
if (user && !user.roles) {
|
||||
user.roles = [role_user.role_id];
|
||||
}
|
||||
});
|
||||
|
||||
return tableData;
|
||||
},
|
||||
|
||||
importTags: function importTags(ops, tableData, transaction) {
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
_.each(tableData, function (tag) {
|
||||
// Validate minimum tag fields
|
||||
if (areEmpty(tag, 'name', 'slug')) {
|
||||
return;
|
||||
}
|
||||
|
||||
ops.push(models.Tag.findOne({name: tag.name}, {transacting: transaction}).then(function (_tag) {
|
||||
if (!_tag) {
|
||||
return models.Tag.add(tag, _.extend(internal, {transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'tag', data: tag});
|
||||
});
|
||||
}
|
||||
return when.resolve(_tag);
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
importPosts: function importPosts(ops, tableData, transaction) {
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
_.each(tableData, function (post) {
|
||||
// Validate minimum post fields
|
||||
if (areEmpty(post, 'title', 'slug', 'markdown')) {
|
||||
return;
|
||||
}
|
||||
ops.push(models.Post.add(post, _.extend(internal, {transacting: transaction, importing: true}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'post', data: post});
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
importUsers: function importUsers(ops, tableData, transaction) {
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
_.each(tableData, function (user) {
|
||||
// Validate minimum user fields
|
||||
if (areEmpty(user, 'name', 'slug', 'email')) {
|
||||
return;
|
||||
}
|
||||
|
||||
ops.push(models.User.add(user, _.extend(internal, {transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'user', data: user});
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
importSingleUser: function importSingleUser(ops, tableData, transaction) {
|
||||
// don't override the users credentials
|
||||
tableData = stripProperties(['id', 'email', 'password'], tableData);
|
||||
tableData[0].id = 1;
|
||||
ops.push(models.User.edit(tableData[0], _.extend(internal, {id: 1, transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.otherwise(function (error) {
|
||||
return when.reject(error);
|
||||
}));
|
||||
},
|
||||
|
||||
importSettings: function importSettings(ops, tableData, transaction) {
|
||||
// for settings we need to update individual settings, and insert any missing ones
|
||||
// settings we MUST NOT update are 'core' and 'theme' settings
|
||||
// as all of these will cause side effects which don't make sense for an import
|
||||
var blackList = ['core', 'theme'];
|
||||
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
tableData = _.filter(tableData, function (data) {
|
||||
return blackList.indexOf(data.type) === -1;
|
||||
});
|
||||
|
||||
// Clean up legacy plugin setting references
|
||||
_.each(tableData, function (datum) {
|
||||
datum.key = updatedSettingKeys[datum.key] || datum.key;
|
||||
});
|
||||
|
||||
ops.push(models.Settings.edit(tableData, _.extend(internal, {transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'setting', data: tableData});
|
||||
}));
|
||||
},
|
||||
|
||||
/** For later **/
|
||||
importApps: function importApps(ops, tableData, transaction) {
|
||||
tableData = stripProperties(['id'], tableData);
|
||||
_.each(tableData, function (app) {
|
||||
// Avoid duplicates
|
||||
ops.push(models.App.findOne({name: app.name}, {transacting: transaction}).then(function (_app) {
|
||||
if (!_app) {
|
||||
return models.App.add(app, _.extend(internal, {transacting: transaction}))
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.catch(function (error) {
|
||||
return when.reject({raw: error, model: 'app', data: app});
|
||||
});
|
||||
}
|
||||
return when.resolve(_app);
|
||||
}));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = utils;
|
@ -399,7 +399,8 @@ User = ghostBookshelf.Model.extend({
|
||||
|
||||
options = this.filterOptions(options, 'add');
|
||||
options.withRelated = _.union([ 'roles' ], options.include);
|
||||
return Role.findOne({name: 'Author'}).then(function (authorRole) {
|
||||
|
||||
return Role.findOne({name: 'Author'}, _.pick(options, 'transacting')).then(function (authorRole) {
|
||||
// Get the role we're going to assign to this user, or the author role if there isn't one
|
||||
roles = data.roles || [authorRole.get('id')];
|
||||
|
||||
@ -412,7 +413,7 @@ User = ghostBookshelf.Model.extend({
|
||||
|
||||
return validatePasswordLength(userData.password);
|
||||
}).then(function () {
|
||||
return self.forge().fetch();
|
||||
return self.forge().fetch(options);
|
||||
}).then(function () {
|
||||
// Generate a new password hash
|
||||
return generatePasswordHash(data.password);
|
||||
@ -438,7 +439,7 @@ User = ghostBookshelf.Model.extend({
|
||||
}
|
||||
});
|
||||
|
||||
return userData.roles().attach(roles);
|
||||
return userData.roles().attach(roles, options);
|
||||
}).then(function () {
|
||||
// find and return the added user
|
||||
return self.findOne({id: userData.id}, options);
|
||||
|
@ -515,15 +515,128 @@ describe('Import', function () {
|
||||
});
|
||||
|
||||
describe('003', function () {
|
||||
knex = config.database.knex;
|
||||
|
||||
beforeEach(testUtils.setup('owner', 'settings'));
|
||||
beforeEach(testUtils.setup('roles', 'owner', 'settings'));
|
||||
|
||||
should.exist(Importer003);
|
||||
|
||||
it('safely imports data from 003 (single user)', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003').then(function (exported) {
|
||||
exportData = exported;
|
||||
return importer('003', exportData);
|
||||
}).then(function () {
|
||||
// Grab the data from tables
|
||||
return when.all([
|
||||
knex('users').select(),
|
||||
knex('posts').select(),
|
||||
knex('settings').select(),
|
||||
knex('tags').select()
|
||||
]);
|
||||
}).then(function (importedData) {
|
||||
should.exist(importedData);
|
||||
|
||||
importedData.length.should.equal(4, 'Did not get data successfully');
|
||||
|
||||
var users = importedData[0],
|
||||
posts = importedData[1],
|
||||
settings = importedData[2],
|
||||
tags = importedData[3];
|
||||
|
||||
// user should still have the credentials from the original insert, not the import
|
||||
users[0].email.should.equal(testUtils.DataGenerator.Content.users[0].email);
|
||||
users[0].password.should.equal(testUtils.DataGenerator.Content.users[0].password);
|
||||
// but the name, slug, and bio should have been overridden
|
||||
users[0].name.should.equal(exportData.data.users[0].name);
|
||||
users[0].slug.should.equal(exportData.data.users[0].slug);
|
||||
users[0].bio.should.equal(exportData.data.users[0].bio);
|
||||
// test posts
|
||||
posts.length.should.equal(1, 'Wrong number of posts');
|
||||
// test tags
|
||||
tags.length.should.equal(1, 'no new tags');
|
||||
|
||||
// test settings
|
||||
settings.length.should.be.above(0, 'Wrong number of settings');
|
||||
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('safely imports data from 003 (multi user)', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('export-003-mu').then(function (exported) {
|
||||
exportData = exported;
|
||||
return importer('003', exportData);
|
||||
}).then(function () {
|
||||
// Grab the data from tables
|
||||
return when.all([
|
||||
knex('users').select(),
|
||||
knex('posts').select(),
|
||||
knex('settings').select(),
|
||||
knex('tags').select(),
|
||||
knex('roles_users').select()
|
||||
]);
|
||||
}).then(function (importedData) {
|
||||
should.exist(importedData);
|
||||
var user2,
|
||||
user3;
|
||||
|
||||
importedData.length.should.equal(5, 'Did not get data successfully');
|
||||
|
||||
var users = importedData[0],
|
||||
posts = importedData[1],
|
||||
settings = importedData[2],
|
||||
tags = importedData[3],
|
||||
roles_users = importedData[4];
|
||||
|
||||
// we imported 2 users, the original user should be untouched
|
||||
users.length.should.equal(3, 'There should only be three users');
|
||||
users[0].email.should.equal(testUtils.DataGenerator.Content.users[0].email);
|
||||
users[0].password.should.equal(testUtils.DataGenerator.Content.users[0].password);
|
||||
|
||||
// the other two users should have the imported data, but they get inserted in different orders
|
||||
user2 = _.find(users, function (user) {
|
||||
return user.name === 'Josephine Bloggs';
|
||||
});
|
||||
user3 = _.find(users, function (user) {
|
||||
return user.name === 'Smith Wellingsworth';
|
||||
});
|
||||
user2.email.should.equal(exportData.data.users[0].email);
|
||||
user3.email.should.equal(exportData.data.users[1].email);
|
||||
|
||||
roles_users.length.should.equal(2, 'There should be 3 role relations');
|
||||
|
||||
_.each(roles_users, function (roleUser) {
|
||||
if (roleUser.user_id === user2.id) {
|
||||
roleUser.role_id.should.equal(1, 'Josephine should be an admin');
|
||||
}
|
||||
|
||||
if (roleUser.user_id === user3.id) {
|
||||
roleUser.role_id.should.equal(3, 'Smith should be an author by default');
|
||||
}
|
||||
});
|
||||
|
||||
// test posts
|
||||
posts.length.should.equal(1, 'Wrong number of posts');
|
||||
// test tags
|
||||
tags.length.should.equal(1, 'no new tags');
|
||||
|
||||
// test settings
|
||||
settings.length.should.be.above(0, 'Wrong number of settings');
|
||||
_.findWhere(settings, {key: 'databaseVersion'}).value.should.equal('003', 'Wrong database version');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('handles validation errors nicely', function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.fixtures.loadExportFixture('broken-validation').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-badValidation').then(function (exported) {
|
||||
exportData = exported;
|
||||
return importer('003', exportData);
|
||||
}).catch(function (response) {
|
||||
@ -544,7 +657,7 @@ describe('Import', function () {
|
||||
|
||||
it('handles database errors nicely', function (done) {
|
||||
var exportData;
|
||||
testUtils.fixtures.loadExportFixture('broken-db-errors').then(function (exported) {
|
||||
testUtils.fixtures.loadExportFixture('export-003-dbErrors').then(function (exported) {
|
||||
exportData = exported;
|
||||
return importer('003', exportData);
|
||||
}).catch(function (response) {
|
||||
|
392
core/test/utils/fixtures/export-003-mu.json
Normal file
392
core/test/utils/fixtures/export-003-mu.json
Normal file
@ -0,0 +1,392 @@
|
||||
{
|
||||
"meta": {
|
||||
"exported_on": 1388318311015,
|
||||
"version": "003"
|
||||
},
|
||||
"data": {
|
||||
"posts": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "8492fbba-1102-4b53-8e3e-abe207952f0c",
|
||||
"title": "Welcome to Ghost",
|
||||
"slug": "welcome-to-ghost",
|
||||
"markdown": "You're live! Nice.",
|
||||
"html": "<p>You're live! Nice.</p>",
|
||||
"image": null,
|
||||
"featured": 0,
|
||||
"page": 0,
|
||||
"status": "published",
|
||||
"language": "en_US",
|
||||
"meta_title": null,
|
||||
"meta_description": null,
|
||||
"author_id": 1,
|
||||
"created_at": 1388318310782,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310782,
|
||||
"updated_by": 1,
|
||||
"published_at": 1388318310783,
|
||||
"published_by": 1
|
||||
}
|
||||
],
|
||||
"users": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "e5188224-4742-4c32-a2d6-e9c5c5d4c123",
|
||||
"name": "Josephine Bloggs",
|
||||
"slug": "josephine-blogs",
|
||||
"password": "$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKABC",
|
||||
"email": "josephinebloggs@example.com",
|
||||
"image": null,
|
||||
"cover": null,
|
||||
"bio": "A blogger",
|
||||
"website": null,
|
||||
"location": null,
|
||||
"accessibility": null,
|
||||
"status": "active",
|
||||
"language": "en_US",
|
||||
"meta_title": null,
|
||||
"meta_description": null,
|
||||
"last_login": null,
|
||||
"created_at": 1388319501897,
|
||||
"created_by": 1,
|
||||
"updated_at": null,
|
||||
"updated_by": null
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"uuid": "e5188224-4742-4c32-a2d6-e9c5c5d4c456",
|
||||
"name": "Smith Wellingsworth",
|
||||
"slug": "smith-wellingsworth",
|
||||
"email": "swellingsworth@example.com",
|
||||
"password": "$2a$10$.pZeeBE0gHXd0PTnbT/ph.GEKgd0Wd3q2pWna3ynTGBkPKnGIKZL6",
|
||||
"image": null,
|
||||
"cover": null,
|
||||
"bio": null,
|
||||
"website": null,
|
||||
"location": null,
|
||||
"accessibility": null,
|
||||
"status": "invited",
|
||||
"language": "en_US",
|
||||
"meta_title": null,
|
||||
"meta_description": null,
|
||||
"last_login": null,
|
||||
"created_at": 1388319501897,
|
||||
"created_by": 1,
|
||||
"updated_at": null,
|
||||
"updated_by": null
|
||||
}
|
||||
],
|
||||
"roles": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "d2ea9c7f-7e6b-4cae-b009-35c298206852",
|
||||
"name": "Administrator",
|
||||
"description": "Administrators",
|
||||
"created_at": 1388318310794,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310794,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"uuid": "b0d7d6b0-5b88-45b5-b0e5-a487741b843d",
|
||||
"name": "Editor",
|
||||
"description": "Editors",
|
||||
"created_at": 1388318310796,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310796,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"uuid": "9f72e817-5490-4ccf-bc78-c557dc9613ca",
|
||||
"name": "Author",
|
||||
"description": "Authors",
|
||||
"created_at": 1388318310799,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310799,
|
||||
"updated_by": 1
|
||||
}
|
||||
],
|
||||
"roles_users": [
|
||||
{
|
||||
"id": 1,
|
||||
"role_id": 1,
|
||||
"user_id": 1
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "bdfbd261-e0fb-4c8e-abab-aece7a9e8e34",
|
||||
"name": "Edit posts",
|
||||
"object_type": "post",
|
||||
"action_type": "edit",
|
||||
"object_id": null,
|
||||
"created_at": 1388318310803,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310803,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"uuid": "580d31c4-e3db-40f3-969d-9a1caea9d1bb",
|
||||
"name": "Remove posts",
|
||||
"object_type": "post",
|
||||
"action_type": "remove",
|
||||
"object_id": null,
|
||||
"created_at": 1388318310814,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310814,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"uuid": "c1f8b024-e383-494a-835d-6fb673f143db",
|
||||
"name": "Create posts",
|
||||
"object_type": "post",
|
||||
"action_type": "create",
|
||||
"object_id": null,
|
||||
"created_at": 1388318310818,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310818,
|
||||
"updated_by": 1
|
||||
}
|
||||
],
|
||||
"permissions_users": [],
|
||||
"permissions_roles": [
|
||||
{
|
||||
"id": 1,
|
||||
"role_id": 1,
|
||||
"permission_id": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"role_id": 1,
|
||||
"permission_id": 2
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"role_id": 1,
|
||||
"permission_id": 3
|
||||
}
|
||||
],
|
||||
"settings": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "f90aa810-4fa2-49fe-a39b-7c0d2ebb473e",
|
||||
"key": "databaseVersion",
|
||||
"value": "001",
|
||||
"type": "core",
|
||||
"created_at": 1388318310829,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310829,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"uuid": "95ce1c53-69b0-4f5f-be91-d3aeb39046b5",
|
||||
"key": "dbHash",
|
||||
"value": null,
|
||||
"type": "core",
|
||||
"created_at": 1388318310829,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310829,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"uuid": "c356fbde-0bc5-4fe1-9309-2510291aa34d",
|
||||
"key": "title",
|
||||
"value": "Ghost",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310830,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310830,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"uuid": "858dc11f-8f9e-4011-99ee-d94c48d5a2ce",
|
||||
"key": "description",
|
||||
"value": "Just a blogging platform.",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310830,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310830,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"uuid": "37ca5ae7-bca6-4dd5-8021-4ef6c6dcb097",
|
||||
"key": "email",
|
||||
"value": "josephinebloggs@example.com",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310830,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310830,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"uuid": "1672d62c-fab7-4f22-b333-8cf760189f67",
|
||||
"key": "logo",
|
||||
"value": "",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310830,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310830,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"uuid": "cd8b0456-578b-467a-857e-551bad17a14d",
|
||||
"key": "cover",
|
||||
"value": "",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310830,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310830,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"uuid": "c4a074a4-05c7-49f7-83eb-068302c15d82",
|
||||
"key": "defaultLang",
|
||||
"value": "en_US",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310830,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310830,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"uuid": "21f2f5da-9bee-4dae-b3b7-b8d7baf8be33",
|
||||
"key": "postsPerPage",
|
||||
"value": "6",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310830,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310830,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"uuid": "2d21b736-f85a-4119-a0e3-5fc898b1bf47",
|
||||
"key": "forceI18n",
|
||||
"value": "true",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310831,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310831,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"uuid": "5c5b91b8-6062-4104-b855-9e121f72b0f0",
|
||||
"key": "permalinks",
|
||||
"value": "/:slug/",
|
||||
"type": "blog",
|
||||
"created_at": 1388318310831,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310831,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"uuid": "795cb328-3e38-4906-81a8-fcdff19d914f",
|
||||
"key": "activeTheme",
|
||||
"value": "notcasper",
|
||||
"type": "theme",
|
||||
"created_at": 1388318310831,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310831,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"uuid": "f3afce35-5166-453e-86c3-50dfff74dca7",
|
||||
"key": "activeApps",
|
||||
"value": "[]",
|
||||
"type": "plugin",
|
||||
"created_at": 1388318310831,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310831,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"uuid": "2ea560a3-2304-449d-a62b-f7b622987510",
|
||||
"key": "installedApps",
|
||||
"value": "[]",
|
||||
"type": "plugin",
|
||||
"created_at": 1388318310831,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310831,
|
||||
"updated_by": 1
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "a950117a-9735-4584-931d-25a28015a80d",
|
||||
"name": "Getting Started",
|
||||
"slug": "getting-started",
|
||||
"description": null,
|
||||
"parent_id": null,
|
||||
"meta_title": null,
|
||||
"meta_description": null,
|
||||
"created_at": 1388318310790,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318310790,
|
||||
"updated_by": 1
|
||||
}
|
||||
],
|
||||
"posts_tags": [
|
||||
{
|
||||
"id": 1,
|
||||
"post_id": 1,
|
||||
"tag_id": 1
|
||||
}
|
||||
],
|
||||
"apps": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "4d7557f0-0949-4946-9fe8-ec030e0727f0",
|
||||
"name": "Kudos",
|
||||
"slug": "kudos",
|
||||
"version": "0.0.1",
|
||||
"status": "installed",
|
||||
"created_at": 1388318312790,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318312790,
|
||||
"updated_by": 1
|
||||
}
|
||||
],
|
||||
"app_settings": [
|
||||
{
|
||||
"id": 1,
|
||||
"uuid": "790e4551-b9cc-4954-8f5d-b6e651bc7342",
|
||||
"key": "position",
|
||||
"value": "bottom",
|
||||
"app_id": 1,
|
||||
"created_at": 1388318312790,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318312790,
|
||||
"updated_by": 1
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"uuid": "29682b66-cdeb-4773-9821-bcf40ea93b58",
|
||||
"key": "size",
|
||||
"value": "60",
|
||||
"app_id": 1,
|
||||
"created_at": 1388318312790,
|
||||
"created_by": 1,
|
||||
"updated_at": 1388318312790,
|
||||
"updated_by": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user