From 9d21a14b4be97359e1376925ba0d53e4a0be53a3 Mon Sep 17 00:00:00 2001 From: Simon Backx Date: Mon, 30 May 2022 15:41:02 +0200 Subject: [PATCH] Added integration test for MEGA.sendEmailJob (#14944) closes https://github.com/TryGhost/Team/issues/1632 --- core/server/services/mega/mega.js | 3 +- .../__snapshots__/newsletters.test.js.snap | 53 +++++++++++ test/integration/services/mega.test.js | 94 +++++++++++++++++++ 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 test/integration/services/mega.test.js diff --git a/core/server/services/mega/mega.js b/core/server/services/mega/mega.js index 8ffebbf45f..6cf862e645 100644 --- a/core/server/services/mega/mega.js +++ b/core/server/services/mega/mega.js @@ -541,7 +541,8 @@ module.exports = { _partitionMembersBySegment: partitionMembersBySegment, _getEmailMemberRows: getEmailMemberRows, _getFromAddress: getFromAddress, - _getReplyToAddress: getReplyToAddress + _getReplyToAddress: getReplyToAddress, + _sendEmailJob: sendEmailJob }; /** diff --git a/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap b/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap index 2f5fc83002..c0c5df00cc 100644 --- a/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap +++ b/test/e2e-api/admin/__snapshots__/newsletters.test.js.snap @@ -102,6 +102,59 @@ Object { } `; +exports[`Newsletters API Can add a newsletter - with custom sender_email and subscribe existing members 1: [body] 1`] = ` +Object { + "meta": Object { + "opted_in_member_count": 6, + "sent_email_verification": Array [ + "sender_email", + ], + }, + "newsletters": Array [ + Object { + "body_font_category": "serif", + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "description": null, + "footer_content": null, + "header_image": null, + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": "My test newsletter with custom sender_email and subscribe existing", + "sender_email": null, + "sender_name": "Test", + "sender_reply_to": "newsletter", + "show_badge": true, + "show_feature_image": true, + "show_header_icon": true, + "show_header_name": true, + "show_header_title": true, + "slug": "my-test-newsletter-with-custom-sender_email-and-subscribe-existing", + "sort_order": 10, + "status": "active", + "subscribe_on_signup": true, + "title_alignment": "center", + "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 add a newsletter - with custom sender_email and subscribe existing members 2: [headers] 1`] = ` +Object { + "access-control-allow-origin": "http://127.0.0.1:2369", + "cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0", + "content-length": "827", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "location": StringMatching /https\\?:\\\\/\\\\/\\.\\*\\?\\\\/newsletters\\\\/\\[a-f0-9\\]\\{24\\}\\\\//, + "vary": "Origin, Accept-Encoding", + "x-cache-invalidate": "/*", + "x-powered-by": "Express", +} +`; + exports[`Newsletters API Can add a newsletter 1: [body] 1`] = ` Object { "newsletters": Array [ diff --git a/test/integration/services/mega.test.js b/test/integration/services/mega.test.js new file mode 100644 index 0000000000..e0a92dfad4 --- /dev/null +++ b/test/integration/services/mega.test.js @@ -0,0 +1,94 @@ +require('should'); +const {agentProvider, fixtureManager, mockManager} = require('../../utils/e2e-framework'); +const moment = require('moment'); +const ObjectId = require('bson-objectid'); +const {_sendEmailJob} = require('../../../core/server/services/mega/mega'); +const models = require('../../../core/server/models'); +const sinon = require('sinon'); +const mailgunProvider = require('../../../core/server/services/bulk-email/mailgun'); + +let agent; + +async function createPublishedPostEmail() { + const post = { + title: 'A random test post', + status: 'draft', + feature_image_alt: 'Testing sending', + feature_image_caption: 'Testing feature image caption', + created_at: moment().subtract(2, 'days').toISOString(), + updated_at: moment().subtract(2, 'days').toISOString(), + created_by: ObjectId().toHexString(), + updated_by: ObjectId().toHexString() + }; + + const res = await agent.post('posts/') + .body({posts: [post]}) + .expectStatus(201); + + const id = res.body.posts[0].id; + + const updatedPost = { + status: 'published', + updated_at: res.body.posts[0].updated_at + }; + + const newsletterSlug = fixtureManager.get('newsletters', 0).slug; + await agent.put(`posts/${id}/?newsletter=${newsletterSlug}`) + .body({posts: [updatedPost]}) + .expectStatus(200); + + const emailModel = await models.Email.findOne({ + post_id: id + }); + should.exist(emailModel); + + return emailModel; +} + +describe('MEGA', function () { + describe('sendEmailJob', function () { + before(async function () { + agent = await agentProvider.getAdminAPIAgent(); + await fixtureManager.init('newsletters', 'members:newsletters'); + await agent.loginAsOwner(); + }); + + afterEach(function () { + mockManager.restore(); + }); + + it('Can send a scheduled post email', async function () { + sinon.stub(mailgunProvider, 'getInstance').returns({}); + sinon.stub(mailgunProvider, 'send').callsFake(async () => { + return { + id: 'stubbed-email-id' + }; + }); + + // Prepare a post and email model + const emailModel = await createPublishedPostEmail(); + + // Launch email job + await _sendEmailJob({emailModel, options: {}}); + + await emailModel.refresh(); + emailModel.get('status').should.eql('submitted'); + }); + + it('Can handle a failed post email', async function () { + sinon.stub(mailgunProvider, 'getInstance').returns({}); + sinon.stub(mailgunProvider, 'send').callsFake(async () => { + throw new Error('Failed to send'); + }); + + // Prepare a post and email model + const emailModel = await createPublishedPostEmail(); + + // Launch email job + await _sendEmailJob({emailModel, options: {}}); + + await emailModel.refresh(); + emailModel.get('status').should.eql('failed'); + }); + }); +});