notification email tests

fix test
This commit is contained in:
Ulf Gebhardt 2025-04-07 23:24:33 +02:00
parent 574da51327
commit 8c6e6e8882
Signed by: ulfgebhardt
GPG Key ID: DA6B843E748679C9
2 changed files with 360 additions and 75 deletions

View File

@ -19,8 +19,10 @@ jest.mock('../helpers/email/sendMail', () => ({
}))
const chatMessageTemplateMock = jest.fn()
const notificationTemplateMock = jest.fn()
jest.mock('../helpers/email/templateBuilder', () => ({
chatMessageTemplate: () => chatMessageTemplateMock(),
notificationTemplate: () => notificationTemplateMock(),
}))
let isUserOnlineMock = jest.fn()
@ -85,8 +87,8 @@ afterAll(async () => {
beforeEach(async () => {
publishSpy.mockClear()
notifiedUser = await neode.create(
'User',
notifiedUser = await Factory.build(
'user',
{
id: 'you',
name: 'Al Capone',
@ -186,6 +188,7 @@ describe('notifications', () => {
describe('commenter is not me', () => {
beforeEach(async () => {
jest.clearAllMocks()
commentContent = 'Commenters comment.'
commentAuthor = await neode.create(
'User',
@ -201,25 +204,8 @@ describe('notifications', () => {
)
})
it('sends me a notification', async () => {
it('sends me a notification and email', async () => {
await createCommentOnPostAction()
const expected = expect.objectContaining({
data: {
notifications: [
{
read: false,
createdAt: expect.any(String),
reason: 'commented_on_post',
from: {
__typename: 'Comment',
id: 'c47',
content: commentContent,
},
relatedUser: null,
},
],
},
})
await expect(
query({
query: notificationQuery,
@ -227,24 +213,85 @@ describe('notifications', () => {
read: false,
},
}),
).resolves.toEqual(expected)
).resolves.toMatchObject(
expect.objectContaining({
data: {
notifications: [
{
read: false,
createdAt: expect.any(String),
reason: 'commented_on_post',
from: {
__typename: 'Comment',
id: 'c47',
content: commentContent,
},
relatedUser: null,
},
],
},
}),
)
// Mail
expect(sendMailMock).toHaveBeenCalledTimes(1)
expect(notificationTemplateMock).toHaveBeenCalledTimes(1)
})
it('sends me no notification if I have blocked the comment author', async () => {
await notifiedUser.relateTo(commentAuthor, 'blocked')
await createCommentOnPostAction()
const expected = expect.objectContaining({
data: { notifications: [] },
})
describe('if I have disabled `emailNotificationsCommentOnObservedPost`', () => {
it('sends me a notification but no email', async () => {
await notifiedUser.update({ emailNotificationsCommentOnObservedPost: false })
await createCommentOnPostAction()
await expect(
query({
query: notificationQuery,
variables: {
read: false,
},
}),
).resolves.toMatchObject(
expect.objectContaining({
data: {
notifications: [
{
read: false,
createdAt: expect.any(String),
reason: 'commented_on_post',
from: {
__typename: 'Comment',
id: 'c47',
content: commentContent,
},
relatedUser: null,
},
],
},
}),
)
await expect(
query({
query: notificationQuery,
variables: {
read: false,
},
}),
).resolves.toEqual(expected)
// No Mail
expect(sendMailMock).not.toHaveBeenCalled()
expect(notificationTemplateMock).not.toHaveBeenCalled()
})
})
describe('if I have blocked the comment author', () => {
it('sends me no notification', async () => {
await notifiedUser.relateTo(commentAuthor, 'blocked')
await createCommentOnPostAction()
const expected = expect.objectContaining({
data: { notifications: [] },
})
await expect(
query({
query: notificationQuery,
variables: {
read: false,
},
}),
).resolves.toEqual(expected)
})
})
})
@ -273,6 +320,7 @@ describe('notifications', () => {
})
beforeEach(async () => {
jest.clearAllMocks()
postAuthor = await neode.create(
'User',
{
@ -295,7 +343,7 @@ describe('notifications', () => {
'Hey <a class="mention" data-mention-id="you" href="/profile/you/al-capone">@al-capone</a> how do you do?'
})
it('sends me a notification', async () => {
it('sends me a notification and email', async () => {
await createPostAction()
const expectedContent =
'Hey <a class="mention" data-mention-id="you" href="/profile/you/al-capone" target="_blank">@al-capone</a> how do you do?'
@ -323,6 +371,47 @@ describe('notifications', () => {
],
},
})
// Mail
expect(sendMailMock).toHaveBeenCalledTimes(1)
expect(notificationTemplateMock).toHaveBeenCalledTimes(1)
})
describe('if I have disabled `emailNotificationsMention`', () => {
it('sends me a notification but no email', async () => {
await notifiedUser.update({ emailNotificationsMention: false })
await createPostAction()
const expectedContent =
'Hey <a class="mention" data-mention-id="you" href="/profile/you/al-capone" target="_blank">@al-capone</a> how do you do?'
await expect(
query({
query: notificationQuery,
variables: {
read: false,
},
}),
).resolves.toMatchObject({
errors: undefined,
data: {
notifications: [
{
read: false,
createdAt: expect.any(String),
reason: 'mentioned_in_post',
from: {
__typename: 'Post',
id: 'p47',
content: expectedContent,
},
},
],
},
})
// Mail
expect(sendMailMock).not.toHaveBeenCalled()
expect(notificationTemplateMock).not.toHaveBeenCalled()
})
})
it('publishes `NOTIFICATION_ADDED` to me', async () => {
@ -688,7 +777,7 @@ describe('notifications', () => {
roomId = room.data.CreateRoom.id
})
describe('chatReceiver is online', () => {
describe('if the chatReceiver is online', () => {
it('sends no email', async () => {
isUserOnlineMock = jest.fn().mockReturnValue(true)
@ -705,7 +794,7 @@ describe('notifications', () => {
})
})
describe('chatReceiver is offline', () => {
describe('if the chatReceiver is offline', () => {
it('sends an email', async () => {
isUserOnlineMock = jest.fn().mockReturnValue(false)
@ -722,7 +811,7 @@ describe('notifications', () => {
})
})
describe('chatReceiver has blocked chatSender', () => {
describe('if the chatReceiver has blocked chatSender', () => {
it('sends no email', async () => {
isUserOnlineMock = jest.fn().mockReturnValue(false)
await chatReceiver.relateTo(chatSender, 'blocked')
@ -740,10 +829,10 @@ describe('notifications', () => {
})
})
describe('chatReceiver has disabled email notifications', () => {
describe('if the chatReceiver has disabled `emailNotificationsChatMessage`', () => {
it('sends no email', async () => {
isUserOnlineMock = jest.fn().mockReturnValue(false)
await chatReceiver.update({ sendNotificationEmails: false })
await chatReceiver.update({ emailNotificationsChatMessage: false })
await mutate({
mutation: createMessageMutation(),
@ -763,8 +852,8 @@ describe('notifications', () => {
let groupOwner
beforeEach(async () => {
groupOwner = await neode.create(
'User',
groupOwner = await Factory.build(
'user',
{
id: 'group-owner',
name: 'Group Owner',
@ -791,7 +880,7 @@ describe('notifications', () => {
})
describe('user joins group', () => {
beforeEach(async () => {
const joinGroupAction = async () => {
authenticatedUser = await notifiedUser.toJson()
await mutate({
mutation: joinGroupMutation(),
@ -801,9 +890,14 @@ describe('notifications', () => {
},
})
authenticatedUser = await groupOwner.toJson()
}
beforeEach(async () => {
jest.clearAllMocks()
})
it('has the notification in database', async () => {
it('sends the group owner a notification and email', async () => {
await joinGroupAction()
await expect(
query({
query: notificationQuery,
@ -827,19 +921,50 @@ describe('notifications', () => {
},
errors: undefined,
})
// Mail
expect(sendMailMock).toHaveBeenCalledTimes(1)
expect(notificationTemplateMock).toHaveBeenCalledTimes(1)
})
describe('if the group owner has disabled `emailNotificationsGroupMemberJoined`', () => {
it('sends the group owner a notification but no email', async () => {
await groupOwner.update({ emailNotificationsGroupMemberJoined: false })
await joinGroupAction()
await expect(
query({
query: notificationQuery,
}),
).resolves.toMatchObject({
data: {
notifications: [
{
read: false,
reason: 'user_joined_group',
createdAt: expect.any(String),
from: {
__typename: 'Group',
id: 'closed-group',
},
relatedUser: {
id: 'you',
},
},
],
},
errors: undefined,
})
// Mail
expect(sendMailMock).not.toHaveBeenCalled()
expect(notificationTemplateMock).not.toHaveBeenCalled()
})
})
})
describe('user leaves group', () => {
beforeEach(async () => {
describe('user joins and leaves group', () => {
const leaveGroupAction = async () => {
authenticatedUser = await notifiedUser.toJson()
await mutate({
mutation: joinGroupMutation(),
variables: {
groupId: 'closed-group',
userId: authenticatedUser.id,
},
})
await mutate({
mutation: leaveGroupMutation(),
variables: {
@ -848,9 +973,22 @@ describe('notifications', () => {
},
})
authenticatedUser = await groupOwner.toJson()
}
beforeEach(async () => {
jest.clearAllMocks()
authenticatedUser = await notifiedUser.toJson()
await mutate({
mutation: joinGroupMutation(),
variables: {
groupId: 'closed-group',
userId: authenticatedUser.id,
},
})
})
it('has two the notification in database', async () => {
it('sends the group owner two notifications and emails', async () => {
await leaveGroupAction()
await expect(
query({
query: notificationQuery,
@ -886,19 +1024,61 @@ describe('notifications', () => {
},
errors: undefined,
})
// Mail
expect(sendMailMock).toHaveBeenCalledTimes(2)
expect(notificationTemplateMock).toHaveBeenCalledTimes(2)
})
describe('if the group owner has disabled `emailNotificationsGroupMemberLeft`', () => {
it('sends the group owner two notification but only only one email', async () => {
await groupOwner.update({ emailNotificationsGroupMemberLeft: false })
await leaveGroupAction()
await expect(
query({
query: notificationQuery,
}),
).resolves.toMatchObject({
data: {
notifications: [
{
read: false,
reason: 'user_left_group',
createdAt: expect.any(String),
from: {
__typename: 'Group',
id: 'closed-group',
},
relatedUser: {
id: 'you',
},
},
{
read: false,
reason: 'user_joined_group',
createdAt: expect.any(String),
from: {
__typename: 'Group',
id: 'closed-group',
},
relatedUser: {
id: 'you',
},
},
],
},
errors: undefined,
})
// Mail
expect(sendMailMock).toHaveBeenCalledTimes(1)
expect(notificationTemplateMock).toHaveBeenCalledTimes(1)
})
})
})
describe('user role in group changes', () => {
beforeEach(async () => {
authenticatedUser = await notifiedUser.toJson()
await mutate({
mutation: joinGroupMutation(),
variables: {
groupId: 'closed-group',
userId: authenticatedUser.id,
},
})
const changeGroupMemberRoleAction = async () => {
authenticatedUser = await groupOwner.toJson()
await mutate({
mutation: changeGroupMemberRoleMutation(),
@ -909,9 +1089,23 @@ describe('notifications', () => {
},
})
authenticatedUser = await notifiedUser.toJson()
}
beforeEach(async () => {
authenticatedUser = await notifiedUser.toJson()
await mutate({
mutation: joinGroupMutation(),
variables: {
groupId: 'closed-group',
userId: authenticatedUser.id,
},
})
// Clear after because the above generates a notification not related
jest.clearAllMocks()
})
it('has notification in database', async () => {
it('sends the group member a notification and email', async () => {
await changeGroupMemberRoleAction()
await expect(
query({
query: notificationQuery,
@ -935,19 +1129,49 @@ describe('notifications', () => {
},
errors: undefined,
})
// Mail
expect(sendMailMock).toHaveBeenCalledTimes(1)
expect(notificationTemplateMock).toHaveBeenCalledTimes(1)
})
describe('if the group member has disabled `emailNotificationsGroupMemberRoleChanged`', () => {
it('sends the group member a notification but no email', async () => {
notifiedUser.update({ emailNotificationsGroupMemberRoleChanged: false })
await changeGroupMemberRoleAction()
await expect(
query({
query: notificationQuery,
}),
).resolves.toMatchObject({
data: {
notifications: [
{
read: false,
reason: 'changed_group_member_role',
createdAt: expect.any(String),
from: {
__typename: 'Group',
id: 'closed-group',
},
relatedUser: {
id: 'group-owner',
},
},
],
},
errors: undefined,
})
// Mail
expect(sendMailMock).not.toHaveBeenCalled()
expect(notificationTemplateMock).not.toHaveBeenCalled()
})
})
})
describe('user is removed from group', () => {
beforeEach(async () => {
authenticatedUser = await notifiedUser.toJson()
await mutate({
mutation: joinGroupMutation(),
variables: {
groupId: 'closed-group',
userId: authenticatedUser.id,
},
})
const removeUserFromGroupAction = async () => {
authenticatedUser = await groupOwner.toJson()
await mutate({
mutation: removeUserFromGroupMutation(),
@ -957,9 +1181,23 @@ describe('notifications', () => {
},
})
authenticatedUser = await notifiedUser.toJson()
}
beforeEach(async () => {
authenticatedUser = await notifiedUser.toJson()
await mutate({
mutation: joinGroupMutation(),
variables: {
groupId: 'closed-group',
userId: authenticatedUser.id,
},
})
// Clear after because the above generates a notification not related
jest.clearAllMocks()
})
it('has notification in database', async () => {
it('sends the previous group member a notification and email', async () => {
await removeUserFromGroupAction()
await expect(
query({
query: notificationQuery,
@ -983,6 +1221,44 @@ describe('notifications', () => {
},
errors: undefined,
})
// Mail
expect(sendMailMock).toHaveBeenCalledTimes(1)
expect(notificationTemplateMock).toHaveBeenCalledTimes(1)
})
describe('if the previous group member has disabled `emailNotificationsGroupMemberRemoved`', () => {
it('sends the previous group member a notification but no email', async () => {
notifiedUser.update({ emailNotificationsGroupMemberRemoved: false })
await removeUserFromGroupAction()
await expect(
query({
query: notificationQuery,
}),
).resolves.toMatchObject({
data: {
notifications: [
{
read: false,
reason: 'removed_user_from_group',
createdAt: expect.any(String),
from: {
__typename: 'Group',
id: 'closed-group',
},
relatedUser: {
id: 'group-owner',
},
},
],
},
errors: undefined,
})
// Mail
expect(sendMailMock).not.toHaveBeenCalled()
expect(notificationTemplateMock).not.toHaveBeenCalled()
})
})
})
})

View File

@ -769,6 +769,15 @@ describe('emailNotificationSettings', () => {
},
],
},
{
type: 'chat',
settings: [
{
name: 'chatMessage',
value: true,
},
],
},
{
type: 'group',
settings: [