2018-10-13 00:48:49 +02:00
const should = require ( 'should' ) ;
2019-06-18 15:13:55 +02:00
const sinon = require ( 'sinon' ) ;
2020-03-30 16:26:47 +01:00
const serializers = require ( '../../../../../../../core/server/api/v2/utils/serializers' ) ;
2019-06-18 15:13:55 +02:00
const urlUtils = require ( '../../../../../../utils/urlUtils' ) ;
2018-10-13 00:48:49 +02:00
describe ( 'Unit: v2/utils/serializers/input/posts' , function ( ) {
2018-10-19 10:40:47 +02:00
describe ( 'browse' , function ( ) {
it ( 'default' , function ( ) {
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'content' ,
2018-10-19 10:40:47 +02:00
options : {
context : {
user : 0 ,
2019-01-24 14:19:34 +00:00
api _key : {
id : 1 ,
type : 'content'
2019-07-05 13:40:43 +02:00
}
2018-10-19 10:40:47 +02:00
}
2018-10-13 00:48:49 +02:00
}
2018-10-19 10:40:47 +02:00
} ;
2018-10-13 00:48:49 +02:00
2018-10-19 10:40:47 +02:00
serializers . input . posts . browse ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( 'type:post' ) ;
2018-10-19 10:40:47 +02:00
} ) ;
2018-10-13 00:48:49 +02:00
2018-10-19 10:40:47 +02:00
it ( 'should not work for non public context' , function ( ) {
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'admin' ,
2018-10-19 10:40:47 +02:00
options : {
2018-11-05 21:48:31 +01:00
context : {
user : 1
}
2018-10-19 10:40:47 +02:00
}
} ;
2018-10-13 00:48:49 +02:00
2018-10-19 10:40:47 +02:00
serializers . input . posts . browse ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
should . equal ( frame . options . filter , '(type:post)+status:[draft,published,scheduled]' ) ;
2018-10-19 10:40:47 +02:00
} ) ;
2018-10-13 00:48:49 +02:00
2018-10-19 10:40:47 +02:00
it ( 'combine filters' , function ( ) {
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'content' ,
2018-10-19 10:40:47 +02:00
options : {
context : {
user : 0 ,
2019-01-24 14:19:34 +00:00
api _key : {
id : 1 ,
type : 'content'
2019-07-05 13:40:43 +02:00
}
2018-10-19 10:40:47 +02:00
} ,
filter : 'status:published+tag:eins'
}
} ;
2018-10-18 16:48:47 +05:30
2018-10-19 10:40:47 +02:00
serializers . input . posts . browse ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( '(status:published+tag:eins)+type:post' ) ;
2018-10-18 16:48:47 +05:30
} ) ;
🐛 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 11:53:40 +01:00
it ( 'combine filters' , function ( ) {
2018-10-18 16:48:47 +05:30
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'content' ,
2018-10-18 16:48:47 +05:30
options : {
context : {
user : 0 ,
2019-01-24 14:19:34 +00:00
api _key : {
id : 1 ,
type : 'content'
2019-07-05 13:40:43 +02:00
}
2018-10-18 16:48:47 +05:30
} ,
2018-10-19 10:40:47 +02:00
filter : 'page:true+tag:eins'
2018-10-18 16:48:47 +05:30
}
} ;
2018-10-19 10:40:47 +02:00
serializers . input . posts . browse ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( '(page:true+tag:eins)+type:post' ) ;
2018-10-18 16:48:47 +05:30
} ) ;
🐛 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 11:53:40 +01:00
it ( 'combine filters' , function ( ) {
2018-10-18 16:48:47 +05:30
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'content' ,
2018-10-18 16:48:47 +05:30
options : {
context : {
user : 0 ,
2019-01-24 14:19:34 +00:00
api _key : {
id : 1 ,
type : 'content'
2019-07-05 13:40:43 +02:00
}
2018-10-18 16:48:47 +05:30
} ,
2018-10-19 10:40:47 +02:00
filter : 'page:true'
}
} ;
serializers . input . posts . browse ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( '(page:true)+type: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 11:53:40 +01:00
} ) ;
it ( 'combine filters' , function ( ) {
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'content' ,
🐛 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 11:53:40 +01:00
options : {
context : {
user : 0 ,
2019-01-24 14:19:34 +00:00
api _key : {
id : 1 ,
type : 'content'
2019-07-05 13:40:43 +02:00
}
🐛 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 11:53:40 +01:00
} ,
filter : '(page:true,page:false)'
}
} ;
serializers . input . posts . browse ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( '((page:true,page:false))+type:post' ) ;
2018-10-19 10:40:47 +02:00
} ) ;
2018-11-06 19:09:16 +05:30
it ( 'remove mobiledoc option from formats' , function ( ) {
const apiConfig = { } ;
const frame = {
2019-02-25 19:52:45 +01:00
apiType : 'content' ,
2018-11-06 19:09:16 +05:30
options : {
formats : [ 'html' , 'mobiledoc' , 'plaintext' ] ,
context : { }
}
} ;
serializers . input . posts . browse ( apiConfig , frame ) ;
frame . options . formats . should . not . containEql ( 'mobiledoc' ) ;
frame . options . formats . should . containEql ( 'html' ) ;
frame . options . formats . should . containEql ( 'plaintext' ) ;
} ) ;
2018-10-19 10:40:47 +02:00
} ) ;
describe ( 'read' , function ( ) {
2019-09-16 11:51:54 +01:00
it ( 'with apiType of "content" it forces type filter' , function ( ) {
2018-10-19 10:40:47 +02:00
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'content' ,
options : { } ,
2018-10-19 10:40:47 +02:00
data : { }
} ;
serializers . input . posts . read ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( 'type:post' ) ;
2018-10-19 10:40:47 +02:00
} ) ;
2019-09-16 11:51:54 +01:00
it ( 'with apiType of "content" it forces type:post filter' , function ( ) {
2018-10-19 10:40:47 +02:00
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'content' ,
2019-02-22 12:07:34 +01:00
options : {
2019-09-16 11:51:54 +01:00
filter : 'type:page'
2019-02-22 12:07:34 +01:00
} ,
data : { }
2018-10-18 16:48:47 +05:30
} ;
2018-10-19 10:40:47 +02:00
serializers . input . posts . read ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( '(type:page)+type:post' ) ;
2018-10-19 10:40:47 +02:00
} ) ;
2018-10-19 10:54:05 +02:00
2019-09-16 11:51:54 +01:00
it ( 'with apiType of "admin" it forces type & status false filter' , function ( ) {
2018-10-19 10:54:05 +02:00
const apiConfig = { } ;
const frame = {
2019-02-14 18:17:02 +01:00
apiType : 'admin' ,
2018-10-19 10:54:05 +02:00
options : {
context : {
2019-02-14 18:17:02 +01:00
api _key : {
id : 1 ,
type : 'admin'
}
2018-10-19 10:54:05 +02:00
}
} ,
data : { }
} ;
serializers . input . posts . read ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( '(type:post)+status:[draft,published,scheduled]' ) ;
2019-02-22 12:07:34 +01:00
} ) ;
2019-09-16 11:51:54 +01:00
it ( 'with apiType of "admin" it forces type:post filter & respects custom status filter' , function ( ) {
2019-02-22 12:07:34 +01:00
const apiConfig = { } ;
const frame = {
apiType : 'admin' ,
options : {
context : {
api _key : {
id : 1 ,
type : 'admin'
}
} ,
filter : 'status:draft'
} ,
data : { }
} ;
serializers . input . posts . read ( apiConfig , frame ) ;
2019-09-16 11:51:54 +01:00
frame . options . filter . should . eql ( '(status:draft)+type:post' ) ;
2018-10-19 10:54:05 +02:00
} ) ;
2018-11-06 19:09:16 +05:30
it ( 'remove mobiledoc option from formats' , function ( ) {
const apiConfig = { } ;
const frame = {
2019-02-25 19:52:45 +01:00
apiType : 'content' ,
2018-11-06 19:09:16 +05:30
options : {
formats : [ 'html' , 'mobiledoc' , 'plaintext' ] ,
context : { }
} ,
data : { }
} ;
serializers . input . posts . read ( apiConfig , frame ) ;
frame . options . formats . should . not . containEql ( 'mobiledoc' ) ;
frame . options . formats . should . containEql ( 'html' ) ;
frame . options . formats . should . containEql ( 'plaintext' ) ;
} ) ;
2018-10-19 10:40:47 +02:00
} ) ;
describe ( 'edit' , function ( ) {
2019-01-18 11:29:56 +00:00
describe ( 'Ensure html to mobiledoc conversion' , function ( ) {
it ( 'no transformation when no html source option provided' , function ( ) {
const apiConfig = { } ;
const mobiledoc = '{"version":"0.3.1","atoms":[],"cards":[],"sections":[]}' ;
const frame = {
2019-02-22 04:17:14 +01:00
options : { } ,
2019-01-18 11:29:56 +00:00
data : {
posts : [
{
id : 'id1' ,
html : '<p>convert me</p>' ,
mobiledoc : mobiledoc
}
]
}
} ;
serializers . input . posts . edit ( apiConfig , frame ) ;
let postData = frame . data . posts [ 0 ] ;
postData . mobiledoc . should . equal ( mobiledoc ) ;
} ) ;
it ( 'no transformation when html data is empty' , function ( ) {
const apiConfig = { } ;
const mobiledoc = '{"version":"0.3.1","atoms":[],"cards":[],"sections":[]}' ;
const frame = {
options : {
source : 'html'
} ,
data : {
posts : [
{
id : 'id1' ,
html : '' ,
mobiledoc : mobiledoc
}
]
}
} ;
serializers . input . posts . edit ( apiConfig , frame ) ;
let postData = frame . data . posts [ 0 ] ;
postData . mobiledoc . should . equal ( mobiledoc ) ;
} ) ;
it ( 'transforms html when html is present in data and source options' , function ( ) {
const apiConfig = { } ;
const mobiledoc = '{"version":"0.3.1","atoms":[],"cards":[],"sections":[]}' ;
const frame = {
options : {
source : 'html'
} ,
data : {
posts : [
{
id : 'id1' ,
html : '<p>this is great feature</p>' ,
mobiledoc : mobiledoc
}
]
}
} ;
serializers . input . posts . edit ( apiConfig , frame ) ;
let postData = frame . data . posts [ 0 ] ;
postData . mobiledoc . should . not . equal ( mobiledoc ) ;
postData . mobiledoc . should . equal ( '{"version":"0.3.1","atoms":[],"cards":[],"markups":[],"sections":[[1,"p",[[0,[],0,"this is great feature"]]]]}' ) ;
} ) ;
2019-05-04 11:30:59 +01:00
it ( 'preserves html cards in transformed html' , function ( ) {
const apiConfig = { } ;
const frame = {
options : {
source : 'html'
} ,
data : {
posts : [
{
id : 'id1' ,
2019-07-05 13:40:43 +02:00
html : '<p>this is great feature</p>\n<!--kg-card-begin: html--><div class="custom">My Custom HTML</div><!--kg-card-end: html-->\n<p>custom html preserved!</p>'
2019-05-04 11:30:59 +01:00
}
]
}
} ;
serializers . input . posts . edit ( apiConfig , frame ) ;
let postData = frame . data . posts [ 0 ] ;
2019-05-04 11:46:13 +01:00
postData . mobiledoc . should . equal ( '{"version":"0.3.1","atoms":[],"cards":[["html",{"html":"<div class=\\"custom\\">My Custom HTML</div>"}]],"markups":[],"sections":[[1,"p",[[0,[],0,"this is great feature"]]],[10,0],[1,"p",[[0,[],0,"custom html preserved!"]]]]}' ) ;
2019-05-04 11:30:59 +01:00
} ) ;
2019-01-18 11:29:56 +00:00
} ) ;
2019-02-22 13:01:04 +01:00
describe ( 'Ensure relations format' , function ( ) {
it ( 'relations is array of objects' , function ( ) {
const apiConfig = { } ;
const frame = {
options : { } ,
data : {
posts : [
{
id : 'id1' ,
authors : [ { id : 'id' } ] ,
tags : [ { slug : 'slug1' , name : 'hey' } , { slug : 'slug2' } ]
}
]
}
} ;
serializers . input . posts . edit ( apiConfig , frame ) ;
frame . data . posts [ 0 ] . authors . should . eql ( [ { id : 'id' } ] ) ;
frame . data . posts [ 0 ] . tags . should . eql ( [ { slug : 'slug1' , name : 'hey' } , { slug : 'slug2' } ] ) ;
} ) ;
it ( 'authors is array of strings' , function ( ) {
const apiConfig = { } ;
const frame = {
options : { } ,
data : {
posts : [
{
id : 'id1' ,
authors : [ 'email1' , 'email2' ] ,
2019-07-05 13:40:43 +02:00
tags : [ 'name1' , 'name2' ]
2019-02-22 13:01:04 +01:00
}
]
}
} ;
serializers . input . posts . edit ( apiConfig , frame ) ;
frame . data . posts [ 0 ] . authors . should . eql ( [ { email : 'email1' } , { email : 'email2' } ] ) ;
frame . data . posts [ 0 ] . tags . should . eql ( [ { name : 'name1' } , { name : 'name2' } ] ) ;
} ) ;
} ) ;
2018-10-18 16:48:47 +05:30
} ) ;
2018-10-13 00:48:49 +02:00
} ) ;