NotificationsController.test.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. import { beforeEach, describe, expect, it, vi } from 'vitest'
  2. import NotificationsController from '../../../app/js/NotificationsController.ts'
  3. import Notifications from '../../../app/js/Notifications.js'
  4. import { ObjectId } from 'mongodb-legacy'
  5. const modulePath = '../../../app/js/NotificationsController.js'
  6. const userId = '51dc93e6fb625a261300003b'
  7. const notificationId = '51dc93e6fb625a261300003c'
  8. const notificationKey = 'my-notification-key'
  9. vi.mock('../../../app/js/Notifications', () => ({
  10. default: {
  11. addNotification: vi.fn(),
  12. getUserNotifications: vi.fn(),
  13. removeNotificationByKeyOnly: vi.fn(),
  14. removeNotificationId: vi.fn(),
  15. removeNotificationKey: vi.fn(),
  16. },
  17. }))
  18. interface InputNotification {
  19. user_id: string
  20. key: string
  21. messageOpts?: object
  22. templateKey?: string
  23. }
  24. interface DatabaseNotification {
  25. _id: ObjectId
  26. user_id: ObjectId
  27. key: string
  28. messageOpts?: object
  29. templateKey?: string
  30. }
  31. function convertInputNotificationToDatabaseNotification(
  32. inputNotification: InputNotification
  33. ): DatabaseNotification {
  34. return {
  35. ...inputNotification,
  36. _id: new ObjectId(),
  37. user_id: new ObjectId(inputNotification.user_id),
  38. }
  39. }
  40. describe('Notifications Controller', () => {
  41. let controller: typeof NotificationsController,
  42. stubbedNotification: Array<InputNotification>
  43. beforeEach(async () => {
  44. vi.doMock('@overleaf/metrics', () => ({
  45. default: {
  46. inc: vi.fn(),
  47. mongodb: {
  48. monitor: vi.fn(),
  49. },
  50. },
  51. }))
  52. controller = (await import(modulePath)).default
  53. stubbedNotification = [
  54. {
  55. user_id: new ObjectId().toString(),
  56. key: notificationKey,
  57. messageOpts: { info: 'some info' },
  58. templateKey: 'template-key',
  59. },
  60. ]
  61. })
  62. describe('getUserNotifications', () => {
  63. it('should ask the notifications for the users notifications', async () => {
  64. const databaseNotifications = stubbedNotification.map(
  65. convertInputNotificationToDatabaseNotification
  66. )
  67. vi.mocked(Notifications.getUserNotifications).mockResolvedValue(
  68. databaseNotifications
  69. )
  70. const req = {
  71. params: {
  72. user_id: userId,
  73. },
  74. }
  75. await new Promise<void>(resolve => {
  76. controller.getUserNotifications(req, {
  77. json: result => {
  78. expect(result).toBe(databaseNotifications)
  79. expect(Notifications.getUserNotifications).toHaveBeenCalledWith(
  80. userId
  81. )
  82. resolve()
  83. },
  84. })
  85. })
  86. })
  87. })
  88. describe('addNotification', () => {
  89. it('should tell the notifications to add the notification for the user', async () => {
  90. vi.mocked(Notifications.addNotification).mockResolvedValue({
  91. acknowledged: true,
  92. upsertedId: new ObjectId(),
  93. matchedCount: 1,
  94. modifiedCount: 1,
  95. upsertedCount: 0,
  96. })
  97. const req = {
  98. params: {
  99. user_id: userId,
  100. },
  101. body: stubbedNotification[0],
  102. }
  103. await new Promise<void>(resolve => {
  104. controller.addNotification(req, {
  105. sendStatus: code => {
  106. expect(Notifications.addNotification).toHaveBeenCalledWith(
  107. userId,
  108. stubbedNotification[0]
  109. )
  110. expect(code).toBe(200)
  111. resolve()
  112. },
  113. })
  114. })
  115. })
  116. })
  117. describe('removeNotificationId', () => {
  118. it('should tell the notifications to mark the notification Id as read', async () => {
  119. vi.mocked(Notifications.removeNotificationId).mockResolvedValue({
  120. acknowledged: true,
  121. upsertedId: null,
  122. upsertedCount: 0,
  123. matchedCount: 1,
  124. modifiedCount: 1,
  125. })
  126. const req = {
  127. params: {
  128. user_id: userId,
  129. notification_id: notificationId,
  130. },
  131. }
  132. await new Promise<void>(resolve => {
  133. controller.removeNotificationId(req, {
  134. sendStatus: code => {
  135. expect(Notifications.removeNotificationId).toHaveBeenCalledWith(
  136. userId,
  137. notificationId
  138. )
  139. expect(code).toBe(200)
  140. resolve()
  141. },
  142. })
  143. })
  144. })
  145. })
  146. describe('removeNotificationKey', () => {
  147. it('should tell the notifications to mark the notification Key as read', async () => {
  148. vi.mocked(Notifications.removeNotificationKey).mockResolvedValue({
  149. acknowledged: true,
  150. upsertedId: null,
  151. upsertedCount: 0,
  152. matchedCount: 1,
  153. modifiedCount: 1,
  154. })
  155. const req = {
  156. params: {
  157. user_id: userId,
  158. },
  159. body: { key: notificationKey },
  160. }
  161. await new Promise<void>(resolve => {
  162. controller.removeNotificationKey(req, {
  163. sendStatus: code => {
  164. expect(Notifications.removeNotificationKey).toHaveBeenCalledWith(
  165. userId,
  166. notificationKey
  167. )
  168. expect(code).toBe(200)
  169. resolve()
  170. },
  171. })
  172. })
  173. })
  174. })
  175. describe('removeNotificationByKeyOnly', () => {
  176. it('should tell the notifications to mark the notification Key as read', async () => {
  177. vi.mocked(Notifications.removeNotificationByKeyOnly).mockResolvedValue({
  178. acknowledged: true,
  179. upsertedId: null,
  180. upsertedCount: 0,
  181. matchedCount: 1,
  182. modifiedCount: 1,
  183. })
  184. const req = {
  185. params: {
  186. key: notificationKey,
  187. },
  188. }
  189. await new Promise<void>(resolve =>
  190. controller.removeNotificationByKeyOnly(req, {
  191. sendStatus: code => {
  192. expect(
  193. Notifications.removeNotificationByKeyOnly
  194. ).toHaveBeenCalledWith(notificationKey)
  195. expect(code).toBe(200)
  196. resolve()
  197. },
  198. })
  199. )
  200. })
  201. })
  202. })