From 805c9f22f5d690d86b9b88a3268976e910848469 Mon Sep 17 00:00:00 2001 From: Fabien 'egg' O'Carroll Date: Tue, 1 Feb 2022 18:57:27 +0200 Subject: [PATCH] Added e2e test for comping Members (#14094) no-issue refs https://github.com/TryGhost/Members/commit/6860e3c1 refs https://github.com/TryGhost/Members/commit/03a6d694 This adds an e2e tests for the regression we had with comping members. The stripe service imports the members service, which will instantiate members-ssr once it is loaded, which will use the uninstantiated settings cache resulting in errors due to a missing theme_session_secret. For this reason we require the stripe service inside of the test function, rather than at the top level of the file --- package.json | 2 +- test/e2e-api/admin/members.test.js | 98 +++++++++++++++++++++++++++++- yarn.lock | 8 +-- 3 files changed, 101 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index b234664b31..6917bec517 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "@tryghost/limit-service": "1.0.9", "@tryghost/logging": "2.0.2", "@tryghost/magic-link": "1.0.17", - "@tryghost/members-api": "4.8.9", + "@tryghost/members-api": "4.8.10", "@tryghost/members-importer": "0.5.0", "@tryghost/members-offers": "0.10.6", "@tryghost/members-ssr": "1.0.19", diff --git a/test/e2e-api/admin/members.test.js b/test/e2e-api/admin/members.test.js index e2169a082b..679f025e5f 100644 --- a/test/e2e-api/admin/members.test.js +++ b/test/e2e-api/admin/members.test.js @@ -11,6 +11,10 @@ const Papa = require('papaparse'); describe('Members API', function () { let request; + beforeEach(function () { + sinon.stub(labs, 'isSet').withArgs('multipleProducts').returns(false); + }); + afterEach(function () { sinon.restore(); }); @@ -19,7 +23,6 @@ describe('Members API', function () { await localUtils.startGhost(); request = supertest.agent(config.get('url')); await localUtils.doAuth(request, 'members', 'members:emails'); - sinon.stub(labs, 'isSet').withArgs('members').returns(true); }); it('Can browse', async function () { @@ -184,6 +187,96 @@ describe('Members API', function () { .expect(422); }); + it('Can add complimentary subscription', async function () { + const stripeService = require('../../../core/server/services/stripe'); + stripeService.api._configured = true; + const fakePrice = { + id: 'price_1', + product: '', + active: true, + nickname: 'Complimentary', + unit_amount: 0, + currency: 'USD', + type: 'recurring', + recurring: { + interval: 'year' + } + }; + const fakeSubscription = { + id: 'sub_1', + customer: 'cus_1', + status: 'active', + cancel_at_period_end: false, + metadata: {}, + current_period_end: Date.now() / 1000, + start_date: Date.now() / 1000, + plan: fakePrice, + items: { + data: [{ + price: fakePrice + }] + } + }; + sinon.stub(stripeService.api, 'createCustomer').callsFake(async function (data) { + return { + id: 'cus_1', + email: data.email + }; + }); + sinon.stub(stripeService.api, 'createPrice').resolves(fakePrice); + sinon.stub(stripeService.api, 'createSubscription').resolves(fakeSubscription); + sinon.stub(stripeService.api, 'getSubscription').resolves(fakeSubscription); + const initialMember = { + name: 'Name', + email: 'compedtest@test.com', + subscribed: true + }; + + const compedPayload = { + comped: true + }; + + const res = await request + .post(localUtils.API.getApiQuery(`members/`)) + .send({members: [initialMember]}) + .set('Origin', config.get('url')) + .expect('Content-Type', /json/) + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(201); + + should.not.exist(res.headers['x-cache-invalidate']); + const jsonResponse = res.body; + should.exist(jsonResponse); + should.exist(jsonResponse.members); + jsonResponse.members.should.have.length(1); + + should.exist(res.headers.location); + res.headers.location.should.equal(`http://127.0.0.1:2369${localUtils.API.getApiQuery('members/')}${res.body.members[0].id}/`); + + const newMember = jsonResponse.members[0]; + + const res2 = await request + .put(localUtils.API.getApiQuery(`members/${newMember.id}/`)) + .send({members: [compedPayload]}) + .set('Origin', config.get('url')) + .expect(200); + + should.not.exist(res2.headers['x-cache-invalidate']); + + const jsonResponse2 = res2.body; + + should.exist(jsonResponse2); + should.exist(jsonResponse2.members); + jsonResponse2.members.should.have.length(1); + localUtils.API.checkResponse(jsonResponse2.members[0], 'member', ['subscriptions', 'products']); + + const member = jsonResponse2.members[0]; + + should.equal(member.status, 'comped'); + should.equal(member.subscriptions.length, 1); + stripeService.api._configured = false; + }); + it('Can edit by id', async function () { const memberToChange = { name: 'change me', @@ -392,7 +485,8 @@ describe('Members API', function () { // 2 from above posts, 2 from above import data[data.length - 1].free.should.equal(4); data[data.length - 1].paid.should.equal(0); - data[data.length - 1].comped.should.equal(0); + // 1 from the comped test + data[data.length - 1].comped.should.equal(1); }); it('Can import CSV and bulk destroy via auto-added label', function () { diff --git a/yarn.lock b/yarn.lock index 65a9f7aea0..3077418474 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1551,10 +1551,10 @@ "@tryghost/domain-events" "^0.1.6" "@tryghost/member-events" "^0.3.4" -"@tryghost/members-api@4.8.9": - version "4.8.9" - resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-4.8.9.tgz#f7a44e937501ee909c09d7ee5ddd2e55501f5f98" - integrity sha512-OtIRTEAGAbu6luzA1J5ugXAFQDoZ78jIm0IHjPSPFXt10SqihkmFY2vXc3+bofSBl7O/XXD6dqxz1ZG+GWwdAQ== +"@tryghost/members-api@4.8.10": + version "4.8.10" + resolved "https://registry.yarnpkg.com/@tryghost/members-api/-/members-api-4.8.10.tgz#ad1c6a0b09936879b0d9ccfba46e4f275bb573c1" + integrity sha512-3KgasTzWVYHCnZbMHFQxAbBquREq1nMq73v9fpD0vLKnjoumQlNMA0hf44pjqsF+lucUA8RkBR2miULKUkPhWA== dependencies: "@nexes/nql" "^0.6.0" "@tryghost/debug" "^0.1.2"