mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-24 06:35:49 +03:00
Fixed TXT content of report emails (#15090)
fixes https://github.com/TryGhost/Team/issues/1718 - Text content of report emails still had some placeholder text - Converts HTML comments to TXT to include in the TXT version of the email - Added support for Regexp matchers in the email mocker - Added tests to check if the email content is in the new comment/report emails
This commit is contained in:
parent
308a28d31a
commit
57a743e3aa
@ -1,6 +1,7 @@
|
||||
const {promises: fs} = require('fs');
|
||||
const path = require('path');
|
||||
const moment = require('moment');
|
||||
const htmlToPlaintext = require('../../../shared/html-to-plaintext');
|
||||
|
||||
class CommentsServiceEmails {
|
||||
constructor({config, logging, models, mailer, settingsCache, urlService, urlUtils}) {
|
||||
@ -128,7 +129,7 @@ class CommentsServiceEmails {
|
||||
postTitle: post.get('title'),
|
||||
postUrl: this.urlService.getUrlByResourceId(post.get('id'), {absolute: true}),
|
||||
commentHtml: comment.get('html'),
|
||||
commentText: 'todo: we need to convert html to text first!',
|
||||
commentText: htmlToPlaintext.email(comment.get('html')),
|
||||
commentDate: moment(comment.get('created_at')).tz(this.settingsCache.get('timezone')).format('D MMM YYYY'),
|
||||
|
||||
reporterName: reporter.name,
|
||||
|
@ -95,6 +95,7 @@ module.exports = class GhostMailer {
|
||||
* @param {string} message.html - email content
|
||||
* @param {string} message.to - email recipient address
|
||||
* @param {string} [message.from] - sender email address
|
||||
* @param {string} [message.text] - text version of this message
|
||||
* @param {boolean} [message.forceTextContent] - maps to generateTextFromHTML nodemailer option
|
||||
* which is: "if set to true uses HTML to generate plain text body part from the HTML if the text is not defined"
|
||||
* (ref: https://github.com/nodemailer/nodemailer/tree/da2f1d278f91b4262e940c0b37638e7027184b1d#e-mail-message-fields)
|
||||
|
@ -40,7 +40,7 @@ Object {
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"edited_at": null,
|
||||
"html": "This is a message",
|
||||
"html": "<p>This is a message</p><p>New line</p>",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"liked": Any<Boolean>,
|
||||
"likes_count": Any<Number>,
|
||||
@ -72,7 +72,7 @@ exports[`Comments API when authenticated Can browse all comments of a post 2: [h
|
||||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "1035",
|
||||
"content-length": "1057",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Encoding",
|
||||
@ -86,7 +86,7 @@ Object {
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"edited_at": null,
|
||||
"html": "This is a message",
|
||||
"html": "<p>This is a message</p><p>New line</p>",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"liked": false,
|
||||
"likes_count": 0,
|
||||
@ -101,7 +101,7 @@ exports[`Comments API when authenticated Can comment on a post 2: [headers] 1`]
|
||||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "197",
|
||||
"content-length": "219",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/comments\\\\/\\[a-f0-9\\]\\{24\\}\\\\//,
|
||||
@ -169,7 +169,7 @@ Object {
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"edited_at": null,
|
||||
"html": "This is a message",
|
||||
"html": "<p>This is a message</p><p>New line</p>",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"liked": Any<Boolean>,
|
||||
"likes_count": Any<Number>,
|
||||
@ -239,7 +239,7 @@ exports[`Comments API when authenticated Can like a comment 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "626",
|
||||
"content-length": "648",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Encoding",
|
||||
@ -262,7 +262,7 @@ Object {
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"edited_at": null,
|
||||
"html": "This is a message",
|
||||
"html": "<p>This is a message</p><p>New line</p>",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"liked": Any<Boolean>,
|
||||
"likes_count": Any<Number>,
|
||||
@ -301,7 +301,7 @@ exports[`Comments API when authenticated Can like a comment 5: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "625",
|
||||
"content-length": "647",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Encoding",
|
||||
@ -473,7 +473,7 @@ Object {
|
||||
Object {
|
||||
"created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/,
|
||||
"edited_at": null,
|
||||
"html": "This is a message",
|
||||
"html": "<p>This is a message</p><p>New line</p>",
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"liked": Any<Boolean>,
|
||||
"likes_count": Any<Number>,
|
||||
@ -512,7 +512,7 @@ exports[`Comments API when authenticated Can remove a like 3: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "626",
|
||||
"content-length": "648",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Encoding",
|
||||
|
@ -40,6 +40,10 @@ async function sleep(ms) {
|
||||
});
|
||||
}
|
||||
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||
}
|
||||
|
||||
describe('Comments API', function () {
|
||||
before(async function () {
|
||||
membersAgent = await agentProvider.getMembersAPIAgent();
|
||||
@ -101,7 +105,7 @@ describe('Comments API', function () {
|
||||
.post(`/api/comments/`)
|
||||
.body({comments: [{
|
||||
post_id: postId,
|
||||
html: 'This is a message'
|
||||
html: '<p>This is a <strong>message</strong></p><p>New line</p>'
|
||||
}]})
|
||||
.expectStatus(201)
|
||||
.matchHeaderSnapshot({
|
||||
@ -121,7 +125,9 @@ describe('Comments API', function () {
|
||||
mockManager.assert.sentEmailCount(1);
|
||||
mockManager.assert.sentEmail({
|
||||
subject: '💬 You have a new comment on one of your posts',
|
||||
to: fixtureManager.get('users', 0).email
|
||||
to: fixtureManager.get('users', 0).email,
|
||||
// Note that the <strong> tag is removed by the sanitizer
|
||||
html: new RegExp(escapeRegExp('<p>This is a message</p><p>New line</p>'))
|
||||
});
|
||||
});
|
||||
|
||||
@ -294,7 +300,9 @@ describe('Comments API', function () {
|
||||
|
||||
mockManager.assert.sentEmail({
|
||||
subject: '🚩 A comment has been reported on your post',
|
||||
to: fixtureManager.get('users', 0).email
|
||||
to: fixtureManager.get('users', 0).email,
|
||||
html: new RegExp(escapeRegExp('<p>This is a message</p><p>New line</p>')),
|
||||
text: new RegExp(escapeRegExp('This is a message\n\nNew line'))
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -85,6 +85,12 @@ const sentEmail = (matchers) => {
|
||||
|
||||
// We use assert, rather than sinon.assert.calledWith, as we end up with much better error messaging
|
||||
assert.notEqual(spyCall.args[0][key], undefined, `Expected email to have property ${key}`);
|
||||
|
||||
if (value instanceof RegExp) {
|
||||
assert.match(spyCall.args[0][key], value, `Expected Email ${emailCount} to have ${key} that matches ${value}, got ${spyCall.args[0][key]}`);
|
||||
return;
|
||||
}
|
||||
|
||||
assert.equal(spyCall.args[0][key], value, `Expected Email ${emailCount} to have ${key} of ${value}`);
|
||||
});
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user