MongoHelper.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. const { expect } = require('chai')
  2. const { ObjectId: NativeObjectId } = require('mongodb-legacy')
  3. const { ObjectId: MongooseObjectId } = require('mongoose').mongo
  4. const { User: UserModel } = require('../../../app/src/models/User')
  5. const { db } = require('../../../app/src/infrastructure/mongodb')
  6. const {
  7. normalizeQuery,
  8. normalizeMultiQuery,
  9. } = require('../../../app/src/Features/Helpers/Mongo')
  10. const User = require('./helpers/User').promises
  11. describe('MongoTests', function () {
  12. let userIdAsString, userEmail, userIds
  13. beforeEach(async function setUpUsers() {
  14. // the first user in the db should not match the target user
  15. const otherUser = new User()
  16. await otherUser.ensureUserExists()
  17. const user = new User()
  18. await user.ensureUserExists()
  19. userIdAsString = user.id
  20. userEmail = user.email
  21. // the last user in the db should not match the target user
  22. const yetAnotherUser = new User()
  23. await yetAnotherUser.ensureUserExists()
  24. userIds = [otherUser.id, user.id, yetAnotherUser.id]
  25. })
  26. describe('normalizeQuery', function () {
  27. async function expectToWork(blob) {
  28. const query = normalizeQuery(blob)
  29. expect(query).to.exist
  30. expect(query._id).to.be.instanceof(NativeObjectId)
  31. expect(query._id).to.deep.equal(new NativeObjectId(userIdAsString))
  32. const user = await db.users.findOne(query)
  33. expect(user).to.exist
  34. expect(user.email).to.equal(userEmail)
  35. }
  36. it('should work with the user id as string', async function () {
  37. await expectToWork(userIdAsString)
  38. })
  39. it('should work with the user id in an object', async function () {
  40. await expectToWork({ _id: userIdAsString })
  41. })
  42. it('should pass back the object with id', function () {
  43. const inputQuery = { _id: userIdAsString, other: 1 }
  44. const query = normalizeMultiQuery(inputQuery)
  45. expect(inputQuery).to.equal(query)
  46. })
  47. describe('with an ObjectId from mongoose', function () {
  48. let user
  49. beforeEach(async function getUser() {
  50. user = await UserModel.findById(userIdAsString).exec()
  51. expect(user).to.exist
  52. expect(user._id).to.exist
  53. expect(user.email).to.equal(userEmail)
  54. })
  55. it('should have a mongoose ObjectId', function () {
  56. expect(user._id).to.be.instanceof(MongooseObjectId)
  57. })
  58. it('should work with the users _id field', async function () {
  59. await expectToWork(user._id)
  60. })
  61. })
  62. describe('with an ObjectId from the native driver', function () {
  63. let user
  64. beforeEach(async function getUser() {
  65. user = await db.users.findOne({
  66. _id: new NativeObjectId(userIdAsString),
  67. })
  68. expect(user).to.exist
  69. expect(user._id).to.exist
  70. expect(user.email).to.equal(userEmail)
  71. })
  72. it('should have a native ObjectId', function () {
  73. expect(user._id).to.be.instanceof(NativeObjectId)
  74. })
  75. it('should work with the users _id field', async function () {
  76. await expectToWork(user._id)
  77. })
  78. })
  79. })
  80. describe('normalizeMultiQuery', function () {
  81. let ghost
  82. beforeEach(async function addGhost() {
  83. // add a user which is not part of the initial three users
  84. ghost = new User()
  85. ghost.emails[0].email = ghost.email = 'ghost@ghost.com'
  86. await ghost.ensureUserExists()
  87. })
  88. async function expectToFindTheThreeUsers(query) {
  89. const users = await db.users.find(query).toArray()
  90. expect(users).to.have.length(3)
  91. expect(users.map(user => user._id.toString()).sort()).to.deep.equal(
  92. userIds.sort()
  93. )
  94. }
  95. describe('with an array as query', function () {
  96. function expectInQueryWithNativeObjectIds(query) {
  97. expect(query).to.exist
  98. expect(query._id).to.exist
  99. expect(query._id.$in).to.exist
  100. expect(
  101. query._id.$in.map(id => id instanceof NativeObjectId)
  102. ).to.deep.equal([true, true, true])
  103. }
  104. it('should transform all strings to native ObjectIds', function () {
  105. const query = normalizeMultiQuery(userIds)
  106. expectInQueryWithNativeObjectIds(query)
  107. })
  108. it('should transform all Mongoose ObjectIds to native ObjectIds', function () {
  109. const query = normalizeMultiQuery(
  110. userIds.map(userId => new NativeObjectId(userId))
  111. )
  112. expectInQueryWithNativeObjectIds(query)
  113. })
  114. it('should leave all native Objects as native ObjectIds', function () {
  115. const query = normalizeMultiQuery(
  116. userIds.map(userId => new NativeObjectId(userId))
  117. )
  118. expectInQueryWithNativeObjectIds(query)
  119. })
  120. it('should find the three users from string ids', async function () {
  121. const query = normalizeMultiQuery(userIds)
  122. await expectToFindTheThreeUsers(query)
  123. })
  124. it('should find the three users from Mongoose ObjectIds', async function () {
  125. const query = normalizeMultiQuery(
  126. userIds.map(userId => new NativeObjectId(userId))
  127. )
  128. await expectToFindTheThreeUsers(query)
  129. })
  130. it('should find the three users from native ObjectIds', async function () {
  131. const query = normalizeMultiQuery(
  132. userIds.map(userId => new NativeObjectId(userId))
  133. )
  134. await expectToFindTheThreeUsers(query)
  135. })
  136. })
  137. describe('with an object as query', function () {
  138. beforeEach(async function addHiddenFlag() {
  139. // add a mongo field that does not exist on the other users
  140. await ghost.mongoUpdate({ $set: { hidden: 1 } })
  141. })
  142. it('should pass through the query', function () {
  143. const inputQuery = { complex: 1 }
  144. const query = normalizeMultiQuery(inputQuery)
  145. expect(inputQuery).to.equal(query)
  146. })
  147. describe('when searching for hidden users', function () {
  148. it('should match the ghost only', async function () {
  149. const query = normalizeMultiQuery({ hidden: 1 })
  150. const users = await db.users.find(query).toArray()
  151. expect(users).to.have.length(1)
  152. expect(users[0]._id.toString()).to.equal(ghost.id)
  153. })
  154. })
  155. describe('when searching for non hidden users', function () {
  156. it('should find the three users', async function () {
  157. const query = normalizeMultiQuery({ hidden: { $exists: false } })
  158. await expectToFindTheThreeUsers(query)
  159. })
  160. })
  161. })
  162. })
  163. })