2022-08-04 09:24:04 +02:00

721 lines
21 KiB
JavaScript

import { createTestClient } from 'apollo-server-testing'
import Factory, { cleanDatabase } from '../../db/factories'
import { createGroupMutation, groupQuery } from '../../db/graphql/groups'
import { getNeode, getDriver } from '../../db/neo4j'
import createServer from '../../server'
const driver = getDriver()
const neode = getNeode()
let query
let mutate
let authenticatedUser
let user
const categoryIds = ['cat9', 'cat4', 'cat15']
let variables = {}
beforeAll(async () => {
await cleanDatabase()
const { server } = createServer({
context: () => {
return {
driver,
neode,
user: authenticatedUser,
}
},
})
query = createTestClient(server).query
mutate = createTestClient(server).mutate
})
afterAll(async () => {
await cleanDatabase()
})
beforeEach(async () => {
variables = {}
user = await Factory.build(
'user',
{
id: 'current-user',
name: 'TestUser',
},
{
email: 'test@example.org',
password: '1234',
},
)
await Promise.all([
neode.create('Category', {
id: 'cat9',
name: 'Democracy & Politics',
icon: 'university',
}),
neode.create('Category', {
id: 'cat4',
name: 'Environment & Nature',
icon: 'tree',
}),
neode.create('Category', {
id: 'cat15',
name: 'Consumption & Sustainability',
icon: 'shopping-cart',
}),
neode.create('Category', {
id: 'cat27',
name: 'Animal Protection',
icon: 'paw',
}),
])
authenticatedUser = null
})
// TODO: avoid database clean after each test in the future if possible for performance and flakyness reasons by filling the database step by step, see issue https://github.com/Ocelot-Social-Community/Ocelot-Social/issues/4543
afterEach(async () => {
await cleanDatabase()
})
describe('Group', () => {
describe('unauthenticated', () => {
it('throws authorization error', async () => {
const { errors } = await query({ query: groupQuery, variables: {} })
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
})
})
describe('authenticated', () => {
beforeEach(async () => {
authenticatedUser = await user.toJson()
})
let otherUser
beforeEach(async () => {
otherUser = await Factory.build(
'user',
{
id: 'other-user',
name: 'Other TestUser',
},
{
email: 'test2@example.org',
password: '1234',
},
)
authenticatedUser = await otherUser.toJson()
await mutate({
mutation: createGroupMutation,
variables: {
id: 'others-group',
name: 'Uninteresting Group',
about: 'We will change nothing!',
description: 'We love it like it is!?',
groupType: 'closed',
actionRadius: 'international',
categoryIds,
},
})
authenticatedUser = await user.toJson()
await mutate({
mutation: createGroupMutation,
variables: {
id: 'my-group',
name: 'The Best Group',
about: 'We will change the world!',
description: 'Some description',
groupType: 'public',
actionRadius: 'regional',
categoryIds,
},
})
})
describe('query can fetch', () => {
it('groups where user is member (or owner in this case)', async () => {
const expected = {
data: {
Group: [
{
id: 'my-group',
slug: 'the-best-group',
myRole: 'owner',
},
],
},
errors: undefined,
}
await expect(
query({ query: groupQuery, variables: { isMember: true } }),
).resolves.toMatchObject(expected)
})
it('groups where user is not(!) member', async () => {
const expected = {
data: {
Group: expect.arrayContaining([
expect.objectContaining({
id: 'others-group',
slug: 'uninteresting-group',
myRole: null,
}),
]),
},
errors: undefined,
}
await expect(
query({ query: groupQuery, variables: { isMember: false } }),
).resolves.toMatchObject(expected)
})
it('all groups', async () => {
const expected = {
data: {
Group: expect.arrayContaining([
expect.objectContaining({
id: 'my-group',
slug: 'the-best-group',
myRole: 'owner',
}),
expect.objectContaining({
id: 'others-group',
slug: 'uninteresting-group',
myRole: null,
}),
]),
},
errors: undefined,
}
await expect(query({ query: groupQuery, variables: {} })).resolves.toMatchObject(expected)
})
})
// Wolle: describe('can be filtered', () => {
// let followedUser, happyPost, cryPost
// beforeEach(async () => {
// ;[followedUser] = await Promise.all([
// Factory.build(
// 'user',
// {
// id: 'followed-by-me',
// name: 'Followed User',
// },
// {
// email: 'followed@example.org',
// password: '1234',
// },
// ),
// ])
// ;[happyPost, cryPost] = await Promise.all([
// Factory.build('post', { id: 'happy-post' }, { categoryIds: ['cat4'] }),
// Factory.build('post', { id: 'cry-post' }, { categoryIds: ['cat15'] }),
// Factory.build(
// 'post',
// {
// id: 'post-by-followed-user',
// },
// {
// categoryIds: ['cat9'],
// author: followedUser,
// },
// ),
// ])
// })
// describe('no filter', () => {
// it('returns all posts', async () => {
// const postQueryNoFilters = gql`
// query Post($filter: _PostFilter) {
// Post(filter: $filter) {
// id
// }
// }
// `
// const expected = [{ id: 'happy-post' }, { id: 'cry-post' }, { id: 'post-by-followed-user' }]
// variables = { filter: {} }
// await expect(query({ query: postQueryNoFilters, variables })).resolves.toMatchObject({
// data: {
// Post: expect.arrayContaining(expected),
// },
// })
// })
// })
// /* it('by categories', async () => {
// const postQueryFilteredByCategories = gql`
// query Post($filter: _PostFilter) {
// Post(filter: $filter) {
// id
// categories {
// id
// }
// }
// }
// `
// const expected = {
// data: {
// Post: [
// {
// id: 'post-by-followed-user',
// categories: [{ id: 'cat9' }],
// },
// ],
// },
// }
// variables = { ...variables, filter: { categories_some: { id_in: ['cat9'] } } }
// await expect(
// query({ query: postQueryFilteredByCategories, variables }),
// ).resolves.toMatchObject(expected)
// }) */
// describe('by emotions', () => {
// const postQueryFilteredByEmotions = gql`
// query Post($filter: _PostFilter) {
// Post(filter: $filter) {
// id
// emotions {
// emotion
// }
// }
// }
// `
// it('filters by single emotion', async () => {
// const expected = {
// data: {
// Post: [
// {
// id: 'happy-post',
// emotions: [{ emotion: 'happy' }],
// },
// ],
// },
// }
// await user.relateTo(happyPost, 'emoted', { emotion: 'happy' })
// variables = { ...variables, filter: { emotions_some: { emotion_in: ['happy'] } } }
// await expect(
// query({ query: postQueryFilteredByEmotions, variables }),
// ).resolves.toMatchObject(expected)
// })
// it('filters by multiple emotions', async () => {
// const expected = [
// {
// id: 'happy-post',
// emotions: [{ emotion: 'happy' }],
// },
// {
// id: 'cry-post',
// emotions: [{ emotion: 'cry' }],
// },
// ]
// await user.relateTo(happyPost, 'emoted', { emotion: 'happy' })
// await user.relateTo(cryPost, 'emoted', { emotion: 'cry' })
// variables = { ...variables, filter: { emotions_some: { emotion_in: ['happy', 'cry'] } } }
// await expect(
// query({ query: postQueryFilteredByEmotions, variables }),
// ).resolves.toMatchObject({
// data: {
// Post: expect.arrayContaining(expected),
// },
// errors: undefined,
// })
// })
// })
// it('by followed-by', async () => {
// const postQueryFilteredByUsersFollowed = gql`
// query Post($filter: _PostFilter) {
// Post(filter: $filter) {
// id
// author {
// id
// name
// }
// }
// }
// `
// await user.relateTo(followedUser, 'following')
// variables = { filter: { author: { followedBy_some: { id: 'current-user' } } } }
// await expect(
// query({ query: postQueryFilteredByUsersFollowed, variables }),
// ).resolves.toMatchObject({
// data: {
// Post: [
// {
// id: 'post-by-followed-user',
// author: { id: 'followed-by-me', name: 'Followed User' },
// },
// ],
// },
// errors: undefined,
// })
// })
// })
})
})
describe('CreateGroup', () => {
beforeEach(() => {
variables = {
...variables,
id: 'g589',
name: 'The Best Group',
slug: 'the-group',
about: 'We will change the world!',
description: 'Some description',
groupType: 'public',
actionRadius: 'regional',
categoryIds,
}
})
describe('unauthenticated', () => {
it('throws authorization error', async () => {
const { errors } = await mutate({ mutation: createGroupMutation, variables })
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
})
})
describe('authenticated', () => {
beforeEach(async () => {
authenticatedUser = await user.toJson()
})
it('creates a group', async () => {
const expected = {
data: {
CreateGroup: {
name: 'The Best Group',
slug: 'the-group',
about: 'We will change the world!',
},
},
errors: undefined,
}
await expect(mutate({ mutation: createGroupMutation, variables })).resolves.toMatchObject(
expected,
)
})
it('assigns the authenticated user as owner', async () => {
const expected = {
data: {
CreateGroup: {
name: 'The Best Group',
myRole: 'owner',
// Wolle: owner: {
// name: 'TestUser',
// },
},
},
errors: undefined,
}
await expect(mutate({ mutation: createGroupMutation, variables })).resolves.toMatchObject(
expected,
)
})
it('`disabled` and `deleted` default to `false`', async () => {
const expected = { data: { CreateGroup: { disabled: false, deleted: false } } }
await expect(mutate({ mutation: createGroupMutation, variables })).resolves.toMatchObject(
expected,
)
})
})
})
// describe('UpdatePost', () => {
// let author, newlyCreatedPost
// const updatePostMutation = gql`
// mutation ($id: ID!, $title: String!, $content: String!, $image: ImageInput) {
// UpdatePost(id: $id, title: $title, content: $content, image: $image) {
// id
// title
// content
// author {
// name
// slug
// }
// createdAt
// updatedAt
// }
// }
// `
// beforeEach(async () => {
// author = await Factory.build('user', { slug: 'the-author' })
// newlyCreatedPost = await Factory.build(
// 'post',
// {
// id: 'p9876',
// title: 'Old title',
// content: 'Old content',
// },
// {
// author,
// categoryIds,
// },
// )
// variables = {
// id: 'p9876',
// title: 'New title',
// content: 'New content',
// }
// })
// describe('unauthenticated', () => {
// it('throws authorization error', async () => {
// authenticatedUser = null
// expect(mutate({ mutation: updatePostMutation, variables })).resolves.toMatchObject({
// errors: [{ message: 'Not Authorised!' }],
// data: { UpdatePost: null },
// })
// })
// })
// describe('authenticated but not the author', () => {
// beforeEach(async () => {
// authenticatedUser = await user.toJson()
// })
// it('throws authorization error', async () => {
// const { errors } = await mutate({ mutation: updatePostMutation, variables })
// expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
// })
// })
// describe('authenticated as author', () => {
// beforeEach(async () => {
// authenticatedUser = await author.toJson()
// })
// it('updates a post', async () => {
// const expected = {
// data: { UpdatePost: { id: 'p9876', content: 'New content' } },
// errors: undefined,
// }
// await expect(mutate({ mutation: updatePostMutation, variables })).resolves.toMatchObject(
// expected,
// )
// })
// it('updates a post, but maintains non-updated attributes', async () => {
// const expected = {
// data: {
// UpdatePost: { id: 'p9876', content: 'New content', createdAt: expect.any(String) },
// },
// errors: undefined,
// }
// await expect(mutate({ mutation: updatePostMutation, variables })).resolves.toMatchObject(
// expected,
// )
// })
// it('updates the updatedAt attribute', async () => {
// newlyCreatedPost = await newlyCreatedPost.toJson()
// const {
// data: { UpdatePost },
// } = await mutate({ mutation: updatePostMutation, variables })
// expect(newlyCreatedPost.updatedAt).toBeTruthy()
// expect(Date.parse(newlyCreatedPost.updatedAt)).toEqual(expect.any(Number))
// expect(UpdatePost.updatedAt).toBeTruthy()
// expect(Date.parse(UpdatePost.updatedAt)).toEqual(expect.any(Number))
// expect(newlyCreatedPost.updatedAt).not.toEqual(UpdatePost.updatedAt)
// })
// /* describe('no new category ids provided for update', () => {
// it('resolves and keeps current categories', async () => {
// const expected = {
// data: {
// UpdatePost: {
// id: 'p9876',
// categories: expect.arrayContaining([{ id: 'cat9' }, { id: 'cat4' }, { id: 'cat15' }]),
// },
// },
// errors: undefined,
// }
// await expect(mutate({ mutation: updatePostMutation, variables })).resolves.toMatchObject(
// expected,
// )
// })
// }) */
// /* describe('given category ids', () => {
// beforeEach(() => {
// variables = { ...variables, categoryIds: ['cat27'] }
// })
// it('updates categories of a post', async () => {
// const expected = {
// data: {
// UpdatePost: {
// id: 'p9876',
// categories: expect.arrayContaining([{ id: 'cat27' }]),
// },
// },
// errors: undefined,
// }
// await expect(mutate({ mutation: updatePostMutation, variables })).resolves.toMatchObject(
// expected,
// )
// })
// }) */
// describe('params.image', () => {
// describe('is object', () => {
// beforeEach(() => {
// variables = { ...variables, image: { sensitive: true } }
// })
// it('updates the image', async () => {
// await expect(neode.first('Image', { sensitive: true })).resolves.toBeFalsy()
// await mutate({ mutation: updatePostMutation, variables })
// await expect(neode.first('Image', { sensitive: true })).resolves.toBeTruthy()
// })
// })
// describe('is null', () => {
// beforeEach(() => {
// variables = { ...variables, image: null }
// })
// it('deletes the image', async () => {
// await expect(neode.all('Image')).resolves.toHaveLength(6)
// await mutate({ mutation: updatePostMutation, variables })
// await expect(neode.all('Image')).resolves.toHaveLength(5)
// })
// })
// describe('is undefined', () => {
// beforeEach(() => {
// delete variables.image
// })
// it('keeps the image unchanged', async () => {
// await expect(neode.first('Image', { sensitive: true })).resolves.toBeFalsy()
// await mutate({ mutation: updatePostMutation, variables })
// await expect(neode.first('Image', { sensitive: true })).resolves.toBeFalsy()
// })
// })
// })
// })
// })
// describe('DeletePost', () => {
// let author
// const deletePostMutation = gql`
// mutation ($id: ID!) {
// DeletePost(id: $id) {
// id
// deleted
// content
// contentExcerpt
// image {
// url
// }
// comments {
// deleted
// content
// contentExcerpt
// }
// }
// }
// `
// beforeEach(async () => {
// author = await Factory.build('user')
// await Factory.build(
// 'post',
// {
// id: 'p4711',
// title: 'I will be deleted',
// content: 'To be deleted',
// },
// {
// image: Factory.build('image', {
// url: 'path/to/some/image',
// }),
// author,
// categoryIds,
// },
// )
// variables = { ...variables, id: 'p4711' }
// })
// describe('unauthenticated', () => {
// it('throws authorization error', async () => {
// const { errors } = await mutate({ mutation: deletePostMutation, variables })
// expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
// })
// })
// describe('authenticated but not the author', () => {
// beforeEach(async () => {
// authenticatedUser = await user.toJson()
// })
// it('throws authorization error', async () => {
// const { errors } = await mutate({ mutation: deletePostMutation, variables })
// expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
// })
// })
// describe('authenticated as author', () => {
// beforeEach(async () => {
// authenticatedUser = await author.toJson()
// })
// it('marks the post as deleted and blacks out attributes', async () => {
// const expected = {
// data: {
// DeletePost: {
// id: 'p4711',
// deleted: true,
// content: 'UNAVAILABLE',
// contentExcerpt: 'UNAVAILABLE',
// image: null,
// comments: [],
// },
// },
// }
// await expect(mutate({ mutation: deletePostMutation, variables })).resolves.toMatchObject(
// expected,
// )
// })
// describe('if there are comments on the post', () => {
// beforeEach(async () => {
// await Factory.build(
// 'comment',
// {
// content: 'to be deleted comment content',
// contentExcerpt: 'to be deleted comment content',
// },
// {
// postId: 'p4711',
// },
// )
// })
// it('marks the comments as deleted', async () => {
// const expected = {
// data: {
// DeletePost: {
// id: 'p4711',
// deleted: true,
// content: 'UNAVAILABLE',
// contentExcerpt: 'UNAVAILABLE',
// image: null,
// comments: [
// {
// deleted: true,
// // Should we black out the comment content in the database, too?
// content: 'UNAVAILABLE',
// contentExcerpt: 'UNAVAILABLE',
// },
// ],
// },
// },
// }
// await expect(mutate({ mutation: deletePostMutation, variables })).resolves.toMatchObject(
// expected,
// )
// })
// })
// })
// })