diff --git a/test/api/unit/libs/payments/amazon/upgrade-groupplan.test.js b/test/api/unit/libs/payments/amazon/upgrade-groupplan.test.js index e3dfe1c3c0..26cec74835 100644 --- a/test/api/unit/libs/payments/amazon/upgrade-groupplan.test.js +++ b/test/api/unit/libs/payments/amazon/upgrade-groupplan.test.js @@ -31,11 +31,14 @@ describe('#upgradeGroupPlan', () => { group = generateGroup({ name: 'test group', type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); await group.save(); + user.guilds.push(group._id); + await user.save(); + spy = sinon.stub(amzLib, 'authorizeOnBillingAgreement'); spy.resolves([]); diff --git a/test/api/unit/libs/payments/group-plans/group-payments-cancel.test.js b/test/api/unit/libs/payments/group-plans/group-payments-cancel.test.js index ccbe63f328..49cb80d4e3 100644 --- a/test/api/unit/libs/payments/group-plans/group-payments-cancel.test.js +++ b/test/api/unit/libs/payments/group-plans/group-payments-cancel.test.js @@ -21,11 +21,14 @@ describe('Canceling a subscription for group', () => { group = generateGroup({ name: 'test group', type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); await group.save(); + user.guilds.push(group._id); + await user.save(); + data = { user, sub: { @@ -141,6 +144,8 @@ describe('Canceling a subscription for group', () => { it('prevents non group leader from managing subscription', async () => { const groupMember = new User(); + groupMember.guilds.push(group._id); + await groupMember.save(); data.user = groupMember; data.groupId = group._id; @@ -162,7 +167,9 @@ describe('Canceling a subscription for group', () => { let updatedGroup = await Group.findById(group._id).exec(); const newLeader = new User(); + newLeader.profile.name = 'newLeader'; updatedGroup.leader = newLeader._id; + await newLeader.save(); await updatedGroup.save(); await api.cancelSubscription(data); @@ -185,8 +192,6 @@ describe('Canceling a subscription for group', () => { '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); @@ -211,10 +216,15 @@ describe('Canceling a subscription for group', () => { 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([ + expect(sender.sendTxn).to.be.have.callCount(6); + const recipientCall = sender.sendTxn.getCalls().find(call => { + const isRecipient = call.args[0]._id === recipient._id; + const isGroupMemberCancel = call.args[1] === 'group-member-cancel'; + return isRecipient && isGroupMemberCancel; + }); + expect(recipientCall.args[0]._id).to.equal(recipient._id); + expect(recipientCall.args[1]).to.equal('group-member-cancel'); + expect(recipientCall.args[2]).to.eql([ { name: 'LEADER', content: user.profile.name }, { name: 'GROUP_NAME', content: group.name }, ]); @@ -246,8 +256,6 @@ describe('Canceling a subscription for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -259,11 +267,13 @@ describe('Canceling a subscription for group', () => { const group2 = generateGroup({ name: 'test group2', type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); data.groupId = group2._id; await group2.save(); + user.guilds.push(group2._id); + await user.save(); recipient.guilds.push(group2._id); await recipient.save(); @@ -285,8 +295,6 @@ describe('Canceling a subscription for group', () => { }); 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); @@ -298,7 +306,7 @@ describe('Canceling a subscription for group', () => { const group2 = generateGroup({ name: 'test group2', type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); user.guilds.push(group2._id); diff --git a/test/api/unit/libs/payments/group-plans/group-payments-create.test.js b/test/api/unit/libs/payments/group-plans/group-payments-create.test.js index 788f9ea7c2..383d7dfe6f 100644 --- a/test/api/unit/libs/payments/group-plans/group-payments-create.test.js +++ b/test/api/unit/libs/payments/group-plans/group-payments-create.test.js @@ -12,6 +12,7 @@ import { model as Group } from '../../../../../../website/server/models/group'; import { generateGroup, } from '../../../../../helpers/api-unit.helper'; +import i18n from '../../../../../../website/common/script/i18n'; describe('Purchasing a group plan for group', () => { const EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_GOOGLE = 'Google_subscription'; @@ -33,11 +34,14 @@ describe('Purchasing a group plan for group', () => { group = generateGroup({ name: groupName, type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); await group.save(); + user.guilds.push(group._id); + await user.save(); + data = { user, sub: { @@ -112,6 +116,30 @@ describe('Purchasing a group plan for group', () => { expect(updatedGroup.purchased.plan.dateCreated).to.exist; }); + it('does not create a group plan for a public guild', async () => { + const publicGroup = generateGroup({ + name: groupName, + type: 'guild', + privacy: 'public', + leader: user._id, + }); + await publicGroup.save(); + + expect(publicGroup.purchased.plan.planId).to.not.exist; + data.groupId = publicGroup._id; + + await expect(api.createSubscription(data)) + .to.eventually.be.rejected.and.to.eql({ + httpCode: 401, + name: 'NotAuthorized', + message: i18n.t('onlyPrivateGuildsCanUpgrade'), + }); + + const updatedGroup = await Group.findById(publicGroup._id).exec(); + + expect(updatedGroup.purchased.plan.planId).to.not.exist; + }); + it('sends an email', async () => { expect(group.purchased.plan.planId).to.not.exist; data.groupId = group._id; @@ -148,8 +176,6 @@ describe('Purchasing a group plan for group', () => { }); it('grants all members of a group a subscription', async () => { - user.guilds.push(group._id); - await user.save(); expect(group.purchased.plan.planId).to.not.exist; data.groupId = group._id; @@ -179,17 +205,28 @@ describe('Purchasing a group plan for group', () => { await api.createSubscription(data); - expect(sender.sendTxn).to.be.calledTwice; - expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id); - expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join'); - expect(sender.sendTxn.firstCall.args[2]).to.eql([ + expect(sender.sendTxn).to.be.calledThrice; + const recipientCall = sender.sendTxn.getCalls().find(call => { + const isRecipient = call.args[0]._id === recipient._id; + const isJoin = call.args[1] === 'group-member-join'; + return isRecipient && isJoin; + }); + expect(recipientCall.args[0]._id).to.equal(recipient._id); + expect(recipientCall.args[1]).to.equal('group-member-join'); + expect(recipientCall.args[2]).to.eql([ { name: 'LEADER', content: user.profile.name }, { name: 'GROUP_NAME', content: group.name }, { name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NONE }, ]); + // confirm that the other email sent is appropriate: - expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader); - expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins'); + const leaderCall = sender.sendTxn.getCalls().find(call => { + const isLeader = call.args[0]._id === group.leader; + const isSubscriptionBegin = call.args[1] === 'group-subscription-begins'; + return isLeader && isSubscriptionBegin; + }); + expect(leaderCall.args[0]._id).to.equal(group.leader); + expect(leaderCall.args[1]).to.equal('group-subscription-begins'); }); it('sends one email to subscribed member of group, stating subscription is cancelled (Stripe)', async () => { @@ -205,17 +242,28 @@ describe('Purchasing a group plan for group', () => { await api.createSubscription(data); - expect(sender.sendTxn).to.be.calledTwice; - expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id); - expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join'); - expect(sender.sendTxn.firstCall.args[2]).to.eql([ + expect(sender.sendTxn).to.be.calledThrice; + const recipientCall = sender.sendTxn.getCalls().find(call => { + const isRecipient = call.args[0]._id === recipient._id; + const isJoin = call.args[1] === 'group-member-join'; + return isRecipient && isJoin; + }); + expect(recipientCall.args[0]._id).to.equal(recipient._id); + expect(recipientCall.args[1]).to.equal('group-member-join'); + expect(recipientCall.args[2]).to.eql([ { name: 'LEADER', content: user.profile.name }, { name: 'GROUP_NAME', content: group.name }, { name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL }, ]); + // confirm that the other email sent is not a cancel-subscription email: - expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader); - expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins'); + const leaderCall = sender.sendTxn.getCalls().find(call => { + const isLeader = call.args[0]._id === group.leader; + const isSubscriptionBegin = call.args[1] === 'group-subscription-begins'; + return isLeader && isSubscriptionBegin; + }); + expect(leaderCall.args[0]._id).to.equal(group.leader); + expect(leaderCall.args[1]).to.equal('group-subscription-begins'); }); it('sends one email to subscribed member of group, stating subscription is cancelled (Amazon)', async () => { @@ -238,17 +286,28 @@ describe('Purchasing a group plan for group', () => { await api.createSubscription(data); - expect(sender.sendTxn).to.be.calledTwice; - expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id); - expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join'); - expect(sender.sendTxn.firstCall.args[2]).to.eql([ + expect(sender.sendTxn).to.be.calledThrice; + const recipientCall = sender.sendTxn.getCalls().find(call => { + const isRecipient = call.args[0]._id === recipient._id; + const isJoin = call.args[1] === 'group-member-join'; + return isRecipient && isJoin; + }); + expect(recipientCall.args[0]._id).to.equal(recipient._id); + expect(recipientCall.args[1]).to.equal('group-member-join'); + expect(recipientCall.args[2]).to.eql([ { name: 'LEADER', content: user.profile.name }, { name: 'GROUP_NAME', content: group.name }, { name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL }, ]); + // confirm that the other email sent is not a cancel-subscription email: - expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader); - expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins'); + const leaderCall = sender.sendTxn.getCalls().find(call => { + const isLeader = call.args[0]._id === group.leader; + const isSubscriptionBegin = call.args[1] === 'group-subscription-begins'; + return isLeader && isSubscriptionBegin; + }); + expect(leaderCall.args[0]._id).to.equal(group.leader); + expect(leaderCall.args[1]).to.equal('group-subscription-begins'); amzLib.getBillingAgreementDetails.restore(); }); @@ -275,17 +334,28 @@ describe('Purchasing a group plan for group', () => { await api.createSubscription(data); - expect(sender.sendTxn).to.be.calledTwice; - expect(sender.sendTxn.firstCall.args[0]._id).to.equal(recipient._id); - expect(sender.sendTxn.firstCall.args[1]).to.equal('group-member-join'); - expect(sender.sendTxn.firstCall.args[2]).to.eql([ + expect(sender.sendTxn).to.be.calledThrice; + const recipientCall = sender.sendTxn.getCalls().find(call => { + const isRecipient = call.args[0]._id === recipient._id; + const isJoin = call.args[1] === 'group-member-join'; + return isRecipient && isJoin; + }); + expect(recipientCall.args[0]._id).to.equal(recipient._id); + expect(recipientCall.args[1]).to.equal('group-member-join'); + expect(recipientCall.args[2]).to.eql([ { name: 'LEADER', content: user.profile.name }, { name: 'GROUP_NAME', content: group.name }, { name: 'PREVIOUS_SUBSCRIPTION_TYPE', content: EMAIL_TEMPLATE_SUBSCRIPTION_TYPE_NORMAL }, ]); + // confirm that the other email sent is not a cancel-subscription email: - expect(sender.sendTxn.secondCall.args[0]._id).to.equal(group.leader); - expect(sender.sendTxn.secondCall.args[1]).to.equal('group-subscription-begins'); + const leaderCall = sender.sendTxn.getCalls().find(call => { + const isLeader = call.args[0]._id === group.leader; + const isSubscriptionBegin = call.args[1] === 'group-subscription-begins'; + return isLeader && isSubscriptionBegin; + }); + expect(leaderCall.args[0]._id).to.equal(group.leader); + expect(leaderCall.args[1]).to.equal('group-subscription-begins'); paypalPayments.paypalBillingAgreementGet.restore(); paypalPayments.paypalBillingAgreementCancel.restore(); @@ -302,8 +372,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -356,8 +424,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -419,8 +485,6 @@ describe('Purchasing a group plan for group', () => { data.gift = undefined; - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -455,8 +519,6 @@ describe('Purchasing a group plan for group', () => { data.gift = undefined; - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -483,8 +545,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -511,8 +571,6 @@ describe('Purchasing a group plan for group', () => { await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -541,8 +599,6 @@ describe('Purchasing a group plan for group', () => { await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -566,8 +622,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await recipient.cancelSubscription(); @@ -589,8 +643,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await recipient.cancelSubscription(); @@ -611,8 +663,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -632,8 +682,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -653,8 +701,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -688,8 +734,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -713,8 +757,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -726,13 +768,15 @@ describe('Purchasing a group plan for group', () => { const group2 = generateGroup({ name: 'test group2', type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); data.groupId = group2._id; await group2.save(); recipient.guilds.push(group2._id); await recipient.save(); + user.guilds.push(group2._id); + await user.save(); await api.createSubscription(data); @@ -757,8 +801,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -770,17 +812,22 @@ describe('Purchasing a group plan for group', () => { const group2 = generateGroup({ name: 'test group2', type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); data.groupId = group2._id; await group2.save(); recipient.guilds.push(group2._id); await recipient.save(); + user.guilds.push(group2._id); + await user.save(); await api.createSubscription(data); const updatedGroup = await Group.findById(group._id).exec(); + updatedGroup.memberCount = 2; + await updatedGroup.save(); + await updatedGroup.leave(recipient); updatedUser = await User.findById(recipient._id).exec(); @@ -806,8 +853,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -835,8 +880,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -864,8 +907,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); @@ -894,8 +935,6 @@ describe('Purchasing a group plan for group', () => { recipient.guilds.push(group._id); await recipient.save(); - user.guilds.push(group._id); - await user.save(); data.groupId = group._id; await api.createSubscription(data); diff --git a/test/api/unit/libs/payments/stripe/upgrade-group-plan.test.js b/test/api/unit/libs/payments/stripe/upgrade-group-plan.test.js index a1ce194cae..045d119a0e 100644 --- a/test/api/unit/libs/payments/stripe/upgrade-group-plan.test.js +++ b/test/api/unit/libs/payments/stripe/upgrade-group-plan.test.js @@ -33,11 +33,14 @@ describe('Stripe - Upgrade Group Plan', () => { group = generateGroup({ name: 'test group', type: 'guild', - privacy: 'public', + privacy: 'private', leader: user._id, }); await group.save(); + user.guilds.push(group._id); + await user.save(); + spy = sinon.stub(stripe.subscriptions, 'update'); spy.resolves([]); data.groupId = group._id; diff --git a/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js b/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js index e848908db4..56de50b822 100644 --- a/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js +++ b/test/api/v3/integration/groups/POST-groups_groupId_leave.test.js @@ -274,6 +274,7 @@ describe('POST /groups/:groupId/leave', () => { each(typesOfGroups, (groupDetails, groupType) => { context(`Leaving a group plan when the group is a ${groupType}`, () => { + if (groupDetails.privacy === 'public') return; // public guilds cannot be group plans let groupWithPlan; let leader; let member; @@ -341,6 +342,7 @@ describe('POST /groups/:groupId/leave', () => { each(typesOfGroups, (groupDetails, groupType) => { context(`Leaving a group with extraMonths left plan when the group is a ${groupType}`, () => { + if (groupDetails.privacy === 'public') return; // public guilds cannot be group plans const extraMonths = 12; let groupWithPlan; let member; diff --git a/test/api/v3/integration/payments/stripe/POST-payments_stripe_checkout.test.js b/test/api/v3/integration/payments/stripe/POST-payments_stripe_checkout.test.js index 82ba66c2e0..b73d6f8533 100644 --- a/test/api/v3/integration/payments/stripe/POST-payments_stripe_checkout.test.js +++ b/test/api/v3/integration/payments/stripe/POST-payments_stripe_checkout.test.js @@ -32,7 +32,7 @@ describe('payments - stripe - #checkout', () => { stripePayments.checkout.restore(); }); - it('cancels a user subscription', async () => { + it('creates a user subscription', async () => { user = await generateUser({ 'profile.name': 'sender', 'purchased.plan.customerId': 'customer-id', @@ -48,7 +48,7 @@ describe('payments - stripe - #checkout', () => { expect(stripeCheckoutSubscriptionStub.args[0][0].groupId).to.eql(undefined); }); - it('cancels a group subscription', async () => { + it('creates a group subscription', async () => { user = await generateUser({ 'profile.name': 'sender', 'purchased.plan.customerId': 'customer-id', diff --git a/website/client/src/components/groups/group.vue b/website/client/src/components/groups/group.vue index 6f58e1f4b1..533c63d3a2 100644 --- a/website/client/src/components/groups/group.vue +++ b/website/client/src/components/groups/group.vue @@ -106,7 +106,7 @@