Fixed invalid tierId handling during member paid checkout (#20455)

- fixes https://linear.app/tryghost/issue/SLO-90
This commit is contained in:
Sag 2024-06-24 17:33:39 +02:00 committed by GitHub
parent b10b81b7d7
commit 725ebc3e9f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 67 additions and 3 deletions

View File

@ -10,6 +10,7 @@ const messages = {
notFound: 'Not Found.',
offerNotFound: 'This offer does not exist.',
offerArchived: 'This offer is archived.',
tierNotFound: 'This tier does not exist.',
tierArchived: 'This tier is archived.',
existingSubscription: 'A subscription exists for this Member.',
unableToCheckout: 'Unable to initiate checkout session',
@ -258,9 +259,22 @@ module.exports = class RouterController {
tier = await this._tiersService.api.read(offer.tier.id);
cadence = offer.cadence;
} else {
} else if (tierId) {
offer = null;
tier = await this._tiersService.api.read(tierId);
try {
// If the tierId is not a valid ID, the following line will throw
tier = await this._tiersService.api.read(tierId);
if (!tier) {
throw undefined;
}
} catch (err) {
throw new BadRequestError({
message: tpl(messages.tierNotFound),
context: 'Tier with id "' + tierId + '" not found'
});
}
}
if (tier.status === 'archived') {

View File

@ -162,7 +162,7 @@ describe('RouterController', function () {
}
});
it('returns a BadRequestError if offer is not found', async function () {
it('returns a BadRequestError if offer is not found by offerId', async function () {
offersAPI = {
getOffer: sinon.stub().resolves(null)
};
@ -184,6 +184,56 @@ describe('RouterController', function () {
assert.equal(error.context, 'Offer with id "invalid" not found');
}
});
it('returns a BadRequestError if tier is not found by tierId', async function () {
tiersService = {
api: {
read: sinon.stub().resolves(null)
}
};
const routerController = new RouterController({
tiersService,
paymentsService,
offersAPI,
stripeAPIService,
labsService
});
try {
await routerController._getSubscriptionCheckoutData({tierId: 'invalid', cadence: 'year'});
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, 'Tier with id "invalid" not found');
}
});
it('returns a BadRequestError if fetching tier by tierId throws', async function () {
tiersService = {
api: {
read: sinon.stub().rejects(new Error('Fail to fetch tier'))
}
};
const routerController = new RouterController({
tiersService,
paymentsService,
offersAPI,
stripeAPIService,
labsService
});
try {
await routerController._getSubscriptionCheckoutData({tierId: 'invalid', cadence: 'year'});
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, 'Tier with id "invalid" not found');
}
});
});
afterEach(function () {