mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-20 22:42:53 -05:00
Implements Models & Data API for Apps
closes #2138 - Adds new models for AppField and AppSetting - Removed permitted attributes from App model (handled by base) - Added reference from Post to AppFields - Added fixture data to DataGenerator - Added integration tests for Apps, AppSettings, AppFields - Added import for Apps - Added app_fields to default fixtures
This commit is contained in:
parent
7b003beb17
commit
41cef386bc
18 changed files with 959 additions and 20 deletions
|
@ -12,7 +12,8 @@ Importer000 = function () {
|
|||
this.importFrom = {
|
||||
'000': this.basicImport,
|
||||
'001': this.basicImport,
|
||||
'002': this.basicImport
|
||||
'002': this.basicImport,
|
||||
'003': this.basicImport
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -35,6 +36,7 @@ Importer000.prototype.canImport = function (data) {
|
|||
|
||||
|
||||
function stripProperties(properties, data) {
|
||||
data = _.clone(data, true);
|
||||
_.each(data, function (obj) {
|
||||
_.each(properties, function (property) {
|
||||
delete obj[property];
|
||||
|
@ -125,6 +127,47 @@ function importSettings(ops, tableData, transaction) {
|
|||
.otherwise(function (error) { return when.reject(error); }));
|
||||
}
|
||||
|
||||
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, {transacting: transaction})
|
||||
// add pass-through error handling so that bluebird doesn't think we've dropped it
|
||||
.otherwise(function (error) { return when.reject(error); });
|
||||
}
|
||||
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
|
||||
.otherwise(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 = [],
|
||||
|
@ -153,6 +196,20 @@ Importer000.prototype.basicImport = function (data) {
|
|||
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
|
||||
* roles
|
||||
|
|
8
core/server/data/import/003.js
Normal file
8
core/server/data/import/003.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
var Importer000 = require('./000');
|
||||
|
||||
module.exports = {
|
||||
Importer003: Importer000,
|
||||
importData: function (data) {
|
||||
return new Importer000.importData(data);
|
||||
}
|
||||
};
|
|
@ -1,12 +1,11 @@
|
|||
var ghostBookshelf = require('./base'),
|
||||
AppSetting = require('./appSetting'),
|
||||
App,
|
||||
Apps;
|
||||
|
||||
App = ghostBookshelf.Model.extend({
|
||||
tableName: 'apps',
|
||||
|
||||
permittedAttributes: ['id', 'uuid', 'name', 'created_at', 'created_by', 'updated_at', 'updated_by'],
|
||||
|
||||
validate: function () {
|
||||
ghostBookshelf.validator.check(this.get('name'), "App name cannot be blank").notEmpty();
|
||||
},
|
||||
|
@ -14,6 +13,10 @@ App = ghostBookshelf.Model.extend({
|
|||
permissions: function () {
|
||||
// Have to use the require here because of circular dependencies
|
||||
return this.belongsToMany(require('./permission').Permission, 'permissions_apps');
|
||||
},
|
||||
|
||||
settings: function () {
|
||||
return this.belongsToMany(AppSetting, 'app_settings');
|
||||
}
|
||||
});
|
||||
|
||||
|
|
32
core/server/models/appField.js
Normal file
32
core/server/models/appField.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
var ghostBookshelf = require('./base'),
|
||||
Post = require('./post').Post,
|
||||
AppField,
|
||||
AppFields;
|
||||
|
||||
AppField = ghostBookshelf.Model.extend({
|
||||
tableName: 'app_fields',
|
||||
|
||||
validate: function () {
|
||||
ghostBookshelf.validator.check(this.get('key'), 'Key cannot be blank').notEmpty();
|
||||
ghostBookshelf.validator.check(this.get('key'), 'Key maximum length is 150 characters.').len(0, 150);
|
||||
ghostBookshelf.validator.check(this.get('app_id'), 'App cannot be blank').notEmpty();
|
||||
ghostBookshelf.validator.check(this.get('type'), 'Type maximum length is 150 characters.').len(0, 150);
|
||||
ghostBookshelf.validator.check(this.get('relatable_id'), 'Relatable id cannot be blank').notEmpty();
|
||||
ghostBookshelf.validator.check(this.get('relatable_type'), 'Relatable type cannot be blank').notEmpty();
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
post: function () {
|
||||
return this.morphOne(Post, 'relatable');
|
||||
}
|
||||
});
|
||||
|
||||
AppFields = ghostBookshelf.Collection.extend({
|
||||
model: AppField
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
AppField: AppField,
|
||||
AppFields: AppFields
|
||||
};
|
30
core/server/models/appSetting.js
Normal file
30
core/server/models/appSetting.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
var ghostBookshelf = require('./base'),
|
||||
App = require('./app'),
|
||||
AppSetting,
|
||||
AppSettings;
|
||||
|
||||
AppSetting = ghostBookshelf.Model.extend({
|
||||
tableName: 'app_settings',
|
||||
|
||||
validate: function () {
|
||||
ghostBookshelf.validator.check(this.get('key'), 'Key cannot be blank').notEmpty();
|
||||
ghostBookshelf.validator.check(this.get('key'), 'Key maximum length is 150 characters.').len(0, 150);
|
||||
ghostBookshelf.validator.check(this.get('app_id'), 'App cannot be blank').notEmpty();
|
||||
ghostBookshelf.validator.check(this.get('type'), 'Type maximum length is 150 characters.').len(0, 150);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
app: function () {
|
||||
return this.belongsTo(App);
|
||||
}
|
||||
});
|
||||
|
||||
AppSettings = ghostBookshelf.Collection.extend({
|
||||
model: AppSetting
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
AppSetting: AppSetting,
|
||||
AppSettings: AppSettings
|
||||
};
|
|
@ -12,6 +12,8 @@ module.exports = {
|
|||
Base: require('./base'),
|
||||
Session: require('./session').Session,
|
||||
App: require('./app').App,
|
||||
AppField: require('./appField').AppField,
|
||||
AppSetting: require('./appSetting').AppSetting,
|
||||
|
||||
init: function () {
|
||||
return migrations.init();
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
var ghostBookshelf = require('./base'),
|
||||
_ = require('lodash'),
|
||||
when = require('when'),
|
||||
User = require('./user').User,
|
||||
Role = require('./role').Role,
|
||||
App = require('./app').App,
|
||||
|
|
|
@ -5,6 +5,7 @@ var _ = require('lodash'),
|
|||
Showdown = require('showdown'),
|
||||
ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'),
|
||||
converter = new Showdown.converter({extensions: [ghostgfm]}),
|
||||
AppField = require('./appField').AppField,
|
||||
User = require('./user').User,
|
||||
Tag = require('./tag').Tag,
|
||||
Tags = require('./tag').Tags,
|
||||
|
@ -198,6 +199,10 @@ Post = ghostBookshelf.Model.extend({
|
|||
|
||||
tags: function () {
|
||||
return this.belongsToMany(Tag);
|
||||
},
|
||||
|
||||
fields: function () {
|
||||
return this.morphMany(AppField, 'relatable');
|
||||
}
|
||||
|
||||
}, {
|
||||
|
@ -206,7 +211,8 @@ Post = ghostBookshelf.Model.extend({
|
|||
// Extends base model findAll to eager-fetch author and user relationships.
|
||||
findAll: function (options) {
|
||||
options = options || {};
|
||||
options.withRelated = [ 'author', 'tags' ];
|
||||
|
||||
options.withRelated = [ 'author', 'tags', 'fields' ];
|
||||
return ghostBookshelf.Model.findAll.call(this, options);
|
||||
},
|
||||
|
||||
|
@ -223,7 +229,7 @@ Post = ghostBookshelf.Model.extend({
|
|||
delete args.status;
|
||||
}
|
||||
|
||||
options.withRelated = [ 'author', 'tags' ];
|
||||
options.withRelated = [ 'author', 'tags', 'fields' ];
|
||||
return ghostBookshelf.Model.findOne.call(this, args, options);
|
||||
},
|
||||
|
||||
|
@ -289,7 +295,7 @@ Post = ghostBookshelf.Model.extend({
|
|||
}
|
||||
|
||||
// Fetch related models
|
||||
opts.withRelated = [ 'author', 'tags' ];
|
||||
opts.withRelated = [ 'author', 'tags', 'fields' ];
|
||||
|
||||
// If a query param for a tag is attached
|
||||
// we need to fetch the tag model to find its id
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
Models = require('../models'),
|
||||
errors = require('../errorHandling'),
|
||||
User = Models.User,
|
||||
|
|
76
core/test/integration/model/model_app_fields_spec.js
Normal file
76
core/test/integration/model/model_app_fields_spec.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*globals describe, before, beforeEach, afterEach, it*/
|
||||
var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
_ = require("lodash"),
|
||||
|
||||
// Stuff we are testing
|
||||
Models = require('../../../server/models'),
|
||||
knex = require('../../../server/models/base').knex;
|
||||
|
||||
describe('App Fields Model', function () {
|
||||
|
||||
var AppFieldsModel = Models.AppField;
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
return testUtils.insertApps();
|
||||
})
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
AppFieldsModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
AppFieldsModel.read({id: 1}).then(function (foundAppField) {
|
||||
should.exist(foundAppField);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
AppFieldsModel.read({id: 1}).then(function (foundAppField) {
|
||||
should.exist(foundAppField);
|
||||
|
||||
return foundAppField.set({value: "350"}).save();
|
||||
}).then(function () {
|
||||
return AppFieldsModel.read({id: 1});
|
||||
}).then(function (updatedAppField) {
|
||||
should.exist(updatedAppField);
|
||||
|
||||
updatedAppField.get("value").should.equal("350");
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
76
core/test/integration/model/model_app_settings_spec.js
Normal file
76
core/test/integration/model/model_app_settings_spec.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*globals describe, before, beforeEach, afterEach, it*/
|
||||
var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
_ = require("lodash"),
|
||||
|
||||
// Stuff we are testing
|
||||
Models = require('../../../server/models'),
|
||||
knex = require('../../../server/models/base').knex;
|
||||
|
||||
describe('App Setting Model', function () {
|
||||
|
||||
var AppSettingModel = Models.AppSetting;
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
return testUtils.insertAppWithSettings();
|
||||
})
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
AppSettingModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
AppSettingModel.read({id: 1}).then(function (foundAppSetting) {
|
||||
should.exist(foundAppSetting);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
AppSettingModel.read({id: 1}).then(function (foundAppSetting) {
|
||||
should.exist(foundAppSetting);
|
||||
|
||||
return foundAppSetting.set({value: "350"}).save();
|
||||
}).then(function () {
|
||||
return AppSettingModel.read({id: 1});
|
||||
}).then(function (updatedAppSetting) {
|
||||
should.exist(updatedAppSetting);
|
||||
|
||||
updatedAppSetting.get("value").should.equal("350");
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
106
core/test/integration/model/model_apps_spec.js
Normal file
106
core/test/integration/model/model_apps_spec.js
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*globals describe, before, beforeEach, afterEach, it*/
|
||||
var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
_ = require("lodash"),
|
||||
|
||||
// Stuff we are testing
|
||||
Models = require('../../../server/models'),
|
||||
knex = require('../../../server/models/base').knex;
|
||||
|
||||
describe('App Model', function () {
|
||||
|
||||
var AppModel = Models.App;
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
beforeEach(function (done) {
|
||||
testUtils.initData()
|
||||
.then(function () {
|
||||
return testUtils.insertDefaultApp();
|
||||
})
|
||||
.then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
afterEach(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can browse', function (done) {
|
||||
AppModel.browse().then(function (results) {
|
||||
|
||||
should.exist(results);
|
||||
|
||||
results.length.should.be.above(0);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can read', function (done) {
|
||||
AppModel.read({id: 1}).then(function (foundApp) {
|
||||
should.exist(foundApp);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can edit', function (done) {
|
||||
AppModel.read({id: 1}).then(function (foundApp) {
|
||||
should.exist(foundApp);
|
||||
|
||||
return foundApp.set({name: "New App"}).save();
|
||||
}).then(function () {
|
||||
return AppModel.read({id: 1});
|
||||
}).then(function (updatedApp) {
|
||||
should.exist(updatedApp);
|
||||
|
||||
updatedApp.get("name").should.equal("New App");
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can add", function (done) {
|
||||
var newApp = testUtils.DataGenerator.forKnex.createApp(testUtils.DataGenerator.Content.apps[1]);
|
||||
|
||||
AppModel.add(newApp).then(function (createdApp) {
|
||||
should.exist(createdApp);
|
||||
|
||||
createdApp.attributes.name.should.equal(newApp.name);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("can delete", function (done) {
|
||||
AppModel.read({id: 1}).then(function (foundApp) {
|
||||
should.exist(foundApp);
|
||||
|
||||
return AppModel['delete'](1);
|
||||
}).then(function () {
|
||||
return AppModel.browse();
|
||||
}).then(function (foundApp) {
|
||||
var hasRemovedId = foundApp.any(function (foundApp) {
|
||||
return foundApp.id === 1;
|
||||
});
|
||||
|
||||
hasRemovedId.should.equal(false);
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
|
@ -6,13 +6,12 @@ var testUtils = require('../../utils'),
|
|||
sequence = require('when/sequence'),
|
||||
|
||||
// Stuff we are testing
|
||||
DataGenerator = require('../../utils/fixtures/data-generator'),
|
||||
Models = require('../../../server/models');
|
||||
Models = require('../../../server/models'),
|
||||
DataGenerator = testUtils.DataGenerator;
|
||||
|
||||
describe('Post Model', function () {
|
||||
|
||||
var PostModel = Models.Post,
|
||||
UserModel = Models.User;
|
||||
var PostModel = Models.Post;
|
||||
|
||||
before(function (done) {
|
||||
testUtils.clearData().then(function () {
|
||||
|
@ -66,7 +65,7 @@ describe('Post Model', function () {
|
|||
}).then(null, done);
|
||||
});
|
||||
|
||||
it('can findAll, returning author and user data', function (done) {
|
||||
it('can findAll, returning author, user and field data', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.findAll({}).then(function (results) {
|
||||
|
@ -75,13 +74,15 @@ describe('Post Model', function () {
|
|||
firstPost = results.models[0].toJSON();
|
||||
|
||||
firstPost.author.should.be.an.Object;
|
||||
firstPost.fields.should.be.an.Array;
|
||||
firstPost.author.name.should.equal(DataGenerator.Content.users[0].name);
|
||||
firstPost.fields[0].key.should.equal(DataGenerator.Content.app_fields[0].key);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
});
|
||||
|
||||
it('can findOne, returning author and user data', function (done) {
|
||||
it('can findOne, returning author, user and field data', function (done) {
|
||||
var firstPost;
|
||||
|
||||
PostModel.findOne({}).then(function (result) {
|
||||
|
@ -89,7 +90,9 @@ describe('Post Model', function () {
|
|||
firstPost = result.toJSON();
|
||||
|
||||
firstPost.author.should.be.an.Object;
|
||||
firstPost.fields.should.be.an.Array;
|
||||
firstPost.author.name.should.equal(testUtils.DataGenerator.Content.users[0].name);
|
||||
firstPost.fields[0].key.should.equal(DataGenerator.Content.app_fields[0].key);
|
||||
|
||||
done();
|
||||
}, done);
|
||||
|
|
|
@ -15,6 +15,7 @@ var testUtils = require('../utils'),
|
|||
Importer000 = require('../../server/data/import/000'),
|
||||
Importer001 = require('../../server/data/import/001'),
|
||||
Importer002 = require('../../server/data/import/002'),
|
||||
Importer003 = require('../../server/data/import/003'),
|
||||
fixtures = require('../../server/data/fixtures'),
|
||||
Settings = require('../../server/models/settings').Settings;
|
||||
|
||||
|
@ -82,6 +83,21 @@ describe("Import", function () {
|
|||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("resolves 003", function (done) {
|
||||
var importStub = sandbox.stub(Importer003, "importData", function () {
|
||||
return when.resolve();
|
||||
}),
|
||||
fakeData = { test: true };
|
||||
|
||||
importer("003", fakeData).then(function () {
|
||||
importStub.calledWith(fakeData).should.equal(true);
|
||||
|
||||
importStub.restore();
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
describe("000", function () {
|
||||
should.exist(Importer000);
|
||||
|
||||
|
@ -336,7 +352,7 @@ describe("Import", function () {
|
|||
});
|
||||
|
||||
describe("002", function () {
|
||||
should.exist(Importer001);
|
||||
should.exist(Importer002);
|
||||
|
||||
beforeEach(function (done) {
|
||||
// migrate to current version
|
||||
|
@ -521,4 +537,53 @@ describe("Import", function () {
|
|||
}).then(null, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe("003", function () {
|
||||
should.exist(Importer003);
|
||||
|
||||
beforeEach(function (done) {
|
||||
// migrate to current version
|
||||
migration.migrateUp().then(function () {
|
||||
// Load the fixtures
|
||||
return fixtures.populateFixtures();
|
||||
}).then(function () {
|
||||
// Initialise the default settings
|
||||
return Settings.populateDefaults();
|
||||
}).then(function () {
|
||||
return testUtils.insertDefaultUser();
|
||||
}).then(function () {
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
|
||||
it("safely imports data from 003", function (done) {
|
||||
var exportData;
|
||||
|
||||
testUtils.loadExportFixture('export-003').then(function (exported) {
|
||||
exportData = exported;
|
||||
return importer("003", exportData);
|
||||
}).then(function () {
|
||||
// Grab the data from tables
|
||||
return when.all([
|
||||
knex("apps").select(),
|
||||
knex("app_settings").select()
|
||||
]);
|
||||
}).then(function (importedData) {
|
||||
should.exist(importedData);
|
||||
|
||||
importedData.length.should.equal(2, 'Did not get data successfully');
|
||||
|
||||
var apps = importedData[0],
|
||||
app_settings = importedData[1];
|
||||
|
||||
// test apps
|
||||
apps.length.should.equal(exportData.data.apps.length, 'imported apps');
|
||||
|
||||
// test app settings
|
||||
// app_settings.length.should.equal(exportData.data.app_settings.length, 'imported app settings');
|
||||
|
||||
done();
|
||||
}).then(null, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ var _ = require('lodash'),
|
|||
posts: ['posts', 'page', 'limit', 'pages', 'total'],
|
||||
post: ['id', 'uuid', 'title', 'slug', 'markdown', 'html', 'meta_title', 'meta_description',
|
||||
'featured', 'image', 'status', 'language', 'author_id', 'created_at', 'created_by', 'updated_at',
|
||||
'updated_by', 'published_at', 'published_by', 'page', 'author', 'tags'],
|
||||
'updated_by', 'published_at', 'published_by', 'page', 'author', 'tags', 'fields'],
|
||||
// TODO: remove databaseVersion, dbHash
|
||||
settings: ['databaseVersion', 'dbHash', 'title', 'description', 'email', 'logo', 'cover', 'defaultLang',
|
||||
"permalinks", 'postsPerPage', 'forceI18n', 'activeTheme', 'activeApps', 'installedApps',
|
||||
|
|
|
@ -113,6 +113,30 @@ DataGenerator.Content = {
|
|||
{
|
||||
name: 'Hemingway'
|
||||
}
|
||||
],
|
||||
|
||||
app_fields: [
|
||||
{
|
||||
key: 'count',
|
||||
value: '120',
|
||||
type: 'number'
|
||||
},
|
||||
{
|
||||
key: 'words',
|
||||
value: '512',
|
||||
type: 'number'
|
||||
}
|
||||
],
|
||||
|
||||
app_settings: [
|
||||
{
|
||||
key: 'color',
|
||||
value: 'ghosty'
|
||||
},
|
||||
{
|
||||
key: 'setting',
|
||||
value: 'value'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
@ -120,7 +144,9 @@ DataGenerator.forKnex = (function () {
|
|||
|
||||
var posts,
|
||||
tags,
|
||||
posts_tags;
|
||||
posts_tags,
|
||||
apps,
|
||||
app_fields;
|
||||
|
||||
function createPost(overrides) {
|
||||
return _.defaults(overrides, {
|
||||
|
@ -205,6 +231,25 @@ DataGenerator.forKnex = (function () {
|
|||
});
|
||||
}
|
||||
|
||||
function createAppField(overrides) {
|
||||
return _.defaults(overrides, {
|
||||
uuid: uuid.v4(),
|
||||
created_by: 1,
|
||||
created_at: new Date(),
|
||||
app_id: 1,
|
||||
relatable_id: 1,
|
||||
relatable_type: 'posts'
|
||||
});
|
||||
}
|
||||
|
||||
function createAppSetting(overrides) {
|
||||
return _.defaults(overrides, {
|
||||
uuid: uuid.v4(),
|
||||
created_by: 1,
|
||||
created_at: new Date()
|
||||
});
|
||||
}
|
||||
|
||||
posts = [
|
||||
createPost(DataGenerator.Content.posts[0]),
|
||||
createPost(DataGenerator.Content.posts[1]),
|
||||
|
@ -232,6 +277,17 @@ DataGenerator.forKnex = (function () {
|
|||
{ post_id: 5, tag_id: 5 }
|
||||
];
|
||||
|
||||
apps = [
|
||||
createApp(DataGenerator.Content.apps[0]),
|
||||
createApp(DataGenerator.Content.apps[1]),
|
||||
createApp(DataGenerator.Content.apps[2])
|
||||
];
|
||||
|
||||
app_fields = [
|
||||
createAppField(DataGenerator.Content.app_fields[0]),
|
||||
createAppField(DataGenerator.Content.app_fields[1])
|
||||
];
|
||||
|
||||
return {
|
||||
createPost: createPost,
|
||||
createGenericPost: createGenericPost,
|
||||
|
@ -239,10 +295,16 @@ DataGenerator.forKnex = (function () {
|
|||
createUser: createUser,
|
||||
createGenericUser: createGenericUser,
|
||||
createUserRole: createUserRole,
|
||||
createPostsTags: createPostsTags,
|
||||
createApp: createApp,
|
||||
createAppField: createAppField,
|
||||
createAppSetting: createAppSetting,
|
||||
|
||||
posts: posts,
|
||||
tags: tags,
|
||||
posts_tags: posts_tags
|
||||
posts_tags: posts_tags,
|
||||
apps: apps,
|
||||
app_fields: app_fields
|
||||
};
|
||||
|
||||
}());
|
||||
|
|
366
core/test/utils/fixtures/export-003.json
Normal file
366
core/test/utils/fixtures/export-003.json
Normal file
|
@ -0,0 +1,366 @@
|
|||
{
|
||||
"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
|
||||
}
|
||||
],
|
||||
"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",
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ function clearData() {
|
|||
}
|
||||
|
||||
function insertPosts() {
|
||||
// ToDo: Get rid of pyramid of doom
|
||||
return when(knex('posts').insert(DataGenerator.forKnex.posts).then(function () {
|
||||
return knex('tags').insert(DataGenerator.forKnex.tags).then(function () {
|
||||
return knex('posts_tags').insert(DataGenerator.forKnex.posts_tags);
|
||||
|
@ -114,9 +115,55 @@ function insertDefaultApp() {
|
|||
});
|
||||
}
|
||||
|
||||
function insertApps() {
|
||||
return knex('apps').insert(DataGenerator.forKnex.apps).then(function () {
|
||||
return knex('app_fields').insert(DataGenerator.forKnex.app_fields);
|
||||
});
|
||||
}
|
||||
|
||||
function insertAppWithSettings() {
|
||||
var apps = [], app_settings = [];
|
||||
|
||||
apps.push(DataGenerator.forKnex.createApp(DataGenerator.Content.apps[0]));
|
||||
app_settings.push(DataGenerator.forKnex.createAppSetting(DataGenerator.Content.app_settings[0]));
|
||||
app_settings.push(DataGenerator.forKnex.createAppSetting(DataGenerator.Content.app_settings[1]));
|
||||
|
||||
return knex('apps').insert(apps, 'id')
|
||||
.then(function (results) {
|
||||
var appId = results[0];
|
||||
|
||||
for (var i = 0; i < app_settings.length; i++) {
|
||||
app_settings[i].app_id = appId;
|
||||
}
|
||||
|
||||
return knex('app_settings').insert(app_settings);
|
||||
});
|
||||
}
|
||||
function insertAppWithFields() {
|
||||
var apps = [], app_fields = [];
|
||||
|
||||
apps.push(DataGenerator.forKnex.createApp(DataGenerator.Content.apps[0]));
|
||||
app_fields.push(DataGenerator.forKnex.createAppField(DataGenerator.Content.app_fields[0]));
|
||||
app_fields.push(DataGenerator.forKnex.createAppField(DataGenerator.Content.app_fields[1]));
|
||||
|
||||
return knex('apps').insert(apps, 'id')
|
||||
.then(function (results) {
|
||||
var appId = results[0];
|
||||
|
||||
for (var i = 0; i < app_fields.length; i++) {
|
||||
app_fields[i].app_id = appId;
|
||||
}
|
||||
|
||||
return knex('app_fields').insert(app_fields);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function insertDefaultFixtures() {
|
||||
return when(insertDefaultUser().then(function () {
|
||||
return insertPosts();
|
||||
return insertPosts().then(function () {
|
||||
return insertApps();
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -146,6 +193,9 @@ module.exports = {
|
|||
insertMorePostsTags: insertMorePostsTags,
|
||||
insertDefaultUser: insertDefaultUser,
|
||||
insertDefaultApp: insertDefaultApp,
|
||||
insertApps: insertApps,
|
||||
insertAppWithSettings: insertAppWithSettings,
|
||||
insertAppWithFields: insertAppWithFields,
|
||||
|
||||
loadExportFixture: loadExportFixture,
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue