diff --git a/ghost/core/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap b/ghost/core/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap index bf4bc49b3c..8c148c29b8 100644 --- a/ghost/core/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap +++ b/ghost/core/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap @@ -120,6 +120,201 @@ Object { } `; +exports[`Newsletters API Can add a newsletter - with custom sender_email 3: [metadata 1] 1`] = ` +Object { + "forceTextContent": true, + "from": "noreply@example.com", + "subject": "Verify email address", + "to": "test@example.com", +} +`; + +exports[`Newsletters API Can add a newsletter - with custom sender_email 4: [html 1] 1`] = ` +" + + + + + + Confirm your email address + + + + + + + + + +
  +
+ + + + + + + + + + +
+ + + + +
+

Hey there,

+

Please confirm your email address with this link:

+ + + + + + +
+ + + + + + +
Confirm email address
+
+

For your security, the link will expire in 24 hours time.

+
+

You can also copy & paste this URL into your browser:

+

http://127.0.0.1:2369/ghost/#/settings/newsletters/?verifyEmail=REPLACED_TOKEN

+
+
+ + +
+ + + + + + + +
+ If you did not make this request, you can simply delete this message.
This email address will not be used. +
+ Sent to test@example.com +
+
+ + + +
+
 
+ + +" +`; + +exports[`Newsletters API Can add a newsletter - with custom sender_email 5: [text 1] 1`] = ` +" + Hey there, + + Please confirm your email address with this link: + + http://127.0.0.1:2369/ghost/#/settings/newsletters/?verifyEmail=REPLACED_TOKEN + + For your security, the link will expire in 24 hours time. + + --- + + Sent to test@example.com + If you did not make this request, you can simply delete this message. This email address will not be used. + " +`; + exports[`Newsletters API Can add a newsletter - with custom sender_email and subscribe existing members 1: [body] 1`] = ` Object { "meta": Object { @@ -576,6 +771,201 @@ Object { } `; +exports[`Newsletters API Can edit a newsletters and update the sender_email when already set 3: [metadata 1] 1`] = ` +Object { + "forceTextContent": true, + "from": "noreply@example.com", + "subject": "Verify email address", + "to": "updated@example.com", +} +`; + +exports[`Newsletters API Can edit a newsletters and update the sender_email when already set 4: [html 1] 1`] = ` +" + + + + + + Confirm your email address + + + + + + + + + +
  +
+ + + + + + + + + + +
+ + + + +
+

Hey there,

+

Please confirm your email address with this link:

+ + + + + + +
+ + + + + + +
Confirm email address
+
+

For your security, the link will expire in 24 hours time.

+
+

You can also copy & paste this URL into your browser:

+

http://127.0.0.1:2369/ghost/#/settings/newsletters/?verifyEmail=REPLACED_TOKEN

+
+
+ + +
+ + + + + + + +
+ If you did not make this request, you can simply delete this message.
This email address will not be used. +
+ Sent to updated@example.com +
+
+ + + +
+
 
+ + +" +`; + +exports[`Newsletters API Can edit a newsletters and update the sender_email when already set 5: [text 1] 1`] = ` +" + Hey there, + + Please confirm your email address with this link: + + http://127.0.0.1:2369/ghost/#/settings/newsletters/?verifyEmail=REPLACED_TOKEN + + For your security, the link will expire in 24 hours time. + + --- + + Sent to updated@example.com + If you did not make this request, you can simply delete this message. This email address will not be used. + " +`; + exports[`Newsletters API Can edit newsletters 1: [body] 1`] = ` Object { "newsletters": Array [ @@ -1085,6 +1475,242 @@ Object { } `; +exports[`Newsletters API Can verify property updates 1: [metadata 1] 1`] = ` +Object { + "forceTextContent": true, + "from": "noreply@example.com", + "subject": "Verify email address", + "to": "verify@example.com", +} +`; + +exports[`Newsletters API Can verify property updates 2: [html 1] 1`] = ` +" + + + + + + Confirm your email address + + + + + + + + + +
  +
+ + + + + + + + + + +
+ + + + +
+

Hey there,

+

Please confirm your email address with this link:

+ + + + + + +
+ + + + + + +
Confirm email address
+
+

For your security, the link will expire in 24 hours time.

+
+

You can also copy & paste this URL into your browser:

+

http://127.0.0.1:2369/ghost/#/settings/newsletters/?verifyEmail=REPLACED_TOKEN

+
+
+ + +
+ + + + + + + +
+ If you did not make this request, you can simply delete this message.
This email address will not be used. +
+ Sent to verify@example.com +
+
+ + + +
+
 
