SubscriptionHandlerTests.coffee 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. SandboxedModule = require('sandboxed-module')
  2. should = require('chai').should()
  3. sinon = require 'sinon'
  4. querystring = require 'querystring'
  5. modulePath = "../../../../app/js/Features/Subscription/SubscriptionHandler"
  6. SubscriptionHandler = require modulePath
  7. mockRecurlySubscriptions =
  8. "subscription-123-active":
  9. uuid: "subscription-123-active"
  10. plan:
  11. name: "Gold"
  12. plan_code: "gold"
  13. current_period_ends_at: new Date()
  14. state: "active"
  15. unit_amount_in_cents: 999
  16. account:
  17. account_code: "user-123"
  18. describe "Subscription Handler sanboxed", ->
  19. beforeEach ->
  20. @Settings =
  21. plans : [{
  22. planCode: "collaborator"
  23. name: "Collaborator"
  24. features:
  25. collaborators: -1
  26. versioning: true
  27. }]
  28. defaultPlanCode :
  29. collaborators: 0
  30. versioning: false
  31. @activeRecurlySubscription = mockRecurlySubscriptions["subscription-123-active"]
  32. @User = {}
  33. @user =
  34. _id: "user_id_here_"
  35. @subscription =
  36. recurlySubscription_id: @activeRecurlySubscription.uuid
  37. @RecurlyWrapper =
  38. getSubscription: sinon.stub().callsArgWith(2, null, @activeRecurlySubscription)
  39. updateSubscription: sinon.stub().callsArgWith(2, null, @activeRecurlySubscription)
  40. cancelSubscription: sinon.stub().callsArgWith(1)
  41. reactivateSubscription: sinon.stub().callsArgWith(1)
  42. redeemCoupon:sinon.stub().callsArgWith(2)
  43. @DropboxHandler =
  44. unlinkAccount:sinon.stub().callsArgWith(1)
  45. @SubscriptionUpdater =
  46. syncSubscription: sinon.stub().callsArgWith(2)
  47. startFreeTrial: sinon.stub().callsArgWith(1)
  48. @LimitationsManager =
  49. userHasSubscription: sinon.stub()
  50. userHasSubscriptionOrFreeTrial: sinon.stub()
  51. @EmailHandler =
  52. sendEmail:sinon.stub()
  53. @SubscriptionHandler = SandboxedModule.require modulePath, requires:
  54. "./RecurlyWrapper": @RecurlyWrapper
  55. "settings-sharelatex": @Settings
  56. '../../models/User': User:@User
  57. './SubscriptionUpdater': @SubscriptionUpdater
  58. "logger-sharelatex":{log:->}
  59. './LimitationsManager':@LimitationsManager
  60. "../Email/EmailHandler":@EmailHandler
  61. "../Dropbox/DropboxHandler":@DropboxHandler
  62. @SubscriptionHandler.syncSubscriptionToUser = sinon.stub().callsArgWith(2)
  63. describe "createSubscription", ->
  64. beforeEach (done) ->
  65. @SubscriptionHandler.createSubscription(@user, @activeRecurlySubscription.uuid, done)
  66. it "should get the subscription", (done)->
  67. @RecurlyWrapper.getSubscription.calledWith(@activeRecurlySubscription.uuid, {recurlyJsResult: true}).should.equal true
  68. done()
  69. it "should sync the subscription to the user", (done)->
  70. @SubscriptionUpdater.syncSubscription.calledOnce.should.equal true
  71. @SubscriptionUpdater.syncSubscription.args[0][0].should.deep.equal @activeRecurlySubscription
  72. @SubscriptionUpdater.syncSubscription.args[0][1].should.deep.equal @user._id
  73. done()
  74. describe "updateSubscription", ->
  75. describe "with a user with a subscription", ->
  76. describe "with a valid plan code", ->
  77. beforeEach (done) ->
  78. @plan_code = "collaborator"
  79. @LimitationsManager.userHasSubscription.callsArgWith(1, null, true, @subscription)
  80. @SubscriptionHandler.updateSubscription(@user, @plan_code, null, done)
  81. it "should update the subscription", ->
  82. @RecurlyWrapper.updateSubscription.calledWith(@subscription.recurlySubscription_id).should.equal true
  83. updateOptions = @RecurlyWrapper.updateSubscription.args[0][1]
  84. updateOptions.plan_code.should.equal @plan_code
  85. it "should update immediately", ->
  86. updateOptions = @RecurlyWrapper.updateSubscription.args[0][1]
  87. updateOptions.timeframe.should.equal "now"
  88. it "should sync the new subscription to the user", ->
  89. @SubscriptionUpdater.syncSubscription.calledOnce.should.equal true
  90. @SubscriptionUpdater.syncSubscription.args[0][0].should.deep.equal @activeRecurlySubscription
  91. @SubscriptionUpdater.syncSubscription.args[0][1].should.deep.equal @user._id
  92. describe "with a user without a subscription", ->
  93. beforeEach (done) ->
  94. @LimitationsManager.userHasSubscription.callsArgWith(1, null, false)
  95. @SubscriptionHandler.updateSubscription(@user, @plan_code, null, done)
  96. it "should redirect to the subscription dashboard", ->
  97. @RecurlyWrapper.updateSubscription.called.should.equal false
  98. @SubscriptionHandler.syncSubscriptionToUser.called.should.equal false
  99. describe "with a coupon code", ->
  100. beforeEach (done) ->
  101. @plan_code = "collaborator"
  102. @coupon_code = "1231312"
  103. @LimitationsManager.userHasSubscription.callsArgWith(1, null, true, @subscription)
  104. @SubscriptionHandler.updateSubscription(@user, @plan_code, @coupon_code, done)
  105. it "should get the users account", ->
  106. @RecurlyWrapper.getSubscription.calledWith(@activeRecurlySubscription.uuid).should.equal true
  107. it "should redeme the coupon", (done)->
  108. @RecurlyWrapper.redeemCoupon.calledWith(@activeRecurlySubscription.account.account_code, @coupon_code).should.equal true
  109. done()
  110. it "should update the subscription", ->
  111. @RecurlyWrapper.updateSubscription.calledWith(@subscription.recurlySubscription_id).should.equal true
  112. updateOptions = @RecurlyWrapper.updateSubscription.args[0][1]
  113. updateOptions.plan_code.should.equal @plan_code
  114. describe "cancelSubscription", ->
  115. describe "with a user without a subscription", ->
  116. beforeEach (done) ->
  117. @LimitationsManager.userHasSubscription.callsArgWith(1, null, false, @subscription)
  118. @SubscriptionHandler.cancelSubscription @user, done
  119. it "should redirect to the subscription dashboard", ->
  120. @RecurlyWrapper.cancelSubscription.called.should.equal false
  121. describe "with a user with a subscription", ->
  122. beforeEach (done) ->
  123. @LimitationsManager.userHasSubscription.callsArgWith(1, null, true, @subscription)
  124. @SubscriptionHandler.cancelSubscription @user, done
  125. it "should cancel the subscription", ->
  126. @RecurlyWrapper.cancelSubscription.called.should.equal true
  127. @RecurlyWrapper.cancelSubscription.calledWith(@subscription.recurlySubscription_id).should.equal true
  128. it "should unlink dropbox", ->
  129. @DropboxHandler.unlinkAccount.called.should.equal true
  130. @DropboxHandler.unlinkAccount.calledWith(@user._id).should.equal true
  131. describe "reactiveRecurlySubscription", ->
  132. describe "with a user without a subscription", ->
  133. beforeEach (done) ->
  134. @LimitationsManager.userHasSubscription.callsArgWith(1, null, false, @subscription)
  135. @SubscriptionHandler.reactivateSubscription @user, done
  136. it "should redirect to the subscription dashboard", ->
  137. @RecurlyWrapper.reactivateSubscription.called.should.equal false
  138. describe "with a user with a subscription", ->
  139. beforeEach (done) ->
  140. @LimitationsManager.userHasSubscription.callsArgWith(1, null, true, @subscription)
  141. @SubscriptionHandler.reactivateSubscription @user, done
  142. it "should reactivate the subscription", ->
  143. @RecurlyWrapper.reactivateSubscription.called.should.equal true
  144. @RecurlyWrapper.reactivateSubscription.calledWith(@subscription.recurlySubscription_id).should.equal true
  145. describe "recurlyCallback", ->
  146. describe "with an actionable request", ->
  147. beforeEach (done) ->
  148. @user.id = @activeRecurlySubscription.account.account_code
  149. @User.findById = (userId, callback) =>
  150. userId.should.equal @user.id
  151. callback null, @user
  152. @SubscriptionHandler.recurlyCallback(@activeRecurlySubscription, done)
  153. it "should request the affected subscription from the API", ->
  154. @RecurlyWrapper.getSubscription.calledWith(@activeRecurlySubscription.uuid).should.equal true
  155. it "should request the account details of the subscription", ->
  156. options = @RecurlyWrapper.getSubscription.args[0][1]
  157. options.includeAccount.should.equal true
  158. it "should sync the subscription to the user", ->
  159. @SubscriptionUpdater.syncSubscription.calledOnce.should.equal true
  160. @SubscriptionUpdater.syncSubscription.args[0][0].should.deep.equal @activeRecurlySubscription
  161. @SubscriptionUpdater.syncSubscription.args[0][1].should.deep.equal @user._id