From 9440ad5cc36d1f1c52f2255e8d5e5b62477c9320 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 16 Apr 2025 17:34:29 +0200 Subject: [PATCH] feat(backend): no notification mails to users online (#8397) --- ...ificationsMiddleware.online-status.spec.ts | 146 ++++++++++++++++++ .../notifications/notificationsMiddleware.ts | 5 +- 2 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 backend/src/middleware/notifications/notificationsMiddleware.online-status.spec.ts diff --git a/backend/src/middleware/notifications/notificationsMiddleware.online-status.spec.ts b/backend/src/middleware/notifications/notificationsMiddleware.online-status.spec.ts new file mode 100644 index 000000000..acc446d6b --- /dev/null +++ b/backend/src/middleware/notifications/notificationsMiddleware.online-status.spec.ts @@ -0,0 +1,146 @@ +import { createTestClient } from 'apollo-server-testing' +import gql from 'graphql-tag' + +import Factory, { cleanDatabase } from '@db/factories' +import { getNeode, getDriver } from '@db/neo4j' +import CONFIG from '@src/config' +import createServer from '@src/server' + +CONFIG.CATEGORIES_ACTIVE = false + +const sendMailMock = jest.fn() +jest.mock('../helpers/email/sendMail', () => ({ + sendMail: () => sendMailMock(), +})) + +let isUserOnlineMock = jest.fn().mockReturnValue(false) +jest.mock('../helpers/isUserOnline', () => ({ + isUserOnline: () => isUserOnlineMock(), +})) + +let server, mutate, authenticatedUser + +let postAuthor + +const driver = getDriver() +const neode = getNeode() + +const createPostMutation = gql` + mutation ($id: ID, $title: String!, $content: String!, $groupId: ID) { + CreatePost(id: $id, title: $title, content: $content, groupId: $groupId) { + id + title + content + } + } +` + +beforeAll(async () => { + await cleanDatabase() + + const createServerResult = createServer({ + context: () => { + return { + user: authenticatedUser, + neode, + driver, + cypherParams: { + currentUserId: authenticatedUser ? authenticatedUser.id : null, + }, + } + }, + }) + server = createServerResult.server + const createTestClientResult = createTestClient(server) + mutate = createTestClientResult.mutate +}) + +afterAll(async () => { + await cleanDatabase() + driver.close() +}) + +afterEach(async () => { + await cleanDatabase() +}) + +describe('online status and sending emails', () => { + beforeEach(async () => { + postAuthor = await Factory.build( + 'user', + { + id: 'post-author', + name: 'Post Author', + slug: 'post-author', + }, + { + email: 'test@example.org', + password: '1234', + }, + ) + await Factory.build( + 'user', + { + id: 'other-user', + name: 'Other User', + slug: 'other-user', + }, + { + email: 'test2@example.org', + password: '1234', + }, + ) + }) + + describe('user is online', () => { + beforeAll(() => { + isUserOnlineMock = jest.fn().mockReturnValue(true) + }) + + describe('mentioned in post', () => { + beforeEach(async () => { + jest.clearAllMocks() + authenticatedUser = await postAuthor.toJson() + await mutate({ + mutation: createPostMutation, + variables: { + id: 'post-online-1', + title: 'This post mentions the other user', + content: + 'Hello @other-user, are you fine?', + }, + }) + }) + + it('sends NO email to the other user', () => { + expect(sendMailMock).not.toBeCalled() + }) + }) + }) + + describe('user is offline', () => { + beforeAll(() => { + isUserOnlineMock = jest.fn().mockReturnValue(false) + }) + + describe('mentioned in post', () => { + beforeEach(async () => { + jest.clearAllMocks() + authenticatedUser = await postAuthor.toJson() + await mutate({ + mutation: createPostMutation, + variables: { + id: 'post-offline-1', + title: 'This post mentions the other user', + content: + 'Hello @other-user, are you fine?', + }, + }) + }) + + it('sends email to the other user', () => { + expect(sendMailMock).toBeCalledTimes(1) + }) + }) + }) +}) diff --git a/backend/src/middleware/notifications/notificationsMiddleware.ts b/backend/src/middleware/notifications/notificationsMiddleware.ts index 62050b3cc..f70e9fc89 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.ts +++ b/backend/src/middleware/notifications/notificationsMiddleware.ts @@ -49,7 +49,10 @@ const publishNotifications = async (context, promises, emailNotificationSetting: ) notifications.forEach((notificationAdded, index) => { pubsub.publish(NOTIFICATION_ADDED, { notificationAdded }) - if (notificationAdded.to[emailNotificationSetting] ?? true) { + if ( + (notificationAdded.to[emailNotificationSetting] ?? true) && + !isUserOnline(notificationAdded.to) + ) { sendMail( notificationTemplate({ email: notificationsEmailAddresses[index].email,