Add AB test for plans (+15 squashed commits)

Squashed commits:
[45c2237] Add a `subscription-form-switch-to-student` event
[1ad9b8f] change experiment name, and re-enable switch-to-student workflow
[f7cdb78] Remove debug
[4b9778a] Incorporate collaborator alternative plans
[701e80b] Add collaborator plans for heron and ibis
[287aa0f] AB test plans from editor page
[c74052e] Fix change-plan view for default plans
[1a947d6] Use correct plan codes
[1eecda7] Adjust prices
[69c4c7b] Introduce two plans
[8b8d5f8] Rename sixpack experiment
[c332002] Fix up the change-plan page
[c7af52d] Overhaul change-plan page, show only plans from current generation
[33d86bf] update plan
[5bbd946] Add a basic plans AB test
This commit is contained in:
Shane Kilkelly 2016-10-13 13:47:05 +01:00
parent d0f9a07197
commit d5a7514923
11 changed files with 418 additions and 179 deletions

View file

@ -8,6 +8,7 @@ Settings = require 'settings-sharelatex'
logger = require('logger-sharelatex')
GeoIpLookup = require("../../infrastructure/GeoIpLookup")
SubscriptionDomainHandler = require("./SubscriptionDomainHandler")
UserGetter = require "../User/UserGetter"
module.exports = SubscriptionController =
@ -21,14 +22,27 @@ module.exports = SubscriptionController =
if req.query.v?
viewName = "#{viewName}_#{req.query.v}"
logger.log viewName:viewName, "showing plans page"
currentUser = null
GeoIpLookup.getCurrencyCode req.query?.ip || req.ip, (err, recomendedCurrency)->
return next(err) if err?
res.render viewName,
title: "plans_and_pricing"
plans: plans
baseUrl: baseUrl
gaExperiments: Settings.gaExperiments.plansPage
recomendedCurrency:recomendedCurrency
render = () ->
res.render viewName,
title: "plans_and_pricing"
plans: plans
baseUrl: baseUrl
gaExperiments: Settings.gaExperiments.plansPage
recomendedCurrency:recomendedCurrency
shouldABTestPlans: currentUser == null or (currentUser?.signUpDate? and currentUser.signUpDate >= (new Date('2011-10-18')))
user_id = AuthenticationController.getLoggedInUserId(req)
if user_id?
console.log '>> user is logged in'
UserGetter.getUser user_id, {signUpDate: 1}, (err, user) ->
return next(err) if err?
currentUser = user
render()
else
console.log '>> not logged in'
render()
#get to show the recurly.js page
paymentPage: (req, res, next) ->

View file

@ -44,7 +44,7 @@ module.exports =
allPlans = {}
plans.forEach (plan)->
allPlans[plan.planCode] = plan
result =
allPlans: allPlans
@ -54,7 +54,7 @@ module.exports =
result.studentAccounts = _.filter plans, (plan)->
plan.planCode.indexOf("student") != -1
result.groupMonthlyPlans = _.filter plans, (plan)->
plan.groupPlan and !plan.annual
@ -68,4 +68,3 @@ module.exports =
!plan.groupPlan and plan.annual and plan.planCode.indexOf("student") == -1
return result

View file

@ -12,8 +12,8 @@ block scripts
mixin printPlan(plan)
-if (!plan.hideFromUsers)
tr(ng-controller="ChangePlanFormController")
td(ng-init="plan=#{JSON.stringify(plan)}")
tr(ng-controller="ChangePlanFormController", ng-init="plan=#{JSON.stringify(plan)}", ng-show="shouldShowPlan(plan.planCode)")
td
strong #{plan.name}
td {{refreshPrice(plan.planCode)}}
-if (plan.annual)
@ -46,8 +46,8 @@ block content
|  
| #{translate("your_billing_details_were_saved")}
.card(ng-if="view == 'overview'")
.page-header
h1 #{translate("your_subscription")}
.page-header(x-current-plan="#{subscription.planCode}")
h1 #{translate("your_subscription")}
- if (subscription && user._id+'' == subscription.admin_id+'')
case subscription.state
@ -56,7 +56,8 @@ block content
when "active"
p !{translate("currently_subscribed_to_plan", {planName:"<strong>" + subscription.name + "</strong>"})}
a(href, ng-click="changePlan = true") !{translate("change_plan")}.
span(ng-show="!isNextGenPlan")
a(href, ng-click="changePlan = true") !{translate("change_plan")}.
p !{translate("next_payment_of_x_collectected_on_y", {paymentAmmount:"<strong>" + subscription.price + "</strong>", collectionDate:"<strong>" + subscription.nextPaymentDueAt + "</strong>"})}
p.pull-right
p

