mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
Cancel users free group plan when they leave a group (#9543)
* Cancel users free group plan when they leave a group * Fixed lint
This commit is contained in:
@@ -10,6 +10,8 @@ import { v4 as generateUUID } from 'uuid';
|
||||
import {
|
||||
each,
|
||||
} from 'lodash';
|
||||
import { model as User } from '../../../../../website/server/models/user';
|
||||
import * as payments from '../../../../../website/server/libs/payments';
|
||||
|
||||
describe('POST /groups/:groupId/leave', () => {
|
||||
let typesOfGroups = {
|
||||
@@ -264,4 +266,45 @@ describe('POST /groups/:groupId/leave', () => {
|
||||
expect(userWithNonExistentParty.party).to.eql({});
|
||||
});
|
||||
});
|
||||
|
||||
context('Leaving a group plan', () => {
|
||||
it('cancels the free subscription', async () => {
|
||||
// Create group
|
||||
let { group, groupLeader, members } = await createAndPopulateGroup({
|
||||
groupDetails: {
|
||||
name: 'Test Private Guild',
|
||||
type: 'guild',
|
||||
},
|
||||
members: 1,
|
||||
});
|
||||
|
||||
let leader = groupLeader;
|
||||
let member = members[0];
|
||||
let userWithFreePlan = await User.findById(leader._id).exec();
|
||||
|
||||
// Create subscription
|
||||
let paymentData = {
|
||||
user: userWithFreePlan,
|
||||
groupId: group._id,
|
||||
sub: {
|
||||
key: 'basic_3mo',
|
||||
},
|
||||
customerId: 'customer-id',
|
||||
paymentMethod: 'Payment Method',
|
||||
headers: {
|
||||
'x-client': 'habitica-web',
|
||||
'user-agent': '',
|
||||
},
|
||||
};
|
||||
await payments.createSubscription(paymentData);
|
||||
await member.sync();
|
||||
expect(member.purchased.plan.planId).to.equal('group_plan_auto');
|
||||
expect(member.purchased.plan.dateTerminated).to.not.exist;
|
||||
|
||||
// Leave
|
||||
await member.post(`/groups/${group._id}/leave`);
|
||||
await member.sync();
|
||||
expect(member.purchased.plan.dateTerminated).to.exist;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -755,13 +755,20 @@ api.leaveGroup = {
|
||||
}
|
||||
|
||||
await group.leave(user, req.query.keep, req.body.keepChallenges);
|
||||
|
||||
if (group.hasNotCancelled()) await group.updateGroupPlan(true);
|
||||
|
||||
if (group.hasNotCancelled()) await group.updateGroupPlan(true);
|
||||
_removeMessagesFromMember(user, group._id);
|
||||
|
||||
await user.save();
|
||||
|
||||
if (group.type !== 'party') {
|
||||
let guildIndex = user.guilds.indexOf(group._id);
|
||||
user.guilds.splice(guildIndex, 1);
|
||||
}
|
||||
|
||||
let isMemberOfGroupPlan = await user.isMemberOfGroupPlan();
|
||||
if (!isMemberOfGroupPlan) {
|
||||
await payments.cancelGroupSubscriptionForUser(user, group);
|
||||
}
|
||||
|
||||
res.respond(200, {});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -275,6 +275,19 @@ schema.methods.daysUserHasMissed = function daysUserHasMissed (now, req = {}) {
|
||||
return {daysMissed, timezoneOffsetFromUserPrefs};
|
||||
};
|
||||
|
||||
async function getUserGroupData (user) {
|
||||
const userGroups = user.getGroups();
|
||||
|
||||
const groups = await Group
|
||||
.find({
|
||||
_id: {$in: userGroups},
|
||||
})
|
||||
.select('leaderOnly leader purchased')
|
||||
.exec();
|
||||
|
||||
return groups;
|
||||
}
|
||||
|
||||
// Determine if the user can get gems: some groups restrict their members ability to obtain them.
|
||||
// User is allowed to buy gems if no group has `leaderOnly.getGems` === true or if
|
||||
// its the group leader
|
||||
@@ -286,16 +299,17 @@ schema.methods.canGetGems = async function canObtainGems () {
|
||||
return true;
|
||||
}
|
||||
|
||||
const userGroups = user.getGroups();
|
||||
|
||||
const groups = await Group
|
||||
.find({
|
||||
_id: {$in: userGroups},
|
||||
})
|
||||
.select('leaderOnly leader purchased')
|
||||
.exec();
|
||||
const groups = await getUserGroupData(user);
|
||||
|
||||
return groups.every(g => {
|
||||
return !g.isSubscribed() || g.leader === user._id || g.leaderOnly.getGems !== true;
|
||||
});
|
||||
};
|
||||
|
||||
schema.methods.isMemberOfGroupPlan = async function isMemberOfGroupPlan () {
|
||||
const groups = await getUserGroupData(this);
|
||||
|
||||
return groups.every(g => {
|
||||
return g.isSubscribed();
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user