Start to refactor backend tests

This commit is contained in:
roschaefer 2019-08-29 20:36:30 +02:00
parent 4b96454b90
commit cf8ead10f3
3 changed files with 149 additions and 188 deletions

View File

@ -197,7 +197,7 @@ const permissions = shield(
RemovePostEmotions: isAuthenticated,
block: isAuthenticated,
unblock: isAuthenticated,
markAsRead: belongsToMe
markAsRead: belongsToMe,
},
User: {
email: isMyOwn,

View File

@ -1,36 +1,33 @@
import { neo4jgraphql } from 'neo4j-graphql-js'
export default {
Query: {
notifications: async (parent, args, context, resolveInfo) => {
const { user, driver } = context
let session
const { user } = context
const session = context.driver.session()
let notifications
let whereClause
let orderByClause
switch(args.read) {
switch (args.read) {
case true:
whereClause = 'WHERE notification.read = TRUE'
break;
break
case false:
whereClause = 'WHERE notification.read = FALSE'
break;
break
default:
whereClause = ''
}
switch(args.orderBy) {
switch (args.orderBy) {
case 'createdAt_asc':
orderByClause = 'ORDER BY notification.createdAt ASC'
break;
break
case 'createdAt_desc':
orderByClause = 'ORDER BY notification.createdAt DESC'
break;
break
default:
orderByClause = ''
}
try {
session = context.driver.session()
const cypher = `
MATCH (resource)-[notification:NOTIFIED]->(user:User {id:$id})
${whereClause}
@ -44,12 +41,12 @@ export default {
...record.get('notification').properties,
from: {
__typename: record.get('resource').labels.find(l => resourceTypes.includes(l)),
...record.get('resource').properties
...record.get('resource').properties,
},
to: {
__typename: 'User',
...record.get('user').properties,
}
},
}
})
} finally {
@ -61,6 +58,6 @@ export default {
Mutation: {
markAsRead: async (parent, params, context, resolveInfo) => {
return null
}
},
},
}

View File

@ -1,25 +1,41 @@
import { GraphQLClient } from 'graphql-request'
import Factory from '../../seed/factories'
import { host, login, gql } from '../../jest/helpers'
import { neode } from '../../bootstrap/neo4j'
import { neode as getNeode, getDriver } from '../../bootstrap/neo4j'
import { createTestClient } from 'apollo-server-testing'
import createServer from '../.././server'
let client
const factory = Factory()
const instance = neode()
const neode = getNeode()
const driver = getDriver()
const userParams = {
id: 'you',
email: 'test@example.org',
password: '1234',
}
const categoryIds = ['cat9']
let authenticatedUser
let variables
let query
let mutate
beforeAll(() => {
const { server } = createServer({
context: () => {
return {
driver,
user: authenticatedUser,
}
},
})
query = createTestClient(server).query
mutate = createTestClient(server).mutate
})
beforeEach(async () => {
await factory.create('User', userParams)
await instance.create('Category', {
id: 'cat9',
name: 'Democracy & Politics',
icon: 'university',
})
authenticatedUser = null
variables = { orderBy: 'createdAt_asc' }
})
afterEach(async () => {
@ -28,129 +44,132 @@ afterEach(async () => {
describe('notifications', () => {
const notificationQuery = gql`
query {
notifications {
id
query($read: Boolean, $orderBy: NOTIFIEDOrdering) {
notifications(read: $read, orderBy: $orderBy) {
from {
__typename
... on Post {
content
}
... on Comment {
content
}
}
read
createdAt
}
}
`
const setupNotifications = [
`
MATCH(user:User {id: 'neighbor'})
MERGE (:Post {id: 'p1', content: 'Not for you'})
-[:NOTIFIED {createdAt: "2019-08-29T17:33:48.651Z", read: false, reason: "mentioned_in_post"}]
->(user);
`,
`
MATCH(user:User {id: 'you'})
MERGE (:Post {id: 'p2', content: 'Already seen post mentioning'})
-[:NOTIFIED {createdAt: "2019-08-30T17:33:48.651Z", read: true, reason: "mentioned_in_post"}]
->(user);
`,
`
MATCH(user:User {id: 'you'})
MERGE (:Post {id: 'p3', content: 'You have been mentioned in a post'})
-[:NOTIFIED {createdAt: "2019-08-31T17:33:48.651Z", read: false, reason: "mentioned_in_post"}]
->(user);
`,
`
MATCH(user:User {id: 'you'})
MATCH(post:Post {id: 'p3'})
CREATE (comment:Comment {id: 'c1', content: 'You have seen this comment mentioning already'})
MERGE (comment)-[:COMMENTS]->(post)
MERGE (comment)
-[:NOTIFIED {createdAt: "2019-08-30T15:33:48.651Z", read: true, reason: "mentioned_in_comment"}]
->(user);
`,
`
MATCH(user:User {id: 'you'})
MATCH(post:Post {id: 'p3'})
CREATE (comment:Comment {id: 'c2', content: 'You have been mentioned in a comment'})
MERGE (comment)-[:COMMENTS]->(post)
MERGE (comment)
-[:NOTIFIED {createdAt: "2019-08-31T17:33:48.651Z", read: false, reason: "mentioned_in_comment"}]
->(user);
`,
`
MATCH(user:User {id: 'neighbor'})
MATCH(post:Post {id: 'p3'})
CREATE (comment:Comment {id: 'c3', content: 'Somebody else was mentioned in a comment'})
MERGE (comment)-[:COMMENTS]->(post)
MERGE (comment)
-[:NOTIFIED {createdAt: "2019-09-01T17:33:48.651Z", read: false, reason: "mentioned_in_comment"}]
->(user);
`,
]
describe('unauthenticated', () => {
it('throws authorization error', async () => {
client = new GraphQLClient(host)
await expect(client.request(notificationQuery)).rejects.toThrow('Not Authorised')
const result = await query({ query: notificationQuery })
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
})
})
describe('authenticated', () => {
let headers
beforeEach(async () => {
headers = await login({
email: 'test@example.org',
password: '1234',
})
client = new GraphQLClient(host, {
headers,
})
const user = await factory.create('User', userParams)
authenticatedUser = await user.toJson()
})
describe('given some notifications', () => {
beforeEach(async () => {
const neighborParams = {
email: 'neighbor@example.org',
password: '1234',
id: 'neighbor',
}
await Promise.all([
factory.create('User', neighborParams),
factory.create('Notification', {
id: 'post-mention-not-for-you',
reason: 'mentioned_in_post',
}),
factory.create('Notification', {
id: 'post-mention-already-seen',
read: true,
reason: 'mentioned_in_post',
}),
factory.create('Notification', {
id: 'post-mention-unseen',
reason: 'mentioned_in_post',
}),
factory.create('Notification', {
id: 'comment-mention-not-for-you',
reason: 'mentioned_in_comment',
}),
factory.create('Notification', {
id: 'comment-mention-already-seen',
read: true,
reason: 'mentioned_in_comment',
}),
factory.create('Notification', {
id: 'comment-mention-unseen',
reason: 'mentioned_in_comment',
}),
])
await factory.authenticateAs(neighborParams)
await factory.create('Post', { id: 'p1', categoryIds })
await Promise.all([
factory.relate('Notification', 'User', {
from: 'post-mention-not-for-you',
to: 'neighbor',
}),
factory.relate('Notification', 'Post', {
from: 'p1',
to: 'post-mention-not-for-you',
}),
factory.relate('Notification', 'User', {
from: 'post-mention-unseen',
to: 'you',
}),
factory.relate('Notification', 'Post', {
from: 'p1',
to: 'post-mention-unseen',
}),
factory.relate('Notification', 'User', {
from: 'post-mention-already-seen',
to: 'you',
}),
factory.relate('Notification', 'Post', {
from: 'p1',
to: 'post-mention-already-seen',
}),
])
// Comment and its notifications
await Promise.all([
factory.create('Comment', {
id: 'c1',
postId: 'p1',
}),
])
await Promise.all([
factory.relate('Notification', 'User', {
from: 'comment-mention-not-for-you',
to: 'neighbor',
}),
factory.relate('Notification', 'Comment', {
from: 'c1',
to: 'comment-mention-not-for-you',
}),
factory.relate('Notification', 'User', {
from: 'comment-mention-unseen',
to: 'you',
}),
factory.relate('Notification', 'Comment', {
from: 'c1',
to: 'comment-mention-unseen',
}),
factory.relate('Notification', 'User', {
from: 'comment-mention-already-seen',
to: 'you',
}),
factory.relate('Notification', 'Comment', {
from: 'c1',
to: 'comment-mention-already-seen',
}),
])
await factory.create('User', { id: 'neighbor' })
await Promise.all(setupNotifications.map(s => neode.cypher(s)))
})
describe('no filters', () => {
it('returns all notifications of current user', async () => {
const expected = expect.objectContaining({
data: {
notifications: [
{
from: {
__typename: 'Comment',
content: 'You have seen this comment mentioning already',
},
read: true,
createdAt: '2019-08-30T15:33:48.651Z',
},
{
from: {
__typename: 'Post',
content: 'Already seen post mentioning',
},
read: true,
createdAt: '2019-08-30T17:33:48.651Z',
},
{
from: {
__typename: 'Comment',
content: 'You have been mentioned in a comment',
},
read: false,
createdAt: '2019-08-31T17:33:48.651Z',
},
{
from: {
__typename: 'Post',
content: 'You have been mentioned in a post',
},
read: false,
createdAt: '2019-08-31T17:33:48.651Z',
},
],
},
})
await expect(query({ query: notificationQuery, variables })).resolves.toEqual(expected)
})
})
describe('filter for read: false', () => {
@ -167,7 +186,7 @@ describe('notifications', () => {
}
}
`
const variables = { read: false }
it('returns only unread notifications of current user', async () => {
const expected = {
currentUser: {
@ -194,61 +213,6 @@ describe('notifications', () => {
).resolves.toEqual(expected)
})
})
describe('no filters', () => {
const queryCurrentUserNotifications = gql`
query {
notifications(orderBy: createdAt_desc) {
id
post {
id
}
comment {
id
}
}
}
`
it('returns all notifications of current user', async () => {
const expected = {
currentUser: {
notifications: expect.arrayContaining([
{
id: 'post-mention-unseen',
post: {
id: 'p1',
},
comment: null,
},
{
id: 'post-mention-already-seen',
post: {
id: 'p1',
},
comment: null,
},
{
id: 'comment-mention-unseen',
comment: {
id: 'c1',
},
post: null,
},
{
id: 'comment-mention-already-seen',
comment: {
id: 'c1',
},
post: null,
},
]),
},
}
await expect(client.request(queryCurrentUserNotifications, variables)).resolves.toEqual(
expected,
)
})
})
})
})
})