2019-11-05 07:32:53 +03:00
const should = require ( 'should' ) ;
const supertest = require ( 'supertest' ) ;
const ObjectId = require ( 'bson-objectid' ) ;
2019-11-08 07:37:53 +03:00
const testUtils = require ( '../../utils' ) ;
2019-11-05 07:32:53 +03:00
const localUtils = require ( './utils' ) ;
2020-05-27 20:47:53 +03:00
const config = require ( '../../../core/shared/config' ) ;
2020-04-20 14:47:12 +03:00
const models = require ( '../../../core/server/models/index' ) ;
2019-11-08 07:37:53 +03:00
2019-11-05 07:32:53 +03:00
describe ( 'Email Preview API' , function ( ) {
2019-11-08 07:37:53 +03:00
let request ;
2019-11-05 07:32:53 +03:00
2020-11-30 17:25:22 +03:00
before ( async function ( ) {
2021-11-18 11:55:35 +03:00
await localUtils . startGhost ( ) ;
2020-11-30 17:25:22 +03:00
request = supertest . agent ( config . get ( 'url' ) ) ;
2022-05-11 18:52:24 +03:00
await localUtils . doAuth ( request , 'users:extra' , 'newsletters' , 'posts' ) ;
2019-11-05 07:32:53 +03:00
} ) ;
describe ( 'Read' , function ( ) {
2020-11-30 17:25:22 +03:00
it ( 'can\'t retrieve for non existent post' , async function ( ) {
2022-04-25 20:42:39 +03:00
const res = await request . get ( localUtils . API . getApiQuery ( ` email_previews/posts/ ${ ObjectId ( ) . toHexString ( ) } / ` ) )
2019-11-05 07:32:53 +03:00
. set ( 'Origin' , config . get ( 'url' ) )
. set ( 'Accept' , 'application/json' )
. expect ( 'Content-Type' , /json/ )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
2020-11-30 17:25:22 +03:00
. expect ( 404 ) ;
should . not . exist ( res . headers [ 'x-cache-invalidate' ] ) ;
const jsonResponse = res . body ;
should . exist ( jsonResponse ) ;
should . exist ( jsonResponse . errors ) ;
testUtils . API . checkResponseValue ( jsonResponse . errors [ 0 ] , [
'message' ,
'context' ,
'type' ,
'details' ,
'property' ,
'help' ,
'code' ,
2022-05-07 17:28:28 +03:00
'id' ,
'ghostErrorCode'
2020-11-30 17:25:22 +03:00
] ) ;
2019-11-05 07:32:53 +03:00
} ) ;
2020-11-30 17:25:22 +03:00
it ( 'can read post email preview with fields' , async function ( ) {
const res = await request
2022-04-25 17:46:28 +03:00
. get ( localUtils . API . getApiQuery ( ` email_previews/posts/ ${ testUtils . DataGenerator . Content . posts [ 0 ] . id } / ` ) )
2019-11-05 07:32:53 +03:00
. set ( 'Origin' , config . get ( 'url' ) )
. set ( 'Accept' , 'application/json' )
. expect ( 'Content-Type' , /json/ )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
2020-11-30 17:25:22 +03:00
. expect ( 200 ) ;
should . not . exist ( res . headers [ 'x-cache-invalidate' ] ) ;
const jsonResponse = res . body ;
should . exist ( jsonResponse ) ;
should . exist ( jsonResponse . email _previews ) ;
2022-04-25 20:38:46 +03:00
localUtils . API . checkResponse ( jsonResponse . email _previews [ 0 ] , 'email_previews' , null , null ) ;
2019-11-05 07:32:53 +03:00
} ) ;
2020-04-20 14:47:12 +03:00
2020-11-30 17:25:22 +03:00
it ( 'can read post email preview with email card and replacements' , async function ( ) {
2020-04-20 14:47:12 +03:00
const post = testUtils . DataGenerator . forKnex . createPost ( {
2021-04-21 18:02:02 +03:00
id : ObjectId ( ) . toHexString ( ) ,
2020-04-20 14:47:12 +03:00
title : 'Post with email-only card' ,
slug : 'email-only-card' ,
2020-04-20 16:25:58 +03:00
mobiledoc : '{"version":"0.3.1","atoms":[],"cards":[["email",{"html":"<p>Hey {first_name \\"there\\"} {unknown}</p><p><strong>Welcome to your first Ghost email!</strong></p>"}],["email",{"html":"<p>Another email card with a similar replacement, {first_name, \\"see?\\"}</p>"}]],"markups":[],"sections":[[10,0],[1,"p",[[0,[],0,"This is the actual post content..."]]],[10,1],[1,"p",[]]]}' ,
2020-04-20 14:47:12 +03:00
html : '<p>This is the actual post content...</p>' ,
plaintext : 'This is the actual post content...' ,
status : 'draft' ,
uuid : 'd52c42ae-2755-455c-80ec-70b2ec55c904'
} ) ;
2020-11-30 17:25:22 +03:00
await models . Post . add ( post , { context : { internal : true } } ) ;
const res = await request
2022-04-25 17:46:28 +03:00
. get ( localUtils . API . getApiQuery ( ` email_previews/posts/ ${ post . id } / ` ) )
2020-11-30 17:25:22 +03:00
. set ( 'Origin' , config . get ( 'url' ) )
. set ( 'Accept' , 'application/json' )
. expect ( 'Content-Type' , /json/ )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
. expect ( 200 ) ;
should . not . exist ( res . headers [ 'x-cache-invalidate' ] ) ;
const jsonResponse = res . body ;
should . exist ( jsonResponse ) ;
should . exist ( jsonResponse . email _previews ) ;
jsonResponse . email _previews [ 0 ] . html . should . match ( /Hey there {unknown}/ ) ;
jsonResponse . email _previews [ 0 ] . html . should . match ( /Welcome to your first Ghost email!/ ) ;
jsonResponse . email _previews [ 0 ] . html . should . match ( /This is the actual post content\.\.\./ ) ;
jsonResponse . email _previews [ 0 ] . html . should . match ( /Another email card with a similar replacement, see\?/ ) ;
jsonResponse . email _previews [ 0 ] . plaintext . should . match ( /Hey there {unknown}/ ) ;
jsonResponse . email _previews [ 0 ] . plaintext . should . match ( /Welcome to your first Ghost email!/ ) ;
jsonResponse . email _previews [ 0 ] . plaintext . should . match ( /This is the actual post content\.\.\./ ) ;
jsonResponse . email _previews [ 0 ] . plaintext . should . match ( /Another email card with a similar replacement, see\?/ ) ;
2020-04-20 14:47:12 +03:00
} ) ;
2020-08-12 21:46:25 +03:00
2020-11-30 17:25:22 +03:00
it ( 'has custom content transformations for email compatibility' , async function ( ) {
2020-08-12 21:46:25 +03:00
const post = testUtils . DataGenerator . forKnex . createPost ( {
2021-04-21 18:02:02 +03:00
id : ObjectId ( ) . toHexString ( ) ,
2020-08-12 21:46:25 +03:00
title : 'Post with email-only card' ,
slug : 'email-only-card' ,
2020-08-12 22:14:06 +03:00
mobiledoc : '{"version":"0.3.1","atoms":[],"cards":[],"markups":[["a",["href","https://ghost.org"]]],"sections":[[1,"p",[[0,[],0,"Testing "],[0,[0],1,"links"],[0,[],0," in email excerpt and apostrophes \'"]]]]}' ,
2020-08-12 21:46:25 +03:00
html : '<p>This is the actual post content...</p>' ,
plaintext : 'This is the actual post content...' ,
status : 'draft' ,
uuid : 'd52c42ae-2755-455c-80ec-70b2ec55c904'
} ) ;
2020-11-30 17:25:22 +03:00
await models . Post . add ( post , { context : { internal : true } } ) ;
const res = await request
2022-04-25 17:46:28 +03:00
. get ( localUtils . API . getApiQuery ( ` email_previews/posts/ ${ post . id } / ` ) )
2020-11-30 17:25:22 +03:00
. set ( 'Origin' , config . get ( 'url' ) )
. set ( 'Accept' , 'application/json' )
. expect ( 'Content-Type' , /json/ )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
. expect ( 200 ) ;
should . not . exist ( res . headers [ 'x-cache-invalidate' ] ) ;
const jsonResponse = res . body ;
should . exist ( jsonResponse ) ;
should . exist ( jsonResponse . email _previews ) ;
const [ preview ] = jsonResponse . email _previews ;
preview . html . should . containEql ( 'Testing links in email excerpt' ) ;
preview . html . should . match ( /'/ ) ;
preview . html . should . not . match ( /'/ ) ;
2020-08-12 21:46:25 +03:00
} ) ;
2022-05-11 18:52:24 +03:00
it ( 'uses the posts newsletter' , async function ( ) {
const defaultNewsletter = await models . Newsletter . getDefaultNewsletter ( ) ;
defaultNewsletter . id . should . not . eql ( testUtils . DataGenerator . Content . newsletters [ 0 ] . id , 'Should use a non-default newsletter for this test' ) ;
const post = testUtils . DataGenerator . forKnex . createPost ( {
id : ObjectId ( ) . toHexString ( ) ,
title : 'Post with email-only card' ,
slug : 'email-only-card' ,
mobiledoc : '{"version":"0.3.1","atoms":[],"cards":[],"markups":[["a",["href","https://ghost.org"]]],"sections":[[1,"p",[[0,[],0,"Testing "],[0,[0],1,"links"],[0,[],0," in email excerpt and apostrophes \'"]]]]}' ,
html : '<p>This is the actual post content...</p>' ,
plaintext : 'This is the actual post content...' ,
status : 'scheduled' ,
uuid : 'd52c42ae-2755-455c-80ec-70b2ec55c904' ,
newsletter _id : testUtils . DataGenerator . Content . newsletters [ 0 ] . id
} ) ;
await models . Post . add ( post , { context : { internal : true } } ) ;
const res = await request
. get ( localUtils . API . getApiQuery ( ` email_previews/posts/ ${ post . id } / ` ) )
. set ( 'Origin' , config . get ( 'url' ) )
. set ( 'Accept' , 'application/json' )
. expect ( 'Content-Type' , /json/ )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
. expect ( 200 ) ;
should . not . exist ( res . headers [ 'x-cache-invalidate' ] ) ;
const jsonResponse = res . body ;
should . exist ( jsonResponse ) ;
2022-05-16 14:15:54 +03:00
should . exist ( jsonResponse . email _previews ) ;
const [ preview ] = jsonResponse . email _previews ;
preview . html . should . containEql ( testUtils . DataGenerator . Content . newsletters [ 0 ] . name ) ;
} ) ;
it ( 'uses the newsletter provided through ?newsletter=slug' , async function ( ) {
const defaultNewsletter = await models . Newsletter . getDefaultNewsletter ( ) ;
const selectedNewsletter = testUtils . DataGenerator . Content . newsletters [ 0 ] ;
selectedNewsletter . id . should . not . eql ( defaultNewsletter . id , 'Should use a non-default newsletter for this test' ) ;
const post = testUtils . DataGenerator . forKnex . createPost ( {
id : ObjectId ( ) . toHexString ( ) ,
title : 'Post with email-only card' ,
slug : 'email-only-card' ,
mobiledoc : '{"version":"0.3.1","atoms":[],"cards":[],"markups":[["a",["href","https://ghost.org"]]],"sections":[[1,"p",[[0,[],0,"Testing "],[0,[0],1,"links"],[0,[],0," in email excerpt and apostrophes \'"]]]]}' ,
html : '<p>This is the actual post content...</p>' ,
plaintext : 'This is the actual post content...' ,
status : 'draft' ,
uuid : 'd52c42ae-2755-455c-80ec-70b2ec55c904'
} ) ;
await models . Post . add ( post , { context : { internal : true } } ) ;
const res = await request
. get ( localUtils . API . getApiQuery ( ` email_previews/posts/ ${ post . id } /?newsletter= ${ selectedNewsletter . slug } ` ) )
. set ( 'Origin' , config . get ( 'url' ) )
. set ( 'Accept' , 'application/json' )
. expect ( 'Content-Type' , /json/ )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
. expect ( 200 ) ;
should . not . exist ( res . headers [ 'x-cache-invalidate' ] ) ;
const jsonResponse = res . body ;
should . exist ( jsonResponse ) ;
2022-05-11 18:52:24 +03:00
should . exist ( jsonResponse . email _previews ) ;
const [ preview ] = jsonResponse . email _previews ;
preview . html . should . containEql ( testUtils . DataGenerator . Content . newsletters [ 0 ] . name ) ;
} ) ;
2019-11-05 07:32:53 +03:00
} ) ;
2020-05-28 11:56:53 +03:00
describe ( 'As Owner' , function ( ) {
2020-11-30 17:25:22 +03:00
it ( 'can send test email' , async function ( ) {
2022-04-25 17:46:28 +03:00
const url = localUtils . API . getApiQuery ( ` email_previews/posts/ ${ testUtils . DataGenerator . Content . posts [ 0 ] . id } / ` ) ;
2020-11-30 17:25:22 +03:00
await request
2020-05-28 11:56:53 +03:00
. post ( url )
. set ( 'Origin' , config . get ( 'url' ) )
. send ( {
emails : [ 'test@ghost.org' ]
} )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
2022-04-26 13:55:15 +03:00
. expect ( 204 )
2022-03-17 19:13:25 +03:00
. expect ( ( res ) => {
res . body . should . be . empty ( ) ;
} ) ;
2020-05-28 11:56:53 +03:00
} ) ;
} ) ;
2020-11-30 17:25:22 +03:00
2020-05-28 11:56:53 +03:00
describe ( 'As Admin' , function ( ) {
2020-11-30 17:25:22 +03:00
before ( async function ( ) {
const user = await testUtils . createUser ( {
2020-05-28 11:56:53 +03:00
user : testUtils . DataGenerator . forKnex . createUser ( { email : 'admin+1@ghost.org' } ) ,
role : testUtils . DataGenerator . Content . roles [ 0 ] . name
} ) ;
2020-11-30 17:25:22 +03:00
request . user = user ;
await localUtils . doAuth ( request ) ;
2020-05-28 11:56:53 +03:00
} ) ;
2020-11-30 17:25:22 +03:00
it ( 'can send test email' , async function ( ) {
2022-04-25 17:46:28 +03:00
const url = localUtils . API . getApiQuery ( ` email_previews/posts/ ${ testUtils . DataGenerator . Content . posts [ 0 ] . id } / ` ) ;
2020-11-30 17:25:22 +03:00
await request
2020-05-28 11:56:53 +03:00
. post ( url )
. set ( 'Origin' , config . get ( 'url' ) )
. send ( {
emails : [ 'test@ghost.org' ]
} )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
2022-04-26 13:55:15 +03:00
. expect ( 204 )
2022-03-17 19:13:25 +03:00
. expect ( ( res ) => {
res . body . should . be . empty ( ) ;
} ) ;
2020-05-28 11:56:53 +03:00
} ) ;
} ) ;
2020-11-30 17:25:22 +03:00
2020-05-28 11:56:53 +03:00
describe ( 'As Editor' , function ( ) {
2020-11-30 17:25:22 +03:00
before ( async function ( ) {
const user = await testUtils . createUser ( {
2020-05-28 11:56:53 +03:00
user : testUtils . DataGenerator . forKnex . createUser ( {
email : 'test+editor@ghost.org'
} ) ,
role : testUtils . DataGenerator . Content . roles [ 1 ] . name
} ) ;
2020-11-30 17:25:22 +03:00
request . user = user ;
await localUtils . doAuth ( request ) ;
2020-05-28 11:56:53 +03:00
} ) ;
2020-11-30 17:25:22 +03:00
it ( 'can send test email' , async function ( ) {
2022-04-25 17:46:28 +03:00
const url = localUtils . API . getApiQuery ( ` email_previews/posts/ ${ testUtils . DataGenerator . Content . posts [ 0 ] . id } / ` ) ;
2020-11-30 17:25:22 +03:00
await request
2020-05-28 11:56:53 +03:00
. post ( url )
. set ( 'Origin' , config . get ( 'url' ) )
. send ( {
emails : [ 'test@ghost.org' ]
} )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
2022-04-26 13:55:15 +03:00
. expect ( 204 )
2022-03-17 19:13:25 +03:00
. expect ( ( res ) => {
res . body . should . be . empty ( ) ;
} ) ;
2020-05-28 11:56:53 +03:00
} ) ;
} ) ;
2020-11-30 17:25:22 +03:00
2020-05-28 11:56:53 +03:00
describe ( 'As Author' , function ( ) {
2020-11-30 17:25:22 +03:00
before ( async function ( ) {
const user = await testUtils . createUser ( {
2020-05-28 11:56:53 +03:00
user : testUtils . DataGenerator . forKnex . createUser ( {
email : 'test+author@ghost.org'
} ) ,
role : testUtils . DataGenerator . Content . roles [ 2 ] . name
} ) ;
2020-11-30 17:25:22 +03:00
request . user = user ;
await localUtils . doAuth ( request ) ;
2020-05-28 11:56:53 +03:00
} ) ;
2020-11-30 17:25:22 +03:00
it ( 'cannot send test email' , async function ( ) {
2022-04-25 17:46:28 +03:00
const url = localUtils . API . getApiQuery ( ` email_previews/posts/ ${ testUtils . DataGenerator . Content . posts [ 0 ] . id } / ` ) ;
2020-11-30 17:25:22 +03:00
await request
2020-05-28 11:56:53 +03:00
. post ( url )
. set ( 'Origin' , config . get ( 'url' ) )
. send ( {
emails : [ 'test@ghost.org' ]
} )
. set ( 'Accept' , 'application/json' )
. expect ( 'Content-Type' , /json/ )
. expect ( 'Cache-Control' , testUtils . cacheRules . private )
2022-03-17 19:13:25 +03:00
. expect ( 403 )
. expect ( ( res ) => {
res . body . should . be . an . Object ( ) . with . property ( 'errors' ) ;
} ) ;
2020-05-28 11:56:53 +03:00
} ) ;
} ) ;
2019-11-05 07:32:53 +03:00
} ) ;