0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-01-20 22:42:53 -05:00

Use bookshelf-relations for Permission model: roles

refs https://github.com/TryGhost/Ghost/pull/9592

- we add bookshelf-relations step by step if we need it
- with https://github.com/TryGhost/Ghost/pull/9592 we have rewritten the test env to use Bookshelf
  - this is important for our new url service
  - because the service is listening on model updates and updates the urls based on the model events
- so with moving to Bookshelf, we need any easy way to add relations
  - the test env inserts test fixtures
  - it adds permissions and each permission get's roles attached
  - `models.Permission.add({roles: [...]})
This commit is contained in:
kirrg001 2018-04-25 12:27:39 +02:00
parent 27ebc3d1ac
commit 02abe3862e
4 changed files with 94 additions and 4 deletions

View file

@ -63,6 +63,11 @@ ghostBookshelf.plugin('bookshelf-relations', {
}
};
// CASE: disable after hook for specific relations
if (['permissions_roles'].indexOf(existing.relatedData.joinTableName) !== -1) {
return Promise.resolve();
}
return Promise.each(targets.models, function (target, index) {
queryOptions.query.where[existing.relatedData.otherKey] = target.id;

View file

@ -1,14 +1,36 @@
var ghostBookshelf = require('./base'),
'use strict';
Permission,
const ghostBookshelf = require('./base');
let Permission,
Permissions;
Permission = ghostBookshelf.Model.extend({
tableName: 'permissions',
relationships: ['roles'],
relationshipBelongsTo: {
roles: 'roles'
},
/**
* The base model keeps only the columns, which are defined in the schema.
* We have to add the relations on top, otherwise bookshelf-relations
* has no access to the nested relations, which should be updated.
*/
permittedAttributes: function permittedAttributes() {
let filteredKeys = ghostBookshelf.Model.prototype.permittedAttributes.apply(this, arguments);
this.relationships.forEach((key) => {
filteredKeys.push(key);
});
return filteredKeys;
},
roles: function roles() {
return this.belongsToMany('Role');
return this.belongsToMany('Role', 'permissions_roles', 'permission_id', 'role_id');
},
users: function users() {

View file

@ -75,7 +75,7 @@ describe('Permission Model', function () {
return PermissionModel.destroy(firstPermission);
}).then(function (response) {
response.toJSON().should.be.empty();
response.toJSON({shallow: true}).should.be.empty();
return PermissionModel.findOne(firstPermission);
}).then(function (newResults) {
should.equal(newResults, null);

View file

@ -0,0 +1,63 @@
'use strict';
const should = require('should'),
sinon = require('sinon'),
models = require('../../../server/models'),
testUtils = require('../../utils'),
sandbox = sinon.sandbox.create();
describe('Unit: models/permission', function () {
before(function () {
models.init();
});
after(function () {
sandbox.restore();
});
describe('add', function () {
let knexMock;
before(function () {
knexMock = new testUtils.mocks.knex();
knexMock.mock();
});
after(function () {
knexMock.unmock();
});
it('without roles', function () {
return models.Permission.add({name: 'test', object_type: 'something', action_type: 'read something'})
.then(function (permission) {
permission.get('name').should.eql('test');
permission.get('object_type').should.eql('something');
permission.get('action_type').should.eql('read something');
});
});
it('with roles', function () {
return models.Permission.add({
name: 'test',
object_type: 'something',
action_type: 'write something',
roles: [testUtils.DataGenerator.forKnex.roles[1]]
}).then(function (permission) {
permission.get('name').should.eql('test');
permission.get('object_type').should.eql('something');
permission.get('action_type').should.eql('write something');
permission.related('roles').models[0].id.should.eql(testUtils.DataGenerator.forKnex.roles[1].id);
});
});
it('[error] validation', function () {
return models.Permission.add({})
.then(function () {
'Should fail'.should.be.true();
})
.catch(function (err) {
err.length.should.eql(3);
});
});
});
});