From 9f3b6f18184c3aa2dd66aca8ca659feaabe06b8e Mon Sep 17 00:00:00 2001 From: Hannah Wolfe Date: Fri, 25 Mar 2022 11:53:08 +0000 Subject: [PATCH] Added missing e2e emails API browse & retry tests refs: https://github.com/TryGhost/Team/issues/1446 - changed Emails API tests to use the new e2e test framework - Added missing tests for browse and retry endpoints --- .../server/api/canary/{email.js => emails.js} | 0 core/server/api/canary/index.js | 2 +- .../admin/__snapshots__/emails.test.js.snap | 185 ++++++++++++++++++ test/e2e-api/admin/emails.test.js | 93 ++++++--- 4 files changed, 257 insertions(+), 23 deletions(-) rename core/server/api/canary/{email.js => emails.js} (100%) create mode 100644 test/e2e-api/admin/__snapshots__/emails.test.js.snap diff --git a/core/server/api/canary/email.js b/core/server/api/canary/emails.js similarity index 100% rename from core/server/api/canary/email.js rename to core/server/api/canary/emails.js diff --git a/core/server/api/canary/index.js b/core/server/api/canary/index.js index 6f9ce78fb7..30195e82a3 100644 --- a/core/server/api/canary/index.js +++ b/core/server/api/canary/index.js @@ -158,7 +158,7 @@ module.exports = { }, get emails() { - return shared.pipeline(require('./email'), localUtils); + return shared.pipeline(require('./emails'), localUtils); }, get site() { diff --git a/test/e2e-api/admin/__snapshots__/emails.test.js.snap b/test/e2e-api/admin/__snapshots__/emails.test.js.snap new file mode 100644 index 0000000000..67a560034e --- /dev/null +++ b/test/e2e-api/admin/__snapshots__/emails.test.js.snap @@ -0,0 +1,185 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Emails API Can browse emails 1: [body] 1`] = ` +Object { + "emails": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "delivered_count": 0, + "email_count": 2, + "error": null, + "error_data": null, + "failed_count": 0, + "from": null, + "html": "

Look! I'm an email

", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "opened_count": 0, + "plaintext": "Waba-daba-dab-da", + "post_id": "618ba1ffbe2896088840a6df", + "recipient_filter": "all", + "reply_to": null, + "status": "submitted", + "subject": "You got mailed!", + "submitted_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "track_opens": false, + "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\\}/, + }, + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "delivered_count": 0, + "email_count": 3, + "error": "Everything went south", + "error_data": null, + "failed_count": 0, + "from": null, + "html": "

What's that? Another email!

", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "opened_count": 0, + "plaintext": "yes this is an email", + "post_id": "618ba1ffbe2896088840a6e1", + "recipient_filter": "status:-free", + "reply_to": null, + "status": "failed", + "subject": "You got mailed! Again!", + "submitted_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "track_opens": false, + "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\\}/, + }, + ], + "meta": Object { + "pagination": Object { + "limit": 15, + "next": null, + "page": 1, + "pages": 1, + "prev": null, + "total": 2, + }, + }, +} +`; + +exports[`Emails API Can browse emails 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": "1201", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-powered-by": "Express", +} +`; + +exports[`Emails API Can read an email 1: [body] 1`] = ` +Object { + "emails": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "delivered_count": 0, + "email_count": 2, + "error": null, + "error_data": null, + "failed_count": 0, + "from": null, + "html": "

Look! I'm an email

", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "opened_count": 0, + "plaintext": "Waba-daba-dab-da", + "post_id": "618ba1ffbe2896088840a6df", + "recipient_filter": "all", + "reply_to": null, + "status": "submitted", + "subject": "You got mailed!", + "submitted_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "track_opens": false, + "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\\}/, + }, + ], +} +`; + +exports[`Emails API Can read an email 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": "540", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-powered-by": "Express", +} +`; + +exports[`Emails API Can retry a failed email 1: [body] 1`] = ` +Object { + "emails": Array [ + Object { + "created_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "delivered_count": 0, + "email_count": 3, + "error": "Everything went south", + "error_data": null, + "failed_count": 0, + "from": null, + "html": "

What's that? Another email!

", + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "opened_count": 0, + "plaintext": "yes this is an email", + "post_id": "618ba1ffbe2896088840a6e1", + "recipient_filter": "status:-free", + "reply_to": null, + "status": "pending", + "subject": "You got mailed! Again!", + "submitted_at": StringMatching /\\\\d\\{4\\}-\\\\d\\{2\\}-\\\\d\\{2\\}T\\\\d\\{2\\}:\\\\d\\{2\\}:\\\\d\\{2\\}\\\\\\.000Z/, + "track_opens": false, + "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\\}/, + }, + ], +} +`; + +exports[`Emails API Can retry a failed email 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": "586", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-powered-by": "Express", +} +`; + +exports[`Emails API Errors when retrying an email that was successful 1: [body] 1`] = ` +Object { + "errors": Array [ + Object { + "code": null, + "context": null, + "details": null, + "help": null, + "id": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/, + "message": "Only failed emails can be retried", + "property": null, + "type": "IncorrectUsageError", + }, + ], +} +`; + +exports[`Emails API Errors when retrying an email that was successful 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": "203", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Origin, Accept-Encoding", + "x-powered-by": "Express", +} +`; diff --git a/test/e2e-api/admin/emails.test.js b/test/e2e-api/admin/emails.test.js index ce411f2da3..f2fec0d764 100644 --- a/test/e2e-api/admin/emails.test.js +++ b/test/e2e-api/admin/emails.test.js @@ -1,31 +1,80 @@ -const should = require('should'); -const supertest = require('supertest'); -const testUtils = require('../../utils'); -const config = require('../../../core/shared/config'); -const localUtils = require('./utils'); +const {agentProvider, fixtureManager, matchers, mockManager} = require('../../utils/e2e-framework'); +const {anyEtag, anyObjectId, anyUuid, anyISODateTime, anyErrorId} = matchers; -describe('Email API', function () { - let request; +const matchEmail = { + id: anyObjectId, + uuid: anyUuid, + created_at: anyISODateTime, + updated_at: anyISODateTime, + submitted_at: anyISODateTime +}; + +describe('Emails API', function () { + let agent; before(async function () { - await localUtils.startGhost(); - request = supertest.agent(config.get('url')); - await localUtils.doAuth(request, 'posts', 'emails'); + agent = await agentProvider.getAdminAPIAgent(); + await fixtureManager.init('posts', 'emails'); + await agent.loginAsOwner(); + }); + + beforeEach(function () { + mockManager.mockEvents(); + }); + + afterEach(function () { + mockManager.restore(); + }); + + it('Can browse emails', async function () { + await agent + .get('emails') + .expectStatus(200) + .matchBodySnapshot({ + emails: new Array(2).fill(matchEmail) + }) + .matchHeaderSnapshot({ + etag: anyEtag + }); }); it('Can read an email', async function () { - const res = await request - .get(localUtils.API.getApiQuery(`emails/${testUtils.DataGenerator.Content.emails[0].id}/`)) - .set('Origin', config.get('url')) - .expect('Content-Type', /json/) - .expect('Cache-Control', testUtils.cacheRules.private) - .expect(200); + await agent + .get(`emails/${fixtureManager.get('emails', 0).id}/`) + .expectStatus(200) + .matchBodySnapshot({ + emails: [matchEmail] + }) + .matchHeaderSnapshot({ + etag: anyEtag + }); + }); - should.not.exist(res.headers['x-cache-invalidate']); - const jsonResponse = res.body; - should.exist(jsonResponse); - should.exist(jsonResponse.emails); - jsonResponse.emails.should.have.length(1); - localUtils.API.checkResponse(jsonResponse.emails[0], 'email'); + it('Can retry a failed email', async function () { + await agent + .put(`emails/${fixtureManager.get('emails', 1).id}/retry`) + .expectStatus(200) + .matchBodySnapshot({ + emails: [matchEmail] + }) + .matchHeaderSnapshot({ + etag: anyEtag + }); + + mockManager.assert.emittedEvent('email.edited'); + }); + + it('Errors when retrying an email that was successful', async function () { + await agent + .put(`emails/${fixtureManager.get('emails', 0).id}/retry`) + .expectStatus(400) + .matchBodySnapshot({ + errors: [{ + id: anyErrorId + }] + }) + .matchHeaderSnapshot({ + etag: anyEtag + }); }); });