diff --git a/ghost/members-api/lib/controllers/RouterController.js b/ghost/members-api/lib/controllers/RouterController.js index 2e8b4961af..a900bb3314 100644 --- a/ghost/members-api/lib/controllers/RouterController.js +++ b/ghost/members-api/lib/controllers/RouterController.js @@ -204,7 +204,6 @@ module.exports = class RouterController { * @returns */ async _getSubscriptionCheckoutData(body) { - const ghostPriceId = body.priceId; const tierId = body.tierId; const offerId = body.offerId; @@ -213,33 +212,35 @@ module.exports = class RouterController { let offer; // Validate basic input - if (!ghostPriceId && !offerId && !tierId && !cadence) { + if (!offerId && !tierId) { + logging.error('[RouterController._getSubscriptionCheckoutData] Expected offerId or tierId, received none'); throw new BadRequestError({ - message: tpl(messages.badRequest) + message: tpl(messages.badRequest), + context: 'Expected offerId or tierId, received none' }); } - if (offerId && (ghostPriceId || (tierId && cadence))) { + if (offerId && tierId) { + logging.error('[RouterController._getSubscriptionCheckoutData] Expected offerId or tierId, received both'); throw new BadRequestError({ - message: tpl(messages.badRequest) - }); - } - - if (ghostPriceId && tierId && cadence) { - throw new BadRequestError({ - message: tpl(messages.badRequest) + message: tpl(messages.badRequest), + context: 'Expected offerId or tierId, received both' }); } if (tierId && !cadence) { + logging.error('[RouterController._getSubscriptionCheckoutData] Expected cadence to be "month" or "year", received ', cadence); throw new BadRequestError({ - message: tpl(messages.badRequest) + message: tpl(messages.badRequest), + context: 'Expected cadence to be "month" or "year", received ' + cadence }); } - if (cadence && cadence !== 'month' && cadence !== 'year') { + if (tierId && cadence && cadence !== 'month' && cadence !== 'year') { + logging.error('[RouterController._getSubscriptionCheckoutData] Expected cadence to be "month" or "year", received ', cadence); throw new BadRequestError({ - message: tpl(messages.badRequest) + message: tpl(messages.badRequest), + context: 'Expected cadence to be "month" or "year", received "' + cadence + '"' }); } diff --git a/ghost/members-api/test/unit/lib/controllers/router.test.js b/ghost/members-api/test/unit/lib/controllers/router.test.js index 3e77a4cd8d..4b54322721 100644 --- a/ghost/members-api/test/unit/lib/controllers/router.test.js +++ b/ghost/members-api/test/unit/lib/controllers/router.test.js @@ -1,4 +1,7 @@ const sinon = require('sinon'); +const assert = require('assert').strict; +const errors = require('@tryghost/errors'); + const RouterController = require('../../../../lib/controllers/RouterController'); describe('RouterController', function () { @@ -86,6 +89,80 @@ describe('RouterController', function () { })).should.be.true(); }); + describe('_getSubscriptionCheckoutData', function () { + it('returns a BadRequestError if both offerId and tierId are missing', async function () { + const routerController = new RouterController({ + tiersService, + paymentsService, + offersAPI, + stripeAPIService, + labsService + }); + + try { + await routerController._getSubscriptionCheckoutData({body: {}}); + assert.fail('Expected function to throw BadRequestError'); + } catch (error) { + assert(error instanceof errors.BadRequestError, 'Error should be an instance of BadRequestError'); + assert.equal(error.context, 'Expected offerId or tierId, received none'); + } + }); + + it('returns a BadRequestError if both offerId and tierId are provided', async function () { + const routerController = new RouterController({ + tiersService, + paymentsService, + offersAPI, + stripeAPIService, + labsService + }); + + try { + await routerController._getSubscriptionCheckoutData({tierId: 'tier_123', offerId: 'offer_123'}); + assert.fail('Expected function to throw BadRequestError'); + } catch (error) { + assert(error instanceof errors.BadRequestError, 'Error should be an instance of BadRequestError'); + assert.equal(error.context, 'Expected offerId or tierId, received both'); + } + }); + + it('returns a BadRequestError if tierId is provided wihout a cadence', async function () { + const routerController = new RouterController({ + tiersService, + paymentsService, + offersAPI, + stripeAPIService, + labsService + }); + + try { + await routerController._getSubscriptionCheckoutData({tierId: 'tier_123'}); + assert.fail('Expected function to throw BadRequestError'); + } catch (error) { + assert(error instanceof errors.BadRequestError, 'Error should be an instance of BadRequestError'); + assert.equal(error.context, 'Expected cadence to be "month" or "year", received undefined'); + } + }); + + it('returns a BadRequestError if tierId is provided wihout a valid cadence', async function () { + const routerController = new RouterController({ + tiersService, + paymentsService, + offersAPI, + stripeAPIService, + labsService + }); + + try { + await routerController._getSubscriptionCheckoutData({tierId: 'tier_123', cadence: 'day'}); + assert.fail('Expected function to throw BadRequestError'); + } catch (error) { + assert(error instanceof errors.BadRequestError, 'Error should be an instance of BadRequestError'); + assert.equal(error.context, 'Expected cadence to be "month" or "year", received "day"'); + } + }); + }); + afterEach(function () { sinon.restore(); });