diff --git a/ghost/members-api/lib/repositories/member.js b/ghost/members-api/lib/repositories/member.js index f623431b18..a29b73c4be 100644 --- a/ghost/members-api/lib/repositories/member.js +++ b/ghost/members-api/lib/repositories/member.js @@ -841,13 +841,10 @@ module.exports = class MemberRepository { ghostProduct = await this._productRepository.get({stripe_product_id: subscriptionPriceData.product}, {...options, forUpdate: true}); // Use first Ghost product as default product in case of missing link if (!ghostProduct) { - let {data: pageData} = await this._productRepository.list({ - limit: 1, - filter: 'type:paid', - ...options, - forUpdate: true + ghostProduct = await this._productRepository.getDefaultProduct({ + forUpdate: true, + ...options }); - ghostProduct = (pageData && pageData[0]) || null; } // Link Stripe Product & Price to Ghost Product @@ -1386,17 +1383,17 @@ module.exports = class MemberRepository { return this.isActiveSubscriptionStatus(subscription.get('status')); }); - const productPage = await this._productRepository.list({ - limit: 1, + const ghostProductModel = await this._productRepository.getDefaultProduct({ withRelated: ['stripePrices'], - filter: 'type:paid', ...options }); - const defaultProduct = productPage && productPage.data && productPage.data[0] && productPage.data[0].toJSON(); + const defaultProduct = ghostProductModel?.toJSON(); if (!defaultProduct) { - throw new errors.NotFoundError({message: tpl(messages.productNotFound)}); + throw new errors.NotFoundError({ + message: tpl(messages.productNotFound, {id: '"default"'}) + }); } const zeroValuePrices = defaultProduct.stripePrices.filter((price) => { diff --git a/ghost/members-api/test/unit/lib/repositories/member.test.js b/ghost/members-api/test/unit/lib/repositories/member.test.js index 864b82185c..471e3639dc 100644 --- a/ghost/members-api/test/unit/lib/repositories/member.test.js +++ b/ghost/members-api/test/unit/lib/repositories/member.test.js @@ -53,6 +53,54 @@ describe('MemberRepository', function () { }); }); + describe('setComplimentarySubscription', function () { + let Member; + let productRepository; + + beforeEach(function () { + Member = { + findOne: sinon.stub().resolves({ + id: 'member_id_123', + related: () => { + return { + fetch: () => { + return { + models: [] + }; + } + }; + } + }) + }; + }); + + it('throws an error when there is no default product', async function () { + productRepository = { + getDefaultProduct: sinon.stub().resolves(null) + }; + + const repo = new MemberRepository({ + Member, + stripeAPIService: { + configured: true + }, + productRepository + }); + + try { + await repo.setComplimentarySubscription({ + id: 'member_id_123' + }, { + transacting: true + }); + + assert.fail('setComplimentarySubscription should have thrown'); + } catch (err) { + assert.equal(err.message, 'Could not find Product "default"'); + } + }); + }); + describe('linkSubscription', function (){ let Member; let notifySpy;