diff --git a/backend/src/middleware/notifications/notificationsMiddleware.js b/backend/src/middleware/notifications/notificationsMiddleware.js index efe363b24..9f594a1f7 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.js +++ b/backend/src/middleware/notifications/notificationsMiddleware.js @@ -73,6 +73,17 @@ const handleLeaveGroup = async (resolve, root, args, context, resolveInfo) => { return user } +const handleChangeGroupMemberRole = async (resolve, root, args, context, resolveInfo) => { + const { groupId, userId } = args + const user = await resolve(root, args, context, resolveInfo) + if (user) { + await publishNotifications(context, [ + notifyMemberOfGroup(groupId, userId, 'changed_group_member_role', context), + ]) + } + return user +} + const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo) => { const idsOfUsers = extractMentionedUsers(args.content) const post = await resolve(root, args, context, resolveInfo) @@ -148,6 +159,37 @@ const notifyOwnersOfGroup = async (groupId, userId, reason, context) => { } } +const notifyMemberOfGroup = async (groupId, userId, reason, context) => { + const cypher = ` + MATCH (group:Group { id: $groupId })<-[membership:MEMBER_OF]-(user:User { id: $userId }) + WITH user, group + MERGE (group)-[notification:NOTIFIED {reason: $reason}]->(user) + WITH group, user, notification + SET notification.read = FALSE + SET notification.createdAt = COALESCE(notification.createdAt, toString(datetime())) + SET notification.updatedAt = toString(datetime()) + SET notification.relatedUserId = $userId + RETURN notification {.*, from: group, to: properties(user)} + ` + const session = context.driver.session() + const writeTxResultPromise = session.writeTransaction(async (transaction) => { + const notificationTransactionResponse = await transaction.run(cypher, { + groupId, + reason, + userId, + }) + return notificationTransactionResponse.records.map((record) => record.get('notification')) + }) + try { + const notifications = await writeTxResultPromise + return notifications + } catch (error) { + throw new Error(error) + } finally { + session.close() + } +} + const notifyUsersOfMention = async (label, id, idsOfUsers, reason, context) => { if (!(idsOfUsers && idsOfUsers.length)) return [] await validateNotifyUsers(label, reason) @@ -244,5 +286,6 @@ export default { UpdateComment: handleContentDataOfComment, JoinGroup: handleJoinGroup, LeaveGroup: handleLeaveGroup, + ChangeGroupMemberRole: handleChangeGroupMemberRole, }, } diff --git a/backend/src/middleware/notifications/notificationsMiddleware.spec.js b/backend/src/middleware/notifications/notificationsMiddleware.spec.js index 2a609dc55..851c76f9c 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.spec.js +++ b/backend/src/middleware/notifications/notificationsMiddleware.spec.js @@ -7,7 +7,7 @@ import { createGroupMutation, joinGroupMutation, leaveGroupMutation, - // changeGroupMemberRoleMutation, + changeGroupMemberRoleMutation, // removeUserFromGroupMutation, } from '../../graphql/groups' @@ -763,5 +763,54 @@ describe('notifications', () => { }) }) }) + + describe('user role in group changes', () => { + beforeEach(async () => { + authenticatedUser = await notifiedUser.toJson() + await mutate({ + mutation: joinGroupMutation(), + variables: { + groupId: 'closed-group', + userId: authenticatedUser.id, + }, + }) + authenticatedUser = await groupOwner.toJson() + await mutate({ + mutation: changeGroupMemberRoleMutation(), + variables: { + groupId: 'closed-group', + userId: 'you', + roleInGroup: 'admin', + }, + }) + authenticatedUser = await notifiedUser.toJson() + }) + + it('has notification in database', async () => { + 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: 'you', + }, + }, + ], + }, + errors: undefined, + }) + }) + }) }) }) diff --git a/backend/src/schema/types/type/NOTIFIED.gql b/backend/src/schema/types/type/NOTIFIED.gql index 61bdd5141..8173fc8f7 100644 --- a/backend/src/schema/types/type/NOTIFIED.gql +++ b/backend/src/schema/types/type/NOTIFIED.gql @@ -24,6 +24,7 @@ enum NotificationReason { commented_on_post user_joined_group user_left_group + changed_group_member_role } type Query {