MongoHelper.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. const { expect } = require('chai')
  2. const { ObjectId: NativeObjectId } = require('mongodb')
  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(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({ _id: NativeObjectId(userIdAsString) })
  66. expect(user).to.exist
  67. expect(user._id).to.exist
  68. expect(user.email).to.equal(userEmail)
  69. })
  70. it('should have a native ObjectId', function () {
  71. expect(user._id).to.be.instanceof(NativeObjectId)
  72. })
  73. it('should work with the users _id field', async function () {
  74. await expectToWork(user._id)
  75. })
  76. })
  77. })
  78. describe('normalizeMultiQuery', function () {
  79. let ghost
  80. beforeEach(async function addGhost() {
  81. // add a user which is not part of the initial three users
  82. ghost = new User()
  83. ghost.emails[0].email = ghost.email = 'ghost@ghost.com'
  84. await ghost.ensureUserExists()
  85. })
  86. async function expectToFindTheThreeUsers(query) {
  87. const users = await db.users.find(query).toArray()
  88. expect(users).to.have.length(3)
  89. expect(users.map(user => user._id.toString()).sort()).to.deep.equal(
  90. userIds.sort()
  91. )
  92. }
  93. describe('with an array as query', function () {
  94. function expectInQueryWithNativeObjectIds(query) {
  95. expect(query).to.exist
  96. expect(query._id).to.exist
  97. expect(query._id.$in).to.exist
  98. expect(
  99. query._id.$in.map(id => id instanceof NativeObjectId)
  100. ).to.deep.equal([true, true, true])
  101. }
  102. it('should transform all strings to native ObjectIds', function () {
  103. const query = normalizeMultiQuery(userIds)
  104. expectInQueryWithNativeObjectIds(query)
  105. })
  106. it('should transform all Mongoose ObjectIds to native ObjectIds', function () {
  107. const query = normalizeMultiQuery(userIds.map(MongooseObjectId))
  108. expectInQueryWithNativeObjectIds(query)
  109. })
  110. it('should leave all native Objects as native ObjectIds', function () {
  111. const query = normalizeMultiQuery(userIds.map(NativeObjectId))
  112. expectInQueryWithNativeObjectIds(query)
  113. })
  114. it('should find the three users from string ids', async function () {
  115. const query = normalizeMultiQuery(userIds)
  116. await expectToFindTheThreeUsers(query)
  117. })
  118. it('should find the three users from Mongoose ObjectIds', async function () {
  119. const query = normalizeMultiQuery(userIds.map(MongooseObjectId))
  120. await expectToFindTheThreeUsers(query)
  121. })
  122. it('should find the three users from native ObjectIds', async function () {
  123. const query = normalizeMultiQuery(userIds.map(NativeObjectId))
  124. await expectToFindTheThreeUsers(query)
  125. })
  126. })
  127. describe('with an object as query', function () {
  128. beforeEach(async function addHiddenFlag() {
  129. // add a mongo field that does not exist on the other users
  130. await ghost.mongoUpdate({ $set: { hidden: 1 } })
  131. })
  132. it('should pass through the query', function () {
  133. const inputQuery = { complex: 1 }
  134. const query = normalizeMultiQuery(inputQuery)
  135. expect(inputQuery).to.equal(query)
  136. })
  137. describe('when searching for hidden users', function () {
  138. it('should match the ghost only', async function () {
  139. const query = normalizeMultiQuery({ hidden: 1 })
  140. const users = await db.users.find(query).toArray()
  141. expect(users).to.have.length(1)
  142. expect(users[0]._id.toString()).to.equal(ghost.id)
  143. })
  144. })
  145. describe('when searching for non hidden users', function () {
  146. it('should find the three users', async function () {
  147. const query = normalizeMultiQuery({ hidden: { $exists: false } })
  148. await expectToFindTheThreeUsers(query)
  149. })
  150. })
  151. })
  152. })
  153. })