mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 05:37:22 +01:00
Add logic for different types of sub upgrades
This commit is contained in:
committed by
Phillip Thelen
parent
8dfa21a4b8
commit
64a3515c10
@@ -322,6 +322,7 @@ describe('Apple Payments', () => {
|
|||||||
const newOption = subOptions[3];
|
const newOption = subOptions[3];
|
||||||
it(`upgrades a subscription from ${option.sku} to ${newOption.sku}`, async () => {
|
it(`upgrades a subscription from ${option.sku} to ${newOption.sku}`, async () => {
|
||||||
const oldSub = common.content.subscriptionBlocks[option.subKey];
|
const oldSub = common.content.subscriptionBlocks[option.subKey];
|
||||||
|
oldSub.logic = 'refundAndRepay';
|
||||||
user.profile.name = 'sender';
|
user.profile.name = 'sender';
|
||||||
user.purchased.plan.paymentMethod = applePayments.constants.PAYMENT_METHOD_APPLE;
|
user.purchased.plan.paymentMethod = applePayments.constants.PAYMENT_METHOD_APPLE;
|
||||||
user.purchased.plan.customerId = token;
|
user.purchased.plan.customerId = token;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
import * as worldState from '../../../../../website/server/libs/worldState';
|
import * as worldState from '../../../../../website/server/libs/worldState';
|
||||||
import { TransactionModel } from '../../../../../website/server/models/transaction';
|
import { TransactionModel } from '../../../../../website/server/models/transaction';
|
||||||
|
|
||||||
describe.only('payments/index', () => {
|
describe('payments/index', () => {
|
||||||
let user;
|
let user;
|
||||||
let group;
|
let group;
|
||||||
let data;
|
let data;
|
||||||
@@ -213,14 +213,14 @@ describe.only('payments/index', () => {
|
|||||||
|
|
||||||
it('keeps plan.dateCreated when changing subscription type', async () => {
|
it('keeps plan.dateCreated when changing subscription type', async () => {
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
const initialDate = recipient.purchased.plan.dateCreated
|
const initialDate = recipient.purchased.plan.dateCreated;
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
expect(recipient.purchased.plan.dateCreated).to.eql(initialDate);
|
expect(recipient.purchased.plan.dateCreated).to.eql(initialDate);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets plan.dateCurrentTypeCreated when changing subscription type', async () => {
|
it('sets plan.dateCurrentTypeCreated when changing subscription type', async () => {
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
const initialDate = recipient.purchased.plan.dateCurrentTypeCreated
|
const initialDate = recipient.purchased.plan.dateCurrentTypeCreated;
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
expect(recipient.purchased.plan.dateCurrentTypeCreated).to.not.eql(initialDate);
|
expect(recipient.purchased.plan.dateCurrentTypeCreated).to.not.eql(initialDate);
|
||||||
});
|
});
|
||||||
@@ -426,14 +426,14 @@ describe.only('payments/index', () => {
|
|||||||
|
|
||||||
it('keeps plan.dateCreated when changing subscription type', async () => {
|
it('keeps plan.dateCreated when changing subscription type', async () => {
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
const initialDate = user.purchased.plan.dateCreated
|
const initialDate = user.purchased.plan.dateCreated;
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
expect(user.purchased.plan.dateCreated).to.eql(initialDate);
|
expect(user.purchased.plan.dateCreated).to.eql(initialDate);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets plan.dateCurrentTypeCreated when changing subscription type', async () => {
|
it('sets plan.dateCurrentTypeCreated when changing subscription type', async () => {
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
const initialDate = user.purchased.plan.dateCurrentTypeCreated
|
const initialDate = user.purchased.plan.dateCurrentTypeCreated;
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
expect(user.purchased.plan.dateCurrentTypeCreated).to.not.eql(initialDate);
|
expect(user.purchased.plan.dateCurrentTypeCreated).to.not.eql(initialDate);
|
||||||
});
|
});
|
||||||
@@ -667,66 +667,464 @@ describe.only('payments/index', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
context('Upgrades subscription', () => {
|
context('Upgrades subscription', () => {
|
||||||
it('Adds 10 to plan.consecutive.gemCapExtra from basic_earned to basic_6mo', async () => {
|
context('Using payDifference logic', () => {
|
||||||
data.sub.key = 'basic_earned';
|
beforeEach(async () => {
|
||||||
expect(user.purchased.plan.planId).to.not.exist;
|
data.updatedFrom = { logic: 'payDifference' };
|
||||||
|
});
|
||||||
|
it('Adds 10 to plan.consecutive.gemCapExtra from basic_earned to basic_6mo', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(0);
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(0);
|
||||||
|
|
||||||
data.sub.key = 'basic_6mo';
|
data.sub.key = 'basic_6mo';
|
||||||
data.updatedFrom = { key: 'basic_earned' };
|
data.updatedFrom.key = 'basic_earned';
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 15 to plan.consecutive.gemCapExtra when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(5);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(20);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets when upgrading from basic_6mo to basic_12mo', async () => {
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_6mo';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 3 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Adds 15 to plan.consecutive.gemCapExtra when upgrading from basic_3mo to basic_12mo', async () => {
|
context('Using payFull logic', () => {
|
||||||
expect(user.purchased.plan.planId).to.not.exist;
|
beforeEach(async () => {
|
||||||
|
data.updatedFrom = { logic: 'payFull' };
|
||||||
|
});
|
||||||
|
it('Adds 10 to plan.consecutive.gemCapExtra from basic_earned to basic_6mo', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(5);
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(0);
|
||||||
|
|
||||||
data.sub.key = 'basic_12mo';
|
data.sub.key = 'basic_6mo';
|
||||||
data.updatedFrom = { key: 'basic_3mo' };
|
data.updatedFrom.key = 'basic_earned';
|
||||||
await api.createSubscription(data);
|
await api.createSubscription(data);
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(20);
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 20 to plan.consecutive.gemCapExtra when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(5);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(25);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 4 to plan.consecutive.trinkets when upgrading from basic_6mo to basic_12mo', async () => {
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_6mo';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 4 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(5);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo', async () => {
|
context('Using refundAndRepay logic', () => {
|
||||||
data.sub.key = 'basic_earned';
|
let clock;
|
||||||
expect(user.purchased.plan.planId).to.not.exist;
|
beforeEach(async () => {
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-01-01'));
|
||||||
|
data.updatedFrom = { logic: 'refundAndRepay' };
|
||||||
|
});
|
||||||
|
context('Upgrades within first half of subscription', () => {
|
||||||
|
it('Adds 10 to plan.consecutive.gemCapExtra from basic_earned to basic_6mo', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
await api.createSubscription(data);
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(0);
|
||||||
|
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
data.sub.key = 'basic_6mo';
|
||||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-01-10'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
|
||||||
|
});
|
||||||
|
|
||||||
data.sub.key = 'basic_6mo';
|
it('Adds 15 to plan.consecutive.gemCapExtra when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
data.updatedFrom = { key: 'basic_earned' };
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
await api.createSubscription(data);
|
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
|
||||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Adds 3 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo', async () => {
|
await api.createSubscription(data);
|
||||||
expect(user.purchased.plan.planId).to.not.exist;
|
|
||||||
|
|
||||||
await api.createSubscription(data);
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(5);
|
||||||
|
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
data.sub.key = 'basic_12mo';
|
||||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-02-05'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(20);
|
||||||
|
});
|
||||||
|
|
||||||
data.sub.key = 'basic_12mo';
|
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo', async () => {
|
||||||
data.updatedFrom = { key: 'basic_3mo' };
|
data.sub.key = 'basic_earned';
|
||||||
await api.createSubscription(data);
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
|
||||||
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-01-08'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 3 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-01-31'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets when upgrading from basic_6mo to basic_12mo', async () => {
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_6mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-01-28'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo after initial cycle', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2024-01-08'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets when upgrading from basic_6mo to basic_12mo after initial cycle', async () => {
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_6mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-08-28'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 3 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo after initial cycle', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-07-31'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
context('Upgrades within second half of subscription', () => {
|
||||||
|
it('Adds 10 to plan.consecutive.gemCapExtra from basic_earned to basic_6mo', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(0);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-01-20'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(10);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 20 to plan.consecutive.gemCapExtra when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(5);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-02-24'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.gemCapExtra).to.eql(25);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-01-28'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 4 to plan.consecutive.trinkets when upgrading from basic_6mo to basic_12mo', async () => {
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_6mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-05-28'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 4 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-03-03'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(5);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 2 to plan.consecutive.trinkets from basic_earned to basic_6mo after initial cycle', async () => {
|
||||||
|
data.sub.key = 'basic_earned';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_earned');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
data.updatedFrom.key = 'basic_earned';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2022-05-28'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 4 to plan.consecutive.trinkets when upgrading from basic_6mo to basic_12mo after initial cycle', async () => {
|
||||||
|
data.sub.key = 'basic_6mo';
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_6mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(2);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_6mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2023-05-28'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(6);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Adds 4 to plan.consecutive.trinkets when upgrading from basic_3mo to basic_12mo after initial cycle', async () => {
|
||||||
|
expect(user.purchased.plan.planId).to.not.exist;
|
||||||
|
|
||||||
|
await api.createSubscription(data);
|
||||||
|
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_3mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
|
||||||
|
|
||||||
|
data.sub.key = 'basic_12mo';
|
||||||
|
data.updatedFrom.key = 'basic_3mo';
|
||||||
|
clock.restore();
|
||||||
|
clock = sinon.useFakeTimers(new Date('2023-09-03'));
|
||||||
|
await api.createSubscription(data);
|
||||||
|
expect(user.purchased.plan.planId).to.eql('basic_12mo');
|
||||||
|
expect(user.purchased.plan.consecutive.trinkets).to.eql(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
afterEach(async () => {
|
||||||
|
if (clock !== null) clock.restore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ api.subscribe = async function subscribe (user, receipt, headers, nextPaymentPro
|
|||||||
};
|
};
|
||||||
if (existingSub) {
|
if (existingSub) {
|
||||||
data.updatedFrom = existingSub;
|
data.updatedFrom = existingSub;
|
||||||
|
data.updatedFrom.logic = 'refundAndRepay';
|
||||||
}
|
}
|
||||||
await payments.createSubscription(data);
|
await payments.createSubscription(data);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -79,8 +79,32 @@ async function prepareSubscriptionValues (data) {
|
|||||||
: undefined;
|
: undefined;
|
||||||
let months;
|
let months;
|
||||||
if (updatedFrom && Number(updatedFrom.months) !== 1) {
|
if (updatedFrom && Number(updatedFrom.months) !== 1) {
|
||||||
months = Math.max(0, Number(block.months) - Number(updatedFrom.months));
|
if (Number(updatedFrom.months) > Number(block.months)) {
|
||||||
} else {
|
months = 0;
|
||||||
|
} else if (data.updatedFrom.logic === 'payDifference') {
|
||||||
|
months = Math.max(0, Number(block.months) - Number(updatedFrom.months));
|
||||||
|
} else if (data.updatedFrom.logic === 'payFull') {
|
||||||
|
months = Number(block.months);
|
||||||
|
} else if (data.updatedFrom.logic === 'refundAndRepay') {
|
||||||
|
const originalMonths = Number(updatedFrom.months);
|
||||||
|
let currentCycleBegin = moment(recipient.purchased.plan.dateCurrentTypeCreated);
|
||||||
|
const today = moment();
|
||||||
|
while (currentCycleBegin.isBefore()) {
|
||||||
|
currentCycleBegin = currentCycleBegin.add({ months: originalMonths });
|
||||||
|
}
|
||||||
|
// Subtract last iteration again, because we overshot
|
||||||
|
currentCycleBegin = currentCycleBegin.subtract({ months: originalMonths });
|
||||||
|
// For simplicity we round every month to 30 days since moment can not add half months
|
||||||
|
if (currentCycleBegin.add({ days: (originalMonths * 30) / 2.0 }).isBefore(today)) {
|
||||||
|
// user is in second half of their subscription cycle. Give them full benefits.
|
||||||
|
months = Number(block.months);
|
||||||
|
} else {
|
||||||
|
// user is in first half of their subscription cycle. Give them the difference.
|
||||||
|
months = Math.max(0, Number(block.months) - Number(updatedFrom.months));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (months === undefined) {
|
||||||
months = Number(block.months);
|
months = Number(block.months);
|
||||||
}
|
}
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
|
|||||||
Reference in New Issue
Block a user