Wrote and tested the mention of a blocked user on a post of a blocker

Co-Authored-By: mattwr18 <mattwr18@gmail.com>
This commit is contained in:
Wolfgang Huß 2019-08-16 18:14:04 +02:00
parent efb5c75c24
commit 0b9a58e317
3 changed files with 109 additions and 99 deletions

View File

@ -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,
},
}
}

View File

@ -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 <a class="mention" data-mention-id="you" href="/profile/you/al-capone">@al-capone</a> 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
</a>
`
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 <a data-mention-id="you" class="mention" href="/profile/you" target="_blank">.'
commentContent:
'One mention of me with <a data-mention-id="you" class="mention" href="/profile/you" target="_blank">.',
},
})
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 =
'<p>Hey Dude, <a class="hashtag" href="/search/hashtag/Democracy">#Democracy</a> should work equal for everybody!? That seems to be the only way to have equal <a class="hashtag" href="/search/hashtag/Liberty">#Liberty</a> for everyone.</p>'
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 =
'<p>Hey Dude, <a class="hashtag" href="/search/hashtag/Elections">#Elections</a> should work equal for everybody!? That seems to be the only way to have equal <a href="/search/hashtag/Liberty">#Liberty</a> for everyone.</p>'
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', () => {
})
})
})
})
})

View File

@ -88,11 +88,9 @@
{{ $t('login.hello') }}
<b>{{ userName }}</b>
<template v-if="user.role !== 'user'">
<ds-text
color="softer"
size="small"
style="margin-bottom: 0"
>{{ user.role | camelCase }}</ds-text>
<ds-text color="softer" size="small" style="margin-bottom: 0">
{{ user.role | camelCase }}
</ds-text>
</template>
<hr />
<ds-menu :routes="routes" :matcher="matcher">
@ -131,10 +129,14 @@
<div id="footer" class="ds-footer">
<a href="https://human-connection.org" target="_blank" v-html="$t('site.made')"></a>
&nbsp;-&nbsp;
<nuxt-link to="/imprint">{{ $t('site.imprint') }}</nuxt-link>&nbsp;&nbsp;
<nuxt-link to="/terms-and-conditions">{{ $t('site.termsAndConditions') }}</nuxt-link>&nbsp;&nbsp;
<nuxt-link to="/code-of-conduct">{{ $t('site.code-of-conduct') }}</nuxt-link>&nbsp;&nbsp;
<nuxt-link to="/data-privacy">{{ $t('site.data-privacy') }}</nuxt-link>&nbsp;&nbsp;
<nuxt-link to="/imprint">{{ $t('site.imprint') }}</nuxt-link>
&nbsp;&nbsp;
<nuxt-link to="/terms-and-conditions">{{ $t('site.termsAndConditions') }}</nuxt-link>
&nbsp;&nbsp;
<nuxt-link to="/code-of-conduct">{{ $t('site.code-of-conduct') }}</nuxt-link>
&nbsp;&nbsp;
<nuxt-link to="/data-privacy">{{ $t('site.data-privacy') }}</nuxt-link>
&nbsp;&nbsp;
<nuxt-link to="/changelog">{{ $t('site.changelog') }}</nuxt-link>
</div>
<div id="overlay" />