+ + +" +`; + +exports[`Newsletters API Can verify property updates 3: [text 1] 1`] = ` +" + Hey there, + + Please confirm your email address with this link: + + http://127.0.0.1:2369/ghost/#/settings/newsletters/?verifyEmail=REPLACED_TOKEN + + For your security, the link will expire in 24 hours time. + + --- + + Sent to verify@example.com + If you did not make this request, you can simply delete this message. This email address will not be used. + " +`; + +exports[`Newsletters API Can verify property updates 4: [body] 1`] = ` +Object { + "newsletters": Array [ + Object { + "background_color": "light", + "body_font_category": "serif", + "border_color": null, + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "description": null, + "feedback_enabled": false, + "footer_content": null, + "header_image": "http://127.0.0.1:2369/content/images/2022/05/test.jpg", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": "Updated newsletter name", + "sender_email": "verify@example.com", + "sender_name": "Jamie", + "sender_reply_to": "newsletter", + "show_badge": true, + "show_comment_cta": true, + "show_feature_image": true, + "show_header_icon": true, + "show_header_name": true, + "show_header_title": true, + "show_latest_posts": false, + "show_post_title_section": true, + "show_subscription_details": false, + "slug": "daily-newsletter", + "sort_order": 1, + "status": "active", + "subscribe_on_signup": false, + "title_alignment": "center", + "title_color": null, + "title_font_category": "serif", + "updated_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "uuid": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/, + "visibility": "members", + }, + ], +} +`; + exports[`Newsletters API Can't add multiple newsletters with same name 1: [body] 1`] = ` Object { "newsletters": Array [ diff --git a/ghost/core/test/e2e-api/admin/newsletters.test.js b/ghost/core/test/e2e-api/admin/newsletters.test.js index 4a676ecdd2..9e59bdb97b 100644 --- a/ghost/core/test/e2e-api/admin/newsletters.test.js +++ b/ghost/core/test/e2e-api/admin/newsletters.test.js @@ -1,7 +1,8 @@ const assert = require('assert'); const sinon = require('sinon'); -const {agentProvider, mockManager, fixtureManager, configUtils, dbUtils, matchers} = require('../../utils/e2e-framework'); +const {agentProvider, mockManager, fixtureManager, configUtils, dbUtils, matchers, regexes} = require('../../utils/e2e-framework'); const {anyContentVersion, anyEtag, anyObjectId, anyUuid, anyISODateTime, anyLocationFor, anyNumber} = matchers; +const {queryStringToken} = regexes; const models = require('../../../core/server/models'); const logging = require('@tryghost/logging'); @@ -28,6 +29,7 @@ const newsletterSnapshotWithoutSortOrder = { describe('Newsletters API', function () { let agent; + let emailMockReceiver; before(async function () { agent = await agentProvider.getAdminAPIAgent(); @@ -36,7 +38,7 @@ describe('Newsletters API', function () { }); beforeEach(function () { - mockManager.mockMail(); + emailMockReceiver = mockManager.mockMail(); }); afterEach(function () { @@ -239,10 +241,17 @@ describe('Newsletters API', function () { location: anyLocationFor('newsletters') }); - mockManager.assert.sentEmail({ - subject: 'Verify email address', - to: 'test@example.com' - }); + emailMockReceiver + .assertSentEmailCount(1) + .matchMetadataSnapshot() + .matchHTMLSnapshot([{ + pattern: queryStringToken('verifyEmail'), + replacement: 'verifyEmail=REPLACED_TOKEN' + }]) + .matchPlaintextSnapshot([{ + pattern: queryStringToken('verifyEmail'), + replacement: 'verifyEmail=REPLACED_TOKEN' + }]); }); it('Can add a newsletter - and subscribe existing members', async function () { @@ -336,10 +345,17 @@ describe('Newsletters API', function () { etag: anyEtag }); - mockManager.assert.sentEmail({ - subject: 'Verify email address', - to: 'updated@example.com' - }); + emailMockReceiver + .assertSentEmailCount(1) + .matchMetadataSnapshot() + .matchHTMLSnapshot([{ + pattern: queryStringToken('verifyEmail'), + replacement: 'verifyEmail=REPLACED_TOKEN' + }]) + .matchPlaintextSnapshot([{ + pattern: queryStringToken('verifyEmail'), + replacement: 'verifyEmail=REPLACED_TOKEN' + }]); }); it('Can verify property updates', async function () { @@ -356,7 +372,20 @@ describe('Newsletters API', function () { }) .expectStatus(200); + // @NOTE: need a way to return snapshot of sent email from email mock receiver const mail = mockManager.assert.sentEmail([]); + emailMockReceiver + .assertSentEmailCount(1) + .matchMetadataSnapshot() + .matchHTMLSnapshot([{ + pattern: queryStringToken('verifyEmail'), + replacement: 'verifyEmail=REPLACED_TOKEN' + }]) + .matchPlaintextSnapshot([{ + pattern: queryStringToken('verifyEmail'), + replacement: 'verifyEmail=REPLACED_TOKEN' + }]); + const $mailHtml = cheerio.load(mail.html); const verifyUrl = new URL($mailHtml('[data-test-verify-link]').attr('href')); @@ -695,10 +724,11 @@ describe('Newsletters API', function () { location: anyLocationFor('newsletters') }); - mockManager.assert.sentEmail({ - subject: 'Verify email address', - to: 'test@example.com' - }); + emailMockReceiver + .assertSentEmailCount(1) + .matchHTMLSnapshot() + .matchPlaintextSnapshot() + .matchMetadataSnapshot(); }); it(`Can't edit multiple newsletters to existing name`, async function () { diff --git a/ghost/core/test/utils/e2e-framework.js b/ghost/core/test/utils/e2e-framework.js index 3cac000ef6..2e6504c6b7 100644 --- a/ghost/core/test/utils/e2e-framework.js +++ b/ghost/core/test/utils/e2e-framework.js @@ -452,7 +452,8 @@ module.exports = { } }, regexes: { - anyMajorMinorVersion: /v\d+\.\d+/gi + anyMajorMinorVersion: /v\d+\.\d+/gi, + queryStringToken: paramName => new RegExp(`${paramName}=(\\w|-)+`, 'g') }, matchers: { anyBoolean: any(Boolean),