Files
habitica/test/api/v3/unit/libs/payments/group-plans/group-payments-cancel.test.js
T
Keith Holliday be60fb0635 Group plans subs to all (#8394)
* Added subscriptions to all members when group subs

* Added unsub when group cancels

* Give user a subscription when they join a subbed group

* Removed subscription when user leaves or is removed from group

* Fixed linting issues:

* Added tests for users with a subscription being upgraded to group plan

* Added tests for checking if existing recurring user sub gets updated during group plan. Added better merging for plans

* Added test for existing gift subscriptions

* Added additional months to user when they have an existing recurring subscription and get upgraded to group sub

* Adds test for user who has cancelled with date termined in the future

* Added test to ensure date termined is reset

* Added tests for extra months carrying over

* Added test for gems bought field

* Add tests to for fields that should remain when upgrading

* Added test for all payment methods

* Added prevention for when a user joins a second group plan

* Fixed subscribing tests

* Separated group plan payment tests

* Added prevention of editing a user with a unlimited sub

* Add tests to ensure group keeps plan if they are in two and leave one

* Ensured users with two group plans do not get cancelled when on group plan is cancelled

* Ensured users without group sub are untouched when group cancels

* Fixed lint issues

* Added new emails

* Added fix for cron tests

* Add restore to stubbed methods

* Ensured cancelled group subscriptions are updated

* Changed group plan exist check to check for date terminated

* Updated you cannont delete active group message

* Removed description requirement

* Added upgrade group plan for Amazon payments

* Fixed lint issues

* Fixed broken tests

* Fixed user delete tests

* Fixed function calls

* Hid cancel button if user has group plan

* Hide difficulty from rewards

* Prevented add user functions to be called when group plan is cancelled

* Fixed merge issue

* Correctly displayed group price

* Added message when you are about to join canclled group plan

* Fixed linting issues

* Updated tests to have no redirect to homes

* Allowed leaving a group with a canceld subscription

* Fixed spelling issues

* Prevented user from changing leader with active sub

* Added payment details title to replace subscription title

* Ensured we do not count leader when displaying upcoming cost

* Prevented party tasks from being displayed twice

* Prevented cancelling and already cancelled sub

* Fixed styles of subscriptions

* Added more specific mystery item tests

* Fixed test to refer to leader

* Extended test range to account for short months

* Fixed merge conflicts

* Updated yarn file

* Added missing locales

* Trigger notification

* Removed yarn

* Fixed locales

* Fixed scope mispelling

* Fixed line endings

* Removed extra advanced options from rewards

* Prevent group leader from leaving an active group plan

* Fixed issue with extra months applied to cancelled group plan

* Ensured member count is calculated when updatedGroupPlan

* Updated amazon payment method constant name

* Added comment to cancel sub user method

* Fixed smantic issues

* Added unite test for user isSubscribed and hasNotCancelled

* Add tests for isSubscribed and hasNotCanceled

* Changed default days remaining to 2 days for group plans

* Fixed logic with adding canceled notice to group invite
2017-03-06 15:09:50 -07:00

327 lines
10 KiB
JavaScript

import moment from 'moment';
import * as sender from '../../../../../../../website/server/libs/email';
import * as api from '../../../../../../../website/server/libs/payments';
import { model as User } from '../../../../../../../website/server/models/user';
import { model as Group } from '../../../../../../../website/server/models/group';
import {
generateGroup,
} from '../../../../../../helpers/api-unit.helper.js';
import i18n from '../../../../../../../website/common/script/i18n';
describe('Canceling a subscription for group', () => {
let plan, group, user, data;
beforeEach(async () => {
user = new User();
user.profile.name = 'sender';
await user.save();
group = generateGroup({
name: 'test group',
type: 'guild',
privacy: 'public',
leader: user._id,
});
await group.save();
data = {
user,
sub: {
key: 'basic_3mo',
},
customerId: 'customer-id',
paymentMethod: 'Payment Method',
headers: {
'x-client': 'habitica-web',
'user-agent': '',
},
};
plan = {
planId: 'basic_3mo',
customerId: 'customer-id',
dateUpdated: new Date(),
gemsBought: 0,
paymentMethod: 'paymentMethod',
extraMonths: 0,
dateTerminated: null,
lastBillingDate: new Date(),
dateCreated: new Date(),
mysteryItems: [],
consecutive: {
trinkets: 0,
offset: 0,
gemCapExtra: 0,
},
};
sandbox.stub(sender, 'sendTxn');
});
afterEach(() => {
sender.sendTxn.restore();
});
it('adds a month termination date by default', async () => {
data.groupId = group._id;
await api.cancelSubscription(data);
let now = new Date();
let updatedGroup = await Group.findById(group._id).exec();
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
expect(daysTillTermination).to.be.within(29, 30); // 1 month +/- 1 days
});
it('adds extraMonths to dateTerminated value', async () => {
group.purchased.plan.extraMonths = 2;
await group.save();
data.groupId = group._id;
await api.cancelSubscription(data);
let now = new Date();
let updatedGroup = await Group.findById(group._id).exec();
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
expect(daysTillTermination).to.be.within(89, 90); // 3 months +/- 1 days
});
it('handles extra month fractions', async () => {
group.purchased.plan.extraMonths = 0.3;
await group.save();
data.groupId = group._id;
await api.cancelSubscription(data);
let now = new Date();
let updatedGroup = await Group.findById(group._id).exec();
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
expect(daysTillTermination).to.be.within(38, 39); // should be about 1 month + 1/3 month
});
it('terminates at next billing date if it exists', async () => {
data.nextBill = moment().add({ days: 15 });
data.groupId = group._id;
await api.cancelSubscription(data);
let now = new Date();
let updatedGroup = await Group.findById(group._id).exec();
let daysTillTermination = moment(updatedGroup.purchased.plan.dateTerminated).diff(now, 'days');
expect(daysTillTermination).to.be.within(13, 15);
});
it('resets plan.extraMonths', async () => {
group.purchased.plan.extraMonths = 5;
await group.save();
data.groupId = group._id;
await api.cancelSubscription(data);
let updatedGroup = await Group.findById(group._id).exec();
expect(updatedGroup.purchased.plan.extraMonths).to.eql(0);
});
it('sends an email', async () => {
data.groupId = group._id;
await api.cancelSubscription(data);
expect(sender.sendTxn).to.be.calledOnce;
expect(sender.sendTxn.firstCall.args[0]._id).to.equal(user._id);
expect(sender.sendTxn.firstCall.args[1]).to.equal('group-cancel-subscription');
expect(sender.sendTxn.firstCall.args[2]).to.eql([
{name: 'GROUP_NAME', content: group.name},
]);
});
it('prevents non group leader from manging subscription', async () => {
let groupMember = new User();
data.user = groupMember;
data.groupId = group._id;
await expect(api.cancelSubscription(data))
.eventually.be.rejected.and.to.eql({
httpCode: 401,
message: i18n.t('onlyGroupLeaderCanManageSubscription'),
name: 'NotAuthorized',
});
});
it('allows old group leader to cancel if they created the subscription', async () => {
data.groupId = group._id;
data.sub = {
key: 'group_monthly',
};
data.paymentMethod = 'Payment Method';
await api.createSubscription(data);
let updatedGroup = await Group.findById(group._id).exec();
let newLeader = new User();
updatedGroup.leader = newLeader._id;
await updatedGroup.save();
await api.cancelSubscription(data);
updatedGroup = await Group.findById(group._id).exec();
expect(updatedGroup.purchased.plan.dateTerminated).to.exist;
});
it('cancels member subscriptions', async () => {
data = {
user,
sub: {
key: 'basic_3mo',
},
customerId: 'customer-id',
paymentMethod: 'Payment Method',
headers: {
'x-client': 'habitica-web',
'user-agent': '',
},
};
user.guilds.push(group._id);
await user.save();
expect(group.purchased.plan.planId).to.not.exist;
data.groupId = group._id;
await api.createSubscription(data);
await api.cancelSubscription(data);
let now = new Date();
now.setHours(0, 0, 0, 0);
let updatedLeader = await User.findById(user._id).exec();
let daysTillTermination = moment(updatedLeader.purchased.plan.dateTerminated).diff(now, 'days');
expect(daysTillTermination).to.be.within(2, 3); // only a few days
});
it('sends an email to members of group', async () => {
let recipient = new User();
recipient.profile.name = 'recipient';
recipient.guilds.push(group._id);
await recipient.save();
data.groupId = group._id;
await api.createSubscription(data);
await api.cancelSubscription(data);
expect(sender.sendTxn).to.be.have.callCount(4);
expect(sender.sendTxn.thirdCall.args[0]._id).to.equal(recipient._id);
expect(sender.sendTxn.thirdCall.args[1]).to.equal('group-member-cancel');
expect(sender.sendTxn.thirdCall.args[2]).to.eql([
{name: 'LEADER', content: user.profile.name},
{name: 'GROUP_NAME', content: group.name},
]);
});
it('does not cancel member subscriptions when member does not have a group plan sub (i.e. UNLIMITED_CUSTOMER_ID)', async () => {
plan.key = 'basic_earned';
plan.customerId = api.constants.UNLIMITED_CUSTOMER_ID;
let recipient = new User();
recipient.profile.name = 'recipient';
recipient.purchased.plan = plan;
recipient.guilds.push(group._id);
await recipient.save();
data.groupId = group._id;
await api.cancelSubscription(data);
let updatedLeader = await User.findById(user._id).exec();
expect(updatedLeader.purchased.plan.dateTerminated).to.not.exist;
});
it('does not cancel a user subscription if they are still in another active group plan', async () => {
let recipient = new User();
recipient.profile.name = 'recipient';
plan.key = 'basic_earned';
recipient.purchased.plan = plan;
recipient.guilds.push(group._id);
await recipient.save();
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
let updatedUser = await User.findById(recipient._id).exec();
let firstDateCreated = updatedUser.purchased.plan.dateCreated;
let extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
let group2 = generateGroup({
name: 'test group2',
type: 'guild',
privacy: 'public',
leader: user._id,
});
data.groupId = group2._id;
await group2.save();
recipient.guilds.push(group2._id);
await recipient.save();
await api.createSubscription(data);
await api.cancelSubscription(data);
updatedUser = await User.findById(recipient._id).exec();
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
expect(updatedUser.purchased.plan.dateUpdated).to.exist;
expect(updatedUser.purchased.plan.gemsBought).to.eql(0);
expect(updatedUser.purchased.plan.paymentMethod).to.eql('Group Plan');
expect(updatedUser.purchased.plan.extraMonths).to.eql(extraMonthsBeforeSecond);
expect(updatedUser.purchased.plan.dateTerminated).to.eql(null);
expect(updatedUser.purchased.plan.lastBillingDate).to.not.exist;
expect(updatedUser.purchased.plan.dateCreated).to.eql(firstDateCreated);
});
it('does cancel a leader subscription with two cancelled group plans', async () => {
user.guilds.push(group._id);
await user.save();
data.groupId = group._id;
await api.createSubscription(data);
let updatedUser = await User.findById(user._id).exec();
let firstDateCreated = updatedUser.purchased.plan.dateCreated;
let extraMonthsBeforeSecond = updatedUser.purchased.plan.extraMonths;
let group2 = generateGroup({
name: 'test group2',
type: 'guild',
privacy: 'public',
leader: user._id,
});
user.guilds.push(group2._id);
await user.save();
data.groupId = group2._id;
await group2.save();
await api.createSubscription(data);
await api.cancelSubscription(data);
data.groupId = group._id;
await api.cancelSubscription(data);
updatedUser = await User.findById(user._id).exec();
expect(updatedUser.purchased.plan.planId).to.eql('group_plan_auto');
expect(updatedUser.purchased.plan.customerId).to.eql('group-plan');
expect(updatedUser.purchased.plan.dateUpdated).to.exist;
expect(updatedUser.purchased.plan.gemsBought).to.eql(0);
expect(updatedUser.purchased.plan.paymentMethod).to.eql('Group Plan');
expect(updatedUser.purchased.plan.extraMonths).to.eql(extraMonthsBeforeSecond);
expect(updatedUser.purchased.plan.dateTerminated).to.exist;
expect(updatedUser.purchased.plan.lastBillingDate).to.not.exist;
expect(updatedUser.purchased.plan.dateCreated).to.eql(firstDateCreated);
});
});