Fixed validation when tierId
is missing during Stripe checkout (#20195)
refs https://linear.app/tryghost/issue/SLO-90 refs https://www.notion.so/ghost/Decoupling-Members-from-Stripe-13b644d4dccb43ea83f683473c690b82 - the members API didn't support passing a Stripe Price ID directly during checkout since end of 2022. However, we did not update the param validation accordingly
This commit is contained in:
parent
534c8879f9
commit
cb8213e7d3
@ -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 + '"'
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user