SubscriptionControllerTests.coffee 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. SandboxedModule = require('sandboxed-module')
  2. sinon = require 'sinon'
  3. Settings = require 'settings-sharelatex'
  4. should = require("chai").should()
  5. MockRequest = require "../helpers/MockRequest"
  6. MockResponse = require "../helpers/MockResponse"
  7. modulePath = '../../../../app/js/Features/Subscription/SubscriptionController'
  8. mockSubscriptions =
  9. "subscription-123-active":
  10. uuid: "subscription-123-active"
  11. plan:
  12. name: "Gold"
  13. plan_code: "gold"
  14. current_period_ends_at: new Date()
  15. state: "active"
  16. unit_amount_in_cents: 999
  17. account:
  18. account_code: "user-123"
  19. describe "Subscription controller sanboxed", ->
  20. beforeEach ->
  21. @user = {}
  22. @activeRecurlySubscription = mockSubscriptions["subscription-123-active"]
  23. @SecurityManager =
  24. getCurrentUser: sinon.stub().callsArgWith(1, null, @user)
  25. @SubscriptionHandler =
  26. createSubscription: sinon.stub().callsArgWith(2)
  27. updateSubscription: sinon.stub().callsArgWith(2)
  28. reactivateSubscription: sinon.stub().callsArgWith(1)
  29. cancelSubscription: sinon.stub().callsArgWith(1)
  30. recurlyCallback: sinon.stub().callsArgWith(1)
  31. startFreeTrial: sinon.stub()
  32. @PlansLocator =
  33. findLocalPlanInSettings: sinon.stub()
  34. @LimitationsManager =
  35. userHasSubscriptionOrFreeTrial: sinon.stub()
  36. userHasSubscription : sinon.stub()
  37. @RecurlyWrapper =
  38. sign: sinon.stub().callsArgWith(1, null, "somthing")
  39. @SubscriptionViewModelBuilder =
  40. buildUsersSubscriptionViewModel:sinon.stub().callsArgWith(1, null, @activeRecurlySubscription)
  41. buildViewModel: sinon.stub()
  42. @SubscriptionController = SandboxedModule.require modulePath, requires:
  43. '../../managers/SecurityManager': @SecurityManager
  44. './SubscriptionHandler': @SubscriptionHandler
  45. "./PlansLocator": @PlansLocator
  46. './SubscriptionViewModelBuilder': @SubscriptionViewModelBuilder
  47. "./LimitationsManager": @LimitationsManager
  48. './RecurlyWrapper': @RecurlyWrapper
  49. "logger-sharelatex": log:->
  50. @res = new MockResponse()
  51. @req = new MockRequest()
  52. @req.body = {}
  53. @req.query =
  54. planCode:"123123"
  55. describe "editBillingDetailsPage", ->
  56. describe "with a user with a subscription", ->
  57. beforeEach (done) ->
  58. @LimitationsManager.userHasSubscription.callsArgWith(1, null, true)
  59. @user.id = @activeRecurlySubscription.account.account_code
  60. @res.callback = done
  61. @SubscriptionController.editBillingDetailsPage(@req, @res)
  62. it "should render the edit billing details page", ->
  63. @res.rendered.should.equal true
  64. @res.renderedTemplate.should.equal "subscriptions/edit-billing-details"
  65. it "should set the correct variables for the template", ->
  66. should.exist @res.renderedVariables.signature
  67. @res.renderedVariables.title.should.equal "Update Billing Details"
  68. @res.renderedVariables.successURL.should.equal "#{Settings.siteUrl}/user/subscription/update"
  69. @res.renderedVariables.user.id.should.equal @user.id
  70. describe "with a user without subscription", ->
  71. beforeEach (done) ->
  72. @res.callback = done
  73. @LimitationsManager.userHasSubscription.callsArgWith(1, null, false)
  74. @SubscriptionController.reactivateSubscription @req, @res
  75. it "should redirect to the subscription dashboard", ->
  76. @res.redirected.should.equal true
  77. @res.redirectedTo.should.equal "/user/subscription"
  78. describe "paymentPage", ->
  79. describe "with a user without a subscription", ->
  80. beforeEach ->
  81. @LimitationsManager.userHasSubscription.callsArgWith(1, null, false)
  82. @PlansLocator.findLocalPlanInSettings.returns({})
  83. describe "with a valid plan code", ->
  84. it "should render the new subscription page", (done)->
  85. @res.render = (page, opts)=>
  86. page.should.equal "subscriptions/new"
  87. done()
  88. @SubscriptionController.paymentPage @req, @res
  89. it "should set the successURL", (done)->
  90. @req.session._csrf = @csrfToken = "mock-csrf-token"
  91. @res.render = (page, opts)=>
  92. url = JSON.parse(opts.subscriptionFormOptions).successURL
  93. url.should.equal("#{Settings.siteUrl}/user/subscription/create?_csrf=#{@csrfToken}")
  94. done()
  95. @SubscriptionController.paymentPage @req, @res
  96. describe "with a user with subscription", ->
  97. it "should redirect to the subscription dashboard", (done)->
  98. @LimitationsManager.userHasSubscription.callsArgWith(1, null, true)
  99. @res.redirect = (url)=>
  100. url.should.equal "/user/subscription"
  101. done()
  102. @SubscriptionController.paymentPage(@req, @res)
  103. describe "with an invalid plan code", ->
  104. it "should redirect to the subscription dashboard", (done)->
  105. @LimitationsManager.userHasSubscription.callsArgWith(1, null, false)
  106. @PlansLocator.findLocalPlanInSettings.returns(null)
  107. @res.redirect = (url)=>
  108. url.should.equal "/user/subscription"
  109. done()
  110. @SubscriptionController.paymentPage(@req, @res)
  111. describe "successful_subscription", ->
  112. beforeEach (done) ->
  113. @SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel.callsArgWith(1, null, {})
  114. @res.callback = done
  115. @SubscriptionController.successful_subscription @req, @res
  116. it "should render the thank you page", ->
  117. @res.renderedVariables.title.should.equal "Thank you!"
  118. describe "userSubscriptionPage", ->
  119. describe "with a user without a subscription", ->
  120. beforeEach (done) ->
  121. @res.callback = done
  122. @LimitationsManager.userHasSubscriptionOrFreeTrial.callsArgWith(1, null, false)
  123. @SubscriptionController.userSubscriptionPage @req, @res
  124. it "should redirect to the plans page", ->
  125. @res.redirected.should.equal true
  126. @res.redirectedTo.should.equal "/user/subscription/plans"
  127. describe "with a user with a paid subscription", ->
  128. beforeEach (done) ->
  129. @res.callback = done
  130. @SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel.callsArgWith(1, null, @activeRecurlySubscription)
  131. @LimitationsManager.userHasSubscriptionOrFreeTrial.callsArgWith(1, null, true)
  132. @SubscriptionController.userSubscriptionPage @req, @res
  133. it "should render the dashboard", (done)->
  134. @res.rendered.should.equal true
  135. @res.renderedTemplate.should.equal "subscriptions/dashboard"
  136. done()
  137. it "should set the correct subscription details", ->
  138. @res.renderedVariables.title.should.equal "Your Subscription"
  139. @res.renderedVariables.subscription.should.deep.equal @activeRecurlySubscription
  140. describe "with a user with a free trial", ->
  141. beforeEach (done) ->
  142. @res.callback = done
  143. @SubscriptionViewModelBuilder.buildUsersSubscriptionViewModel.callsArgWith(1, null, @activeRecurlySubscription)
  144. @LimitationsManager.userHasSubscriptionOrFreeTrial.callsArgWith(1, null, true)
  145. @SubscriptionController.userSubscriptionPage @req, @res
  146. it "should render the dashboard", ->
  147. @res.rendered.should.equal true
  148. @res.renderedTemplate.should.equal "subscriptions/dashboard"
  149. it "should set the correct subscription details", ->
  150. @res.renderedVariables.title.should.equal "Your Subscription"
  151. @res.renderedVariables.subscription.should.deep.equal @activeRecurlySubscription
  152. describe "createSubscription", ->
  153. beforeEach (done)->
  154. @res =
  155. redirect:->
  156. done()
  157. sinon.spy @res, "redirect"
  158. @req.body.recurly_token = "1234"
  159. @SubscriptionController.createSubscription @req, @res
  160. it "should send the user and subscriptionId to the handler", (done)->
  161. @SubscriptionHandler.createSubscription.calledWith(@user, @req.body.recurly_token).should.equal true
  162. done()
  163. it "should redurect to the subscription page", (done)->
  164. @res.redirect.calledWith("/user/subscription/thank-you").should.equal true
  165. done()
  166. describe "updateSubscription", ->
  167. beforeEach (done)->
  168. @res =
  169. redirect:->
  170. done()
  171. sinon.spy @res, "redirect"
  172. @plan_code = "1234"
  173. @req.body.plan_code = @plan_code
  174. @SubscriptionController.updateSubscription @req, @res
  175. it "should send the user and subscriptionId to the handler", (done)->
  176. @SubscriptionHandler.updateSubscription.calledWith(@user, @plan_code).should.equal true
  177. done()
  178. it "should redurect to the subscription page", (done)->
  179. @res.redirect.calledWith("/user/subscription").should.equal true
  180. done()
  181. describe "reactivateSubscription", ->
  182. beforeEach (done)->
  183. @res =
  184. redirect:->
  185. done()
  186. sinon.spy @res, "redirect"
  187. @SubscriptionController.reactivateSubscription @req, @res
  188. it "should tell the handler to reactivate this user", (done)->
  189. @SubscriptionHandler.reactivateSubscription.calledWith(@user).should.equal true
  190. done()
  191. it "should redurect to the subscription page", (done)->
  192. @res.redirect.calledWith("/user/subscription").should.equal true
  193. done()
  194. describe "cancelSubscription", ->
  195. beforeEach (done)->
  196. @res =
  197. redirect:->
  198. done()
  199. sinon.spy @res, "redirect"
  200. @SubscriptionController.cancelSubscription @req, @res
  201. it "should tell the handler to cancel this user", (done)->
  202. @SubscriptionHandler.cancelSubscription.calledWith(@user).should.equal true
  203. done()
  204. it "should redurect to the subscription page", (done)->
  205. @res.redirect.calledWith("/user/subscription").should.equal true
  206. done()
  207. describe "recurly callback", ->
  208. describe "with a actionable request", ->
  209. beforeEach (done)->
  210. @req =
  211. body:
  212. expired_subscription_notification:
  213. subscription:
  214. uuid: @activeRecurlySubscription.uuid
  215. @res = send:->
  216. done()
  217. sinon.spy @res, "send"
  218. @SubscriptionController.recurlyCallback @req, @res
  219. it "should tell the SubscriptionHandler to process the recurly callback", (done)->
  220. @SubscriptionHandler.recurlyCallback.called.should.equal true
  221. done()
  222. it "should send a 200", (done)->
  223. @res.send.calledWith(200)
  224. done()
  225. describe "with a non-actionable request", ->
  226. beforeEach (done) ->
  227. @user.id = @activeRecurlySubscription.account.account_code
  228. @req =
  229. body:
  230. new_subscription_notification:
  231. subscription:
  232. uuid: @activeRecurlySubscription.uuid
  233. @res = send:->
  234. done()
  235. sinon.spy @res, "send"
  236. @SubscriptionController.recurlyCallback @req, @res
  237. it "should not call the subscriptionshandler", ->
  238. @SubscriptionHandler.recurlyCallback.called.should.equal false
  239. it "should respond with a 200 status", ->
  240. @res.send.calledWith(200)