Create notifications on UpdatePost, too

Note that we don't create duplicate notifications. I made use of the behaviour
of XSS-middleware: It removes all css classes from `<a>` anchors. Because
notifications rely on a css class `mention` which gets removed in a later
middleware, this gives us a nice behaviour for re-notifications without creating
duplicates. The downside is that it creates dependencies between middlewares and
it's not that obvious at all.

cc @mattwr18 @ulfgebhardt @appinteractive @Tirokk
This commit is contained in:
Robert Schäfer 2019-04-16 18:07:18 +02:00
parent f86e98b32e
commit fe551ece47
2 changed files with 42 additions and 5 deletions

View File

@ -1,11 +1,13 @@
import extractIds from './extractMentions'
const notify = async (resolve, root, args, context, resolveInfo) => {
const ids = extractIds(args.content) // before mention class gets removed
// extract user ids before xss-middleware removes link classes
const ids = extractIds(args.content)
const post = await resolve(root, args, context, resolveInfo)
const session = context.driver.session()
const { content, id: postId } = post
const { id: postId } = post
const createdAt = (new Date()).toISOString()
const cypher = `
match(u:User) where u.id in $ids
@ -22,6 +24,7 @@ const notify = async (resolve, root, args, context, resolveInfo) => {
export default {
Mutation: {
CreatePost: notify
CreatePost: notify,
UpdatePost: notify
}
}

View File

@ -74,16 +74,50 @@ describe('currentUser { notifications }', () => {
})
it('sends you a notification', async () => {
const newContent = 'Hey <a href="/profile/you/al-capone" target=\"_blank\">@al-capone</a> how do you do?'
const expectedContent = 'Hey <a href="/profile/you/al-capone" target="_blank">@al-capone</a> how do you do?'
const expected = {
currentUser: {
notifications: [
{ read: false, post: { content: newContent } }
{ read: false, post: { content: expectedContent } }
]
}
}
await expect(client.request(query, { read: false })).resolves.toEqual(expected)
})
describe('who mentions me again', () => {
beforeEach(async () => {
const updatedContent = `${post.content} One more mention to <a href="/profile/you" class="mention">@al-capone</a>`
// The response `post.content` contains a link but the XSSmiddleware
// should have the `mention` CSS class removed. I discovered this
// during development and thought: A feature not a bug! This way we
// can encode a re-mentioning of users when you edit your post or
// comment.
const createPostMutation = `
mutation($id: ID!, $content: String!) {
UpdatePost(id: $id, content: $content) {
title
content
}
}
`
authorClient = new GraphQLClient(host, { headers: authorHeaders })
await authorClient.request(createPostMutation, { id: post.id, content: updatedContent })
})
it('creates exactly one more notification', async () => {
const expectedContent = 'Hey <a href="/profile/you/al-capone" target="_blank">@al-capone</a> how do you do? One more mention to <a href="/profile/you" target="_blank">@al-capone</a>'
const expected = {
currentUser: {
notifications: [
{ read: false, post: { content: expectedContent } },
{ read: false, post: { content: expectedContent } }
]
}
}
await expect(client.request(query, { read: false })).resolves.toEqual(expected)
})
})
})
})
})