From 163092f377087562af4bdf1e4add7cc79fbaca57 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Wed, 12 Aug 2020 19:46:25 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fixed=20apostrophes=20not=20disp?= =?UTF-8?q?laying=20correctly=20in=20Outlook=20for=20member=20emails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs https://github.com/TryGhost/Ghost/issues/11536 - Outlook supports `'` as a special char for apostrophes but not `&#apos;` which is what cheerio/juiced render - adds a basic string placement to the email serializer to switch to the older style of special char --- .../services/mega/post-email-serializer.js | 3 ++ .../admin/email_preview_spec.js | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/core/server/services/mega/post-email-serializer.js b/core/server/services/mega/post-email-serializer.js index 25377f1f63..25513b4de0 100644 --- a/core/server/services/mega/post-email-serializer.js +++ b/core/server/services/mega/post-email-serializer.js @@ -131,6 +131,9 @@ const serialize = async (postModel, options = {isBrowserPreview: false}) => { _cheerio('a').attr('target','_blank'); juicedHtml = _cheerio.html(); + // Fix any unsupported chars in Outlook + juicedHtml = juicedHtml.replace(/'/g, '''); + const emailTmpl = { subject: post.email_subject || post.title, html: juicedHtml, diff --git a/test/api-acceptance/admin/email_preview_spec.js b/test/api-acceptance/admin/email_preview_spec.js index edd91d4954..510007c4fc 100644 --- a/test/api-acceptance/admin/email_preview_spec.js +++ b/test/api-acceptance/admin/email_preview_spec.js @@ -108,6 +108,38 @@ describe('Email Preview API', function () { }); }); }); + + it('has custom content transformations for email compatibility', function () { + const post = testUtils.DataGenerator.forKnex.createPost({ + id: ObjectId.generate(), + title: 'Post with email-only card', + slug: 'email-only-card', + mobiledoc: '{"version":"0.3.1","atoms":[],"cards":[],"markups":[],"sections":[[1,"p",[[0,[],0,"This is the actual post content... With an apostrophy: \'"]]],[1,"p",[]]]}', + html: '

This is the actual post content...

', + plaintext: 'This is the actual post content...', + status: 'draft', + uuid: 'd52c42ae-2755-455c-80ec-70b2ec55c904' + }); + + return models.Post.add(post, {context: {internal: true}}).then(() => { + return request + .get(localUtils.API.getApiQuery(`email_preview/posts/${post.id}/`)) + .set('Origin', config.get('url')) + .set('Accept', 'application/json') + .expect('Content-Type', /json/) + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(200) + .then((res) => { + 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(/'/); + jsonResponse.email_previews[0].html.should.not.match(/'/); + }); + }); + }); }); describe('As Owner', function () {