MongoHelper.mjs 6.4 KB

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