View file

@ -3,6 +3,7 @@ block scripts
script(type='text/javascript').
window.recomendedCurrency = '#{recomendedCurrency}'
window.abCurrencyFlag = '#{abCurrencyFlag}'
window.shouldABTestPlans = #{shouldABTestPlans || false}
script(type='text/javascript').
(function() {var s=document.createElement('script'); s.type='text/javascript';s.async=true;
@ -56,133 +57,138 @@ block content
ng-click="changeCurreny(currency)"
) {{currency}} ({{value['symbol']}})
.row(ng-cloak)
.col-md-10.col-md-offset-1
.row
.card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'")
.col-md-4
.card.card-first
.card-header
h2 #{translate("personal")}
.circle #{translate("free")}
ul.list-unstyled
li #{translate("one_collaborator")}
li &nbsp;
li &nbsp;
li &nbsp;
li
br
a.btn.btn-info(
href="/register"
style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
) #{translate("sign_up_now")}
.col-md-4
.card.card-highlighted
.card-header
h2 #{translate("collaborator")}
.circle
span(ng-if="ui.view == 'monthly'")
| {{plans[currencyCode]['collaborator']['monthly']}}
span.small /mo
span(ng-if="ui.view == 'annual'")
| {{plans[currencyCode]['collaborator']['annual']}}
span.small /yr
ul.list-unstyled
li
strong #{translate("collabs_per_proj", {collabcount:10})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
div
.row(ng-cloak)
.col-md-10.col-md-offset-1
.row
.card-group.text-centered(ng-if="ui.view == 'monthly' || ui.view == 'annual'")
.col-md-4
.card.card-first
.card-header
h2 #{translate("personal")}
.circle #{translate("free")}
ul.list-unstyled
li #{translate("one_collaborator")}
li &nbsp;
li &nbsp;
li &nbsp;
li
br
a.btn.btn-info(
href="/register"
style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
) #{translate("sign_up_now")}
.col-md-4
.card.card-highlighted
.card-header
h2 #{translate("collaborator")}
.circle
span(ng-if="ui.view == 'monthly'")
| {{plans[currencyCode]['collaborator']['monthly']}}
span.small /mo
span(ng-if="ui.view == 'annual'")
| {{plans[currencyCode]['collaborator']['annual']}}
span.small /yr
ul.list-unstyled
li
strong #{translate("collabs_per_proj", {collabcount:10})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ (ui.view == 'annual' ? '-annual' : '') + (plansVariant == 'default' ? planQueryString : '_'+plansVariant)}}&currency={{currencyCode}}", ng-click="signUpNowClicked('collaborator')"
)
span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
.col-md-4
.card.card-last
.card-header
h2 #{translate("professional")}
.circle
span(ng-if="ui.view == 'monthly'")
| {{plans[currencyCode]['professional']['monthly']}}
span.small /mo
span(ng-if="ui.view == 'annual'")
| {{plans[currencyCode]['professional']['annual']}}
span.small /yr
ul.list-unstyled
li
strong #{translate("unlimited_collabs")}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}&currency={{currencyCode}}", ng-click="signUpNowClicked('professional')"
)
span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
.card-group.text-centered(ng-if="ui.view == 'student'")
.col-md-4
.card.card-first
.card-header
h2 #{translate("personal")}
.circle #{translate("free")}
ul.list-unstyled
li #{translate("one_collaborator")}
li &nbsp;
li &nbsp;
li &nbsp;
li
br
a.btn.btn-info(
href="/register"
style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
) #{translate("sign_up_now")}
.col-md-4
.card.card-highlighted
.card-header
h2 #{translate("student")}
.circle
span
| {{plans[currencyCode]['student']['monthly']}}
span.small /mo
ul.list-unstyled
li
strong #{translate("collabs_per_proj", {collabcount:6})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=student{{ plansVariant == 'default' ? planQueryString : '_'+plansVariant }}&currency={{currencyCode}}",
ng-click="signUpNowClicked('student')"
) #{translate("start_free_trial")}
.col-md-4
.card.card-last
.card-header
h2 #{translate("student")} (#{translate("annual")})
.circle
span
| {{plans[currencyCode]['student']['annual']}}
span.small /yr
ul.list-unstyled
li
strong #{translate("collabs_per_proj", {collabcount:6})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=student-annual{{ plansVariant == 'default' ? '' : '_'+plansVariant }}&currency={{currencyCode}}",
ng-click="signUpNowClicked('student')"
) #{translate("buy_now")}
ng-href="#{baseUrl}/user/subscription/new?planCode=collaborator{{ ui.view == 'annual' && '-annual' || planQueryString}}&currency={{currencyCode}}", ng-click="signUpNowClicked('collaborator')"
)
span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
.col-md-4
.card.card-last
.card-header
h2 #{translate("professional")}
.circle
span(ng-if="ui.view == 'monthly'")
| {{plans[currencyCode]['professional']['monthly']}}
span.small /mo
span(ng-if="ui.view == 'annual'")
| {{plans[currencyCode]['professional']['annual']}}
span.small /yr
ul.list-unstyled
li
strong #{translate("unlimited_collabs")}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=professional{{ ui.view == 'annual' && '-annual' || planQueryString}}&currency={{currencyCode}}", ng-click="signUpNowClicked('professional')"
)
span(ng-show="ui.view != 'annual'") #{translate("start_free_trial")}
span(ng-show="ui.view == 'annual'") #{translate("buy_now")}
.card-group.text-centered(ng-if="ui.view == 'student'")
.col-md-4
.card.card-first
.card-header
h2 #{translate("personal")}
.circle #{translate("free")}
ul.list-unstyled
li #{translate("one_collaborator")}
li &nbsp;
li &nbsp;
li &nbsp;
li
br
a.btn.btn-info(
href="/register"
style=(getLoggedInUserId() === undefined ? "" : "visibility: hidden")
) #{translate("sign_up_now")}
.col-md-4
.card.card-highlighted
.card-header
h2 #{translate("student")}
.circle
span
| {{plans[currencyCode]['student']['monthly']}}
span.small /mo
ul.list-unstyled
li
strong #{translate("collabs_per_proj", {collabcount:6})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=student{{planQueryString}}&currency={{currencyCode}}", ng-click="signUpNowClicked('student')"
) #{translate("start_free_trial")}
.col-md-4
.card.card-last
.card-header
h2 #{translate("student")} (#{translate("annual")})
.circle
span
| {{plans[currencyCode]['student']['annual']}}
span.small /yr
ul.list-unstyled
li
strong #{translate("collabs_per_proj", {collabcount:6})}
li #{translate("full_doc_history")}
li #{translate("sync_to_dropbox")}
li #{translate("sync_to_github")}
li
br
a.btn.btn-info(
ng-href="#{baseUrl}/user/subscription/new?planCode=student-annual&currency={{currencyCode}}", ng-click="signUpNowClicked('student')"
) #{translate("buy_now")}
.row.row-spaced(ng-cloak)
p.text-centered #{translate("choose_plan_works_for_you", {len:'{{trial_len}}'})}

