mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 22:27:26 +01:00
refactor(payments): unit tests created for calculation of subscription termination date
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
import moment from 'moment';
|
||||
import { calculateSubscriptionTerminationDate } from '../../../../../../website/server/libs/payments/util';
|
||||
import api from '../../../../../../website/server/libs/payments/payments';
|
||||
|
||||
describe('#calculateSubscriptionTerminationDate', () => {
|
||||
let plan;
|
||||
let nextBill;
|
||||
|
||||
beforeEach(() => {
|
||||
plan = {
|
||||
customerId: 'customer-id',
|
||||
extraMonths: 0,
|
||||
};
|
||||
nextBill = moment();
|
||||
});
|
||||
it('should extend date to the exact amount of days left before the next bill will occur', () => {
|
||||
nextBill = moment()
|
||||
.add(5, 'days');
|
||||
const expectedTerminationDate = moment()
|
||||
.add(5, 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
it('if nextBill is null, add 30 days to termination date', () => {
|
||||
nextBill = null;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(30, 'days');
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
it('if nextBill is null and it\'s a group plan, add 2 days instead of 30', () => {
|
||||
nextBill = null;
|
||||
plan.customerId = api.constants.GROUP_PLAN_CUSTOMER_ID;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(2, 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
it('should add 30.5 days for each extraMonth', () => {
|
||||
plan.extraMonths = 4;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(30.5 * 4, 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
it('should round up if total days gained by extraMonth is a decimal number', () => {
|
||||
plan.extraMonths = 5;
|
||||
const expectedTerminationDate = moment()
|
||||
.add(Math.ceil(30.5 * 5), 'days');
|
||||
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
it('behaves like extraMonths is 0 if it\'s set to a negative number', () => {
|
||||
plan.extraMonths = -5;
|
||||
const expectedTerminationDate = moment();
|
||||
const terminationDate = calculateSubscriptionTerminationDate(nextBill, plan, api.constants);
|
||||
expect(expectedTerminationDate.diff(terminationDate, 'days')).to.eql(0);
|
||||
});
|
||||
});
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
} from '../errors';
|
||||
import shared from '../../../common';
|
||||
import { sendNotification as sendPushNotification } from '../pushNotifications';
|
||||
import { calculateSubscriptionTerminationDate } from './util';
|
||||
|
||||
// @TODO: Abstract to shared/constant
|
||||
const JOINED_GROUP_PLAN = 'joined group plan';
|
||||
@@ -309,24 +310,11 @@ async function cancelSubscription (data) {
|
||||
if (data.cancellationReason && data.cancellationReason === JOINED_GROUP_PLAN) sendEmail = false;
|
||||
}
|
||||
|
||||
const now = moment();
|
||||
let defaultRemainingDays = 30;
|
||||
|
||||
if (plan.customerId === this.constants.GROUP_PLAN_CUSTOMER_ID) {
|
||||
defaultRemainingDays = 2;
|
||||
sendEmail = false; // because group-member-cancel email has already been sent
|
||||
}
|
||||
|
||||
const remaining = data.nextBill ? moment(data.nextBill).diff(new Date(), 'days', true) : defaultRemainingDays;
|
||||
if (plan.extraMonths < 0) plan.extraMonths = 0;
|
||||
const extraDays = Math.ceil(30.5 * plan.extraMonths);
|
||||
const nowStr = `${now.format('MM')}/${now.format('DD')}/${now.format('YYYY')}`;
|
||||
const nowStrFormat = 'MM/DD/YYYY';
|
||||
|
||||
plan.dateTerminated = moment(nowStr, nowStrFormat)
|
||||
.add({ days: remaining })
|
||||
.add({ days: extraDays })
|
||||
.toDate();
|
||||
plan.dateTerminated = calculateSubscriptionTerminationDate(data.nextBill, plan, this.constants);
|
||||
|
||||
// clear extra time. If they subscribe again, it'll be recalculated from p.dateTerminated
|
||||
plan.extraMonths = 0;
|
||||
|
||||
32
website/server/libs/payments/util.js
Normal file
32
website/server/libs/payments/util.js
Normal file
@@ -0,0 +1,32 @@
|
||||
import moment from 'moment';
|
||||
|
||||
const DEFAULT_REMAINING_DAYS = 30;
|
||||
const DEFAULT_REMAINING_DAYS_FOR_GROUP_PLAN = 2;
|
||||
|
||||
/**
|
||||
* paymentsApiConstants is provided as parameter because of a dependency cycle
|
||||
* with subscriptions api which will occur if api.constants would be used directly
|
||||
*/
|
||||
export function calculateSubscriptionTerminationDate (
|
||||
nextBill, purchasedPlan, paymentsApiConstants,
|
||||
) {
|
||||
const defaultRemainingDays = (
|
||||
purchasedPlan.customerId === paymentsApiConstants.GROUP_PLAN_CUSTOMER_ID
|
||||
) ? DEFAULT_REMAINING_DAYS_FOR_GROUP_PLAN
|
||||
: DEFAULT_REMAINING_DAYS;
|
||||
const now = moment();
|
||||
|
||||
const remaining = nextBill
|
||||
? moment(nextBill).diff(new Date(), 'days', true)
|
||||
: defaultRemainingDays;
|
||||
|
||||
const extraMonths = Math.max(purchasedPlan.extraMonths, 0);
|
||||
const extraDays = Math.ceil(30.5 * extraMonths);
|
||||
const nowStr = `${now.format('MM')}/${now.format('DD')}/${now.format('YYYY')}`;
|
||||
const nowStrFormat = 'MM/DD/YYYY';
|
||||
|
||||
return moment(nowStr, nowStrFormat)
|
||||
.add({ days: remaining })
|
||||
.add({ days: extraDays })
|
||||
.toDate();
|
||||
}
|
||||
Reference in New Issue
Block a user