SubscriptionControllerTests.coffee 10 KB

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