diff --git a/backend/src/middleware/handleHtmlContent/handleContentData.js b/backend/src/middleware/handleHtmlContent/handleContentData.js index 9b5df87e7..4b8642690 100644 --- a/backend/src/middleware/handleHtmlContent/handleContentData.js +++ b/backend/src/middleware/handleHtmlContent/handleContentData.js @@ -6,16 +6,27 @@ const notifyMentions = async (label, id, idsOfMentionedUsers, context) => { const session = context.driver.session() const createdAt = new Date().toISOString() - const cypher = ` - MATCH (source) - WHERE source.id = $id AND $label IN LABELS(source) - MATCH (source)<-[:WROTE]-(author: User) - MATCH (user: User) - WHERE user.id in $idsOfMentionedUsers - AND NOT (user)<-[:BLOCKED]-(author) - CREATE (notification: Notification {id: apoc.create.uuid(), read: false, createdAt: $createdAt }) - MERGE (source)-[:NOTIFIED]->(notification)-[:NOTIFIED]->(user) + let cypher + if (label === 'Post') { + cypher = ` + MATCH (post: Post { id: $id })<-[:WROTE]-(author: User) + MATCH (user: User) + WHERE user.id in $idsOfMentionedUsers + AND NOT (user)<-[:BLOCKED]-(author) + CREATE (notification: Notification {id: apoc.create.uuid(), read: false, createdAt: $createdAt }) + MERGE (post)-[:NOTIFIED]->(notification)-[:NOTIFIED]->(user) ` + } else { + cypher = ` + MATCH (postAuthor: User)-[:WROTE]->(post: Post)<-[:COMMENTS]-(comment: Comment { id: $id })<-[:WROTE]-(author: User) + MATCH (user: User) + WHERE user.id in $idsOfMentionedUsers + AND NOT (user)<-[:BLOCKED]-(author) + AND NOT (user)<-[:BLOCKED]-(postAuthor) + CREATE (notification: Notification {id: apoc.create.uuid(), read: false, createdAt: $createdAt }) + MERGE (comment)-[:NOTIFIED]->(notification)-[:NOTIFIED]->(user) + ` + } // "author" of comment, blocked Peter: Jenny // "user" mentioned on post by Jenny: Peter // owner of post: Bob @@ -58,12 +69,9 @@ const updateHashtagsOfPost = async (postId, hashtags, context) => { } const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo) => { - // extract user ids before xss-middleware removes classes via the following "resolve" call const idsOfMentionedUsers = extractMentionedUsers(args.content) - // extract tag (hashtag) ids before xss-middleware removes classes via the following "resolve" call const hashtags = extractHashtags(args.content) - // removes classes from the content const post = await resolve(root, args, context, resolveInfo) await notifyMentions('Post', post.id, idsOfMentionedUsers, context) @@ -73,10 +81,7 @@ const handleContentDataOfPost = async (resolve, root, args, context, resolveInfo } const handleContentDataOfComment = async (resolve, root, args, context, resolveInfo) => { - // extract user ids before xss-middleware removes classes via the following "resolve" call const idsOfMentionedUsers = extractMentionedUsers(args.content) - - // removes classes from the content const comment = await resolve(root, args, context, resolveInfo) await notifyMentions('Comment', comment.id, idsOfMentionedUsers, context) @@ -89,6 +94,6 @@ export default { CreatePost: handleContentDataOfPost, UpdatePost: handleContentDataOfPost, CreateComment: handleContentDataOfComment, - // UpdateComment: handleContentDataOfComment, + UpdateComment: handleContentDataOfComment, }, -} \ No newline at end of file +} diff --git a/backend/src/middleware/handleHtmlContent/handleContentData.spec.js b/backend/src/middleware/handleHtmlContent/handleContentData.spec.js index e9c56863a..4b0640804 100644 --- a/backend/src/middleware/handleHtmlContent/handleContentData.spec.js +++ b/backend/src/middleware/handleHtmlContent/handleContentData.spec.js @@ -1,14 +1,7 @@ -import { - gql -} from '../../jest/helpers' +import { gql } from '../../jest/helpers' import Factory from '../../seed/factories' -import { - createTestClient -} from 'apollo-server-testing' -import { - neode, - getDriver -} from '../../bootstrap/neo4j' +import { createTestClient } from 'apollo-server-testing' +import { neode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' const factory = Factory() @@ -51,7 +44,7 @@ afterEach(async () => { }) describe('notifications', () => { - const notificationQuery = gql ` + const notificationQuery = gql` query($read: Boolean) { currentUser { notifications(read: $read, orderBy: createdAt_desc) { @@ -59,6 +52,9 @@ describe('notifications', () => { post { content } + comment { + content + } } } } @@ -85,7 +81,7 @@ describe('notifications', () => { 'Hey @al-capone how do you do?' const createPostAction = async () => { - const createPostMutation = gql ` + const createPostMutation = gql` mutation($id: ID, $title: String!, $content: String!) { CreatePost(id: $id, title: $title, content: $content) { id @@ -100,7 +96,7 @@ describe('notifications', () => { variables: { id: 'p47', title, - content + content, }, }) authenticatedUser = await user.toJson() @@ -113,24 +109,25 @@ describe('notifications', () => { const expected = expect.objectContaining({ data: { currentUser: { - notifications: [{ - read: false, - post: { - content: expectedContent - } - }] + notifications: [ + { + read: false, + post: { + content: expectedContent, + }, + comment: null, + }, + ], }, }, }) - const { - query - } = createTestClient(server) + const { query } = createTestClient(server) await expect( query({ query: notificationQuery, variables: { - read: false - } + read: false, + }, }), ).resolves.toEqual(expected) }) @@ -151,7 +148,7 @@ describe('notifications', () => { @al-capone ` - const updatePostMutation = gql ` + const updatePostMutation = gql` mutation($id: ID!, $title: String!, $content: String!) { UpdatePost(id: $id, content: $content, title: $title) { title @@ -179,17 +176,20 @@ describe('notifications', () => { const expected = expect.objectContaining({ data: { currentUser: { - notifications: [{ + notifications: [ + { read: false, post: { - content: expectedContent - } + content: expectedContent, + }, + comment: null, }, { read: false, post: { - content: expectedContent - } + content: expectedContent, + }, + comment: null, }, ], }, @@ -199,8 +199,8 @@ describe('notifications', () => { query({ query: notificationQuery, variables: { - read: false - } + read: false, + }, }), ).resolves.toEqual(expected) }) @@ -216,51 +216,50 @@ describe('notifications', () => { const expected = expect.objectContaining({ data: { currentUser: { - notifications: [] - } + notifications: [], + }, }, }) - const { - query - } = createTestClient(server) + const { query } = createTestClient(server) await expect( query({ query: notificationQuery, variables: { - read: false - } + read: false, + }, }), ).resolves.toEqual(expected) }) }) - describe('but the author of the post blocked a user I mention in a comment', () => { + describe('but the author of the post blocked me and a mentioner mentions me in a comment', () => { const createCommentOnPostAction = async () => { await createPostAction() - const createCommentMutation = gql ` - mutation($id: ID, $title: String!, $content: String!) { + const createCommentMutation = gql` + mutation($id: ID, $postId: ID!, $commentContent: String!) { CreateComment(id: $id, postId: $postId, content: $commentContent) { id content } } ` - // authenticatedUser = await postAuthor.toJson() - // authenticatedUser = await user.toJson() + authenticatedUser = await commentMentioner.toJson() await mutate({ mutation: createCommentMutation, variables: { id: 'c47', postId: 'p47', - commentContent: 'One mention of me with .' + commentContent: + 'One mention of me with .', }, }) + authenticatedUser = await user.toJson() } - let mentioner + let commentMentioner beforeEach(async () => { await postAuthor.relateTo(user, 'blocked') - mentioner = await instance.create('User', { + commentMentioner = await instance.create('User', { id: 'mentioner', name: 'Mr Mentioner', slug: 'mr-mentioner', @@ -270,23 +269,21 @@ describe('notifications', () => { }) it('sends no notification', async () => { - await createPostAction() + await createCommentOnPostAction() const expected = expect.objectContaining({ data: { currentUser: { - notifications: [] - } + notifications: [], + }, }, }) - const { - query - } = createTestClient(server) + const { query } = createTestClient(server) await expect( query({ query: notificationQuery, variables: { - read: false - } + read: false, + }, }), ).resolves.toEqual(expected) }) @@ -301,7 +298,7 @@ describe('Hashtags', () => { const postTitle = 'Two Hashtags' const postContent = '

Hey Dude, #Democracy should work equal for everybody!? That seems to be the only way to have equal #Liberty for everyone.

' - const postWithHastagsQuery = gql ` + const postWithHastagsQuery = gql` query($id: ID) { Post(id: $id) { tags { @@ -314,7 +311,7 @@ describe('Hashtags', () => { const postWithHastagsVariables = { id: postId, } - const createPostMutation = gql ` + const createPostMutation = gql` mutation($postId: ID, $postTitle: String!, $postContent: String!) { CreatePost(id: $postId, title: $postTitle, content: $postContent) { id @@ -342,26 +339,29 @@ describe('Hashtags', () => { }) it('both Hashtags are created with the "id" set to their "name"', async () => { - const expected = [{ + const expected = [ + { id: 'Democracy', - name: 'Democracy' + name: 'Democracy', }, { id: 'Liberty', - name: 'Liberty' + name: 'Liberty', }, ] await expect( query({ query: postWithHastagsQuery, - variables: postWithHastagsVariables + variables: postWithHastagsVariables, }), ).resolves.toEqual( expect.objectContaining({ data: { - Post: [{ - tags: expect.arrayContaining(expected), - }, ], + Post: [ + { + tags: expect.arrayContaining(expected), + }, + ], }, }), ) @@ -371,7 +371,7 @@ describe('Hashtags', () => { // The already existing Hashtag has no class at this point. const updatedPostContent = '

Hey Dude, #Elections should work equal for everybody!? That seems to be the only way to have equal #Liberty for everyone.

' - const updatePostMutation = gql ` + const updatePostMutation = gql` mutation($postId: ID!, $postTitle: String!, $updatedPostContent: String!) { UpdatePost(id: $postId, title: $postTitle, content: $updatedPostContent) { id @@ -391,26 +391,29 @@ describe('Hashtags', () => { }, }) - const expected = [{ + const expected = [ + { id: 'Elections', - name: 'Elections' + name: 'Elections', }, { id: 'Liberty', - name: 'Liberty' + name: 'Liberty', }, ] await expect( query({ query: postWithHastagsQuery, - variables: postWithHastagsVariables + variables: postWithHastagsVariables, }), ).resolves.toEqual( expect.objectContaining({ data: { - Post: [{ - tags: expect.arrayContaining(expected) - }], + Post: [ + { + tags: expect.arrayContaining(expected), + }, + ], }, }), ) @@ -418,4 +421,4 @@ describe('Hashtags', () => { }) }) }) -}) \ No newline at end of file +}) diff --git a/webapp/layouts/default.vue b/webapp/layouts/default.vue index 435a9724e..eddf4edf5 100644 --- a/webapp/layouts/default.vue +++ b/webapp/layouts/default.vue @@ -88,11 +88,9 @@ {{ $t('login.hello') }} {{ userName }}
@@ -131,10 +129,14 @@