import { gql } from '../../jest/helpers' import Factory from '../../seed/factories' import { createTestClient } from 'apollo-server-testing' import { neode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' const factory = Factory() const driver = getDriver() const instance = neode() let server let query let mutate let user let authenticatedUser beforeAll(() => { const createServerResult = createServer({ context: () => { return { user: authenticatedUser, neode: instance, driver, } }, }) server = createServerResult.server const createTestClientResult = createTestClient(server) query = createTestClientResult.query mutate = createTestClientResult.mutate }) beforeEach(async () => { user = await instance.create('User', { id: 'you', name: 'Al Capone', slug: 'al-capone', email: 'test@example.org', password: '1234', }) }) afterEach(async () => { await factory.cleanDatabase() }) describe('notifications', () => { const notificationQuery = gql ` query($read: Boolean) { currentUser { notifications(read: $read, orderBy: createdAt_desc) { read post { content } } } } ` describe('authenticated', () => { beforeEach(async () => { authenticatedUser = user }) describe('given another user', () => { let postAuthor beforeEach(async () => { postAuthor = await instance.create('User', { email: 'post-author@example.org', password: '1234', id: 'postAuthor', }) }) describe('who mentions me in a post', () => { const title = 'Mentioning Al Capone' const content = 'Hey @al-capone how do you do?' const createPostAction = async () => { const createPostMutation = gql ` mutation($id: ID, $title: String!, $content: String!) { CreatePost(id: $id, title: $title, content: $content) { id title content } } ` authenticatedUser = await postAuthor.toJson() await mutate({ mutation: createPostMutation, variables: { id: 'p47', title, content }, }) authenticatedUser = await user.toJson() } it('sends you a notification', async () => { await createPostAction() const expectedContent = 'Hey @al-capone how do you do?' const expected = expect.objectContaining({ data: { currentUser: { notifications: [{ read: false, post: { content: expectedContent } }] }, }, }) const { query } = createTestClient(server) await expect( query({ query: notificationQuery, variables: { read: false } }), ).resolves.toEqual(expected) }) describe('who mentions me many times', () => { const updatePostAction = async () => { const updatedContent = ` One more mention to @al-capone and again: @al-capone and again @al-capone ` const updatePostMutation = gql ` mutation($id: ID!, $title: String!, $content: String!) { UpdatePost(id: $id, content: $content, title: $title) { title content } } ` authenticatedUser = await postAuthor.toJson() await mutate({ mutation: updatePostMutation, variables: { id: 'p47', title, content: updatedContent, }, }) authenticatedUser = await user.toJson() } it('creates exactly one more notification', async () => { await createPostAction() await updatePostAction() const expectedContent = '
One more mention to

@al-capone

and again:

@al-capone

and again

@al-capone

' const expected = expect.objectContaining({ data: { currentUser: { notifications: [{ read: false, post: { content: expectedContent } }, { read: false, post: { content: expectedContent } }, ], }, }, }) await expect( query({ query: notificationQuery, variables: { read: false } }), ).resolves.toEqual(expected) }) }) describe('but the author of the post blocked me', () => { beforeEach(async () => { await postAuthor.relateTo(user, 'blocked') }) it('sends no notification', async () => { await createPostAction() const expected = expect.objectContaining({ data: { currentUser: { notifications: [] } }, }) const { query } = createTestClient(server) await expect( query({ query: notificationQuery, variables: { read: false } }), ).resolves.toEqual(expected) }) }) describe('but the author of the post blocked a user I mention in a comment', () => { const createCommentOnPostAction = async () => { await createPostAction() const createCommentMutation = gql ` mutation($id: ID, $title: String!, $content: String!) { CreateComment(id: $id, postId: $postId, content: $commentContent) { id content } } ` // authenticatedUser = await postAuthor.toJson() // authenticatedUser = await user.toJson() await mutate({ mutation: createCommentMutation, variables: { id: 'c47', postId: 'p47', commentContent: 'One mention of me with .' }, }) } let mentioner beforeEach(async () => { await postAuthor.relateTo(user, 'blocked') mentioner = await instance.create('User', { id: 'mentioner', name: 'Mr Mentioner', slug: 'mr-mentioner', email: 'mentioner@example.org', password: '1234', }) }) it('sends no notification', async () => { await createPostAction() const expected = expect.objectContaining({ data: { currentUser: { notifications: [] } }, }) const { query } = createTestClient(server) await expect( query({ query: notificationQuery, variables: { read: false } }), ).resolves.toEqual(expected) }) }) }) }) }) }) describe('Hashtags', () => { const postId = 'p135' 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 ` query($id: ID) { Post(id: $id) { tags { id name } } } ` const postWithHastagsVariables = { id: postId, } const createPostMutation = gql ` mutation($postId: ID, $postTitle: String!, $postContent: String!) { CreatePost(id: $postId, title: $postTitle, content: $postContent) { id title content } } ` describe('authenticated', () => { beforeEach(async () => { authenticatedUser = await user.toJson() }) describe('create a Post with Hashtags', () => { beforeEach(async () => { await mutate({ mutation: createPostMutation, variables: { postId, postTitle, postContent, }, }) }) it('both Hashtags are created with the "id" set to their "name"', async () => { const expected = [{ id: 'Democracy', name: 'Democracy' }, { id: 'Liberty', name: 'Liberty' }, ] await expect( query({ query: postWithHastagsQuery, variables: postWithHastagsVariables }), ).resolves.toEqual( expect.objectContaining({ data: { Post: [{ tags: expect.arrayContaining(expected), }, ], }, }), ) }) describe('afterwards update the Post by removing a Hashtag, leaving a Hashtag and add a Hashtag', () => { // 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 ` mutation($postId: ID!, $postTitle: String!, $updatedPostContent: String!) { UpdatePost(id: $postId, title: $postTitle, content: $updatedPostContent) { id title content } } ` it('only one previous Hashtag and the new Hashtag exists', async () => { await mutate({ mutation: updatePostMutation, variables: { postId, postTitle, updatedPostContent, }, }) const expected = [{ id: 'Elections', name: 'Elections' }, { id: 'Liberty', name: 'Liberty' }, ] await expect( query({ query: postWithHastagsQuery, variables: postWithHastagsVariables }), ).resolves.toEqual( expect.objectContaining({ data: { Post: [{ tags: expect.arrayContaining(expected) }], }, }), ) }) }) }) }) })