SubscriptionUpdaterTests.coffee 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. SandboxedModule = require('sandboxed-module')
  2. should = require('chai').should()
  3. sinon = require 'sinon'
  4. modulePath = "../../../../app/js/Features/Subscription/SubscriptionUpdater"
  5. assert = require("chai").assert
  6. ObjectId = require('mongoose').Types.ObjectId
  7. describe "SubscriptionUpdater", ->
  8. beforeEach ->
  9. @recurlySubscription =
  10. uuid: "1238uoijdasjhd"
  11. plan:
  12. plan_code: "kjhsakjds"
  13. @adminUser =
  14. _id: @adminuser_id = "5208dd34438843e2db000007"
  15. @otherUserId = "5208dd34438842e2db000005"
  16. @allUserIds = ["13213", "dsadas", "djsaiud89"]
  17. @subscription = subscription =
  18. admin_id: @adminUser._id
  19. member_ids: @allUserIds
  20. save: sinon.stub().callsArgWith(0)
  21. freeTrial:{}
  22. planCode:"student_or_something"
  23. @groupSubscription =
  24. admin_id: @adminUser._id
  25. member_ids: @allUserIds
  26. save: sinon.stub().callsArgWith(0)
  27. freeTrial:{}
  28. planCode:"group_subscription"
  29. @updateStub = sinon.stub().callsArgWith(2, null)
  30. @findAndModifyStub = sinon.stub().callsArgWith(2, null, @subscription)
  31. @SubscriptionModel = class
  32. constructor: (opts)->
  33. subscription.admin_id = opts.admin_id
  34. return subscription
  35. @remove: sinon.stub().yields()
  36. @SubscriptionModel.update = @updateStub
  37. @SubscriptionModel.findAndModify = @findAndModifyStub
  38. @SubscriptionLocator =
  39. getUsersSubscription: sinon.stub()
  40. getGroupSubscriptionMemberOf:sinon.stub()
  41. @Settings =
  42. freeTrialPlanCode: "collaborator"
  43. defaultPlanCode: "personal"
  44. @UserFeaturesUpdater =
  45. updateFeatures : sinon.stub().callsArgWith(2)
  46. @PlansLocator =
  47. findLocalPlanInSettings: sinon.stub().returns({})
  48. @ReferalAllocator = assignBonus:sinon.stub().callsArgWith(1)
  49. @ReferalAllocator.cock = true
  50. @Modules = {hooks: {fire: sinon.stub().callsArgWith(2, null, null)}}
  51. @SubscriptionUpdater = SandboxedModule.require modulePath, requires:
  52. '../../models/Subscription': Subscription:@SubscriptionModel
  53. './UserFeaturesUpdater': @UserFeaturesUpdater
  54. './SubscriptionLocator': @SubscriptionLocator
  55. './PlansLocator': @PlansLocator
  56. "logger-sharelatex": log:->
  57. 'settings-sharelatex': @Settings
  58. "../Referal/ReferalAllocator" : @ReferalAllocator
  59. '../../infrastructure/Modules': @Modules
  60. describe "syncSubscription", ->
  61. beforeEach ->
  62. @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, @subscription)
  63. @SubscriptionUpdater._updateSubscriptionFromRecurly = sinon.stub().callsArgWith(2)
  64. it "should update the subscription if the user already is admin of one", (done)->
  65. @SubscriptionUpdater._createNewSubscription = sinon.stub()
  66. @SubscriptionUpdater.syncSubscription @recurlySubscription, @adminUser._id, (err)=>
  67. @SubscriptionLocator.getUsersSubscription.calledWith(@adminUser._id).should.equal true
  68. @SubscriptionUpdater._updateSubscriptionFromRecurly.called.should.equal true
  69. @SubscriptionUpdater._updateSubscriptionFromRecurly.calledWith(@recurlySubscription, @subscription).should.equal true
  70. done()
  71. it "should not call updateFeatures with group subscription if recurly subscription is not expired", (done)->
  72. @SubscriptionUpdater.syncSubscription @recurlySubscription, @adminUser._id, (err)=>
  73. @SubscriptionLocator.getUsersSubscription.calledWith(@adminUser._id).should.equal true
  74. @SubscriptionUpdater._updateSubscriptionFromRecurly.called.should.equal true
  75. @SubscriptionUpdater._updateSubscriptionFromRecurly.calledWith(@recurlySubscription, @subscription).should.equal true
  76. @UserFeaturesUpdater.updateFeatures.called.should.equal false
  77. done()
  78. describe "_updateSubscriptionFromRecurly", ->
  79. beforeEach ->
  80. @SubscriptionUpdater._setUsersMinimumFeatures = sinon.stub().callsArgWith(1)
  81. it "should update the subscription with token etc when not expired", (done)->
  82. @SubscriptionUpdater._updateSubscriptionFromRecurly @recurlySubscription, @subscription, (err)=>
  83. @subscription.recurlySubscription_id.should.equal @recurlySubscription.uuid
  84. @subscription.planCode.should.equal @recurlySubscription.plan.plan_code
  85. @subscription.freeTrial.allowed.should.equal true
  86. assert.equal(@subscription.freeTrial.expiresAt, undefined)
  87. assert.equal(@subscription.freeTrial.planCode, undefined)
  88. @subscription.save.called.should.equal true
  89. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@adminUser._id).should.equal true
  90. done()
  91. it "should remove the recurlySubscription_id when expired", (done)->
  92. @recurlySubscription.state = "expired"
  93. @SubscriptionUpdater._updateSubscriptionFromRecurly @recurlySubscription, @subscription, (err)=>
  94. assert.equal(@subscription.recurlySubscription_id, undefined)
  95. @subscription.save.called.should.equal true
  96. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@adminUser._id).should.equal true
  97. done()
  98. it "should update all the users features", (done)->
  99. @SubscriptionUpdater._updateSubscriptionFromRecurly @recurlySubscription, @subscription, (err)=>
  100. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@adminUser._id).should.equal true
  101. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@allUserIds[0]).should.equal true
  102. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@allUserIds[1]).should.equal true
  103. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@allUserIds[2]).should.equal true
  104. done()
  105. it "should set group to true and save how many members can be added to group", (done)->
  106. @PlansLocator.findLocalPlanInSettings.withArgs(@recurlySubscription.plan.plan_code).returns({groupPlan:true, membersLimit:5})
  107. @SubscriptionUpdater._updateSubscriptionFromRecurly @recurlySubscription, @subscription, (err)=>
  108. @subscription.membersLimit.should.equal 5
  109. @subscription.groupPlan.should.equal true
  110. done()
  111. it "should not set group to true or set groupPlan", (done)->
  112. @SubscriptionUpdater._updateSubscriptionFromRecurly @recurlySubscription, @subscription, (err)=>
  113. assert.notEqual @subscription.membersLimit, 5
  114. assert.notEqual @subscription.groupPlan, true
  115. done()
  116. describe "_createNewSubscription", ->
  117. it "should create a new subscription then update the subscription", (done)->
  118. @SubscriptionUpdater._createNewSubscription @adminUser._id, =>
  119. @subscription.admin_id.should.equal @adminUser._id
  120. @subscription.freeTrial.allowed.should.equal false
  121. @subscription.save.called.should.equal true
  122. done()
  123. describe "addUserToGroup", ->
  124. it "should add the users id to the group as a set", (done)->
  125. @SubscriptionUpdater.addUserToGroup @adminUser._id, @otherUserId, =>
  126. searchOps =
  127. admin_id: @adminUser._id
  128. insertOperation =
  129. "$addToSet": {member_ids:@otherUserId}
  130. @findAndModifyStub.calledWith(searchOps, insertOperation).should.equal true
  131. done()
  132. it "should update the users features", (done)->
  133. @SubscriptionUpdater.addUserToGroup @adminUser._id, @otherUserId, =>
  134. @UserFeaturesUpdater.updateFeatures.calledWith(@otherUserId, @subscription.planCode).should.equal true
  135. done()
  136. describe "removeUserFromGroup", ->
  137. beforeEach ->
  138. @SubscriptionUpdater._setUsersMinimumFeatures = sinon.stub().callsArgWith(1)
  139. it "should pull the users id from the group", (done)->
  140. @SubscriptionUpdater.removeUserFromGroup @adminUser._id, @otherUserId, =>
  141. searchOps =
  142. admin_id:@adminUser._id
  143. removeOperation =
  144. "$pull": {member_ids:@otherUserId}
  145. @updateStub.calledWith(searchOps, removeOperation).should.equal true
  146. done()
  147. it "should update the users features", (done)->
  148. @SubscriptionUpdater.removeUserFromGroup @adminUser._id, @otherUserId, =>
  149. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@otherUserId).should.equal true
  150. done()
  151. describe "_setUsersMinimumFeatures", ->
  152. it "should call updateFeatures with the subscription if set", (done)->
  153. @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, @subscription)
  154. @SubscriptionLocator.getGroupSubscriptionMemberOf.callsArgWith(1, null)
  155. @SubscriptionUpdater._setUsersMinimumFeatures @adminUser._id, (err)=>
  156. args = @UserFeaturesUpdater.updateFeatures.args[0]
  157. assert.equal args[0], @adminUser._id
  158. assert.equal args[1], @subscription.planCode
  159. done()
  160. it "should call updateFeatures with the group subscription if set", (done)->
  161. @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null)
  162. @SubscriptionLocator.getGroupSubscriptionMemberOf.callsArgWith(1, null, @groupSubscription)
  163. @SubscriptionUpdater._setUsersMinimumFeatures @adminUser._id, (err)=>
  164. args = @UserFeaturesUpdater.updateFeatures.args[0]
  165. assert.equal args[0], @adminUser._id
  166. assert.equal args[1], @groupSubscription.planCode
  167. done()
  168. it "should call updateFeatures with the overleaf subscription if set", (done)->
  169. @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null)
  170. @SubscriptionLocator.getGroupSubscriptionMemberOf.callsArgWith(1, null, null)
  171. @Modules.hooks.fire = sinon.stub().callsArgWith(2, null, ['ol_pro'])
  172. @SubscriptionUpdater._setUsersMinimumFeatures @adminUser._id, (err)=>
  173. args = @UserFeaturesUpdater.updateFeatures.args[0]
  174. assert.equal args[0], @adminUser._id
  175. assert.equal args[1], 'ol_pro'
  176. done()
  177. it "should call not call updateFeatures with users subscription if the subscription plan code is the default one (downgraded)", (done)->
  178. @subscription.planCode = @Settings.defaultPlanCode
  179. @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null, @subscription)
  180. @SubscriptionLocator.getGroupSubscriptionMemberOf.callsArgWith(1, null, @groupSubscription)
  181. @Modules.hooks.fire = sinon.stub().callsArgWith(2, null, null)
  182. @SubscriptionUpdater._setUsersMinimumFeatures @adminuser_id, (err)=>
  183. args = @UserFeaturesUpdater.updateFeatures.args[0]
  184. assert.equal args[0], @adminUser._id
  185. assert.equal args[1], @groupSubscription.planCode
  186. done()
  187. it "should call updateFeatures with default if there are no subscriptions for user", (done)->
  188. @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null)
  189. @SubscriptionLocator.getGroupSubscriptionMemberOf.callsArgWith(1, null)
  190. @Modules.hooks.fire = sinon.stub().callsArgWith(2, null, null)
  191. @SubscriptionUpdater._setUsersMinimumFeatures @adminuser_id, (err)=>
  192. args = @UserFeaturesUpdater.updateFeatures.args[0]
  193. assert.equal args[0], @adminUser._id
  194. assert.equal args[1], @Settings.defaultPlanCode
  195. done()
  196. it "should call assignBonus", (done)->
  197. @SubscriptionLocator.getUsersSubscription.callsArgWith(1, null)
  198. @SubscriptionLocator.getGroupSubscriptionMemberOf.callsArgWith(1, null)
  199. @SubscriptionUpdater._setUsersMinimumFeatures @adminuser_id, (err)=>
  200. @ReferalAllocator.assignBonus.calledWith(@adminuser_id).should.equal true
  201. done()
  202. describe "deleteSubscription", ->
  203. beforeEach (done) ->
  204. @subscription_id = ObjectId().toString()
  205. @subscription = {
  206. "mock": "subscription",
  207. admin_id: ObjectId(),
  208. member_ids: [ ObjectId(), ObjectId(), ObjectId() ]
  209. }
  210. @SubscriptionLocator.getSubscription = sinon.stub().yields(null, @subscription)
  211. @SubscriptionUpdater._setUsersMinimumFeatures = sinon.stub().yields()
  212. @SubscriptionUpdater.deleteSubscription @subscription_id, done
  213. it "should look up the subscription", ->
  214. @SubscriptionLocator.getSubscription
  215. .calledWith(@subscription_id)
  216. .should.equal true
  217. it "should remove the subscription", ->
  218. @SubscriptionModel.remove
  219. .calledWith({_id: ObjectId(@subscription_id)})
  220. .should.equal true
  221. it "should downgrade the admin_id", ->
  222. @SubscriptionUpdater._setUsersMinimumFeatures
  223. .calledWith(@subscription.admin_id)
  224. .should.equal true
  225. it "should downgrade all of the members", ->
  226. for user_id in @subscription.member_ids
  227. @SubscriptionUpdater._setUsersMinimumFeatures
  228. .calledWith(user_id)
  229. .should.equal true
  230. describe 'refreshSubscription', ->
  231. beforeEach ->
  232. @SubscriptionUpdater._setUsersMinimumFeatures = sinon.stub()
  233. .callsArgWith(1, null)
  234. it 'should call to _setUsersMinimumFeatures', ->
  235. @SubscriptionUpdater.refreshSubscription(@adminUser._id, ()->)
  236. @SubscriptionUpdater._setUsersMinimumFeatures.callCount.should.equal 1
  237. @SubscriptionUpdater._setUsersMinimumFeatures.calledWith(@adminUser._id).should.equal true