Merge pull request #6696 from ErisDS/fixture-migration-amends

Improve code for handling fixture migrations
This commit is contained in:
Sebastian Gierlinger 2016-04-14 16:17:58 +02:00
commit 9a674018b0
8 changed files with 433 additions and 243 deletions

View File

@ -48,18 +48,18 @@
{
"name": "Role",
"entries": [
{
"name": "Administrator",
"description": "Administrators"
},
{
"name": "Editor",
"description": "Editors"
},
{
"name": "Author",
"description": "Authors"
},
{
"name": "Administrator",
"description": "Administrators"
},
{
"name": "Editor",
"description": "Editors"
},
{
"name": "Author",
"description": "Authors"
},
{
"name": "Owner",
"description": "Blog Owner"

View File

@ -2,7 +2,6 @@
// This module handles populating fixtures on a fresh install.
// This is done automatically, by reading the fixtures.json file
// All models, and relationships inside the file are then setup.
var Promise = require('bluebird'),
models = require('../../../models'),
coreUtils = require('../../../utils'),

View File

@ -7,8 +7,9 @@ var _ = require('lodash'),
fixtures = require('./fixtures'),
// Private
// Private
matchFunc,
matchObj,
fetchRelationData,
findRelationFixture,
findModelFixture,
@ -18,7 +19,7 @@ var _ = require('lodash'),
addFixturesForModel,
addFixturesForRelation,
findModelFixtureEntry,
findPermissionModelForObject,
findModelFixtures,
findPermissionRelationsForObject;
/**
@ -54,6 +55,20 @@ matchFunc = function matchFunc(match, key, value) {
};
};
matchObj = function matchObj(match, item) {
var matchObj = {};
if (_.isArray(match)) {
_.each(match, function (matchProp) {
matchObj[matchProp] = item.get(matchProp);
});
} else {
matchObj[match] = item.get(match);
}
return matchObj;
};
/**
* ### Fetch Relation Data
* Before we build relations we need to fetch all of the models from both sides so that we can
@ -63,10 +78,11 @@ matchFunc = function matchFunc(match, key, value) {
* @returns {Promise<*>}
*/
fetchRelationData = function fetchRelationData(relation) {
var props = {
from: models[relation.from.model].findAll(modelOptions),
to: models[relation.to.model].findAll(modelOptions)
};
var fromOptions = _.extend({}, modelOptions, {withRelated: [relation.from.relation]}),
props = {
from: models[relation.from.model].findAll(fromOptions),
to: models[relation.to.model].findAll(modelOptions)
};
return Promise.props(props);
};
@ -81,7 +97,13 @@ fetchRelationData = function fetchRelationData(relation) {
*/
addFixturesForModel = function addFixturesForModel(modelFixture) {
return Promise.mapSeries(modelFixture.entries, function (entry) {
return models[modelFixture.name].add(entry, modelOptions);
return models[modelFixture.name].findOne(entry, modelOptions).then(function (found) {
if (!found) {
return models[modelFixture.name].add(entry, modelOptions);
}
});
}).then(function (results) {
return {expected: modelFixture.entries.length, done: _.compact(results).length};
});
};
@ -94,23 +116,34 @@ addFixturesForModel = function addFixturesForModel(modelFixture) {
* @returns {Promise.<*>}
*/
addFixturesForRelation = function addFixturesForRelation(relationFixture) {
return fetchRelationData(relationFixture).then(function getRelationOps(data) {
var ops = [];
var ops = [], max = 0;
return fetchRelationData(relationFixture).then(function getRelationOps(data) {
_.each(relationFixture.entries, function processEntries(entry, key) {
var fromItem = data.from.find(matchFunc(relationFixture.from.match, key));
_.each(entry, function processEntryValues(value, key) {
var toItem = data.to.filter(matchFunc(relationFixture.to.match, key, value));
if (toItem) {
ops.push(function addRelationItem() {
return fromItem[relationFixture.from.relation]().attach(toItem);
var toItems = data.to.filter(matchFunc(relationFixture.to.match, key, value));
max += toItems.length;
// Remove any duplicates that already exist in the collection
toItems = _.reject(toItems, function (item) {
return fromItem
.related(relationFixture.from.relation)
.findWhere(matchObj(relationFixture.to.match, item));
});
if (toItems && toItems.length > 0) {
ops.push(function addRelationItems() {
return fromItem[relationFixture.from.relation]().attach(toItems);
});
}
});
});
return sequence(ops);
}).then(function (result) {
return {expected: max, done: _(result).map('length').sum()};
});
};
@ -139,13 +172,13 @@ findModelFixtureEntry = function findModelFixtureEntry(modelName, matchExpr) {
};
/**
* ### Find All Model Fixture
* ### Find Model Fixtures
* Find a model fixture name & a matching expression for the FILTER function
* @param {String} modelName
* @param {String|Object|Function} matchExpr
* @returns {Object} model fixture
*/
findPermissionModelForObject = function findPermissionModelForObject(modelName, matchExpr) {
findModelFixtures = function findModelFixtures(modelName, matchExpr) {
var foundModel = _.cloneDeep(findModelFixture(modelName));
foundModel.entries = _.filter(foundModel.entries, matchExpr);
return foundModel;
@ -194,7 +227,7 @@ module.exports = {
addFixturesForModel: addFixturesForModel,
addFixturesForRelation: addFixturesForRelation,
findModelFixtureEntry: findModelFixtureEntry,
findPermissionModelForObject: findPermissionModelForObject,
findModelFixtures: findModelFixtures,
findPermissionRelationsForObject: findPermissionRelationsForObject,
modelOptions: modelOptions
};

View File

@ -30,7 +30,8 @@ Role = ghostBookshelf.Model.extend({
// whitelists for the `options` hash argument on methods, by method name.
// these are the only options that can be passed to Bookshelf / Knex.
validOptions = {
findOne: ['withRelated']
findOne: ['withRelated'],
findAll: ['withRelated']
};
if (validOptions[methodName]) {

View File

@ -11,6 +11,11 @@ var testUtils = require('../utils'),
sandbox = sinon.sandbox.create();
describe('Database Migration (special functions)', function () {
var loggerStub = {
info: sandbox.stub(),
warn: sandbox.stub()
};
before(testUtils.teardown);
afterEach(testUtils.teardown);
afterEach(function () {
@ -18,8 +23,6 @@ describe('Database Migration (special functions)', function () {
});
describe('Fixtures', function () {
beforeEach(testUtils.setup());
// Custom assertion for detection that a permissions is assigned to the correct roles
should.Assertion.add('AssignedToRoles', function (roles) {
var roleNames;
@ -121,70 +124,68 @@ describe('Database Migration (special functions)', function () {
permissions[29].should.be.AssignedToRoles(['Administrator', 'Editor', 'Author']);
});
it('should populate all fixtures correctly', function (done) {
var loggerStub = {
info: sandbox.stub(),
warn: sandbox.stub()
};
describe('Populate', function () {
beforeEach(testUtils.setup());
it('should populate all fixtures correctly', function (done) {
fixtures.populate(loggerStub).then(function () {
var props = {
posts: Models.Post.findAll({include: ['tags']}),
tags: Models.Tag.findAll(),
users: Models.User.findAll({include: ['roles']}),
clients: Models.Client.findAll(),
roles: Models.Role.findAll(),
permissions: Models.Permission.findAll({include: ['roles']})
};
fixtures.populate(loggerStub).then(function () {
var props = {
posts: Models.Post.findAll({include: ['tags']}),
tags: Models.Tag.findAll(),
users: Models.User.findAll({include: ['roles']}),
clients: Models.Client.findAll(),
roles: Models.Role.findAll(),
permissions: Models.Permission.findAll({include: ['roles']})
};
loggerStub.info.called.should.be.true();
loggerStub.warn.called.should.be.false();
loggerStub.info.called.should.be.true();
loggerStub.warn.called.should.be.false();
return Promise.props(props).then(function (result) {
should.exist(result);
return Promise.props(props).then(function (result) {
should.exist(result);
// Post
should.exist(result.posts);
result.posts.length.should.eql(1);
result.posts.at(0).get('title').should.eql('Welcome to Ghost');
// Post
should.exist(result.posts);
result.posts.length.should.eql(1);
result.posts.at(0).get('title').should.eql('Welcome to Ghost');
// Tag
should.exist(result.tags);
result.tags.length.should.eql(1);
result.tags.at(0).get('name').should.eql('Getting Started');
// Tag
should.exist(result.tags);
result.tags.length.should.eql(1);
result.tags.at(0).get('name').should.eql('Getting Started');
// Post Tag relation
result.posts.at(0).related('tags').length.should.eql(1);
result.posts.at(0).related('tags').at(0).get('name').should.eql('Getting Started');
// Post Tag relation
result.posts.at(0).related('tags').length.should.eql(1);
result.posts.at(0).related('tags').at(0).get('name').should.eql('Getting Started');
// Clients
should.exist(result.clients);
result.clients.length.should.eql(2);
result.clients.at(0).get('name').should.eql('Ghost Admin');
result.clients.at(1).get('name').should.eql('Ghost Frontend');
// Clients
should.exist(result.clients);
result.clients.length.should.eql(2);
result.clients.at(0).get('name').should.eql('Ghost Admin');
result.clients.at(1).get('name').should.eql('Ghost Frontend');
// User (Owner)
should.exist(result.users);
result.users.length.should.eql(1);
result.users.at(0).get('name').should.eql('Ghost Owner');
result.users.at(0).related('roles').length.should.eql(1);
result.users.at(0).related('roles').at(0).get('name').should.eql('Owner');
// User (Owner)
should.exist(result.users);
result.users.length.should.eql(1);
result.users.at(0).get('name').should.eql('Ghost Owner');
result.users.at(0).related('roles').length.should.eql(1);
result.users.at(0).related('roles').at(0).get('name').should.eql('Owner');
// Roles
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');
// Roles
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(30);
result.permissions.toJSON().should.be.CompletePermissions();
// Permissions
result.permissions.length.should.eql(30);
result.permissions.toJSON().should.be.CompletePermissions();
done();
});
}).catch(done);
done();
});
}).catch(done);
});
});
});
});

View File

@ -11,7 +11,6 @@ var should = require('should'),
versioning = require('../../server/data/schema/versioning'),
update = rewire('../../server/data/migration/fixtures/update'),
populate = rewire('../../server/data/migration/fixtures/populate'),
fixtureUtils = rewire('../../server/data/migration/fixtures/utils'),
fixtures004 = require('../../server/data/migration/fixtures/004'),
ensureDefaultSettings = require('../../server/data/migration/fixtures/settings'),
@ -92,14 +91,13 @@ describe('Fixtures', function () {
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.secondCall.calledWith(sinon.match.array, sinon.match.object, loggerStub).should.be.true();
sequenceStub.firstCall.args[0].should.be.an.Array().with.lengthOf(1);
sequenceStub.secondCall.args[0].should.be.an.Array().with.lengthOf(8);
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(8);
sequenceStub.secondCall.args[0][0].should.be.a.Function().with.property('name', 'moveJQuery');
sequenceStub.secondCall.args[0][1].should.be.a.Function().with.property('name', 'updatePrivateSetting');
sequenceStub.secondCall.args[0][2].should.be.a.Function().with.property('name', 'updatePasswordSetting');
@ -699,26 +697,43 @@ describe('Fixtures', function () {
clientAddStub = sandbox.stub(models.Client, 'add').returns(Promise.resolve()),
permsAddStub = sandbox.stub(models.Permission, 'add').returns(Promise.resolve()),
// Existence checks
postOneStub = sandbox.stub(models.Post, 'findOne').returns(Promise.resolve()),
tagOneStub = sandbox.stub(models.Tag, 'findOne').returns(Promise.resolve()),
roleOneStub = sandbox.stub(models.Role, 'findOne').returns(Promise.resolve()),
clientOneStub = sandbox.stub(models.Client, 'findOne').returns(Promise.resolve()),
permOneStub = sandbox.stub(models.Permission, 'findOne').returns(Promise.resolve()),
// Relations
modelMethodStub = {filter: sandbox.stub(), find: sandbox.stub()},
fromItem = {
related: sandbox.stub().returnsThis(),
findWhere: sandbox.stub().returns({})
},
toItem = [{get: sandbox.stub()}],
modelMethodStub = {filter: sandbox.stub().returns(toItem), find: sandbox.stub().returns(fromItem)},
permsAllStub = sandbox.stub(models.Permission, 'findAll').returns(Promise.resolve(modelMethodStub)),
rolesAllStub = sandbox.stub(models.Role, 'findAll').returns(Promise.resolve(modelMethodStub)),
postsAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(modelMethodStub)),
tagsAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(modelMethodStub)),
// Create Owner
roleOneStub = sandbox.stub(models.Role, 'findOne').returns(Promise.resolve({id: 1})),
userAddStub = sandbox.stub(models.User, 'add').returns(Promise.resolve({}));
roleOneStub.onCall(4).returns(Promise.resolve({id: 1}));
populate(loggerStub).then(function () {
loggerStub.info.calledTwice.should.be.true();
loggerStub.warn.called.should.be.false();
postOneStub.calledOnce.should.be.true();
postAddStub.calledOnce.should.be.true();
tagOneStub.calledOnce.should.be.true();
tagAddStub.calledOnce.should.be.true();
roleOneStub.callCount.should.be.aboveOrEqual(4);
roleAddStub.callCount.should.eql(4);
clientOneStub.calledTwice.should.be.true();
clientAddStub.calledTwice.should.be.true();
permOneStub.callCount.should.eql(30);
permsAddStub.called.should.be.true();
permsAddStub.callCount.should.eql(30);
@ -736,53 +751,13 @@ describe('Fixtures', function () {
modelMethodStub.find.callCount.should.eql(3 + 1);
// Create Owner
roleOneStub.calledOnce.should.be.true();
roleOneStub.callCount.should.eql(5);
userAddStub.calledOnce.should.be.true();
done();
}).catch(done);
});
describe('Add All Relations', function () {
it('should call attach if relation models are found', function (done) {
var addAllRelations = populate.__get__('addAllRelations'),
emptyMethodStub = {filter: sandbox.stub(), find: sandbox.stub()},
// Setup a chain of methods
dataMethodStub = {
filter: sandbox.stub().returnsThis(),
find: sandbox.stub().returnsThis(),
tags: sandbox.stub().returnsThis(),
attach: sandbox.stub().returns(Promise.resolve())
},
permsAllStub = sandbox.stub(models.Permission, 'findAll').returns(Promise.resolve(emptyMethodStub)),
rolesAllStub = sandbox.stub(models.Role, 'findAll').returns(Promise.resolve(emptyMethodStub)),
postsAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(dataMethodStub)),
tagsAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(dataMethodStub));
addAllRelations().then(function () {
permsAllStub.calledOnce.should.be.true();
rolesAllStub.calledOnce.should.be.true();
postsAllStub.calledOnce.should.be.true();
tagsAllStub.calledOnce.should.be.true();
// Permissions & Roles
emptyMethodStub.filter.called.should.be.true();
emptyMethodStub.filter.callCount.should.eql(22);
emptyMethodStub.find.called.should.be.true();
emptyMethodStub.find.callCount.should.eql(3);
// Posts & Tags
dataMethodStub.filter.calledOnce.should.be.true();
dataMethodStub.find.calledOnce.should.be.true();
dataMethodStub.tags.calledOnce.should.be.true();
dataMethodStub.attach.calledOnce.should.be.true();
dataMethodStub.attach.calledWith(dataMethodStub).should.be.true();
done();
}).catch(done);
});
});
describe('Create Owner', function () {
var createOwner = populate.__get__('createOwner'),
roleOneStub, userAddStub;
@ -818,78 +793,6 @@ describe('Fixtures', function () {
}).catch(done);
});
});
describe('Match Func', function () {
var matchFunc = fixtureUtils.__get__('matchFunc'),
getStub;
beforeEach(function () {
getStub = sandbox.stub();
getStub.withArgs('foo').returns('bar');
getStub.withArgs('fun').returns('baz');
});
it('should match undefined with no args', function () {
matchFunc()({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith(undefined).should.be.true();
});
it('should match key with match string', function () {
matchFunc('foo', 'bar')({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith('foo').should.be.true();
matchFunc('foo', 'buz')({get: getStub}).should.be.false();
getStub.calledTwice.should.be.true();
getStub.secondCall.calledWith('foo').should.be.true();
});
it('should match value when key is 0', function () {
matchFunc('foo', 0, 'bar')({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith('foo').should.be.true();
matchFunc('foo', 0, 'buz')({get: getStub}).should.be.false();
getStub.calledTwice.should.be.true();
getStub.secondCall.calledWith('foo').should.be.true();
});
it('should match key & value when match is array', function () {
matchFunc(['foo', 'fun'], 'bar', 'baz')({get: getStub}).should.be.true();
getStub.calledTwice.should.be.true();
getStub.getCall(0).calledWith('fun').should.be.true();
getStub.getCall(1).calledWith('foo').should.be.true();
matchFunc(['foo', 'fun'], 'baz', 'bar')({get: getStub}).should.be.false();
getStub.callCount.should.eql(4);
getStub.getCall(2).calledWith('fun').should.be.true();
getStub.getCall(3).calledWith('foo').should.be.true();
});
it('should match key only when match is array, but value is all', function () {
matchFunc(['foo', 'fun'], 'bar', 'all')({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith('foo').should.be.true();
matchFunc(['foo', 'fun'], 'all', 'bar')({get: getStub}).should.be.false();
getStub.callCount.should.eql(3);
getStub.getCall(1).calledWith('fun').should.be.true();
getStub.getCall(2).calledWith('foo').should.be.true();
});
it('should match key & value when match and value are arrays', function () {
matchFunc(['foo', 'fun'], 'bar', ['baz', 'buz'])({get: getStub}).should.be.true();
getStub.calledTwice.should.be.true();
getStub.getCall(0).calledWith('fun').should.be.true();
getStub.getCall(1).calledWith('foo').should.be.true();
matchFunc(['foo', 'fun'], 'bar', ['biz', 'buz'])({get: getStub}).should.be.false();
getStub.callCount.should.eql(4);
getStub.getCall(2).calledWith('fun').should.be.true();
getStub.getCall(3).calledWith('foo').should.be.true();
});
});
});
describe('Ensure default settings', function () {
@ -904,40 +807,4 @@ describe('Fixtures', function () {
}).catch(done);
});
});
describe('Utils', function () {
describe('findModelFixtureEntry', function () {
it('should fetch a single fixture entry', function () {
var foundFixture = fixtureUtils.findModelFixtureEntry('Client', {slug: 'ghost-admin'});
foundFixture.should.be.an.Object();
foundFixture.should.eql({
name: 'Ghost Admin',
slug: 'ghost-admin',
status: 'enabled'
});
});
});
describe('findPermissionModelForObject', function () {
it('should fetch a fixture with multiple entries', function () {
var foundFixture = fixtureUtils.findPermissionModelForObject('Permission', {object_type: 'db'});
foundFixture.should.be.an.Object();
foundFixture.entries.should.be.an.Array().with.lengthOf(3);
foundFixture.entries[0].should.eql({
name: 'Export database',
action_type: 'exportContent',
object_type: 'db'
});
});
});
describe('findPermissionRelationsForObject', function () {
it('should fetch a fixture with multiple entries', function () {
var foundFixture = fixtureUtils.findPermissionRelationsForObject('db');
foundFixture.should.be.an.Object();
foundFixture.entries.should.be.an.Object();
foundFixture.entries.should.have.property('Administrator', {db: 'all'});
});
});
});
});

View File

@ -0,0 +1,289 @@
/*global describe, it, beforeEach, afterEach */
var should = require('should'),
sinon = require('sinon'),
Promise = require('bluebird'),
rewire = require('rewire'),
models = require('../../server/models'),
fixtureUtils = rewire('../../server/data/migration/fixtures/utils'),
fixtures = require('../../server/data/migration/fixtures/fixtures'),
sandbox = sinon.sandbox.create();
describe('Utils', function () {
var loggerStub;
beforeEach(function () {
loggerStub = {
info: sandbox.stub(),
warn: sandbox.stub()
};
models.init();
});
afterEach(function () {
sandbox.restore();
});
describe('Match Func', function () {
var matchFunc = fixtureUtils.__get__('matchFunc'),
getStub;
beforeEach(function () {
getStub = sandbox.stub();
getStub.withArgs('foo').returns('bar');
getStub.withArgs('fun').returns('baz');
});
it('should match undefined with no args', function () {
matchFunc()({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith(undefined).should.be.true();
});
it('should match key with match string', function () {
matchFunc('foo', 'bar')({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith('foo').should.be.true();
matchFunc('foo', 'buz')({get: getStub}).should.be.false();
getStub.calledTwice.should.be.true();
getStub.secondCall.calledWith('foo').should.be.true();
});
it('should match value when key is 0', function () {
matchFunc('foo', 0, 'bar')({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith('foo').should.be.true();
matchFunc('foo', 0, 'buz')({get: getStub}).should.be.false();
getStub.calledTwice.should.be.true();
getStub.secondCall.calledWith('foo').should.be.true();
});
it('should match key & value when match is array', function () {
matchFunc(['foo', 'fun'], 'bar', 'baz')({get: getStub}).should.be.true();
getStub.calledTwice.should.be.true();
getStub.getCall(0).calledWith('fun').should.be.true();
getStub.getCall(1).calledWith('foo').should.be.true();
matchFunc(['foo', 'fun'], 'baz', 'bar')({get: getStub}).should.be.false();
getStub.callCount.should.eql(4);
getStub.getCall(2).calledWith('fun').should.be.true();
getStub.getCall(3).calledWith('foo').should.be.true();
});
it('should match key only when match is array, but value is all', function () {
matchFunc(['foo', 'fun'], 'bar', 'all')({get: getStub}).should.be.true();
getStub.calledOnce.should.be.true();
getStub.calledWith('foo').should.be.true();
matchFunc(['foo', 'fun'], 'all', 'bar')({get: getStub}).should.be.false();
getStub.callCount.should.eql(3);
getStub.getCall(1).calledWith('fun').should.be.true();
getStub.getCall(2).calledWith('foo').should.be.true();
});
it('should match key & value when match and value are arrays', function () {
matchFunc(['foo', 'fun'], 'bar', ['baz', 'buz'])({get: getStub}).should.be.true();
getStub.calledTwice.should.be.true();
getStub.getCall(0).calledWith('fun').should.be.true();
getStub.getCall(1).calledWith('foo').should.be.true();
matchFunc(['foo', 'fun'], 'bar', ['biz', 'buz'])({get: getStub}).should.be.false();
getStub.callCount.should.eql(4);
getStub.getCall(2).calledWith('fun').should.be.true();
getStub.getCall(3).calledWith('foo').should.be.true();
});
});
describe('Add Fixtures For Model', function () {
it('should call add for main post fixture', function (done) {
var postOneStub = sandbox.stub(models.Post, 'findOne').returns(Promise.resolve()),
postAddStub = sandbox.stub(models.Post, 'add').returns(Promise.resolve({}));
fixtureUtils.addFixturesForModel(fixtures.models[0]).then(function (result) {
should.exist(result);
result.should.be.an.Object();
result.should.have.property('expected', 1);
result.should.have.property('done', 1);
postOneStub.calledOnce.should.be.true();
postAddStub.calledOnce.should.be.true();
done();
});
});
it('should not call add for main post fixture if it is already found', function (done) {
var postOneStub = sandbox.stub(models.Post, 'findOne').returns(Promise.resolve({})),
postAddStub = sandbox.stub(models.Post, 'add').returns(Promise.resolve({}));
fixtureUtils.addFixturesForModel(fixtures.models[0]).then(function (result) {
should.exist(result);
result.should.be.an.Object();
result.should.have.property('expected', 1);
result.should.have.property('done', 0);
postOneStub.calledOnce.should.be.true();
postAddStub.calledOnce.should.be.false();
done();
});
});
});
describe('Add Fixtures For Relation', function () {
it('should call attach for permissions-roles', function (done) {
var fromItem = {
related: sandbox.stub().returnsThis(),
findWhere: sandbox.stub().returns(),
permissions: sandbox.stub().returnsThis(),
attach: sandbox.stub().returns(Promise.resolve([{}]))
},
toItem = [{get: sandbox.stub()}],
dataMethodStub = {
filter: sandbox.stub().returns(toItem),
find: sandbox.stub().returns(fromItem)
},
permsAllStub = sandbox.stub(models.Permission, 'findAll').returns(Promise.resolve(dataMethodStub)),
rolesAllStub = sandbox.stub(models.Role, 'findAll').returns(Promise.resolve(dataMethodStub));
fixtureUtils.addFixturesForRelation(fixtures.relations[0]).then(function (result) {
should.exist(result);
result.should.be.an.Object();
result.should.have.property('expected', 22);
result.should.have.property('done', 22);
// Permissions & Roles
permsAllStub.calledOnce.should.be.true();
rolesAllStub.calledOnce.should.be.true();
dataMethodStub.filter.callCount.should.eql(22);
dataMethodStub.find.callCount.should.eql(3);
fromItem.related.callCount.should.eql(22);
fromItem.findWhere.callCount.should.eql(22);
toItem[0].get.callCount.should.eql(44);
fromItem.permissions.callCount.should.eql(22);
fromItem.attach.callCount.should.eql(22);
fromItem.attach.calledWith(toItem).should.be.true();
done();
}).catch(done);
});
it('should call attach for posts-tags', function (done) {
var fromItem = {
related: sandbox.stub().returnsThis(),
findWhere: sandbox.stub().returns(),
tags: sandbox.stub().returnsThis(),
attach: sandbox.stub().returns(Promise.resolve([{}]))
},
toItem = [{get: sandbox.stub()}],
dataMethodStub = {
filter: sandbox.stub().returns(toItem),
find: sandbox.stub().returns(fromItem)
},
postsAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(dataMethodStub)),
tagsAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(dataMethodStub));
fixtureUtils.addFixturesForRelation(fixtures.relations[1]).then(function (result) {
should.exist(result);
result.should.be.an.Object();
result.should.have.property('expected', 1);
result.should.have.property('done', 1);
// Posts & Tags
postsAllStub.calledOnce.should.be.true();
tagsAllStub.calledOnce.should.be.true();
dataMethodStub.filter.calledOnce.should.be.true();
dataMethodStub.find.calledOnce.should.be.true();
fromItem.related.calledOnce.should.be.true();
fromItem.findWhere.calledOnce.should.be.true();
toItem[0].get.calledOnce.should.be.true();
fromItem.tags.calledOnce.should.be.true();
fromItem.attach.calledOnce.should.be.true();
fromItem.attach.calledWith(toItem).should.be.true();
done();
}).catch(done);
});
it('will not call attach for posts-tags if already present', function (done) {
var fromItem = {
related: sandbox.stub().returnsThis(),
findWhere: sandbox.stub().returns({}),
tags: sandbox.stub().returnsThis(),
attach: sandbox.stub().returns(Promise.resolve({}))
},
toItem = [{get: sandbox.stub()}],
dataMethodStub = {
filter: sandbox.stub().returns(toItem),
find: sandbox.stub().returns(fromItem)
},
postsAllStub = sandbox.stub(models.Post, 'findAll').returns(Promise.resolve(dataMethodStub)),
tagsAllStub = sandbox.stub(models.Tag, 'findAll').returns(Promise.resolve(dataMethodStub));
fixtureUtils.addFixturesForRelation(fixtures.relations[1]).then(function (result) {
should.exist(result);
result.should.be.an.Object();
result.should.have.property('expected', 1);
result.should.have.property('done', 0);
// Posts & Tags
postsAllStub.calledOnce.should.be.true();
tagsAllStub.calledOnce.should.be.true();
dataMethodStub.filter.calledOnce.should.be.true();
dataMethodStub.find.calledOnce.should.be.true();
fromItem.related.calledOnce.should.be.true();
fromItem.findWhere.calledOnce.should.be.true();
toItem[0].get.calledOnce.should.be.true();
fromItem.tags.called.should.be.false();
fromItem.attach.called.should.be.false();
done();
}).catch(done);
});
});
describe('findModelFixtureEntry', function () {
it('should fetch a single fixture entry', function () {
var foundFixture = fixtureUtils.findModelFixtureEntry('Client', {slug: 'ghost-admin'});
foundFixture.should.be.an.Object();
foundFixture.should.eql({
name: 'Ghost Admin',
slug: 'ghost-admin',
status: 'enabled'
});
});
});
describe('findModelFixtures', function () {
it('should fetch a fixture with multiple entries', function () {
var foundFixture = fixtureUtils.findModelFixtures('Permission', {object_type: 'db'});
foundFixture.should.be.an.Object();
foundFixture.entries.should.be.an.Array().with.lengthOf(3);
foundFixture.entries[0].should.eql({
name: 'Export database',
action_type: 'exportContent',
object_type: 'db'
});
});
});
describe('findPermissionRelationsForObject', function () {
it('should fetch a fixture with multiple entries', function () {
var foundFixture = fixtureUtils.findPermissionRelationsForObject('db');
foundFixture.should.be.an.Object();
foundFixture.entries.should.be.an.Object();
foundFixture.entries.should.have.property('Administrator', {db: 'all'});
});
});
});

View File

@ -316,7 +316,7 @@ fixtures = {
},
permissionsFor: function permissionsFor(obj) {
var permsToInsert = fixtureUtils.findPermissionModelForObject('Permission', {object_type: obj}).entries,
var permsToInsert = fixtureUtils.findModelFixtures('Permission', {object_type: obj}).entries,
permsRolesToInsert = fixtureUtils.findPermissionRelationsForObject(obj).entries,
actions = [],
permissionsRoles = [],