2018-04-15 13:12:20 +03:00
/* eslint no-invalid-this:0 */
2020-05-25 11:49:38 +03:00
const errors = require ( '@tryghost/errors' ) ;
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
const should = require ( 'should' ) ;
const sinon = require ( 'sinon' ) ;
const testUtils = require ( '../../utils' ) ;
2020-03-30 18:26:47 +03:00
const knex = require ( '../../../core/server/data/db' ) . knex ;
const urlService = require ( '../../../core/frontend/services/url' ) ;
const models = require ( '../../../core/server/models' ) ;
2020-08-11 16:01:16 +03:00
const security = require ( '@tryghost/security' ) ;
2018-02-07 12:46:22 +03:00
2018-03-05 11:10:27 +03:00
describe ( 'Unit: models/post' , function ( ) {
2018-10-06 23:13:52 +03:00
const mockDb = require ( 'mock-knex' ) ;
let tracker ;
before ( function ( ) {
models . init ( ) ;
mockDb . mock ( knex ) ;
tracker = mockDb . getTracker ( ) ;
} ) ;
afterEach ( function ( ) {
2019-01-21 19:53:44 +03:00
sinon . restore ( ) ;
2018-10-06 23:13:52 +03:00
} ) ;
after ( function ( ) {
mockDb . unmock ( knex ) ;
} ) ;
describe ( 'filter' , function ( ) {
it ( 'generates correct query for - filter: tags: [photo, video] + id: -{id},limit of: 3, with related: tags' , function ( ) {
const queries = [ ] ;
tracker . install ( ) ;
tracker . on ( 'query' , ( query ) => {
queries . push ( query ) ;
query . response ( [ ] ) ;
} ) ;
return models . Post . findPage ( {
2018-11-15 17:27:31 +03:00
filter : 'tags:[photo, video]+id:-' + testUtils . filterData . data . posts [ 3 ] . id ,
2018-10-06 23:13:52 +03:00
limit : 3 ,
withRelated : [ 'tags' ]
} ) . then ( ( ) => {
queries . length . should . eql ( 2 ) ;
2019-09-16 13:51:54 +03:00
queries [ 0 ] . sql . should . eql ( 'select count(distinct posts.id) as aggregate from `posts` where ((`posts`.`id` != ? and `posts`.`id` in (select `posts_tags`.`post_id` from `posts_tags` inner join `tags` on `tags`.`id` = `posts_tags`.`tag_id` where `tags`.`slug` in (?, ?))) and (`posts`.`type` = ? and `posts`.`status` = ?))' ) ;
2018-10-06 23:13:52 +03:00
queries [ 0 ] . bindings . should . eql ( [
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
testUtils . filterData . data . posts [ 3 ] . id ,
2018-10-06 23:13:52 +03:00
'photo' ,
'video' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published'
2018-10-06 23:13:52 +03:00
] ) ;
2019-09-16 13:51:54 +03:00
queries [ 1 ] . sql . should . eql ( 'select `posts`.* from `posts` where ((`posts`.`id` != ? and `posts`.`id` in (select `posts_tags`.`post_id` from `posts_tags` inner join `tags` on `tags`.`id` = `posts_tags`.`tag_id` where `tags`.`slug` in (?, ?))) and (`posts`.`type` = ? and `posts`.`status` = ?)) order by (SELECT count(*) FROM posts_tags WHERE post_id = posts.id) DESC, CASE WHEN posts.status = \'scheduled\' THEN 1 WHEN posts.status = \'draft\' THEN 2 ELSE 3 END ASC,CASE WHEN posts.status != \'draft\' THEN posts.published_at END DESC,posts.updated_at DESC,posts.id DESC limit ?' ) ;
2018-10-06 23:13:52 +03:00
queries [ 1 ] . bindings . should . eql ( [
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
testUtils . filterData . data . posts [ 3 ] . id ,
2018-10-06 23:13:52 +03:00
'photo' ,
'video' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published' ,
2018-10-06 23:13:52 +03:00
3
] ) ;
} ) ;
} ) ;
it ( 'generates correct query for - filter: authors:[leslie,pat]+(tag:hash-audio,feature_image:-null), with related: authors,tags' , function ( ) {
const queries = [ ] ;
tracker . install ( ) ;
tracker . on ( 'query' , ( query ) => {
queries . push ( query ) ;
query . response ( [ ] ) ;
} ) ;
return models . Post . findPage ( {
filter : 'authors:[leslie,pat]+(tag:hash-audio,feature_image:-null)' ,
withRelated : [ 'authors' , 'tags' ]
} ) . then ( ( ) => {
queries . length . should . eql ( 2 ) ;
2019-09-16 13:51:54 +03:00
queries [ 0 ] . sql . should . eql ( 'select count(distinct posts.id) as aggregate from `posts` where (((`posts`.`feature_image` is not null or `posts`.`id` in (select `posts_tags`.`post_id` from `posts_tags` inner join `tags` on `tags`.`id` = `posts_tags`.`tag_id` where `tags`.`slug` = ?)) and `posts`.`id` in (select `posts_authors`.`post_id` from `posts_authors` inner join `users` as `authors` on `authors`.`id` = `posts_authors`.`author_id` where `authors`.`slug` in (?, ?))) and (`posts`.`type` = ? and `posts`.`status` = ?))' ) ;
2018-10-06 23:13:52 +03:00
queries [ 0 ] . bindings . should . eql ( [
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'hash-audio' ,
2018-10-06 23:13:52 +03:00
'leslie' ,
'pat' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published'
2018-10-06 23:13:52 +03:00
] ) ;
2019-09-16 13:51:54 +03:00
queries [ 1 ] . sql . should . eql ( 'select `posts`.* from `posts` where (((`posts`.`feature_image` is not null or `posts`.`id` in (select `posts_tags`.`post_id` from `posts_tags` inner join `tags` on `tags`.`id` = `posts_tags`.`tag_id` where `tags`.`slug` = ?)) and `posts`.`id` in (select `posts_authors`.`post_id` from `posts_authors` inner join `users` as `authors` on `authors`.`id` = `posts_authors`.`author_id` where `authors`.`slug` in (?, ?))) and (`posts`.`type` = ? and `posts`.`status` = ?)) order by (SELECT count(*) FROM posts_authors WHERE post_id = posts.id) DESC, CASE WHEN posts.status = \'scheduled\' THEN 1 WHEN posts.status = \'draft\' THEN 2 ELSE 3 END ASC,CASE WHEN posts.status != \'draft\' THEN posts.published_at END DESC,posts.updated_at DESC,posts.id DESC limit ?' ) ;
2018-10-06 23:13:52 +03:00
queries [ 1 ] . bindings . should . eql ( [
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'hash-audio' ,
2018-10-06 23:13:52 +03:00
'leslie' ,
'pat' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published' ,
2018-10-06 23:13:52 +03:00
15
] ) ;
} ) ;
} ) ;
it ( 'generates correct query for - filter: published_at:>\'2015-07-20\', limit of: 5, with related: tags' , function ( ) {
const queries = [ ] ;
tracker . install ( ) ;
tracker . on ( 'query' , ( query ) => {
queries . push ( query ) ;
query . response ( [ ] ) ;
} ) ;
return models . Post . findPage ( {
filter : 'published_at:>\'2015-07-20\'' ,
limit : 5 ,
withRelated : [ 'tags' ]
} ) . then ( ( ) => {
queries . length . should . eql ( 2 ) ;
2019-09-16 13:51:54 +03:00
queries [ 0 ] . sql . should . eql ( 'select count(distinct posts.id) as aggregate from `posts` where (`posts`.`published_at` > ? and (`posts`.`type` = ? and `posts`.`status` = ?))' ) ;
2018-10-06 23:13:52 +03:00
queries [ 0 ] . bindings . should . eql ( [
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'2015-07-20' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published'
2018-10-06 23:13:52 +03:00
] ) ;
2019-09-16 13:51:54 +03:00
queries [ 1 ] . sql . should . eql ( 'select `posts`.* from `posts` where (`posts`.`published_at` > ? and (`posts`.`type` = ? and `posts`.`status` = ?)) order by CASE WHEN posts.status = \'scheduled\' THEN 1 WHEN posts.status = \'draft\' THEN 2 ELSE 3 END ASC,CASE WHEN posts.status != \'draft\' THEN posts.published_at END DESC,posts.updated_at DESC,posts.id DESC limit ?' ) ;
2018-10-06 23:13:52 +03:00
queries [ 1 ] . bindings . should . eql ( [
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'2015-07-20' ,
2019-09-16 13:51:54 +03:00
'post' ,
2018-10-06 23:13:52 +03:00
'published' ,
5
] ) ;
} ) ;
} ) ;
describe ( 'primary_tag/primary_author' , function ( ) {
it ( 'generates correct query for - filter: primary_tag:photo, with related: tags' , function ( ) {
const queries = [ ] ;
tracker . install ( ) ;
tracker . on ( 'query' , ( query ) => {
queries . push ( query ) ;
query . response ( [ ] ) ;
} ) ;
return models . Post . findPage ( {
filter : 'primary_tag:photo' ,
withRelated : [ 'tags' ]
} ) . then ( ( ) => {
queries . length . should . eql ( 2 ) ;
2019-09-16 13:51:54 +03:00
queries [ 0 ] . sql . should . eql ( 'select count(distinct posts.id) as aggregate from `posts` where ((`posts`.`id` in (select `posts_tags`.`post_id` from `posts_tags` inner join `tags` on `tags`.`id` = `posts_tags`.`tag_id` and `posts_tags`.`sort_order` = 0 where `tags`.`slug` = ? and `tags`.`visibility` = ?)) and (`posts`.`type` = ? and `posts`.`status` = ?))' ) ;
2018-10-06 23:13:52 +03:00
queries [ 0 ] . bindings . should . eql ( [
'photo' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'public' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published'
2018-10-06 23:13:52 +03:00
] ) ;
2019-09-16 13:51:54 +03:00
queries [ 1 ] . sql . should . eql ( 'select `posts`.* from `posts` where ((`posts`.`id` in (select `posts_tags`.`post_id` from `posts_tags` inner join `tags` on `tags`.`id` = `posts_tags`.`tag_id` and `posts_tags`.`sort_order` = 0 where `tags`.`slug` = ? and `tags`.`visibility` = ?)) and (`posts`.`type` = ? and `posts`.`status` = ?)) order by CASE WHEN posts.status = \'scheduled\' THEN 1 WHEN posts.status = \'draft\' THEN 2 ELSE 3 END ASC,CASE WHEN posts.status != \'draft\' THEN posts.published_at END DESC,posts.updated_at DESC,posts.id DESC limit ?' ) ;
2018-10-06 23:13:52 +03:00
queries [ 1 ] . bindings . should . eql ( [
'photo' ,
'public' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published' ,
2018-10-06 23:13:52 +03:00
15
] ) ;
} ) ;
} ) ;
it ( 'generates correct query for - filter: primary_author:leslie, with related: authors' , function ( ) {
const queries = [ ] ;
tracker . install ( ) ;
tracker . on ( 'query' , ( query ) => {
queries . push ( query ) ;
query . response ( [ ] ) ;
} ) ;
return models . Post . findPage ( {
filter : 'primary_author:leslie' ,
withRelated : [ 'authors' ]
} ) . then ( ( ) => {
queries . length . should . eql ( 2 ) ;
2019-09-16 13:51:54 +03:00
queries [ 0 ] . sql . should . eql ( 'select count(distinct posts.id) as aggregate from `posts` where ((`posts`.`id` in (select `posts_authors`.`post_id` from `posts_authors` inner join `users` as `authors` on `authors`.`id` = `posts_authors`.`author_id` and `posts_authors`.`sort_order` = 0 where `authors`.`slug` = ? and `authors`.`visibility` = ?)) and (`posts`.`type` = ? and `posts`.`status` = ?))' ) ;
2018-10-06 23:13:52 +03:00
queries [ 0 ] . bindings . should . eql ( [
'leslie' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'public' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published'
2018-10-06 23:13:52 +03:00
] ) ;
2019-09-16 13:51:54 +03:00
queries [ 1 ] . sql . should . eql ( 'select `posts`.* from `posts` where ((`posts`.`id` in (select `posts_authors`.`post_id` from `posts_authors` inner join `users` as `authors` on `authors`.`id` = `posts_authors`.`author_id` and `posts_authors`.`sort_order` = 0 where `authors`.`slug` = ? and `authors`.`visibility` = ?)) and (`posts`.`type` = ? and `posts`.`status` = ?)) order by CASE WHEN posts.status = \'scheduled\' THEN 1 WHEN posts.status = \'draft\' THEN 2 ELSE 3 END ASC,CASE WHEN posts.status != \'draft\' THEN posts.published_at END DESC,posts.updated_at DESC,posts.id DESC limit ?' ) ;
2018-10-06 23:13:52 +03:00
queries [ 1 ] . bindings . should . eql ( [
'leslie' ,
'public' ,
2019-09-16 13:51:54 +03:00
'post' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published' ,
2018-10-06 23:13:52 +03:00
15
] ) ;
} ) ;
} ) ;
} ) ;
describe ( 'bad behavior' , function ( ) {
it ( 'generates correct query for - filter: status:[published,draft], limit of: all' , function ( ) {
const queries = [ ] ;
tracker . install ( ) ;
tracker . on ( 'query' , ( query ) => {
queries . push ( query ) ;
query . response ( [ ] ) ;
} ) ;
return models . Post . findPage ( {
filter : 'status:[published,draft]' ,
limit : 'all' ,
status : 'published' ,
where : {
statements : [ {
prop : 'status' ,
op : '=' ,
value : 'published'
} ]
}
} ) . then ( ( ) => {
2020-08-27 02:07:35 +03:00
queries . length . should . eql ( 1 ) ;
2018-10-06 23:13:52 +03:00
2020-08-27 02:07:35 +03:00
queries [ 0 ] . sql . should . eql ( 'select `posts`.* from `posts` where ((`posts`.`status` in (?, ?) and `posts`.`status` = ?) and (`posts`.`type` = ?)) order by CASE WHEN posts.status = \'scheduled\' THEN 1 WHEN posts.status = \'draft\' THEN 2 ELSE 3 END ASC,CASE WHEN posts.status != \'draft\' THEN posts.published_at END DESC,posts.updated_at DESC,posts.id DESC' ) ;
queries [ 0 ] . bindings . should . eql ( [
2018-10-06 23:13:52 +03:00
'published' ,
'draft' ,
🐛 Fixed all known filter limitations (#10159)
refs #10105, closes #10108, closes https://github.com/TryGhost/Ghost/issues/9950, refs https://github.com/TryGhost/Ghost/issues/9923, refs https://github.com/TryGhost/Ghost/issues/9916, refs https://github.com/TryGhost/Ghost/issues/9574, refs https://github.com/TryGhost/Ghost/issues/6345, refs https://github.com/TryGhost/Ghost/issues/6309, refs https://github.com/TryGhost/Ghost/issues/6158, refs https://github.com/TryGhost/GQL/issues/16
- removed GQL dependency
- replaced GQL with our brand new NQL implementation
- fixed all known filter limitations
- GQL suffered from some underlying filter bugs, which NQL tried to fix
- the bugs were mostly in how we query the database for relation filtering
- the underlying problem was caused by a too simple implementation of querying the relations
- mongo-knex has implemented a more robust and complex filtering mechanism for relations
- replaced logic in our bookshelf filter plugin
- we pass the custom, default and override filters from Ghost to NQL, which then are getting parsed and merged into a mongo JSON object. The mongo JSON is getting attached by mongo-knex.
NQL: https://github.com/NexesJS/NQL
mongo-knex: https://github.com/NexesJS/mongo-knex
2018-12-11 13:53:40 +03:00
'published' ,
2019-09-16 13:51:54 +03:00
'post'
2018-10-06 23:13:52 +03:00
] ) ;
} ) ;
} ) ;
} ) ;
} ) ;
2018-02-07 12:46:22 +03:00
2018-10-09 16:31:09 +03:00
describe ( 'toJSON' , function ( ) {
const toJSON = function toJSON ( model , options ) {
return new models . Post ( model ) . toJSON ( options ) ;
} ;
2018-03-05 11:10:27 +03:00
2018-10-09 16:31:09 +03:00
it ( 'ensure mobiledoc revisions are never exposed' , function ( ) {
const post = {
mobiledoc : 'test' ,
2019-07-05 14:40:43 +03:00
mobiledoc _revisions : [ ]
2018-10-09 16:31:09 +03:00
} ;
2018-03-05 11:10:27 +03:00
2018-10-09 16:31:09 +03:00
const json = toJSON ( post , { formats : [ 'mobiledoc' ] } ) ;
2018-03-05 11:10:27 +03:00
2018-10-09 16:31:09 +03:00
should . not . exist ( json . mobiledoc _revisions ) ;
should . exist ( json . mobiledoc ) ;
} ) ;
2018-03-27 17:16:15 +03:00
} ) ;
2018-03-05 11:10:27 +03:00
2018-11-15 17:53:24 +03:00
describe ( 'extraFilters' , function ( ) {
2018-10-06 23:13:52 +03:00
it ( 'generates correct where statement when filter contains unpermitted values' , function ( ) {
const options = {
filter : 'status:[published,draft]' ,
limit : 'all' ,
status : 'published'
} ;
2018-11-15 17:53:24 +03:00
const filter = new models . Post ( ) . extraFilters ( options ) ;
filter . should . eql ( 'status:published' ) ;
2018-10-06 23:13:52 +03:00
} ) ;
} ) ;
describe ( 'enforcedFilters' , function ( ) {
const enforcedFilters = function enforcedFilters ( model , options ) {
return new models . Post ( model ) . enforcedFilters ( options ) ;
} ;
it ( 'returns published status filter for public context' , function ( ) {
const options = {
context : {
public : true
}
} ;
const filter = enforcedFilters ( { } , options ) ;
filter . should . equal ( 'status:published' ) ;
} ) ;
it ( 'returns no status filter for non public context' , function ( ) {
const options = {
context : {
internal : true
}
} ;
const filter = enforcedFilters ( { } , options ) ;
should ( filter ) . equal ( null ) ;
} ) ;
} ) ;
describe ( 'defaultFilters' , function ( ) {
const defaultFilters = function defaultFilters ( model , options ) {
return new models . Post ( model ) . defaultFilters ( options ) ;
} ;
it ( 'returns no default filter for internal context' , function ( ) {
const options = {
context : {
internal : true
}
} ;
const filter = defaultFilters ( { } , options ) ;
should ( filter ) . equal ( null ) ;
} ) ;
2019-09-16 13:51:54 +03:00
it ( 'returns type:post filter for public context' , function ( ) {
2018-10-06 23:13:52 +03:00
const options = {
context : {
public : true
}
} ;
const filter = defaultFilters ( { } , options ) ;
2019-09-16 13:51:54 +03:00
filter . should . equal ( 'type:post' ) ;
2018-10-06 23:13:52 +03:00
} ) ;
2019-09-16 13:51:54 +03:00
it ( 'returns type:post+status:published filter for non public context' , function ( ) {
2018-10-06 23:13:52 +03:00
const options = {
context : 'user'
} ;
const filter = defaultFilters ( { } , options ) ;
2019-09-16 13:51:54 +03:00
filter . should . equal ( 'type:post+status:published' ) ;
2018-10-06 23:13:52 +03:00
} ) ;
} ) ;
2018-10-09 16:31:09 +03:00
} ) ;
describe ( 'Unit: models/post: uses database (@TODO: fix me)' , function ( ) {
before ( function ( ) {
models . init ( ) ;
} ) ;
beforeEach ( function ( ) {
2019-01-21 19:53:44 +03:00
sinon . stub ( security . password , 'hash' ) . resolves ( '$2a$10$we16f8rpbrFZ34xWj0/ZC.LTPUux8ler7bcdTs5qIleN6srRHhilG' ) ;
sinon . stub ( urlService , 'getUrlByResourceId' ) ;
2018-10-09 16:31:09 +03:00
} ) ;
afterEach ( function ( ) {
2019-01-21 19:53:44 +03:00
sinon . restore ( ) ;
2018-10-09 16:31:09 +03:00
} ) ;
after ( function ( ) {
2019-01-21 19:53:44 +03:00
sinon . restore ( ) ;
2018-10-09 16:31:09 +03:00
} ) ;
2018-10-06 23:13:52 +03:00
2018-02-07 12:46:22 +03:00
describe ( 'Permissible' , function ( ) {
describe ( 'As Contributor' , function ( ) {
describe ( 'Editing' , function ( ) {
it ( 'rejects if changing status' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'published' } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'status' ) . returns ( 'draft' ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
false ,
true
2018-02-07 12:46:22 +03:00
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
2019-10-08 16:44:27 +03:00
it ( 'rejects if changing visibility' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { visibility : 'public' } ;
2019-10-08 16:44:27 +03:00
mockPostObj . get . withArgs ( 'visibility' ) . returns ( 'paid' ) ;
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . contributor ,
false ,
false ,
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2019-10-08 16:44:27 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
done ( ) ;
} ) ;
} ) ;
2018-02-07 12:46:22 +03:00
it ( 'rejects if changing author id' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , author _id : 2 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . calledOnce ) . be . true ( ) ;
should ( mockPostObj . related . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if changing authors.0' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , authors : [ { id : 2 } ] } ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . contributor ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledTwice ) . be . false ( ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
2018-03-27 17:16:15 +03:00
it ( 'ignores if changes authors.1' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , authors : [ { id : 1 } , { id : 2 } ] } ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
mockPostObj . get . withArgs ( 'status' ) . returns ( 'draft' ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . contributor ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( result ) => {
should . exist ( result ) ;
should ( result . excludedAttrs ) . deepEqual ( [ 'authors' , 'tags' ] ) ;
should ( mockPostObj . get . callCount ) . eql ( 2 ) ;
should ( mockPostObj . related . callCount ) . eql ( 2 ) ;
done ( ) ;
} ) . catch ( done ) ;
} ) ;
2018-02-07 12:46:22 +03:00
it ( 'rejects if post is not draft' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'published' , author _id : 1 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'status' ) . returns ( 'published' ) ;
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . callCount ) . eql ( 3 ) ;
should ( mockPostObj . related . callCount ) . eql ( 1 ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if contributor is not author of post' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , author _id : 2 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'status' ) . returns ( 'draft' ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . callCount ) . eql ( 1 ) ;
should ( mockPostObj . related . callCount ) . eql ( 0 ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
it ( 'resolves if none of the above cases are true' , function ( ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , author _id : 1 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'status' ) . returns ( 'draft' ) ;
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
return models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( result ) => {
should . exist ( result ) ;
2018-03-27 17:16:15 +03:00
should ( result . excludedAttrs ) . deepEqual ( [ 'authors' , 'tags' ] ) ;
should ( mockPostObj . get . callCount ) . eql ( 3 ) ;
should ( mockPostObj . related . callCount ) . eql ( 1 ) ;
2018-02-07 12:46:22 +03:00
} ) ;
} ) ;
} ) ;
describe ( 'Adding' , function ( ) {
it ( 'rejects if "published" status' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'published' , author _id : 1 } ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-02-07 12:46:22 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if different author id' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , author _id : 2 } ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-02-07 12:46:22 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
2018-03-27 17:16:15 +03:00
it ( 'rejects if different logged in user and `authors.0`' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , authors : [ { id : 2 } ] } ;
2018-03-27 17:16:15 +03:00
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
testUtils . permissions . contributor ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if same logged in user and `authors.0`, but different author_id' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , author _id : 3 , authors : [ { id : 1 } ] } ;
2018-03-27 17:16:15 +03:00
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
testUtils . permissions . contributor ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if different logged in user and `authors.0`, but correct author_id' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , author _id : 1 , authors : [ { id : 2 } ] } ;
2018-03-27 17:16:15 +03:00
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
testUtils . permissions . contributor ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'resolves if same logged in user and `authors.0`' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , authors : [ { id : 1 } ] } ;
2018-03-27 17:16:15 +03:00
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
testUtils . permissions . contributor ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( result ) => {
should . exist ( result ) ;
should ( result . excludedAttrs ) . deepEqual ( [ 'authors' , 'tags' ] ) ;
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) . catch ( done ) ;
} ) ;
2018-02-07 12:46:22 +03:00
it ( 'resolves if none of the above cases are true' , function ( ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { status : 'draft' , author _id : 1 } ;
2018-02-07 12:46:22 +03:00
return models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( result ) => {
should . exist ( result ) ;
2018-03-27 17:16:15 +03:00
should ( result . excludedAttrs ) . deepEqual ( [ 'authors' , 'tags' ] ) ;
2018-02-07 12:46:22 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
} ) ;
} ) ;
} ) ;
describe ( 'Destroying' , function ( ) {
it ( 'rejects if destroying another author\'s post' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
2018-02-07 12:46:22 +03:00
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'destroy' ,
context ,
{ } ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-02-07 12:46:22 +03:00
should ( mockPostObj . get . calledOnce ) . be . true ( ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if destroying a published post' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
2018-02-07 12:46:22 +03:00
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'status' ) . returns ( 'published' ) ;
models . Post . permissible (
mockPostObj ,
'destroy' ,
context ,
{ } ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . calledOnce ) . be . true ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
it ( 'resolves if none of the above cases are true' , function ( ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'status' ) . returns ( 'draft' ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
return models . Post . permissible (
mockPostObj ,
'destroy' ,
context ,
{ } ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . contributor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( result ) => {
should . exist ( result ) ;
2018-03-27 17:16:15 +03:00
should ( result . excludedAttrs ) . deepEqual ( [ 'authors' , 'tags' ] ) ;
should ( mockPostObj . get . calledOnce ) . be . true ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
2018-02-07 12:46:22 +03:00
} ) ;
} ) ;
} ) ;
} ) ;
describe ( 'As Author' , function ( ) {
describe ( 'Editing' , function ( ) {
it ( 'rejects if editing another\'s post' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { author _id : 2 } ;
2018-02-07 12:46:22 +03:00
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 2 } ] } ) ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 2 ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . author ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
done ( ) ;
} ) ;
} ) ;
2019-10-08 16:44:27 +03:00
it ( 'rejects if changing visibility' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { visibility : 'public' } ;
2019-10-08 16:44:27 +03:00
mockPostObj . get . withArgs ( 'visibility' ) . returns ( 'paid' ) ;
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . author ,
false ,
false ,
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2019-10-08 16:44:27 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
done ( ) ;
} ) ;
} ) ;
2018-03-27 17:16:15 +03:00
it ( 'rejects if editing another\'s post (using `authors`)' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { authors : [ { id : 2 } ] } ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . author ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledTwice ) . be . true ( ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if changing author' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { author _id : 2 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . author ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . calledOnce ) . be . true ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if changing authors' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { authors : [ { id : 2 } ] } ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . author ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledTwice ) . be . true ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if changing authors and author_id' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { authors : [ { id : 1 } ] , author _id : 2 } ;
2018-03-27 17:16:15 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . author ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . calledOnce ) . be . true ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
done ( ) ;
} ) ;
} ) ;
it ( 'rejects if changing authors and author_id' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { authors : [ { id : 2 } ] , author _id : 1 } ;
2018-03-27 17:16:15 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . author ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . get . callCount . should . eql ( 1 ) ;
mockPostObj . related . callCount . should . eql ( 2 ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
it ( 'resolves if none of the above cases are true' , function ( ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { author _id : 1 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 1 ) ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
2018-02-07 12:46:22 +03:00
return models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . author ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . calledOnce ) . be . true ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
2018-02-07 12:46:22 +03:00
} ) ;
} ) ;
} ) ;
describe ( 'Adding' , function ( ) {
it ( 'rejects if different author id' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { author _id : 2 } ;
2018-02-07 12:46:22 +03:00
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . author ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-02-07 12:46:22 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
2018-03-27 17:16:15 +03:00
it ( 'rejects if different authors' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { authors : [ { id : 2 } ] } ;
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
testUtils . permissions . author ,
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-03-27 17:16:15 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
done ( ) ;
} ) ;
} ) ;
2018-02-07 12:46:22 +03:00
it ( 'resolves if none of the above cases are true' , function ( ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { author _id : 1 } ;
2018-02-07 12:46:22 +03:00
return models . Post . permissible (
mockPostObj ,
'add' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . author ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
should ( mockPostObj . get . called ) . be . false ( ) ;
} ) ;
} ) ;
} ) ;
} ) ;
describe ( 'Everyone Else' , function ( ) {
it ( 'rejects if hasUserPermissions is false and not current owner' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { author _id : 2 } ;
2018-02-07 12:46:22 +03:00
2018-03-27 17:16:15 +03:00
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 2 } ] } ) ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 2 ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . editor ,
2018-02-07 12:46:22 +03:00
false ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
done ( new Error ( 'Permissible function should have rejected.' ) ) ;
} ) . catch ( ( error ) => {
2020-05-25 11:49:38 +03:00
error . should . be . an . instanceof ( errors . NoPermissionError ) ;
2018-03-27 17:16:15 +03:00
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
2018-02-07 12:46:22 +03:00
done ( ) ;
} ) ;
} ) ;
it ( 'resolves if hasUserPermission is true' , function ( ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { author _id : 2 } ;
2018-02-07 12:46:22 +03:00
mockPostObj . get . withArgs ( 'author_id' ) . returns ( 2 ) ;
return models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2018-03-05 11:10:27 +03:00
testUtils . permissions . editor ,
2018-02-07 12:46:22 +03:00
true ,
2019-01-18 15:39:53 +03:00
true ,
2018-02-07 12:46:22 +03:00
true
) . then ( ( ) => {
should ( mockPostObj . get . called ) . be . false ( ) ;
} ) ;
} ) ;
2019-10-08 16:44:27 +03:00
2020-05-20 08:47:27 +03:00
it ( 'resolves if changing visibility as owner' , function ( done ) {
2020-04-29 18:44:27 +03:00
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { visibility : 'public' } ;
2019-10-08 16:44:27 +03:00
mockPostObj . get . withArgs ( 'visibility' ) . returns ( 'paid' ) ;
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
2020-05-20 08:47:27 +03:00
testUtils . permissions . owner ,
2019-10-08 16:44:27 +03:00
false ,
true ,
true
) . then ( ( ) => {
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
2020-05-20 08:47:27 +03:00
done ( ) ;
} ) . catch ( ( ) => {
done ( new Error ( 'Permissible function should have passed for owner.' ) ) ;
} ) ;
} ) ;
it ( 'resolves if changing visibility as administrator' , function ( done ) {
const mockPostObj = {
get : sinon . stub ( ) ,
related : sinon . stub ( )
} ;
const context = { user : 1 } ;
const unsafeAttrs = { visibility : 'public' } ;
mockPostObj . get . withArgs ( 'visibility' ) . returns ( 'paid' ) ;
mockPostObj . related . withArgs ( 'authors' ) . returns ( { models : [ { id : 1 } ] } ) ;
models . Post . permissible (
mockPostObj ,
'edit' ,
context ,
unsafeAttrs ,
testUtils . permissions . admin ,
false ,
true ,
true
) . then ( ( ) => {
should ( mockPostObj . get . called ) . be . false ( ) ;
should ( mockPostObj . related . calledOnce ) . be . true ( ) ;
done ( ) ;
} ) . catch ( ( ) => {
done ( new Error ( 'Permissible function should have passed for administrator.' ) ) ;
2019-10-08 16:44:27 +03:00
} ) ;
} ) ;
2018-02-07 12:46:22 +03:00
} ) ;
} ) ;
} ) ;