NotificationsHandler.test.mjs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import { vi, assert } from 'vitest'
  2. import sinon from 'sinon'
  3. import path from 'node:path'
  4. const modulePath = path.join(
  5. import.meta.dirname,
  6. '../../../../app/src/Features/Notifications/NotificationsHandler.mjs'
  7. )
  8. describe('NotificationsHandler', function () {
  9. const userId = '123nd3ijdks'
  10. const notificationId = '123njdskj9jlk'
  11. const notificationUrl = 'notification.overleaf.testing'
  12. beforeEach(async function (ctx) {
  13. ctx.request = sinon.stub().callsArgWith(1)
  14. vi.doMock('@overleaf/settings', () => ({
  15. default: {
  16. apis: { notifications: { url: notificationUrl } },
  17. },
  18. }))
  19. vi.doMock('request', () => ({
  20. default: ctx.request,
  21. }))
  22. ctx.handler = (await import(modulePath)).default
  23. })
  24. describe('getUserNotifications', function () {
  25. it('should get unread notifications', async function (ctx) {
  26. const stubbedNotifications = [{ _id: notificationId, user_id: userId }]
  27. ctx.request.callsArgWith(
  28. 1,
  29. null,
  30. { statusCode: 200 },
  31. stubbedNotifications
  32. )
  33. const unreadNotifications =
  34. await ctx.handler.promises.getUserNotifications(userId)
  35. stubbedNotifications.should.deep.equal(unreadNotifications)
  36. const getOpts = {
  37. uri: `${notificationUrl}/user/${userId}`,
  38. json: true,
  39. timeout: 1000,
  40. method: 'GET',
  41. }
  42. ctx.request.calledWith(getOpts).should.equal(true)
  43. })
  44. it('should return empty arrays if there are no notifications', async function (ctx) {
  45. ctx.request.callsArgWith(1, null, { statusCode: 200 }, null)
  46. const unreadNotifications =
  47. await ctx.handler.promises.getUserNotifications(userId)
  48. unreadNotifications.length.should.equal(0)
  49. })
  50. })
  51. describe('markAsRead', function () {
  52. beforeEach(function (ctx) {
  53. ctx.key = 'some key here'
  54. })
  55. it('should send a delete request when a delete has been received to mark a notification', async function (ctx) {
  56. await ctx.handler.promises.markAsReadWithKey(userId, ctx.key)
  57. const opts = {
  58. uri: `${notificationUrl}/user/${userId}`,
  59. json: {
  60. key: ctx.key,
  61. },
  62. timeout: 1000,
  63. method: 'DELETE',
  64. }
  65. ctx.request.calledWith(opts).should.equal(true)
  66. })
  67. })
  68. describe('createNotification', function () {
  69. beforeEach(function (ctx) {
  70. ctx.key = 'some key here'
  71. ctx.messageOpts = { value: 12344 }
  72. ctx.templateKey = 'renderThisHtml'
  73. ctx.expiry = null
  74. })
  75. it('should post the message over', async function (ctx) {
  76. await ctx.handler.promises.createNotification(
  77. userId,
  78. ctx.key,
  79. ctx.templateKey,
  80. ctx.messageOpts,
  81. ctx.expiry
  82. )
  83. const args = ctx.request.args[0][0]
  84. args.uri.should.equal(`${notificationUrl}/user/${userId}`)
  85. args.timeout.should.equal(1000)
  86. const expectedJson = {
  87. key: ctx.key,
  88. templateKey: ctx.templateKey,
  89. messageOpts: ctx.messageOpts,
  90. forceCreate: true,
  91. }
  92. assert.deepEqual(args.json, expectedJson)
  93. })
  94. describe('when expiry date is supplied', function () {
  95. beforeEach(function (ctx) {
  96. ctx.key = 'some key here'
  97. ctx.messageOpts = { value: 12344 }
  98. ctx.templateKey = 'renderThisHtml'
  99. ctx.expiry = new Date()
  100. })
  101. it('should post the message over with expiry field', async function (ctx) {
  102. await ctx.handler.promises.createNotification(
  103. userId,
  104. ctx.key,
  105. ctx.templateKey,
  106. ctx.messageOpts,
  107. ctx.expiry
  108. )
  109. const args = ctx.request.args[0][0]
  110. args.uri.should.equal(`${notificationUrl}/user/${userId}`)
  111. args.timeout.should.equal(1000)
  112. const expectedJson = {
  113. key: ctx.key,
  114. templateKey: ctx.templateKey,
  115. messageOpts: ctx.messageOpts,
  116. expires: ctx.expiry,
  117. forceCreate: true,
  118. }
  119. assert.deepEqual(args.json, expectedJson)
  120. })
  121. })
  122. })
  123. describe('markAsReadByKeyOnly', function () {
  124. beforeEach(function (ctx) {
  125. ctx.key = 'some key here'
  126. })
  127. it('should send a delete request when a delete has been received to mark a notification', async function (ctx) {
  128. await ctx.handler.promises.markAsReadByKeyOnly(ctx.key)
  129. const opts = {
  130. uri: `${notificationUrl}/key/${ctx.key}`,
  131. timeout: 1000,
  132. method: 'DELETE',
  133. }
  134. ctx.request.calledWith(opts).should.equal(true)
  135. })
  136. })
  137. })