UserMembershipHandlerTests.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. const { expect } = require('chai')
  2. const sinon = require('sinon')
  3. const assertCalledWith = sinon.assert.calledWith
  4. const { ObjectId } = require('mongodb-legacy')
  5. const modulePath =
  6. '../../../../app/src/Features/UserMembership/UserMembershipHandler'
  7. const SandboxedModule = require('sandboxed-module')
  8. const EntityConfigs = require('../../../../app/src/Features/UserMembership/UserMembershipEntityConfigs')
  9. const {
  10. UserIsManagerError,
  11. UserNotFoundError,
  12. UserAlreadyAddedError,
  13. } = require('../../../../app/src/Features/UserMembership/UserMembershipErrors')
  14. describe('UserMembershipHandler', function () {
  15. beforeEach(function () {
  16. this.user = { _id: new ObjectId() }
  17. this.newUser = { _id: new ObjectId(), email: 'new-user-email@foo.bar' }
  18. this.fakeEntityId = new ObjectId()
  19. this.subscription = {
  20. _id: 'mock-subscription-id',
  21. groupPlan: true,
  22. membersLimit: 10,
  23. member_ids: [new ObjectId(), new ObjectId()],
  24. manager_ids: [new ObjectId()],
  25. invited_emails: ['mock-email-1@foo.com'],
  26. teamInvites: [{ email: 'mock-email-1@bar.com' }],
  27. update: sinon.stub().returns({
  28. exec: sinon.stub().resolves(),
  29. }),
  30. }
  31. this.institution = {
  32. _id: 'mock-institution-id',
  33. v1Id: 123,
  34. managerIds: [new ObjectId(), new ObjectId(), new ObjectId()],
  35. updateOne: sinon.stub().returns({
  36. exec: sinon.stub().resolves(),
  37. }),
  38. }
  39. this.publisher = {
  40. _id: 'mock-publisher-id',
  41. slug: 'slug',
  42. managerIds: [new ObjectId(), new ObjectId()],
  43. updateOne: sinon.stub().returns({
  44. exec: sinon.stub().resolves(),
  45. }),
  46. }
  47. this.UserMembershipViewModel = {
  48. promises: {
  49. buildAsync: sinon.stub().resolves({ _id: 'mock-member-id' }),
  50. },
  51. build: sinon.stub().returns(this.newUser),
  52. }
  53. this.UserGetter = {
  54. promises: {
  55. getUserByAnyEmail: sinon.stub().resolves(this.newUser),
  56. },
  57. }
  58. this.Institution = {
  59. findOne: sinon.stub().returns({
  60. exec: sinon.stub().resolves(this.institution),
  61. }),
  62. }
  63. this.Subscription = {
  64. findOne: sinon.stub().returns({
  65. exec: sinon.stub().resolves(this.subscription),
  66. }),
  67. }
  68. this.Publisher = {
  69. findOne: sinon.stub().returns({
  70. exec: sinon.stub().resolves(this.publisher),
  71. }),
  72. create: sinon.stub().returns({
  73. exec: sinon.stub().resolves(this.publisher),
  74. }),
  75. }
  76. this.UserMembershipHandler = SandboxedModule.require(modulePath, {
  77. requires: {
  78. 'mongodb-legacy': { ObjectId },
  79. './UserMembershipErrors': {
  80. UserIsManagerError,
  81. UserNotFoundError,
  82. UserAlreadyAddedError,
  83. },
  84. './UserMembershipViewModel': this.UserMembershipViewModel,
  85. '../User/UserGetter': this.UserGetter,
  86. '../../models/Institution': {
  87. Institution: this.Institution,
  88. },
  89. '../../models/Subscription': {
  90. Subscription: this.Subscription,
  91. },
  92. '../../models/Publisher': {
  93. Publisher: this.Publisher,
  94. },
  95. },
  96. })
  97. })
  98. describe('getEntityWithoutAuthorizationCheck', function () {
  99. it('get publisher', async function () {
  100. const subscription =
  101. await this.UserMembershipHandler.promises.getEntityWithoutAuthorizationCheck(
  102. this.fakeEntityId,
  103. EntityConfigs.publisher
  104. )
  105. const expectedQuery = { slug: this.fakeEntityId }
  106. assertCalledWith(this.Publisher.findOne, expectedQuery)
  107. expect(subscription).to.equal(this.publisher)
  108. })
  109. })
  110. describe('getUsers', function () {
  111. describe('group', function () {
  112. it('build view model for all users', async function () {
  113. await this.UserMembershipHandler.promises.getUsers(
  114. this.subscription,
  115. EntityConfigs.group
  116. )
  117. const expectedCallcount =
  118. this.subscription.member_ids.length +
  119. this.subscription.invited_emails.length +
  120. this.subscription.teamInvites.length
  121. expect(
  122. this.UserMembershipViewModel.promises.buildAsync.callCount
  123. ).to.equal(expectedCallcount)
  124. })
  125. })
  126. describe('group mamagers', function () {
  127. it('build view model for all managers', async function () {
  128. await this.UserMembershipHandler.promises.getUsers(
  129. this.subscription,
  130. EntityConfigs.groupManagers
  131. )
  132. const expectedCallcount = this.subscription.manager_ids.length
  133. expect(
  134. this.UserMembershipViewModel.promises.buildAsync.callCount
  135. ).to.equal(expectedCallcount)
  136. })
  137. })
  138. describe('institution', function () {
  139. it('build view model for all managers', async function () {
  140. await this.UserMembershipHandler.promises.getUsers(
  141. this.institution,
  142. EntityConfigs.institution
  143. )
  144. const expectedCallcount = this.institution.managerIds.length
  145. expect(
  146. this.UserMembershipViewModel.promises.buildAsync.callCount
  147. ).to.equal(expectedCallcount)
  148. })
  149. })
  150. })
  151. describe('createEntity', function () {
  152. it('creates publisher', async function () {
  153. await this.UserMembershipHandler.promises.createEntity(
  154. this.fakeEntityId,
  155. EntityConfigs.publisher
  156. )
  157. assertCalledWith(this.Publisher.create, { slug: this.fakeEntityId })
  158. })
  159. })
  160. describe('addUser', function () {
  161. beforeEach(function () {
  162. this.email = this.newUser.email
  163. })
  164. describe('institution', function () {
  165. it('get user', async function () {
  166. await this.UserMembershipHandler.promises.addUser(
  167. this.institution,
  168. EntityConfigs.institution,
  169. this.email
  170. )
  171. assertCalledWith(this.UserGetter.promises.getUserByAnyEmail, this.email)
  172. })
  173. it('handle user not found', async function () {
  174. this.UserGetter.promises.getUserByAnyEmail.resolves(null)
  175. expect(
  176. this.UserMembershipHandler.promises.addUser(
  177. this.institution,
  178. EntityConfigs.institution,
  179. this.email
  180. )
  181. ).to.be.rejectedWith(UserNotFoundError)
  182. })
  183. it('handle user already added', async function () {
  184. this.institution.managerIds.push(this.newUser._id)
  185. expect(
  186. this.UserMembershipHandler.promises.addUser(
  187. this.institution,
  188. EntityConfigs.institution,
  189. this.email
  190. )
  191. ).to.be.rejectedWith(UserAlreadyAddedError)
  192. })
  193. it('add user to institution', async function () {
  194. await this.UserMembershipHandler.promises.addUser(
  195. this.institution,
  196. EntityConfigs.institution,
  197. this.email
  198. )
  199. assertCalledWith(this.institution.updateOne, {
  200. $addToSet: { managerIds: this.newUser._id },
  201. })
  202. })
  203. it('return user view', async function () {
  204. const user = await this.UserMembershipHandler.promises.addUser(
  205. this.institution,
  206. EntityConfigs.institution,
  207. this.email
  208. )
  209. user.should.equal(this.newUser)
  210. })
  211. })
  212. })
  213. describe('removeUser', function () {
  214. describe('institution', function () {
  215. it('remove user from institution', async function () {
  216. await this.UserMembershipHandler.promises.removeUser(
  217. this.institution,
  218. EntityConfigs.institution,
  219. this.newUser._id
  220. )
  221. assertCalledWith(this.institution.updateOne, {
  222. $pull: { managerIds: this.newUser._id },
  223. })
  224. })
  225. it('handle admin', async function () {
  226. this.subscription.admin_id = this.newUser._id
  227. expect(
  228. this.UserMembershipHandler.promises.removeUser(
  229. this.subscription,
  230. EntityConfigs.groupManagers,
  231. this.newUser._id
  232. )
  233. ).to.be.rejectedWith(UserIsManagerError)
  234. })
  235. })
  236. })
  237. })