Add backend tests for RemovePostEmotions

This commit is contained in:
Matt Rider 2019-07-30 13:28:30 +02:00
parent 3e43539e23
commit 0a98113c2d
5 changed files with 199 additions and 33 deletions

View File

@ -24,6 +24,12 @@ const onlyYourself = rule({
return context.user.id === args.id
})
const isMyEmotion = rule({
cache: 'no_cache',
})(async (parent, args, context, info) => {
return context.user.id === args.from.id
})
const isMyOwn = rule({
cache: 'no_cache',
})(async (parent, args, context, info) => {
@ -184,7 +190,7 @@ const permissions = shield(
requestPasswordReset: allow,
resetPassword: allow,
AddPostEmotions: isAuthenticated,
RemovePostEmotions: isAuthenticated,
RemovePostEmotions: isMyEmotion,
},
User: {
email: isMyOwn,

View File

@ -96,14 +96,15 @@ export default {
const transactionRes = await session.run(
`MATCH (userFrom:User {id: $from.id})-[emotedRelation:EMOTED {emotion: $data.emotion}]->(postTo:Post {id: $to.id})
DELETE emotedRelation
RETURN emotedRelation`,
`,
{ from, to, data },
)
session.close()
const [removed] = transactionRes.records.map(record => {
return record.get('emotedRelation')
const [emoted] = transactionRes.records.map(record => {
return record.get('emotedRelation').properties.emotion
})
return !!removed
return !emoted
},
},
}

View File

@ -64,6 +64,7 @@ beforeEach(async () => {
password: '1234',
}
authorParams = {
id: 'u25',
email: 'author@example.org',
password: '1234',
}
@ -387,11 +388,23 @@ describe('DeletePost', () => {
describe('emotions', () => {
let addPostEmotionsVariables
let postEmotionsVariables
let postEmotionsQueryVariables
const postEmotionsQuery = `
query($id: ID!) {
Post(id: $id) {
emotions {
emotion
User {
id
}
}
}
}
`
beforeEach(async () => {
const asAuthor = Factory()
authorParams = {
id: 'u25',
id: authorParams.id,
email: 'wanna-add-emotions@example.org',
password: '1234',
}
@ -402,17 +415,18 @@ describe('emotions', () => {
title: postTitle,
content: postContent,
})
addPostEmotionsVariables = {
from: { id: authorParams.id },
to: { id: 'p1376' },
data: { emotion: 'happy' },
}
postEmotionsVariables = {
id: 'p1376',
}
postEmotionsQueryVariables = { id: 'p1376' }
})
describe('AddPostEmotions', () => {
beforeEach(() => {
addPostEmotionsVariables = {
from: { id: authorParams.id },
to: { id: 'p1376' },
data: { emotion: 'happy' },
}
})
const addPostEmotionsMutation = `
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
AddPostEmotions(from: $from, to: $to, data: $data) {
@ -429,22 +443,13 @@ describe('emotions', () => {
}
}
`
const postEmotionsQuery = `
query($id: ID!) {
Post(id: $id) {
emotions {
emotion
}
}
}
`
describe('unauthenticated', () => {
it('throws authorization error', async () => {
client = new GraphQLClient(host)
await expect(
client.request(addPostEmotionsMutation, {
from: { id: 'u25' },
from: { id: authorParams.id },
to: { id: 'p1376' },
data: { emotion: 'happy' },
}),
@ -472,6 +477,7 @@ describe('emotions', () => {
client.request(addPostEmotionsMutation, addPostEmotionsVariables),
).resolves.toEqual(expected)
})
it('limits the addition of the same emotion to 1', async () => {
const expected = {
Post: [
@ -483,16 +489,21 @@ describe('emotions', () => {
await client.request(addPostEmotionsMutation, addPostEmotionsVariables)
await client.request(addPostEmotionsMutation, addPostEmotionsVariables)
await expect(
client.request(postEmotionsCountQuery, postEmotionsVariables),
client.request(postEmotionsCountQuery, postEmotionsQueryVariables),
).resolves.toEqual(expected)
})
it('allows a user to add more than one emotion', async () => {
const expected = [{ emotion: 'happy' }, { emotion: 'surprised' }]
const expected = [
{ emotion: 'happy', User: { id: authorParams.id } },
{ emotion: 'surprised', User: { id: authorParams.id } },
]
await client.request(addPostEmotionsMutation, addPostEmotionsVariables)
addPostEmotionsVariables.data.emotion = 'surprised'
await client.request(addPostEmotionsMutation, addPostEmotionsVariables)
await expect(client.request(postEmotionsQuery, postEmotionsVariables)).resolves.toEqual({
await expect(
client.request(postEmotionsQuery, postEmotionsQueryVariables),
).resolves.toEqual({
Post: [{ emotions: expect.arrayContaining(expected) }],
})
})
@ -521,22 +532,73 @@ describe('emotions', () => {
})
describe('RemovePostEmotions', () => {
let removePostEmotionsVariables
const removePostEmotionsMutation = `
mutation($from: _UserInput!, $to: _PostInput!, $data: _EMOTEDInput!) {
RemovePostEmotions(from: $from, to: $to, data: $data)
}
`
beforeEach(() => {
removePostEmotionsVariables = {
from: { id: authorParams.id },
to: { id: 'p1376' },
data: { emotion: 'cry' },
}
})
describe('unauthenticated', () => {
it('throws authorization error', async () => {
client = new GraphQLClient(host)
await expect(
client.request(removePostEmotionsMutation, {
from: { id: 'u25' },
to: { id: 'p1376' },
data: { emotion: 'happy' },
}),
client.request(removePostEmotionsMutation, removePostEmotionsVariables),
).rejects.toThrow('Not Authorised')
})
})
describe('authenticated', () => {
let headers
beforeEach(async () => {
headers = await login(authorParams)
client = new GraphQLClient(host, { headers })
await factory.emote({
from: authorParams.id,
to: 'p1376',
data: 'cry',
})
await factory.emote({
from: authorParams.id,
to: 'p1376',
data: 'happy',
})
})
describe('but not the emoter', () => {
it('throws an authorization error', async () => {
removePostEmotionsVariables.from.id = userParams.id
await expect(
client.request(removePostEmotionsMutation, removePostEmotionsVariables),
).rejects.toThrow('Not Authorised')
})
})
describe('as the emoter', () => {
it('removes an emotion from a post', async () => {
const expected = { RemovePostEmotions: true }
await expect(
client.request(removePostEmotionsMutation, removePostEmotionsVariables),
).resolves.toEqual(expected)
})
it('removes only the requested emotion, not all emotions', async () => {
const expected = [{ emotion: 'happy', User: { id: authorParams.id } }]
await client.request(removePostEmotionsMutation, removePostEmotionsVariables)
await expect(
client.request(postEmotionsQuery, postEmotionsQueryVariables),
).resolves.toEqual({
Post: [{ emotions: expect.arrayContaining(expected) }],
})
})
})
})
})
})

View File

@ -130,6 +130,23 @@ export default function Factory(options = {}) {
this.lastResponse = await cleanDatabase({ driver: this.neo4jDriver })
return this
},
async emote({ from, to, data }) {
const mutation = `
mutation {
AddPostEmotions(
from: { id: "${from}" },
to: { id: "${to}" },
data: { emotion: ${data} }
) {
from { id }
to { id }
emotion
}
}
`
this.lastResponse = await this.graphQLClient.request(mutation)
return this
},
}
result.authenticateAs.bind(result)
result.create.bind(result)

View File

@ -487,6 +487,86 @@ import Factory from './factories'
from: 'p15',
to: 'Demokratie',
}),
f.emote({
from: 'u1',
to: 'p15',
data: 'surprised',
}),
f.emote({
from: 'u2',
to: 'p14',
data: 'cry',
}),
f.emote({
from: 'u3',
to: 'p13',
data: 'angry',
}),
f.emote({
from: 'u4',
to: 'p12',
data: 'funny',
}),
f.emote({
from: 'u5',
to: 'p11',
data: 'surprised',
}),
f.emote({
from: 'u6',
to: 'p10',
data: 'cry',
}),
f.emote({
from: 'u5',
to: 'p9',
data: 'happy',
}),
f.emote({
from: 'u4',
to: 'p8',
data: 'angry',
}),
f.emote({
from: 'u3',
to: 'p7',
data: 'funny',
}),
f.emote({
from: 'u2',
to: 'p6',
data: 'surprised',
}),
f.emote({
from: 'u1',
to: 'p5',
data: 'cry',
}),
f.emote({
from: 'u2',
to: 'p4',
data: 'happy',
}),
f.emote({
from: 'u3',
to: 'p3',
data: 'angry',
}),
f.emote({
from: 'u4',
to: 'p2',
data: 'funny',
}),
f.emote({
from: 'u5',
to: 'p1',
data: 'surprised',
}),
f.emote({
from: 'u6',
to: 'p0',
data: 'cry',
}),
])
await Promise.all([