SubscriptionGroupHandlerTests.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. const SandboxedModule = require('sandboxed-module')
  2. const sinon = require('sinon')
  3. const { expect } = require('chai')
  4. const modulePath =
  5. '../../../../app/src/Features/Subscription/SubscriptionGroupHandler'
  6. describe('SubscriptionGroupHandler', function () {
  7. beforeEach(function () {
  8. this.adminUser_id = '12321'
  9. this.newEmail = 'bob@smith.com'
  10. this.user_id = '3121321'
  11. this.email = 'jim@example.com'
  12. this.user = { _id: this.user_id, email: this.newEmail }
  13. this.subscription_id = '31DSd1123D'
  14. this.subscription = {
  15. admin_id: this.adminUser_id,
  16. manager_ids: [this.adminUser_id],
  17. _id: this.subscription_id,
  18. }
  19. this.SubscriptionLocator = {
  20. getUsersSubscription: sinon.stub(),
  21. getSubscriptionByMemberIdAndId: sinon.stub(),
  22. getSubscription: sinon.stub().callsArgWith(1, null, this.subscription),
  23. }
  24. this.UserCreator = {
  25. getUserOrCreateHoldingAccount: sinon
  26. .stub()
  27. .callsArgWith(1, null, this.user),
  28. }
  29. this.SubscriptionUpdater = {
  30. removeUserFromGroup: sinon.stub().callsArgWith(2),
  31. getSubscription: sinon.stub().callsArgWith(2),
  32. }
  33. this.TeamInvitesHandler = { createInvite: sinon.stub().callsArgWith(2) }
  34. this.UserGetter = {
  35. getUser: sinon.stub(),
  36. getUserByAnyEmail: sinon.stub(),
  37. }
  38. this.LimitationsManager = { hasGroupMembersLimitReached: sinon.stub() }
  39. this.OneTimeTokenHandler = {
  40. getValueFromTokenAndExpire: sinon.stub(),
  41. getNewToken: sinon.stub(),
  42. }
  43. this.EmailHandler = { sendEmail: sinon.stub() }
  44. this.Subscription = {
  45. updateOne: sinon.stub().yields(),
  46. updateMany: sinon.stub().yields(),
  47. findOne: sinon.stub().yields(),
  48. }
  49. this.settings = { siteUrl: 'http://www.overleaf.com' }
  50. this.readStub = sinon.stub()
  51. this.NotificationsBuilder = {
  52. groupPlan: sinon.stub().returns({ read: this.readStub }),
  53. }
  54. this.UserMembershipViewModel = {
  55. build(email) {
  56. return { email }
  57. },
  58. }
  59. this.Handler = SandboxedModule.require(modulePath, {
  60. requires: {
  61. '../User/UserCreator': this.UserCreator,
  62. './SubscriptionUpdater': this.SubscriptionUpdater,
  63. './SubscriptionLocator': this.SubscriptionLocator,
  64. '../../models/Subscription': {
  65. Subscription: this.Subscription,
  66. },
  67. '../User/UserGetter': this.UserGetter,
  68. './LimitationsManager': this.LimitationsManager,
  69. '../Security/OneTimeTokenHandler': this.OneTimeTokenHandler,
  70. '../Email/EmailHandler': this.EmailHandler,
  71. '@overleaf/settings': this.settings,
  72. '../Notifications/NotificationsBuilder': this.NotificationsBuilder,
  73. '../UserMembership/UserMembershipViewModel':
  74. this.UserMembershipViewModel,
  75. },
  76. })
  77. })
  78. describe('removeUserFromGroup', function () {
  79. it('should call the subscription updater to remove the user', function (done) {
  80. this.Handler.removeUserFromGroup(
  81. this.adminUser_id,
  82. this.user._id,
  83. err => {
  84. if (err) return done(err)
  85. this.SubscriptionUpdater.removeUserFromGroup
  86. .calledWith(this.adminUser_id, this.user._id)
  87. .should.equal(true)
  88. done()
  89. }
  90. )
  91. })
  92. })
  93. describe('replaceUserReferencesInGroups', function () {
  94. beforeEach(function (done) {
  95. this.oldId = 'ba5eba11'
  96. this.newId = '5ca1ab1e'
  97. this.Handler.replaceUserReferencesInGroups(this.oldId, this.newId, () =>
  98. done()
  99. )
  100. })
  101. it('replaces the admin_id', function () {
  102. this.Subscription.updateOne
  103. .calledWith({ admin_id: this.oldId }, { admin_id: this.newId })
  104. .should.equal(true)
  105. })
  106. it('replaces the manager_ids', function () {
  107. this.Subscription.updateMany
  108. .calledWith(
  109. { manager_ids: 'ba5eba11' },
  110. { $addToSet: { manager_ids: '5ca1ab1e' } }
  111. )
  112. .should.equal(true)
  113. this.Subscription.updateMany
  114. .calledWith(
  115. { manager_ids: 'ba5eba11' },
  116. { $pull: { manager_ids: 'ba5eba11' } }
  117. )
  118. .should.equal(true)
  119. })
  120. it('replaces the member ids', function () {
  121. this.Subscription.updateMany
  122. .calledWith(
  123. { member_ids: this.oldId },
  124. { $addToSet: { member_ids: this.newId } }
  125. )
  126. .should.equal(true)
  127. this.Subscription.updateMany
  128. .calledWith(
  129. { member_ids: this.oldId },
  130. { $pull: { member_ids: this.oldId } }
  131. )
  132. .should.equal(true)
  133. })
  134. })
  135. describe('isUserPartOfGroup', function () {
  136. beforeEach(function () {
  137. this.subscription_id = '123ed13123'
  138. })
  139. it('should return true when user is part of subscription', function (done) {
  140. this.SubscriptionLocator.getSubscriptionByMemberIdAndId.callsArgWith(
  141. 2,
  142. null,
  143. { _id: this.subscription_id }
  144. )
  145. this.Handler.isUserPartOfGroup(
  146. this.user_id,
  147. this.subscription_id,
  148. (err, partOfGroup) => {
  149. if (err) return done(err)
  150. partOfGroup.should.equal(true)
  151. done()
  152. }
  153. )
  154. })
  155. it('should return false when no subscription is found', function (done) {
  156. this.SubscriptionLocator.getSubscriptionByMemberIdAndId.callsArgWith(
  157. 2,
  158. null
  159. )
  160. this.Handler.isUserPartOfGroup(
  161. this.user_id,
  162. this.subscription_id,
  163. (err, partOfGroup) => {
  164. if (err) return done(err)
  165. partOfGroup.should.equal(false)
  166. done()
  167. }
  168. )
  169. })
  170. })
  171. describe('getTotalConfirmedUsersInGroup', function () {
  172. describe('for existing subscriptions', function () {
  173. beforeEach(function () {
  174. this.subscription.member_ids = ['12321', '3121321']
  175. })
  176. it('should call the subscription locator and return 2 users', function (done) {
  177. this.Handler.getTotalConfirmedUsersInGroup(
  178. this.subscription_id,
  179. (err, count) => {
  180. if (err) return done(err)
  181. this.SubscriptionLocator.getSubscription
  182. .calledWith(this.subscription_id)
  183. .should.equal(true)
  184. count.should.equal(2)
  185. done()
  186. }
  187. )
  188. })
  189. })
  190. describe('for nonexistent subscriptions', function () {
  191. it('should return undefined', function (done) {
  192. this.Handler.getTotalConfirmedUsersInGroup('fake-id', (err, count) => {
  193. if (err) return done(err)
  194. expect(count).not.to.exist
  195. done()
  196. })
  197. })
  198. })
  199. })
  200. })