From a6859e22b3b358c0b3552f71860694b91e98b540 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 22 Mar 2016 16:04:33 +0000 Subject: [PATCH 1/2] if user is member of group on downgrade use the group subscription --- .../Subscription/SubscriptionLocator.coffee | 5 ++- .../Subscription/SubscriptionUpdater.coffee | 18 ++++++++-- .../SubscriptionUpdaterTests.coffee | 36 ++++++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionLocator.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionLocator.coffee index 9285f8e575..c728ea65cd 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionLocator.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionLocator.coffee @@ -22,4 +22,7 @@ module.exports = Subscription.findOne _id:subscription_id, callback getSubscriptionByMemberIdAndId: (user_id, subscription_id, callback)-> - Subscription.findOne member_ids: user_id, _id:subscription_id, {_id:1}, callback + Subscription.findOne {member_ids: user_id, _id:subscription_id}, {_id:1}, callback + + getGroupSubscriptionMemberOf: (user_id, callback)-> + Subscription.findOne {member_ids: user_id}, {_id:1}, callback \ No newline at end of file diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionUpdater.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionUpdater.coffee index 18f9058b67..69d31d7277 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionUpdater.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionUpdater.coffee @@ -16,10 +16,24 @@ module.exports = syncSubscription: (recurlySubscription, adminUser_id, callback) -> self = @ logger.log adminUser_id:adminUser_id, recurlySubscription:recurlySubscription, "syncSubscription, creating new if subscription does not exist" - SubscriptionLocator.getUsersSubscription adminUser_id, (err, subscription)-> + jobs = + subscription: (cb)-> + SubscriptionLocator.getUsersSubscription adminUser_id, cb + groupSubscription: (cb)-> + SubscriptionLocator.getGroupSubscriptionMemberOf adminUser_id, cb + async.series jobs, (err, results)-> + {subscription, groupSubscription} = results if subscription? logger.log adminUser_id:adminUser_id, recurlySubscription:recurlySubscription, "subscription does exist" - self._updateSubscription recurlySubscription, subscription, callback + self._updateSubscription recurlySubscription, subscription, (err)-> + if err? + logger.err err:err, adminUser_id:adminUser_id, "error syncing subscription" + return callback(err) + if groupSubscription? and recurlySubscription.state == "expired" + logger.log adminUser_id:adminUser_id, "subscription does exist" + UserFeaturesUpdater.updateFeatures adminUser_id, groupSubscription.planCode, callback + else + callback() else logger.log adminUser_id:adminUser_id, recurlySubscription:recurlySubscription, "subscription does not exist, creating a new one" self._createNewSubscription adminUser_id, (err, subscription)-> diff --git a/services/web/test/UnitTests/coffee/Subscription/SubscriptionUpdaterTests.coffee b/services/web/test/UnitTests/coffee/Subscription/SubscriptionUpdaterTests.coffee index 3fab075c30..924dc42ef2 100644 --- a/services/web/test/UnitTests/coffee/Subscription/SubscriptionUpdaterTests.coffee +++ b/services/web/test/UnitTests/coffee/Subscription/SubscriptionUpdaterTests.coffee @@ -23,6 +23,14 @@ describe "Subscription Updater", -> freeTrial:{} plan_code:"student_or_something" + @groupSubscription = + admin_id: @adminUser._id + members_id: @allUserIds + save: sinon.stub().callsArgWith(0) + freeTrial:{} + plan_code:"group_subscription" + + @updateStub = sinon.stub().callsArgWith(2, null) @findAndModifyStub = sinon.stub().callsArgWith(2, null, @subscription) @SubscriptionModel = class @@ -34,6 +42,7 @@ describe "Subscription Updater", -> @SubscriptionLocator = getUsersSubscription: sinon.stub() + getGroupSubscriptionMemberOf:sinon.stub() @Settings = freeTrialPlanCode: "collaborator" @@ -58,16 +67,41 @@ describe "Subscription Updater", -> describe "syncSubscription", -> - it "should update the subscription if the user already is admin of one", (done)-> + + beforeEach -> + @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, @subscription) + @SubscriptionLocator.getGroupSubscriptionMemberOf.callsArgWith(1, null, @groupSubscription) @SubscriptionUpdater._updateSubscription = sinon.stub().callsArgWith(2) + + it "should update the subscription if the user already is admin of one", (done)-> @SubscriptionUpdater._createNewSubscription = sinon.stub() + @SubscriptionUpdater.syncSubscription @recurlySubscription, @adminUser._id, (err)=> @SubscriptionLocator.getUsersSubscription.calledWith(@adminUser._id).should.equal true @SubscriptionUpdater._updateSubscription.called.should.equal true @SubscriptionUpdater._updateSubscription.calledWith(@recurlySubscription, @subscription).should.equal true done() + it "should sync with the group subscription if the recurly subscription is expired", (done)-> + @recurlySubscription.state = "expired" + + @SubscriptionUpdater.syncSubscription @recurlySubscription, @adminUser._id, (err)=> + @SubscriptionLocator.getUsersSubscription.calledWith(@adminUser._id).should.equal true + @SubscriptionUpdater._updateSubscription.called.should.equal true + @SubscriptionUpdater._updateSubscription.calledWith(@recurlySubscription, @subscription).should.equal true + @UserFeaturesUpdater.updateFeatures.calledWith(@adminUser._id, @groupSubscription.planCode).should.equal true + done() + + it "should not call updateFeatures with group subscription if recurly subscription is not expired", (done)-> + + @SubscriptionUpdater.syncSubscription @recurlySubscription, @adminUser._id, (err)=> + @SubscriptionLocator.getUsersSubscription.calledWith(@adminUser._id).should.equal true + @SubscriptionUpdater._updateSubscription.called.should.equal true + @SubscriptionUpdater._updateSubscription.calledWith(@recurlySubscription, @subscription).should.equal true + @UserFeaturesUpdater.updateFeatures.called.should.equal false + done() + describe "_updateSubscription", -> From c554b0630d8bf610a05982e05656a0072ab5e846 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 22 Mar 2016 16:59:47 +0000 Subject: [PATCH 2/2] if user has subscription before joining group is given option to cancel personal one --- .../SubscriptionGroupController.coffee | 16 +++++++++--- .../app/views/subscriptions/group/invite.jade | 23 ++++++++++++++--- ...roup-subscription-invite-controller.coffee | 25 ++++++++++++++++--- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee b/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee index af8b2414f3..5b20608eea 100644 --- a/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee +++ b/services/web/app/coffee/Features/Subscription/SubscriptionGroupController.coffee @@ -4,6 +4,7 @@ SubscriptionLocator = require("./SubscriptionLocator") ErrorsController = require("../Errors/ErrorController") SubscriptionDomainHandler = require("./SubscriptionDomainHandler") _ = require("underscore") +async = require("async") module.exports = @@ -53,19 +54,26 @@ module.exports = subscription: subscription renderGroupInvitePage: (req, res)-> - subscription_id = req.params.subscription_id + group_subscription_id = req.params.subscription_id user_id = req.session.user._id - licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(subscription_id) + licence = SubscriptionDomainHandler.findDomainLicenceBySubscriptionId(group_subscription_id) if !licence? return ErrorsController.notFound(req, res) - SubscriptionGroupHandler.isUserPartOfGroup user_id, licence.subscription_id, (err, partOfGroup)-> + jobs = + partOfGroup: (cb)-> + SubscriptionGroupHandler.isUserPartOfGroup user_id, licence.group_subscription_id, cb + subscription: (cb)-> + SubscriptionLocator.getUsersSubscription user_id, cb + async.series jobs, (err, results)-> + {partOfGroup, subscription} = results if partOfGroup return res.redirect("/user/subscription/custom_account") else res.render "subscriptions/group/invite", title: "Group Invitation" - subscription_id:subscription_id + group_subscription_id:group_subscription_id licenceName:licence.name + has_personal_subscription: subscription? beginJoinGroup: (req, res)-> subscription_id = req.params.subscription_id diff --git a/services/web/app/views/subscriptions/group/invite.jade b/services/web/app/views/subscriptions/group/invite.jade index 1885ea20b8..3ea26aa0a1 100644 --- a/services/web/app/views/subscriptions/group/invite.jade +++ b/services/web/app/views/subscriptions/group/invite.jade @@ -2,7 +2,8 @@ extends ../../layout block scripts script(type='text/javascript'). - window.subscription_id = '#{subscription_id}' + window.group_subscription_id = '#{group_subscription_id}' + window.has_personal_subscription = '#{has_personal_subscription}' block content .content.content-alt @@ -11,12 +12,26 @@ block content .col-md-8.col-md-offset-2 -if (query.expired) .alert.alert-warning #{translate("email_link_expired")} + + .row + div   .row .col-md-8.col-md-offset-2(ng-cloak) .card(ng-controller="GroupSubscriptionInviteController") .page-header h1.text-centered #{translate("you_are_invited_to_group", {groupName:licenceName})} - div(ng-show="!requestSent").row.text-centered + + div(ng-show="view =='personalSubscription'").row.text-centered + div #{translate("cancel_personal_subscription_first")} + .row + .col-md-12   + .row + .col-md-12 + a.btn.btn.btn-default(ng-click="keepPersonalSubscription()", ng-disabled="inflight") #{translate("not_now")} + span   + a.btn.btn.btn-primary(ng-click="cancelSubscription()", ng-disabled="inflight") #{translate("cancel_your_subscription")} + + div(ng-show="view =='groupSubscriptionInvite'").row.text-centered .row .col-md-12 #{translate("group_provides_you_with_premium_account", {groupName:licenceName})} .row @@ -26,10 +41,10 @@ block content .text-center a.btn.btn-default(href="/project") #{translate("not_now")} span   - a.btn.btn.btn-primary(ng-click="joinGroup()") #{translate("verify_email_address")} + a.btn.btn.btn-primary(ng-click="joinGroup()", ng-disabled="inflight") #{translate("verify_email_address")} - span(ng-show="requestSent").row.text-centered.text-center + span(ng-show="view =='requestSent'").row.text-centered.text-center .row .col-md-12 #{translate("check_email_to_complete_the_upgrade")} .row diff --git a/services/web/public/coffee/main/subscription/group-subscription-invite-controller.coffee b/services/web/public/coffee/main/subscription/group-subscription-invite-controller.coffee index ccfae4a3cf..eadd9e2d83 100644 --- a/services/web/public/coffee/main/subscription/group-subscription-invite-controller.coffee +++ b/services/web/public/coffee/main/subscription/group-subscription-invite-controller.coffee @@ -3,12 +3,31 @@ define [ ], (App) -> App.controller "GroupSubscriptionInviteController", ($scope, $http) -> - $scope.requestSent = false + $scope.inflight = false + + if has_personal_subscription + $scope.view = "personalSubscription" + else + $scope.view = "groupSubscriptionInvite" + + $scope.keepPersonalSubscription = -> + $scope.view = "groupSubscriptionInvite" + + $scope.cancelSubscription = -> + $scope.inflight = true + request = $http.post "/user/subscription/cancel", {_csrf:window.csrfToken} + request.success (data, status)-> + $scope.inflight = false + $scope.view = "groupSubscriptionInvite" + request.error (data, status)-> + console.log "the request failed" $scope.joinGroup = -> - $scope.requestSent = true - request = $http.post "/user/subscription/#{subscription_id}/group/begin-join", {_csrf:window.csrfToken} + $scope.view = "requestSent" + $scope.inflight = true + request = $http.post "/user/subscription/#{group_subscription_id}/group/begin-join", {_csrf:window.csrfToken} request.success (data, status)-> + $scope.inflight = false if status != 200 # assume request worked $scope.requestSent = false request.error (data, status)->