| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- import { beforeEach, describe, expect, it, vi } from 'vitest'
- import { ObjectId } from 'mongodb-legacy'
- import assert from 'node:assert'
- const modulePath = '../../../app/js/Notifications.js'
- const userId = '51dc93e6fb625a261300003b'
- const notificationId = '574ee8d6f40c3a244e704249'
- const notificationKey = 'notification-key'
- describe('Notifications Tests', () => {
- let countStub,
- db,
- deleteOneStub,
- findStub,
- findToArrayStub,
- notifications,
- stubbedNotification,
- stubbedNotificationArray,
- updateOneStub
- beforeEach(async () => {
- findToArrayStub = vi.fn()
- findStub = vi.fn().mockReturnValue({ toArray: findToArrayStub })
- countStub = vi.fn()
- updateOneStub = vi.fn()
- deleteOneStub = vi.fn()
- db = {
- notifications: {
- find: findStub,
- count: countStub,
- updateOne: updateOneStub,
- deleteOne: deleteOneStub,
- },
- }
- vi.doMock('@overleaf/settings', () => ({}))
- vi.doMock('../../../app/js/mongodb', () => ({
- db,
- ObjectId,
- }))
- notifications = await import(modulePath)
- stubbedNotification = {
- user_id: new ObjectId(userId),
- key: 'notification-key',
- messageOpts: 'some info',
- templateKey: 'template-key',
- }
- stubbedNotificationArray = [stubbedNotification]
- })
- describe('getUserNotifications', () => {
- it('should find all notifications and return i', async () => {
- findToArrayStub.mockResolvedValue(stubbedNotificationArray)
- const result = await notifications.getUserNotifications(userId)
- result.should.equal(stubbedNotificationArray)
- assert.deepEqual(findStub.mock.calls[0][0], {
- user_id: new ObjectId(userId),
- templateKey: { $exists: true },
- })
- })
- })
- describe('addNotification', () => {
- let expectedDocument, expectedQuery
- beforeEach(() => {
- stubbedNotification = {
- user_id: new ObjectId(userId),
- key: 'notification-key',
- messageOpts: 'some info',
- templateKey: 'template-key',
- }
- expectedDocument = {
- user_id: stubbedNotification.user_id,
- key: 'notification-key',
- messageOpts: 'some info',
- templateKey: 'template-key',
- }
- expectedQuery = {
- user_id: stubbedNotification.user_id,
- key: 'notification-key',
- }
- updateOneStub.mockResolvedValue()
- countStub.mockResolvedValue(0)
- })
- it('should insert the notification into the collection', async () => {
- await notifications.addNotification(userId, stubbedNotification)
- expect(updateOneStub).toHaveBeenCalledWith(
- expectedQuery,
- { $set: expectedDocument },
- { upsert: true }
- )
- })
- describe('when there is an existing notification', done => {
- beforeEach(() => {
- countStub.mockResolvedValue(1)
- })
- it('should fail to insert', async () => {
- await notifications.addNotification(userId, stubbedNotification)
- expect(updateOneStub).not.toHaveBeenCalled()
- })
- it('should update the key if forceCreate is true', async () => {
- stubbedNotification.forceCreate = true
- await notifications.addNotification(userId, stubbedNotification)
- expect(updateOneStub).toHaveBeenCalledWith(
- expectedQuery,
- { $set: expectedDocument },
- { upsert: true }
- )
- })
- })
- describe('when the notification is set to expire', () => {
- beforeEach(() => {
- stubbedNotification = {
- user_id: new ObjectId(userId),
- key: 'notification-key',
- messageOpts: 'some info',
- templateKey: 'template-key',
- expires: '2922-02-13T09:32:56.289Z',
- }
- expectedDocument = {
- user_id: stubbedNotification.user_id,
- key: 'notification-key',
- messageOpts: 'some info',
- templateKey: 'template-key',
- expires: new Date(stubbedNotification.expires),
- }
- expectedQuery = {
- user_id: stubbedNotification.user_id,
- key: 'notification-key',
- }
- })
- it('should add an `expires` Date field to the document', async () => {
- await notifications.addNotification(userId, stubbedNotification)
- expect(updateOneStub).toHaveBeenCalledWith(
- expectedQuery,
- { $set: expectedDocument },
- { upsert: true }
- )
- })
- })
- describe('when the notification has a nonsensical expires field', () => {
- beforeEach(() => {
- stubbedNotification = {
- user_id: new ObjectId(userId),
- key: 'notification-key',
- messageOpts: 'some info',
- templateKey: 'template-key',
- expires: 'WAT',
- }
- expectedDocument = {
- user_id: stubbedNotification.user_id,
- key: 'notification-key',
- messageOpts: 'some info',
- templateKey: 'template-key',
- expires: new Date(stubbedNotification.expires),
- }
- })
- it('should produce an error', async () => {
- await expect(
- notifications.addNotification(userId, stubbedNotification)
- ).to.eventually.be.rejectedWith(Error)
- expect(updateOneStub).not.toHaveBeenCalled()
- })
- })
- })
- describe('removeNotificationId', () => {
- it('should mark the notification id as read', async () => {
- updateOneStub.mockResolvedValue(null)
- await notifications.removeNotificationId(userId, notificationId)
- const searchOps = {
- user_id: new ObjectId(userId),
- _id: new ObjectId(notificationId),
- }
- const updateOperation = {
- $unset: { templateKey: true, messageOpts: true },
- }
- assert.deepEqual(updateOneStub.mock.calls[0][0], searchOps)
- assert.deepEqual(updateOneStub.mock.calls[0][1], updateOperation)
- })
- })
- describe('removeNotificationKey', () => {
- it('should mark the notification key as read', async () => {
- updateOneStub.mockResolvedValue(null)
- await notifications.removeNotificationKey(userId, notificationKey)
- const searchOps = {
- user_id: new ObjectId(userId),
- key: notificationKey,
- }
- const updateOperation = {
- $unset: { templateKey: true },
- }
- assert.deepEqual(updateOneStub.mock.calls[0][0], searchOps)
- assert.deepEqual(updateOneStub.mock.calls[0][1], updateOperation)
- })
- })
- describe('removeNotificationByKeyOnly', () => {
- it('should mark the notification key as read', async () => {
- updateOneStub.mockResolvedValue(null)
- await notifications.removeNotificationByKeyOnly(notificationKey)
- const searchOps = { key: notificationKey }
- const updateOperation = { $unset: { templateKey: true } }
- assert.deepEqual(updateOneStub.mock.calls[0][0], searchOps)
- assert.deepEqual(updateOneStub.mock.calls[0][1], updateOperation)
- })
- })
- describe('deleteNotificationByKeyOnly', () => {
- it('should completely remove the notification', async () => {
- deleteOneStub.mockResolvedValue()
- await notifications.deleteNotificationByKeyOnly(notificationKey)
- const searchOps = { key: notificationKey }
- expect(deleteOneStub.mock.calls[0][0]).toEqual(searchOps)
- })
- })
- })
|