diff --git a/ghost/core/core/server/services/members/middleware.js b/ghost/core/core/server/services/members/middleware.js index d8dca8927d..b0cbef2d56 100644 --- a/ghost/core/core/server/services/members/middleware.js +++ b/ghost/core/core/server/services/members/middleware.js @@ -101,7 +101,13 @@ const getMemberData = async function (req, res) { const deleteSuppression = async function (req, res) { try { const member = await membersService.ssr.getMemberDataFromSession(req, res); + const options = { + id: member.id, + withRelated: ['newsletters'] + }; await emailSuppressionList.removeEmail(member.email); + await membersService.api.members.update({subscribed: true}, options); + res.writeHead(204); res.end(); } catch (err) { diff --git a/ghost/core/test/e2e-api/members/__snapshots__/middleware.test.js.snap b/ghost/core/test/e2e-api/members/__snapshots__/middleware.test.js.snap index 8e853684a1..f31ab54f9b 100644 --- a/ghost/core/test/e2e-api/members/__snapshots__/middleware.test.js.snap +++ b/ghost/core/test/e2e-api/members/__snapshots__/middleware.test.js.snap @@ -45,6 +45,83 @@ Object { } `; +exports[`Comments API when authenticated can remove member from suppression list and resubscribe to default newsletters 1: [body] 1`] = ` +Object { + "avatar_image": null, + "email": "member@example.com", + "email_suppression": Object { + "info": null, + "suppressed": false, + }, + "enable_comment_notifications": true, + "expertise": "test", + "firstname": "Test", + "name": "Test User", + "newsletters": Array [], + "paid": false, + "subscribed": false, + "subscriptions": Array [], + "uuid": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/, +} +`; + +exports[`Comments API when authenticated can remove member from suppression list and resubscribe to default newsletters 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": "310", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Accept-Encoding", + "x-powered-by": "Express", +} +`; + +exports[`Comments API when authenticated can remove member from suppression list and resubscribe to default newsletters 3: [body] 1`] = ` +Object { + "avatar_image": null, + "email": "member@example.com", + "email_suppression": Object { + "info": null, + "suppressed": false, + }, + "enable_comment_notifications": true, + "expertise": "test", + "firstname": "Test", + "name": "Test User", + "newsletters": Array [ + Object { + "description": null, + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": "Default Newsletter", + "sort_order": 0, + }, + Object { + "description": null, + "id": StringMatching /\\[a-f0-9\\]\\{24\\}/, + "name": "Weekly newsletter", + "sort_order": 2, + }, + ], + "paid": false, + "subscribed": false, + "subscriptions": Array [], + "uuid": StringMatching /\\[a-f0-9\\]\\{8\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{4\\}-\\[a-f0-9\\]\\{12\\}/, +} +`; + +exports[`Comments API when authenticated can remove member from suppression list and resubscribe to default newsletters 4: [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": "500", + "content-type": "application/json; charset=utf-8", + "etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/, + "vary": "Accept-Encoding", + "x-powered-by": "Express", +} +`; + exports[`Comments API when authenticated can update comment notifications 1: [body] 1`] = ` Object { "avatar_image": null, diff --git a/ghost/core/test/e2e-api/members/middleware.test.js b/ghost/core/test/e2e-api/members/middleware.test.js index d4b543173c..bc79602159 100644 --- a/ghost/core/test/e2e-api/members/middleware.test.js +++ b/ghost/core/test/e2e-api/members/middleware.test.js @@ -31,6 +31,10 @@ const memberMatcherUnserialised = (newslettersCount) => { }; }; +async function getDefaultNewsletters() { + return (await models.Newsletter.findAll({filter: 'status:active+subscribe_on_signup:true+visibility:members'})).models; +} + describe('Comments API', function () { before(async function () { membersAgent = await agentProvider.getMembersAPIAgent(); @@ -197,11 +201,43 @@ describe('Comments API', function () { member.get('enable_comment_notifications').should.eql(true); }); - it('can remove member from suppression list', async function () { + it('can remove member from suppression list and resubscribe to default newsletters', async function () { + const newsletters = await getDefaultNewsletters(); + + // unsubscribe member from all newsletters + await membersAgent + .put(`/api/member/`) + .body({ + newsletters: [] + }) + .expectStatus(200) + .matchHeaderSnapshot({ + etag: anyEtag + }) + .matchBodySnapshot(memberMatcher(0)) + .expect(({body}) => { + body.newsletters.should.eql([]); + }); + + // remove email from suppression list await membersAgent .delete(`/api/member/suppression`) .expectStatus(204) .expectEmptyBody(); + + // check that member re-subscribed to default newsletters after removing from suppression list + await membersAgent + .get(`/api/member/`) + .expectStatus(200) + .matchHeaderSnapshot({ + etag: anyEtag + }) + .matchBodySnapshot(memberMatcher(2)) + .expect(({body}) => { + // body should contain default newsletters + body.newsletters[0].id.should.eql(newsletters[0].get('id')); + body.newsletters[1].id.should.eql(newsletters[1].get('id')); + }); }); }); });