UserGetterTests.coffee 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. should = require('chai').should()
  2. SandboxedModule = require('sandboxed-module')
  3. assert = require('assert')
  4. path = require('path')
  5. sinon = require('sinon')
  6. modulePath = path.join __dirname, "../../../../app/js/Features/User/UserGetter"
  7. expect = require("chai").expect
  8. Errors = require "../../../../app/js/Features/Errors/Errors"
  9. describe "UserGetter", ->
  10. beforeEach ->
  11. @fakeUser =
  12. _id: '12390i'
  13. email: 'email2@foo.bar'
  14. emails: [
  15. { email: 'email1@foo.bar', reversedHostname: 'rab.oof' }
  16. { email: 'email2@foo.bar', reversedHostname: 'rab.oof' }
  17. ]
  18. @findOne = sinon.stub().callsArgWith(2, null, @fakeUser)
  19. @find = sinon.stub().callsArgWith(2, null, [ @fakeUser ])
  20. @Mongo =
  21. db: users:
  22. findOne: @findOne
  23. find: @find
  24. ObjectId: (id) -> return id
  25. settings = apis: { v1: { url: 'v1.url', user: '', pass: '' } }
  26. @getUserAffiliations = sinon.stub().callsArgWith(1, null, [])
  27. @UserGetter = SandboxedModule.require modulePath, requires:
  28. "logger-sharelatex": log:->
  29. "../../infrastructure/mongojs": @Mongo
  30. "metrics-sharelatex": timeAsyncMethod: sinon.stub()
  31. 'settings-sharelatex': settings
  32. '../Institutions/InstitutionsAPI':
  33. getUserAffiliations: @getUserAffiliations
  34. "../Errors/Errors": Errors
  35. describe "getUser", ->
  36. it "should get user", (done)->
  37. query = _id: 'foo'
  38. projection = email: 1
  39. @UserGetter.getUser query, projection, (error, user) =>
  40. @findOne.called.should.equal true
  41. @findOne.calledWith(query, projection).should.equal true
  42. user.should.deep.equal @fakeUser
  43. done()
  44. it "should not allow email in query", (done)->
  45. @UserGetter.getUser email: 'foo@bar.com', {}, (error, user) =>
  46. error.should.exist
  47. done()
  48. it "should not allow null query", (done)->
  49. @UserGetter.getUser null, {}, (error, user) =>
  50. error.should.exist
  51. done()
  52. describe "getUserFullEmails", ->
  53. it "should get user", (done)->
  54. @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @fakeUser)
  55. projection = email: 1, emails: 1
  56. @UserGetter.getUserFullEmails @fakeUser._id, (error, fullEmails) =>
  57. @UserGetter.getUser.called.should.equal true
  58. @UserGetter.getUser.calledWith(@fakeUser._id, projection).should.equal true
  59. done()
  60. it "should fetch emails data", (done)->
  61. @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @fakeUser)
  62. @UserGetter.getUserFullEmails @fakeUser._id, (error, fullEmails) =>
  63. assert.deepEqual fullEmails, [
  64. { email: 'email1@foo.bar', reversedHostname: 'rab.oof', default: false }
  65. { email: 'email2@foo.bar', reversedHostname: 'rab.oof', default: true }
  66. ]
  67. done()
  68. it "should merge affiliation data", (done)->
  69. @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @fakeUser)
  70. affiliationsData = [
  71. {
  72. email: 'email1@foo.bar'
  73. role: 'Prof'
  74. department: 'Maths'
  75. inferred: false
  76. institution: { name: 'University Name', isUniversity: true }
  77. }
  78. ]
  79. @getUserAffiliations.callsArgWith(1, null, affiliationsData)
  80. @UserGetter.getUserFullEmails @fakeUser._id, (error, fullEmails) =>
  81. assert.deepEqual fullEmails, [
  82. {
  83. email: 'email1@foo.bar',
  84. reversedHostname: 'rab.oof'
  85. default: false
  86. affiliation:
  87. institution: affiliationsData[0].institution
  88. inferred: affiliationsData[0].inferred
  89. department: affiliationsData[0].department
  90. role: affiliationsData[0].role
  91. }
  92. { email: 'email2@foo.bar', reversedHostname: 'rab.oof', default: true }
  93. ]
  94. done()
  95. it "should get user when it has no emails field", (done)->
  96. @fakeUser =
  97. _id: '12390i'
  98. email: 'email2@foo.bar'
  99. @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @fakeUser)
  100. projection = email: 1, emails: 1
  101. @UserGetter.getUserFullEmails @fakeUser._id, (error, fullEmails) =>
  102. @UserGetter.getUser.called.should.equal true
  103. @UserGetter.getUser.calledWith(@fakeUser._id, projection).should.equal true
  104. assert.deepEqual fullEmails, []
  105. done()
  106. describe "getUserbyMainEmail", ->
  107. it "query user by main email", (done)->
  108. email = 'hello@world.com'
  109. projection = emails: 1
  110. @UserGetter.getUserByMainEmail email, projection, (error, user) =>
  111. @findOne.called.should.equal true
  112. @findOne.calledWith(email: email, projection).should.equal true
  113. done()
  114. it "return user if found", (done)->
  115. email = 'hello@world.com'
  116. @UserGetter.getUserByMainEmail email, (error, user) =>
  117. user.should.deep.equal @fakeUser
  118. done()
  119. it "trim email", (done)->
  120. email = 'hello@world.com'
  121. @UserGetter.getUserByMainEmail " #{email} ", (error, user) =>
  122. @findOne.called.should.equal true
  123. @findOne.calledWith(email: email).should.equal true
  124. done()
  125. describe "getUserByAnyEmail", ->
  126. it "query user for any email", (done)->
  127. email = 'hello@world.com'
  128. expectedQuery =
  129. emails: { $exists: true }
  130. 'emails.email': email
  131. projection = emails: 1
  132. @UserGetter.getUserByAnyEmail " #{email} ", projection, (error, user) =>
  133. @findOne.calledWith(expectedQuery, projection).should.equal true
  134. user.should.deep.equal @fakeUser
  135. done()
  136. it "query contains $exists:true so partial index is used", (done)->
  137. expectedQuery =
  138. emails: { $exists: true }
  139. 'emails.email': ''
  140. @UserGetter.getUserByAnyEmail '', {}, (error, user) =>
  141. @findOne.calledWith(expectedQuery, {}).should.equal true
  142. done()
  143. it "checks main email as well", (done)->
  144. @findOne.callsArgWith(2, null, null)
  145. email = 'hello@world.com'
  146. projection = emails: 1
  147. @UserGetter.getUserByAnyEmail " #{email} ", projection, (error, user) =>
  148. @findOne.calledTwice.should.equal true
  149. @findOne.calledWith(email: email, projection).should.equal true
  150. done()
  151. describe "getUsersByHostname", ->
  152. it "should find user by hostname", (done)->
  153. hostname = "bar.foo"
  154. expectedQuery =
  155. emails: {$exists: true },
  156. 'emails.reversedHostname': hostname.split('').reverse().join('')
  157. projection = emails: 1
  158. @UserGetter.getUsersByHostname hostname, projection, (error, users) =>
  159. @find.calledOnce.should.equal true
  160. @find.calledWith(expectedQuery, projection).should.equal true
  161. done()
  162. describe 'ensureUniqueEmailAddress', ->
  163. beforeEach ->
  164. @UserGetter.getUserByAnyEmail = sinon.stub()
  165. it 'should return error if existing user is found', (done)->
  166. @UserGetter.getUserByAnyEmail.callsArgWith(1, null, @fakeUser)
  167. @UserGetter.ensureUniqueEmailAddress @newEmail, (err)=>
  168. should.exist(err)
  169. expect(err).to.be.an.instanceof(Errors.EmailExistsError)
  170. err.message.should.equal 'alread_exists'
  171. done()
  172. it 'should return null if no user is found', (done)->
  173. @UserGetter.getUserByAnyEmail.callsArgWith(1)
  174. @UserGetter.ensureUniqueEmailAddress @newEmail, (err)=>
  175. should.not.exist(err)
  176. done()