View file

@ -66,6 +66,18 @@ define [
pdfLayout: 'sideBySide'
}
$scope.user = window.user
$scope.startTrialPlanCode = 'collaborator_free_trial_7_days'
$scope.shouldABTestPlans = false
$scope._plansVariant = 'default'
if $scope.user.signUpDate >= '2011-10-18'
$scope.shouldABTestPlans = true
sixpack.participate 'plans-1610', ['default', 'heron', 'ibis'], (chosenVariation, rawResponse)->
$scope._plansVariant = chosenVariation
if chosenVariation in ['heron', 'ibis']
$scope.startTrialPlanCode = "collaborator_#{chosenVariation}"
$scope.settings = window.userSettings
$scope.anonymous = window.anonymous
@ -75,7 +87,7 @@ define [
# Only run the header AB test for newly registered users.
_abTestStartDate = new Date(Date.UTC(2016, 8, 28))
_userSignUpDate = new Date(window.user.signUpDate)
$scope.shouldABTestHeaderLabels = _userSignUpDate > _abTestStartDate
$scope.headerLabelsABVariant = ""
@ -92,7 +104,7 @@ define [
# Tracking code.
$scope.$watch "ui.view", (newView, oldView) ->
if newView? and newView != "editor" and newView != "pdf"
event_tracking.sendMBOnce "ide-open-view-#{ newView }-once"
event_tracking.sendMBOnce "ide-open-view-#{ newView }-once"
$scope.$watch "ui.chatOpen", (isOpen) ->
event_tracking.sendMBOnce "ide-open-chat-once" if isOpen
@ -105,7 +117,7 @@ define [
# End of tracking code.
window._ide = ide
ide.validFileRegex = '^[^\*\/]*$' # Don't allow * and /
ide.project_id = $scope.project_id = window.project_id

View file

@ -29,12 +29,12 @@ define [
$scope.$watch "shouldShowLogs", (shouldShow) ->
if shouldShow
$scope.$applyAsync () ->
$scope.$applyAsync () ->
$scope.shouldDropUp = getFilesDropdownTopCoordAsRatio() > 0.65
# log hints tracking
$scope.logHintsNegFeedbackValues = logHintsFeedback.feedbackOpts
$scope.trackLogHintsLearnMore = () ->
event_tracking.sendMB "logs-hints-learn-more"
@ -108,7 +108,7 @@ define [
_csrf: window.csrfToken
}, {params: params}
parseCompileResponse = (response) ->
parseCompileResponse = (response) ->
# keep last url
last_pdf_url = $scope.pdf.url
@ -469,7 +469,7 @@ define [
event_tracking.sendMB "subscription-start-trial", { source }
window.open("/user/subscription/new?planCode=student_free_trial_7_days")
window.open("/user/subscription/new?planCode=#{$scope.startTrialPlanCode}")
$scope.startedFreeTrial = true
App.factory "synctex", ["ide", "$http", "$q", (ide, $http, $q) ->

View file

@ -10,10 +10,9 @@ define [
w = window.open()
sixpack.convert "track-changes-discount", ->
sixpack.participate 'in-editor-free-trial-plan', ['student', 'collaborator'], (planName, rawResponse)->
ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source)
url = "/user/subscription/new?planCode=#{planName}_free_trial_7_days&ssp=#{planName == 'collaborator'}"
if couponCode?
url = "#{url}&cc=#{couponCode}"
$scope.startedFreeTrial = true
w.location = url
ga?('send', 'event', 'subscription-funnel', 'upgraded-free-trial', source)
url = "/user/subscription/new?planCode=#{$scope.startTrialPlanCode}&ssp=true"
if couponCode?
url = "#{url}&cc=#{couponCode}"
$scope.startedFreeTrial = true
w.location = url

View file

@ -5,12 +5,15 @@ define [
App.controller "NewSubscriptionController", ($scope, MultiCurrencyPricing, abTestManager, $http, sixpack, event_tracking, ccUtils)->
throw new Error("Recurly API Library Missing.") if typeof recurly is "undefined"
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.plans = MultiCurrencyPricing.plans
$scope.switchToStudent = ()->
window.location = "/user/subscription/new?planCode=student_free_trial_7_days&currency=#{$scope.currencyCode}&cc=#{$scope.data.coupon}"
currentPlanCode = window.plan_code
planCode = currentPlanCode.replace('collaborator', 'student')
event_tracking.sendMB 'subscription-form-switch-to-student', { plan: window.plan_code }
window.location = "/user/subscription/new?planCode=#{planCode}&currency=#{$scope.currencyCode}&cc=#{$scope.data.coupon}"
event_tracking.sendMB "subscription-form", { plan : window.plan_code }

View file

@ -5,12 +5,171 @@ define [
App.factory "MultiCurrencyPricing", () ->
currencyCode = window.recomendedCurrency
return {
currencyCode:currencyCode
plans:
heron:
USD:
student:
monthly: "$6"
annual: "$60"
collaborator:
monthly: "$12"
annual: "$144"
EUR:
student:
monthly: "€5"
annual: "€50"
collaborator:
monthly: "€10"
annual: "€120"
GBP:
student:
monthly: "£5"
annual: "£50"
collaborator:
monthly: "£10"
annual: "£120"
SEK:
student:
monthly: "45 kr"
annual: "450 kr"
collaborator:
monthly: "90 kr"
annual: "1080 kr"
CAD:
student:
monthly: "$7"
annual: "$70"
collaborator:
monthly: "$14"
annual: "$168"
NOK:
student:
monthly: "45 kr"
annual: "450 kr"
collaborator:
monthly: "90 kr"
annual: "1080 kr"
DKK:
student:
monthly: "40 kr"
annual: "400 kr"
collaborator:
monthly: "80 kr"
annual: "960 kr"
AUD:
student:
monthly: "$8"
annual: "$80"
collaborator:
monthly: "$16"
annual: "$192"
NZD:
student:
monthly: "$8"
annual: "$80"
collaborator:
monthly: "$16"
annual: "$192"
CHF:
student:
monthly: "Fr 6"
annual: "Fr 60"
collaborator:
monthly: "Fr 12"
annual: "Fr 144"
SGD:
student:
monthly: "$8"
annual: "$80"
collaborator:
monthly: "$16"
annual: "$192"
ibis:
USD:
student:
monthly: "$10"
annual: "$100"
collaborator:
monthly: "$18"
annual: "$216"
EUR:
student:
monthly: "€9"
annual: "€90"
collaborator:
monthly: "€16"
annual: "€192"
GBP:
student:
monthly: "£7"
annual: "£70"
collaborator:
monthly: "£13"
annual: "£156"
SEK:
student:
monthly: "75 kr"
annual: "750 kr"
collaborator:
monthly: "140 kr"
annual: "1680 kr"
CAD:
student:
monthly: "$12"
annual: "$120"
collaborator:
monthly: "$22"
annual: "$264"
NOK:
student:
monthly: "75 kr"
annual: "750 kr"
collaborator:
monthly: "140 kr"
annual: "1680 kr"
DKK:
student:
monthly: "68 kr"
annual: "680 kr"
collaborator:
monthly: "122 kr"
annual: "1464 kr"
AUD:
student:
monthly: "$13"
annual: "$130"
collaborator:
monthly: "$24"
annual: "$288"
NZD:
student:
monthly: "$14"
annual: "$140"
collaborator:
monthly: "$25"
annual: "$300"
CHF:
student:
monthly: "Fr 10"
annual: "Fr 100"
collaborator:
monthly: "Fr 18"
annual: "Fr 216"
SGD:
student:
monthly: "$14"
annual: "$140"
collaborator:
monthly: "$25"
annual: "$300"
plans:
USD:
symbol: "$"
student:
@ -23,7 +182,7 @@ define [
monthly: "$30"
annual: "$360"
EUR:
EUR:
symbol: ""
student:
monthly: "€7"
@ -34,7 +193,7 @@ define [
professional:
monthly: "€28"
annual: "€336"
GBP:
symbol: "£"
student:
@ -117,7 +276,7 @@ define [
professional:
monthly: "$35"
annual: "$420"
CHF:
symbol: "Fr"
student:
@ -141,36 +300,51 @@ define [
professional:
monthly: "$40"
annual: "$480"
}
App.controller "PlansController", ($scope, $modal, event_tracking, abTestManager, MultiCurrencyPricing, $http, sixpack) ->
App.controller "PlansController", ($scope, $modal, event_tracking, abTestManager, MultiCurrencyPricing, $http) ->
$scope.plansVariant = 'default'
$scope.shouldABTestPlans = window.shouldABTestPlans
if $scope.shouldABTestPlans
sixpack.participate 'plans-1610', ['default', 'heron', 'ibis'], (chosenVariation, rawResponse)->
$scope.plansVariant = chosenVariation
if chosenVariation in ['heron', 'ibis']
# overwrite student plans with alternative
for currency, _v of $scope.plans
$scope.plans[currency]['student'] = MultiCurrencyPricing[chosenVariation][currency]['student']
$scope.plans[currency]['collaborator'] = MultiCurrencyPricing[chosenVariation][currency]['collaborator']
$scope.plans = MultiCurrencyPricing.plans
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.trial_len = 7
$scope.planQueryString = '_free_trial_7_days'
$scope.ui =
view: "monthly"
$scope.changeCurreny = (newCurrency)->
$scope.currencyCode = newCurrency
$scope.signUpNowClicked = (plan, annual)->
if $scope.ui.view == "annual"
plan = "#{plan}_annual"
event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan
event_tracking.send 'subscription-funnel', 'sign_up_now_button', plan
# TODO: double check this is correct
if $scope.shouldABTestPlans and plan in ['student', 'collaborator']
sixpack.convert 'plans-1610', () ->
$scope.switchToMonthly = ->
$scope.ui.view = "monthly"
event_tracking.send 'subscription-funnel', 'plans-page', 'monthly-prices'
$scope.switchToStudent = ->
$scope.ui.view = "student"
event_tracking.send 'subscription-funnel', 'plans-page', 'student-prices'
@ -178,7 +352,7 @@ define [
$scope.switchToAnnual = ->
$scope.ui.view = "annual"
event_tracking.send 'subscription-funnel', 'plans-page', 'student-prices'
$scope.openGroupPlanModal = () ->
$modal.open {
templateUrl: "groupPlanModalTemplate"

View file

@ -9,7 +9,7 @@ define [
App.controller "CurrenyDropdownController", ($scope, MultiCurrencyPricing, $q)->
$scope.plans = MultiCurrencyPricing.plans
# $scope.plans = MultiCurrencyPricing.plans
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.changeCurrency = (newCurrency)->
@ -31,7 +31,7 @@ define [
$scope.currencyCode = MultiCurrencyPricing.currencyCode
$scope.pricing = MultiCurrencyPricing
$scope.plans = MultiCurrencyPricing.plans
# $scope.plans = MultiCurrencyPricing.plans
$scope.currencySymbol = MultiCurrencyPricing.plans[MultiCurrencyPricing.currencyCode].symbol
$scope.currencyCode = MultiCurrencyPricing.currencyCode
@ -53,9 +53,9 @@ define [
price = ""
App.controller "ConfirmChangePlanController", ($scope, $modalInstance, $http)->
$scope.confirmChangePlan = ->
body =
body =
plan_code: $scope.plan.planCode
_csrf : window.csrfToken
@ -74,7 +74,7 @@ define [
$scope.confirmLeaveGroup = ->
$scope.inflight = true
$http({
url: "/subscription/group/user",
url: "/subscription/group/user",
method: "DELETE",
params: {admin_user_id: $scope.admin_id, _csrf: window.csrfToken}
}).success ->
@ -87,6 +87,8 @@ define [
App.controller "UserSubscriptionController", ($scope, MultiCurrencyPricing, $http, sixpack, $modal) ->
$scope.plans = MultiCurrencyPricing.plans
freeTrialEndDate = new Date(subscription?.trial_ends_at)
sevenDaysTime = new Date()
@ -96,6 +98,16 @@ define [
freeTrialExpiresUnderSevenDays = freeTrialEndDate < sevenDaysTime
$scope.view = 'overview'
$scope.getSuffix = (planCode) ->
planCode?.match(/(.*?)_(.*)/)?[2] || null
$scope.subscriptionSuffix = $scope.getSuffix(window?.subscription?.planCode)
if $scope.subscriptionSuffix == 'free_trial_7_days'
$scope.subscriptionSuffix = ''
$scope.isNextGenPlan = $scope.subscriptionSuffix in ['heron', 'ibis']
$scope.shouldShowPlan = (planCode) ->
$scope.getSuffix(planCode) not in ['heron', 'ibis']
isMonthlyCollab = subscription?.planCode?.indexOf("collaborator") != -1 and subscription?.planCode?.indexOf("ann") == -1
stillInFreeTrial = freeTrialInFuture and freeTrialExpiresUnderSevenDays
@ -118,7 +130,7 @@ define [
$scope.studentPrice = $scope.currencySymbol + (totalPriceExTax + taxAmmount)
$scope.downgradeToStudent = ->
body =
body =
plan_code: 'student'
_csrf : window.csrfToken
$scope.inflight = true
@ -129,7 +141,7 @@ define [
console.log "something went wrong changing plan"
$scope.cancelSubscription = ->
body =
body =
_csrf : window.csrfToken
$scope.inflight = true
@ -158,7 +170,7 @@ define [
$scope.exendTrial = ->
body =
body =
_csrf : window.csrfToken
$scope.inflight = true
$http.put("/user/subscription/extend", body)
@ -166,6 +178,3 @@ define [
location.reload()
.error ->
console.log "something went wrong changing plan"

View file

@ -20,7 +20,7 @@ mockSubscriptions =
describe "SubscriptionController sanboxed", ->
beforeEach ->
@user = {email:"tom@yahoo.com", _id: 'one'}
@user = {email:"tom@yahoo.com", _id: 'one', signUpDate: new Date('2000-10-01')}
@activeRecurlySubscription = mockSubscriptions["subscription-123-active"]
@AuthenticationController =
@ -63,6 +63,8 @@ describe "SubscriptionController sanboxed", ->
getCurrencyCode:sinon.stub()
@SubscriptionDomainHandler =
getDomainLicencePage:sinon.stub()
@UserGetter =
getUser: sinon.stub().callsArgWith(2, null, @user)
@SubscriptionController = SandboxedModule.require modulePath, requires:
'../Authentication/AuthenticationController': @AuthenticationController
'./SubscriptionHandler': @SubscriptionHandler
@ -76,6 +78,7 @@ describe "SubscriptionController sanboxed", ->
warn:->
"settings-sharelatex": @settings
"./SubscriptionDomainHandler":@SubscriptionDomainHandler
"../User/UserGetter": @UserGetter
@res = new MockResponse()
@ -92,12 +95,31 @@ describe "SubscriptionController sanboxed", ->
@GeoIpLookup.getCurrencyCode.callsArgWith(1, null, @stubbedCurrencyCode)
@res.callback = done
@SubscriptionController.plansPage(@req, @res)
@UserGetter.getUser = sinon.stub().callsArgWith(2, null, @user)
it "should set the recommended currency from the geoiplookup", (done)->
@res.renderedVariables.recomendedCurrency.should.equal(@stubbedCurrencyCode)
@GeoIpLookup.getCurrencyCode.calledWith(@req.ip).should.equal true
done()
it 'should fetch the current user', (done) ->
@UserGetter.getUser.callCount.should.equal 1
done()
it 'should decide not to AB test the plans', (done) ->
@res.renderedVariables.shouldABTestPlans.should.equal false
done()
describe 'when user is not logged in', (done) ->
beforeEach ->
@AuthenticationController.getLoggedInUserId.returns(null)
it 'should not fetch the current user', (done) ->
@UserGetter.getUser.callCount.should.equal 0
done()
describe "editBillingDetailsPage", ->
describe "with a user with a subscription", ->
beforeEach (done) ->