mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
476 lines
18 KiB
JavaScript
476 lines
18 KiB
JavaScript
|
var should = require('should'), // jshint ignore:line
|
||
|
sinon = require('sinon'),
|
||
|
models = require('../../../server/models'),
|
||
|
common = require('../../../server/lib/common'),
|
||
|
utils = require('../../utils'),
|
||
|
|
||
|
sandbox = sinon.sandbox.create();
|
||
|
|
||
|
describe('Models: Post', function () {
|
||
|
before(function () {
|
||
|
models.init();
|
||
|
});
|
||
|
|
||
|
describe('Permissible', function () {
|
||
|
describe('As Contributor', function () {
|
||
|
describe('Editing', function () {
|
||
|
it('rejects if changing status', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'published'};
|
||
|
|
||
|
mockPostObj.get.withArgs('status').returns('draft');
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
false
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledOnce).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('rejects if changing author id', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'draft', author_id: 2};
|
||
|
|
||
|
mockPostObj.get.withArgs('status').returns('draft');
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledTwice).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('rejects if post is not draft', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'published', author_id: 1};
|
||
|
|
||
|
mockPostObj.get.withArgs('status').returns('published');
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledThrice).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('rejects if contributor is not author of post', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'draft', author_id: 2};
|
||
|
|
||
|
mockPostObj.get.withArgs('status').returns('draft');
|
||
|
mockPostObj.get.withArgs('author_id').returns(2);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.callCount).eql(4);
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('resolves if none of the above cases are true', function () {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'draft', author_id: 1};
|
||
|
|
||
|
mockPostObj.get.withArgs('status').returns('draft');
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
|
||
|
return models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then((result) => {
|
||
|
should.exist(result);
|
||
|
should(result.excludedAttrs).deepEqual(['tags']);
|
||
|
should(mockPostObj.get.callCount).eql(4);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Adding', function () {
|
||
|
it('rejects if "published" status', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'published', author_id: 1};
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'add',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.called).be.false();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('rejects if different author id', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'draft', author_id: 2};
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'add',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.called).be.false();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('resolves if none of the above cases are true', function () {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {status: 'draft', author_id: 1};
|
||
|
|
||
|
return models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'add',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then((result) => {
|
||
|
should.exist(result);
|
||
|
should(result.excludedAttrs).deepEqual(['tags']);
|
||
|
should(mockPostObj.get.called).be.false();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Destroying', function () {
|
||
|
it('rejects if destroying another author\'s post', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1};
|
||
|
|
||
|
mockPostObj.get.withArgs('author_id').returns(2);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'destroy',
|
||
|
context,
|
||
|
{},
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledOnce).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('rejects if destroying a published post', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1};
|
||
|
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
mockPostObj.get.withArgs('status').returns('published');
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'destroy',
|
||
|
context,
|
||
|
{},
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledTwice).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('resolves if none of the above cases are true', function () {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1};
|
||
|
|
||
|
mockPostObj.get.withArgs('status').returns('draft');
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
|
||
|
return models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'destroy',
|
||
|
context,
|
||
|
{},
|
||
|
utils.permissions.contributor,
|
||
|
false,
|
||
|
true
|
||
|
).then((result) => {
|
||
|
should.exist(result);
|
||
|
should(result.excludedAttrs).deepEqual(['tags']);
|
||
|
should(mockPostObj.get.calledTwice).be.true();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('As Author', function () {
|
||
|
describe('Editing', function () {
|
||
|
it('rejects if editing another\'s post', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {author_id: 2};
|
||
|
|
||
|
mockPostObj.get.withArgs('author_id').returns(2);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.author,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledOnce).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('rejects if changing author', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {author_id: 2};
|
||
|
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.author,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledTwice).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('resolves if none of the above cases are true', function () {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {author_id: 1};
|
||
|
|
||
|
mockPostObj.get.withArgs('author_id').returns(1);
|
||
|
|
||
|
return models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.author,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
should(mockPostObj.get.calledTwice).be.true();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Adding', function () {
|
||
|
it('rejects if different author id', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {author_id: 2};
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'add',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.author,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.called).be.false();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('resolves if none of the above cases are true', function () {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {author_id: 1};
|
||
|
|
||
|
return models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'add',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.author,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
should(mockPostObj.get.called).be.false();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Everyone Else', function () {
|
||
|
it('rejects if hasUserPermissions is false and not current owner', function (done) {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {author_id: 2};
|
||
|
|
||
|
mockPostObj.get.withArgs('author_id').returns(2);
|
||
|
|
||
|
models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.editor,
|
||
|
false,
|
||
|
true
|
||
|
).then(() => {
|
||
|
done(new Error('Permissible function should have rejected.'));
|
||
|
}).catch((error) => {
|
||
|
error.should.be.an.instanceof(common.errors.NoPermissionError);
|
||
|
should(mockPostObj.get.calledOnce).be.true();
|
||
|
done();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it('resolves if hasUserPermission is true', function () {
|
||
|
var mockPostObj = {
|
||
|
get: sandbox.stub()
|
||
|
},
|
||
|
context = {user: 1},
|
||
|
unsafeAttrs = {author_id: 2};
|
||
|
|
||
|
mockPostObj.get.withArgs('author_id').returns(2);
|
||
|
|
||
|
return models.Post.permissible(
|
||
|
mockPostObj,
|
||
|
'edit',
|
||
|
context,
|
||
|
unsafeAttrs,
|
||
|
utils.permissions.editor,
|
||
|
true,
|
||
|
true
|
||
|
).then(() => {
|
||
|
should(mockPostObj.get.called).be.false();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|