mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-07-14 18:22:21 +00:00
Correctly handle google accounts with multiple subscriptions (#13982)
This commit is contained in:
parent
a0884b5d24
commit
65d2eac4c3
2 changed files with 70 additions and 12 deletions
|
|
@ -326,6 +326,36 @@ describe('Google Payments', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should cancel a user subscription with multiple inactive subscriptions', async () => {
|
||||
const laterDate = moment.utc().add(7, 'days');
|
||||
iap.getPurchaseData.restore();
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{ expirationDate, autoRenewing: false },
|
||||
{ expirationDate: laterDate, autoRenewing: false },
|
||||
]);
|
||||
await googlePayments.cancelSubscribe(user, headers);
|
||||
|
||||
expect(iapSetupStub).to.be.calledOnce;
|
||||
expect(iapValidateStub).to.be.calledOnce;
|
||||
expect(iapValidateStub).to.be.calledWith(iap.GOOGLE, {
|
||||
data: receipt,
|
||||
signature,
|
||||
});
|
||||
expect(iapIsValidatedStub).to.be.calledOnce;
|
||||
expect(iapIsValidatedStub).to.be.calledWith({
|
||||
expirationDate,
|
||||
});
|
||||
expect(iapGetPurchaseDataStub).to.be.calledOnce;
|
||||
|
||||
expect(paymentCancelSubscriptionSpy).to.be.calledOnce;
|
||||
expect(paymentCancelSubscriptionSpy).to.be.calledWith({
|
||||
user,
|
||||
paymentMethod: googlePayments.constants.PAYMENT_METHOD_GOOGLE,
|
||||
nextBill: laterDate.toDate(),
|
||||
headers,
|
||||
});
|
||||
});
|
||||
|
||||
it('should not cancel a user subscription with autorenew', async () => {
|
||||
iap.getPurchaseData.restore();
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
|
|
@ -346,5 +376,28 @@ describe('Google Payments', () => {
|
|||
|
||||
expect(paymentCancelSubscriptionSpy).to.not.be.called;
|
||||
});
|
||||
|
||||
it('should not cancel a user subscription with multiple subscriptions with one autorenew', async () => {
|
||||
iap.getPurchaseData.restore();
|
||||
iapGetPurchaseDataStub = sinon.stub(iap, 'getPurchaseData')
|
||||
.returns([{ expirationDate, autoRenewing: false },
|
||||
{ autoRenewing: true },
|
||||
{ expirationDate, autoRenewing: false }]);
|
||||
await googlePayments.cancelSubscribe(user, headers);
|
||||
|
||||
expect(iapSetupStub).to.be.calledOnce;
|
||||
expect(iapValidateStub).to.be.calledOnce;
|
||||
expect(iapValidateStub).to.be.calledWith(iap.GOOGLE, {
|
||||
data: receipt,
|
||||
signature,
|
||||
});
|
||||
expect(iapIsValidatedStub).to.be.calledOnce;
|
||||
expect(iapIsValidatedStub).to.be.calledWith({
|
||||
expirationDate,
|
||||
});
|
||||
expect(iapGetPurchaseDataStub).to.be.calledOnce;
|
||||
|
||||
expect(paymentCancelSubscriptionSpy).to.not.be.called;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -244,11 +244,15 @@ api.cancelSubscribe = async function cancelSubscribe (user, headers) {
|
|||
|
||||
const purchases = iap.getPurchaseData(googleRes);
|
||||
if (purchases.length === 0) throw new NotAuthorized(this.constants.RESPONSE_INVALID_RECEIPT);
|
||||
const subscriptionData = purchases[0];
|
||||
// Check to make sure the sub isn't active anymore.
|
||||
if (subscriptionData.autoRenewing !== false) return;
|
||||
|
||||
dateTerminated = new Date(Number(subscriptionData.expirationDate));
|
||||
for (const i in purchases) {
|
||||
if (Object.prototype.hasOwnProperty.call(purchases, i)) {
|
||||
const purchase = purchases[i];
|
||||
if (purchase.autoRenewing !== false) return;
|
||||
if (!dateTerminated || Number(purchase.expirationDate) > Number(dateTerminated)) {
|
||||
dateTerminated = new Date(Number(purchase.expirationDate));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// Status:410 means that the subsctiption isn't active anymore and we can safely delete it
|
||||
if (err && err.message === 'Status:410') {
|
||||
|
|
@ -257,13 +261,14 @@ api.cancelSubscribe = async function cancelSubscribe (user, headers) {
|
|||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
await payments.cancelSubscription({
|
||||
user,
|
||||
nextBill: dateTerminated,
|
||||
paymentMethod: this.constants.PAYMENT_METHOD_GOOGLE,
|
||||
headers,
|
||||
});
|
||||
if (dateTerminated) {
|
||||
await payments.cancelSubscription({
|
||||
user,
|
||||
nextBill: dateTerminated,
|
||||
paymentMethod: this.constants.PAYMENT_METHOD_GOOGLE,
|
||||
headers,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default api;
|
||||
|
|
|
|||
Loading…
Reference in a new issue