Ghost/test/unit/server/services/permissions/providers.test.js
Hannah Wolfe 9e96b04542
Moved server unit tests into the server folder
- this is a small part of a bit of cleanup of our test files
- the goal is to make the existing tests clearer with a view to making it easier to write more tests
- this makes the test structure follow the codebase structure more closely
- eventually we will colocate the tests as we break the codebase down further
2021-10-06 12:01:09 +01:00

247 lines
11 KiB
JavaScript

const should = require('should');
const sinon = require('sinon');
const testUtils = require('../../../../utils');
const Promise = require('bluebird');
const models = require('../../../../../core/server/models');
const providers = require('../../../../../core/server/services/permissions/providers');
describe('Permission Providers', function () {
before(function () {
models.init();
});
afterEach(function () {
sinon.restore();
});
describe('User', function () {
it('errors if user cannot be found', function (done) {
const findUserSpy = sinon.stub(models.User, 'findOne').callsFake(function () {
return Promise.resolve();
});
providers.user(1)
.then(function () {
done(new Error('Should have thrown a user not found error'));
})
.catch(function (err) {
findUserSpy.callCount.should.eql(1);
err.errorType.should.eql('NotFoundError');
done();
});
});
it('can load user with role, and permissions', function (done) {
// This test requires quite a lot of unique setup work
const findUserSpy = sinon.stub(models.User, 'findOne').callsFake(function () {
// Create a fake model
const fakeUser = models.User.forge(testUtils.DataGenerator.Content.users[0]);
fakeUser.set('status', 'active');
// Roles & Permissions need to be collections
const fakeAdminRole = models.Roles.forge(testUtils.DataGenerator.Content.roles[0]);
const fakeAdminRolePermissions = models.Permissions.forge(testUtils.DataGenerator.Content.permissions);
// ## Fake the relations
// User is related to roles & permissions
fakeUser.relations = {
roles: fakeAdminRole,
permissions: fakeAdminRolePermissions
};
// We use this inside toJSON.
fakeUser.withRelated = ['roles', 'permissions', 'roles.permissions'];
return Promise.resolve(fakeUser);
});
// Get permissions for the user
providers.user(1)
.then(function (res) {
findUserSpy.callCount.should.eql(1);
res.should.be.an.Object().with.properties('permissions', 'roles');
res.permissions.should.be.an.Array().with.lengthOf(10);
res.roles.should.be.an.Array().with.lengthOf(1);
// @TODO fix this!
// Permissions is an array of models
// Roles is a JSON array
res.permissions[0].should.be.an.Object().with.properties('attributes', 'id');
res.roles[0].should.be.an.Object().with.properties('id', 'name', 'description');
res.permissions[0].should.be.instanceOf(models.Base.Model);
res.roles[0].should.not.be.instanceOf(models.Base.Model);
done();
})
.catch(done);
});
it('can load user with role, and role.permissions', function (done) {
// This test requires quite a lot of unique setup work
const findUserSpy = sinon.stub(models.User, 'findOne').callsFake(function () {
// Create a fake model
const fakeUser = models.User.forge(testUtils.DataGenerator.Content.users[0]);
fakeUser.set('status', 'active');
// Roles & Permissions need to be collections
const fakeAdminRole = models.Roles.forge(testUtils.DataGenerator.Content.roles[0]);
const fakeAdminRolePermissions = models.Permissions.forge(testUtils.DataGenerator.Content.permissions);
// ## Fake the relations
// Roles are related to permissions
fakeAdminRole.models[0].relations = {
permissions: fakeAdminRolePermissions
};
// User is related to roles
fakeUser.relations = {
roles: fakeAdminRole
};
// We use this inside toJSON.
fakeUser.withRelated = ['roles', 'permissions', 'roles.permissions'];
return Promise.resolve(fakeUser);
});
// Get permissions for the user
providers.user(1)
.then(function (res) {
findUserSpy.callCount.should.eql(1);
res.should.be.an.Object().with.properties('permissions', 'roles');
res.permissions.should.be.an.Array().with.lengthOf(10);
res.roles.should.be.an.Array().with.lengthOf(1);
// @TODO fix this!
// Permissions is an array of models
// Roles is a JSON array
res.permissions[0].should.be.an.Object().with.properties('attributes', 'id');
res.roles[0].should.be.an.Object().with.properties('id', 'name', 'description');
res.permissions[0].should.be.instanceOf(models.Base.Model);
res.roles[0].should.not.be.instanceOf(models.Base.Model);
done();
})
.catch(done);
});
it('can load user with role, permissions and role.permissions and deduplicate them', function (done) {
// This test requires quite a lot of unique setup work
const findUserSpy = sinon.stub(models.User, 'findOne').callsFake(function () {
// Create a fake model
const fakeUser = models.User.forge(testUtils.DataGenerator.Content.users[0]);
fakeUser.set('status', 'active');
// Roles & Permissions need to be collections
const fakeAdminRole = models.Roles.forge(testUtils.DataGenerator.Content.roles[0]);
const fakeAdminRolePermissions = models.Permissions.forge(testUtils.DataGenerator.Content.permissions);
// ## Fake the relations
// Roles are related to permissions
fakeAdminRole.models[0].relations = {
permissions: fakeAdminRolePermissions
};
// User is related to roles and permissions
fakeUser.relations = {
roles: fakeAdminRole,
permissions: fakeAdminRolePermissions
};
// We use this inside toJSON.
fakeUser.withRelated = ['roles', 'permissions', 'roles.permissions'];
return Promise.resolve(fakeUser);
});
// Get permissions for the user
providers.user(1)
.then(function (res) {
findUserSpy.callCount.should.eql(1);
res.should.be.an.Object().with.properties('permissions', 'roles');
res.permissions.should.be.an.Array().with.lengthOf(10);
res.roles.should.be.an.Array().with.lengthOf(1);
// @TODO fix this!
// Permissions is an array of models
// Roles is a JSON array
res.permissions[0].should.be.an.Object().with.properties('attributes', 'id');
res.roles[0].should.be.an.Object().with.properties('id', 'name', 'description');
res.permissions[0].should.be.instanceOf(models.Base.Model);
res.roles[0].should.not.be.instanceOf(models.Base.Model);
done();
})
.catch(done);
});
it('throws when user with non-active status is loaded', function (done) {
// This test requires quite a lot of unique setup work
const findUserSpy = sinon.stub(models.User, 'findOne').callsFake(function () {
// Create a fake model
const fakeUser = models.User.forge(testUtils.DataGenerator.Content.users[0]);
fakeUser.set('status', 'locked');
return Promise.resolve(fakeUser);
});
// Get permissions for the user
providers.user(1)
.then(function (res) {
done(new Error('Locked user should should throw an error'));
})
.catch((err) => {
err.errorType.should.equal('UnauthorizedError');
findUserSpy.callCount.should.eql(1);
done();
});
});
});
describe('API Key', function () {
it('errors if api_key cannot be found', function (done) {
let findApiKeySpy = sinon.stub(models.ApiKey, 'findOne');
findApiKeySpy.returns(new Promise.resolve());
providers.apiKey(1)
.then(() => {
done(new Error('Should have thrown an api key not found error'));
})
.catch((err) => {
findApiKeySpy.callCount.should.eql(1);
err.errorType.should.eql('NotFoundError');
done();
});
});
it('can load api_key with role, and role.permissions', function (done) {
const findApiKeySpy = sinon.stub(models.ApiKey, 'findOne').callsFake(function () {
const fakeApiKey = models.ApiKey.forge(testUtils.DataGenerator.Content.api_keys[0]);
const fakeAdminRole = models.Role.forge(testUtils.DataGenerator.Content.roles[0]);
const fakeAdminRolePermissions = models.Permissions.forge(testUtils.DataGenerator.Content.permissions);
fakeAdminRole.relations = {
permissions: fakeAdminRolePermissions
};
fakeApiKey.relations = {
role: fakeAdminRole
};
fakeApiKey.withRelated = ['role', 'role.permissions'];
return Promise.resolve(fakeApiKey);
});
providers.apiKey(1).then((res) => {
findApiKeySpy.callCount.should.eql(1);
res.should.be.an.Object().with.properties('permissions', 'roles');
res.roles.should.be.an.Array().with.lengthOf(1);
res.permissions[0].should.be.an.Object().with.properties('attributes', 'id');
res.roles[0].should.be.an.Object().with.properties('id', 'name', 'description');
res.permissions[0].should.be.instanceOf(models.Base.Model);
res.roles[0].should.not.be.instanceOf(models.Base.Model);
done();
}).catch(done);
});
});
});