diff --git a/backend/src/schema/resolvers/reports.spec.js b/backend/src/schema/resolvers/reports.spec.js
index 4022be1b1..21b1b4a7b 100644
--- a/backend/src/schema/resolvers/reports.spec.js
+++ b/backend/src/schema/resolvers/reports.spec.js
@@ -1,315 +1,16 @@
-import { GraphQLClient } from 'graphql-request'
-import Factory from '../../seed/factories'
-import { host, login, gql } from '../../jest/helpers'
-import { getDriver, neode } from '../../bootstrap/neo4j'
import { createTestClient } from 'apollo-server-testing'
import createServer from '../.././server'
+import Factory from '../../seed/factories'
+import { gql } from '../../jest/helpers'
+import { getDriver, neode as getNeode } from '../../bootstrap/neo4j'
const factory = Factory()
-const instance = neode()
+const instance = getNeode()
const driver = getDriver()
-describe('report mutation', () => {
- let reportMutation
- let headers
- let client
- let variables
- let createPostVariables
- let user
+describe('report resources', () => {
+ let authenticatedUser, currentUser, mutate, query, moderator, abusiveUser
const categoryIds = ['cat9']
-
- const action = () => {
- reportMutation = gql`
- mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) {
- report(
- resourceId: $resourceId
- reasonCategory: $reasonCategory
- reasonDescription: $reasonDescription
- ) {
- createdAt
- reasonCategory
- reasonDescription
- type
- submitter {
- email
- }
- user {
- name
- }
- post {
- title
- }
- comment {
- content
- }
- }
- }
- `
- client = new GraphQLClient(host, {
- headers,
- })
- return client.request(reportMutation, variables)
- }
-
- beforeEach(async () => {
- variables = {
- resourceId: 'whatever',
- reasonCategory: 'other',
- reasonDescription: 'Violates code of conduct !!!',
- }
- headers = {}
- user = await factory.create('User', {
- id: 'u1',
- role: 'user',
- email: 'test@example.org',
- password: '1234',
- })
- await factory.create('User', {
- id: 'u2',
- role: 'user',
- name: 'abusive-user',
- email: 'abusive-user@example.org',
- })
- await instance.create('Category', {
- id: 'cat9',
- name: 'Democracy & Politics',
- icon: 'university',
- })
- })
-
- afterEach(async () => {
- await factory.cleanDatabase()
- })
-
- describe('unauthenticated', () => {
- it('throws authorization error', async () => {
- await expect(action()).rejects.toThrow('Not Authorised')
- })
- })
-
- describe('authenticated', () => {
- beforeEach(async () => {
- headers = await login({
- email: 'test@example.org',
- password: '1234',
- })
- })
-
- describe('invalid resource id', () => {
- it('returns null', async () => {
- await expect(action()).resolves.toEqual({
- report: null,
- })
- })
- })
-
- describe('valid resource id', () => {
- describe('reported resource is a user', () => {
- beforeEach(async () => {
- variables = {
- ...variables,
- resourceId: 'u2',
- }
- })
-
- it('returns type "User"', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- type: 'User',
- },
- })
- })
-
- it('returns resource in user attribute', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- user: {
- name: 'abusive-user',
- },
- },
- })
- })
-
- it('returns the submitter', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- submitter: {
- email: 'test@example.org',
- },
- },
- })
- })
-
- it('returns a date', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- createdAt: expect.any(String),
- },
- })
- })
-
- it('returns the reason category', async () => {
- variables = {
- ...variables,
- reasonCategory: 'criminal_behavior_violation_german_law',
- }
- await expect(action()).resolves.toMatchObject({
- report: {
- reasonCategory: 'criminal_behavior_violation_german_law',
- },
- })
- })
-
- it('gives an error if the reason category is not in enum "ReasonCategory"', async () => {
- variables = {
- ...variables,
- reasonCategory: 'my_category',
- }
- await expect(action()).rejects.toThrow(
- 'got invalid value "my_category"; Expected type ReasonCategory',
- )
- })
-
- it('returns the reason description', async () => {
- variables = {
- ...variables,
- reasonDescription: 'My reason!',
- }
- await expect(action()).resolves.toMatchObject({
- report: {
- reasonDescription: 'My reason!',
- },
- })
- })
-
- it('sanitize the reason description', async () => {
- variables = {
- ...variables,
- reasonDescription: 'My reason !',
- }
- await expect(action()).resolves.toMatchObject({
- report: {
- reasonDescription: 'My reason !',
- },
- })
- })
- })
-
- describe('reported resource is a post', () => {
- beforeEach(async () => {
- await factory.create('Post', {
- author: user,
- id: 'p23',
- title: 'Matt and Robert having a pair-programming',
- categoryIds,
- })
- variables = {
- ...variables,
- resourceId: 'p23',
- }
- })
-
- it('returns type "Post"', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- type: 'Post',
- },
- })
- })
-
- it('returns resource in post attribute', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- post: {
- title: 'Matt and Robert having a pair-programming',
- },
- },
- })
- })
-
- it('returns null in user attribute', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- user: null,
- },
- })
- })
- })
-
- /* An der Stelle würde ich den p23 noch mal prüfen, diesmal muss aber eine error meldung kommen.
- At this point I would check the p23 again, but this time there must be an error message. */
-
- describe('reported resource is a comment', () => {
- beforeEach(async () => {
- createPostVariables = {
- id: 'p1',
- title: 'post to comment on',
- content: 'please comment on me',
- categoryIds,
- }
- await factory.create('Post', { ...createPostVariables, author: user })
- await factory.create('Comment', {
- author: user,
- postId: 'p1',
- id: 'c34',
- content: 'Robert getting tired.',
- })
- variables = {
- ...variables,
- resourceId: 'c34',
- }
- })
-
- it('returns type "Comment"', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- type: 'Comment',
- },
- })
- })
-
- it('returns resource in comment attribute', async () => {
- await expect(action()).resolves.toMatchObject({
- report: {
- comment: {
- content: 'Robert getting tired.',
- },
- },
- })
- })
- })
-
- /* An der Stelle würde ich den c34 noch mal prüfen, diesmal muss aber eine error meldung kommen.
- At this point I would check the c34 again, but this time there must be an error message. */
-
- describe('reported resource is a tag', () => {
- beforeEach(async () => {
- await factory.create('Tag', {
- id: 't23',
- })
- variables = {
- ...variables,
- resourceId: 't23',
- }
- })
-
- it('returns null', async () => {
- await expect(action()).resolves.toMatchObject({
- report: null,
- })
- })
- })
-
- /* An der Stelle würde ich den t23 noch mal prüfen, diesmal muss aber eine error meldung kommen.
- At this point I would check the t23 again, but this time there must be an error message. */
- })
- })
-})
-
-describe('reports query', () => {
- let query, mutate, authenticatedUser, moderator, user, author
- const categoryIds = ['cat9']
-
const reportMutation = gql`
mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) {
report(
@@ -317,32 +18,30 @@ describe('reports query', () => {
reasonCategory: $reasonCategory
reasonDescription: $reasonDescription
) {
- type
- }
- }
- `
- const reportsQuery = gql`
- query {
- reports(orderBy: createdAt_desc) {
createdAt
reasonCategory
reasonDescription
- submitter {
- id
- }
type
+ submitter {
+ email
+ }
user {
- id
+ name
}
post {
- id
+ title
}
comment {
- id
+ content
}
}
}
`
+ const variables = {
+ resourceId: 'whatever',
+ reasonCategory: 'other',
+ reasonDescription: 'Violates code of conduct !!!',
+ }
beforeAll(async () => {
await factory.cleanDatabase()
@@ -350,172 +49,545 @@ describe('reports query', () => {
context: () => {
return {
driver,
+ neode: instance,
user: authenticatedUser,
}
},
})
- query = createTestClient(server).query
mutate = createTestClient(server).mutate
- })
-
- beforeEach(async () => {
- authenticatedUser = null
-
- moderator = await factory.create('User', {
- id: 'mod1',
- role: 'moderator',
- email: 'moderator@example.org',
- password: '1234',
- })
- user = await factory.create('User', {
- id: 'user1',
- role: 'user',
- email: 'test@example.org',
- password: '1234',
- })
- author = await factory.create('User', {
- id: 'auth1',
- role: 'user',
- name: 'abusive-user',
- email: 'abusive-user@example.org',
- })
- await instance.create('Category', {
- id: 'cat9',
- name: 'Democracy & Politics',
- icon: 'university',
- })
-
- await Promise.all([
- factory.create('Post', {
- author,
- id: 'p1',
- categoryIds,
- content: 'Interesting Knowledge',
- }),
- factory.create('Post', {
- author: moderator,
- id: 'p2',
- categoryIds,
- content: 'More things to do …',
- }),
- factory.create('Post', {
- author: user,
- id: 'p3',
- categoryIds,
- content: 'I am at school …',
- }),
- ])
- await Promise.all([
- factory.create('Comment', {
- author: user,
- id: 'c1',
- postId: 'p1',
- }),
- ])
-
- authenticatedUser = await user.toJson()
- await Promise.all([
- mutate({
- mutation: reportMutation,
- variables: {
- resourceId: 'p1',
- reasonCategory: 'other',
- reasonDescription: 'This comment is bigoted',
- },
- }),
- mutate({
- mutation: reportMutation,
- variables: {
- resourceId: 'c1',
- reasonCategory: 'discrimination_etc',
- reasonDescription: 'This post is bigoted',
- },
- }),
- mutate({
- mutation: reportMutation,
- variables: {
- resourceId: 'auth1',
- reasonCategory: 'doxing',
- reasonDescription: 'This user is harassing me with bigoted remarks',
- },
- }),
- ])
- authenticatedUser = null
+ query = createTestClient(server).query
})
afterEach(async () => {
await factory.cleanDatabase()
})
- describe('unauthenticated', () => {
- it('throws authorization error', async () => {
+ describe('report a resource', () => {
+ describe('unauthenticated', () => {
+ it('throws authorization error', async () => {
+ authenticatedUser = null
+ await expect(mutate({ mutation: reportMutation, variables })).resolves.toMatchObject({
+ data: { report: null },
+ errors: [{ message: 'Not Authorised!' }],
+ })
+ })
+ })
+
+ describe('authenticated', () => {
+ beforeEach(async () => {
+ currentUser = await factory.create('User', {
+ id: 'current-user-id',
+ role: 'user',
+ email: 'test@example.org',
+ password: '1234',
+ })
+ await factory.create('User', {
+ id: 'abusive-user-id',
+ role: 'user',
+ name: 'abusive-user',
+ email: 'abusive-user@example.org',
+ })
+ await instance.create('Category', {
+ id: 'cat9',
+ name: 'Democracy & Politics',
+ icon: 'university',
+ })
+
+ authenticatedUser = await currentUser.toJson()
+ })
+
+ describe('invalid resource id', () => {
+ it('returns null', async () => {
+ await expect(mutate({ mutation: reportMutation, variables })).resolves.toMatchObject({
+ data: { report: null },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('valid resource', () => {
+ describe('reported resource is a user', () => {
+ it('returns type "User"', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: { ...variables, resourceId: 'abusive-user-id' },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ type: 'User',
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('returns resource in user attribute', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: { ...variables, resourceId: 'abusive-user-id' },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ user: {
+ name: 'abusive-user',
+ },
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('returns the submitter', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: { ...variables, resourceId: 'abusive-user-id' },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ submitter: {
+ email: 'test@example.org',
+ },
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('returns a date', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: { ...variables, resourceId: 'abusive-user-id' },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ createdAt: expect.any(String),
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('returns the reason category', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'abusive-user-id',
+ reasonCategory: 'criminal_behavior_violation_german_law',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ reasonCategory: 'criminal_behavior_violation_german_law',
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('gives an error if the reason category is not in enum "ReasonCategory"', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'abusive-user-id',
+ reasonCategory: 'category_missing_from_enum_reason_category',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: undefined,
+ errors: [
+ {
+ message:
+ 'Variable "$reasonCategory" got invalid value "category_missing_from_enum_reason_category"; Expected type ReasonCategory.',
+ },
+ ],
+ })
+ })
+
+ it('returns the reason description', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'abusive-user-id',
+ reasonDescription: 'My reason!',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ reasonDescription: 'My reason!',
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('sanitize the reason description', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'abusive-user-id',
+ reasonDescription: 'My reason !',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ reasonDescription: 'My reason !',
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('reported resource is a post', () => {
+ beforeEach(async () => {
+ await factory.create('Post', {
+ author: currentUser,
+ id: 'post-to-report-id',
+ title: 'This is a post that is going to be reported',
+ categoryIds,
+ })
+ })
+
+ it('returns type "Post"', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'post-to-report-id',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ type: 'Post',
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('returns resource in post attribute', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'post-to-report-id',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ post: {
+ title: 'This is a post that is going to be reported',
+ },
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('returns null in user attribute', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'post-to-report-id',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ user: null,
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('reported resource is a comment', () => {
+ let createPostVariables
+ beforeEach(async () => {
+ createPostVariables = {
+ id: 'p1',
+ title: 'post to comment on',
+ content: 'please comment on me',
+ categoryIds,
+ }
+ await factory.create('Post', { ...createPostVariables, author: currentUser })
+ await factory.create('Comment', {
+ author: currentUser,
+ postId: 'p1',
+ id: 'comment-to-report-id',
+ content: 'Post comment to be reported.',
+ })
+ })
+
+ it('returns type "Comment"', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'comment-to-report-id',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ type: 'Comment',
+ },
+ },
+ errors: undefined,
+ })
+ })
+
+ it('returns resource in comment attribute', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'comment-to-report-id',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: {
+ report: {
+ comment: {
+ content: 'Post comment to be reported.',
+ },
+ },
+ },
+ errors: undefined,
+ })
+ })
+ })
+
+ describe('reported resource is a tag', () => {
+ beforeEach(async () => {
+ await factory.create('Tag', {
+ id: 'tag-to-report-id',
+ })
+ })
+
+ it('returns null', async () => {
+ await expect(
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ ...variables,
+ resourceId: 'tag-to-report-id',
+ },
+ }),
+ ).resolves.toMatchObject({
+ data: { report: null },
+ errors: undefined,
+ })
+ })
+ })
+ })
+ })
+ })
+ describe('query for reported resource', () => {
+ const reportsQuery = gql`
+ query {
+ reports(orderBy: createdAt_desc) {
+ createdAt
+ reasonCategory
+ reasonDescription
+ submitter {
+ id
+ }
+ type
+ user {
+ id
+ }
+ post {
+ id
+ }
+ comment {
+ id
+ }
+ }
+ }
+ `
+
+ beforeEach(async () => {
authenticatedUser = null
- expect(query({ query: reportsQuery })).resolves.toMatchObject({
- data: { reports: null },
- errors: [{ message: 'Not Authorised!' }],
- })
- })
- it('role "user" gets no reports', async () => {
- authenticatedUser = await user.toJson()
- expect(query({ query: reportsQuery })).resolves.toMatchObject({
- data: { reports: null },
- errors: [{ message: 'Not Authorised!' }],
+ moderator = await factory.create('User', {
+ id: 'moderator-1',
+ role: 'moderator',
+ email: 'moderator@example.org',
+ password: '1234',
+ })
+ currentUser = await factory.create('User', {
+ id: 'current-user-id',
+ role: 'user',
+ email: 'current.user@example.org',
+ password: '1234',
+ })
+ abusiveUser = await factory.create('User', {
+ id: 'abusive-user-1',
+ role: 'user',
+ name: 'abusive-user',
+ email: 'abusive-user@example.org',
+ })
+ await instance.create('Category', {
+ id: 'cat9',
+ name: 'Democracy & Politics',
+ icon: 'university',
})
- })
- it('role "moderator" gets reports', async () => {
- const expected = {
- // to check 'orderBy: createdAt_desc' is not possible here, because 'createdAt' does not differ
- reports: expect.arrayContaining([
- expect.objectContaining({
- createdAt: expect.any(String),
- reasonCategory: 'doxing',
- reasonDescription: 'This user is harassing me with bigoted remarks',
- submitter: expect.objectContaining({
- id: 'user1',
- }),
- type: 'User',
- user: expect.objectContaining({
- id: 'auth1',
- }),
- post: null,
- comment: null,
- }),
- expect.objectContaining({
- createdAt: expect.any(String),
+ await Promise.all([
+ factory.create('Post', {
+ author: abusiveUser,
+ id: 'abusive-post-1',
+ categoryIds,
+ content: 'Interesting Knowledge',
+ }),
+ factory.create('Post', {
+ author: moderator,
+ id: 'post-2',
+ categoryIds,
+ content: 'More things to do …',
+ }),
+ factory.create('Post', {
+ author: currentUser,
+ id: 'post-3',
+ categoryIds,
+ content: 'I am at school …',
+ }),
+ ])
+ await Promise.all([
+ factory.create('Comment', {
+ author: currentUser,
+ id: 'abusive-comment-1',
+ postId: 'post-1',
+ }),
+ ])
+ authenticatedUser = await currentUser.toJson()
+ await Promise.all([
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ resourceId: 'abusive-post-1',
reasonCategory: 'other',
reasonDescription: 'This comment is bigoted',
- submitter: expect.objectContaining({
- id: 'user1',
- }),
- type: 'Post',
- user: null,
- post: expect.objectContaining({
- id: 'p1',
- }),
- comment: null,
- }),
- expect.objectContaining({
- createdAt: expect.any(String),
+ },
+ }),
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ resourceId: 'abusive-comment-1',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This post is bigoted',
- submitter: expect.objectContaining({
- id: 'user1',
- }),
- type: 'Comment',
- user: null,
- post: null,
- comment: expect.objectContaining({
- id: 'c1',
- }),
- }),
- ]),
- }
+ },
+ }),
+ mutate({
+ mutation: reportMutation,
+ variables: {
+ resourceId: 'abusive-user-1',
+ reasonCategory: 'doxing',
+ reasonDescription: 'This user is harassing me with bigoted remarks',
+ },
+ }),
+ ])
+ authenticatedUser = null
+ })
+ describe('unauthenticated', () => {
+ it('throws authorization error', async () => {
+ authenticatedUser = null
+ expect(query({ query: reportsQuery })).resolves.toMatchObject({
+ data: { reports: null },
+ errors: [{ message: 'Not Authorised!' }],
+ })
+ })
+ })
+ describe('authenticated', () => {
+ it('role "user" gets no reports', async () => {
+ authenticatedUser = await currentUser.toJson()
+ expect(query({ query: reportsQuery })).resolves.toMatchObject({
+ data: { reports: null },
+ errors: [{ message: 'Not Authorised!' }],
+ })
+ })
- authenticatedUser = await moderator.toJson()
- const { data } = await query({ query: reportsQuery })
- expect(data).toEqual(expected)
+ it('role "moderator" gets reports', async () => {
+ const expected = {
+ // to check 'orderBy: createdAt_desc' is not possible here, because 'createdAt' does not differ
+ reports: expect.arrayContaining([
+ expect.objectContaining({
+ createdAt: expect.any(String),
+ reasonCategory: 'doxing',
+ reasonDescription: 'This user is harassing me with bigoted remarks',
+ submitter: expect.objectContaining({
+ id: 'current-user-id',
+ }),
+ type: 'User',
+ user: expect.objectContaining({
+ id: 'abusive-user-1',
+ }),
+ post: null,
+ comment: null,
+ }),
+ expect.objectContaining({
+ createdAt: expect.any(String),
+ reasonCategory: 'other',
+ reasonDescription: 'This comment is bigoted',
+ submitter: expect.objectContaining({
+ id: 'current-user-id',
+ }),
+ type: 'Post',
+ user: null,
+ post: expect.objectContaining({
+ id: 'abusive-post-1',
+ }),
+ comment: null,
+ }),
+ expect.objectContaining({
+ createdAt: expect.any(String),
+ reasonCategory: 'discrimination_etc',
+ reasonDescription: 'This post is bigoted',
+ submitter: expect.objectContaining({
+ id: 'current-user-id',
+ }),
+ type: 'Comment',
+ user: null,
+ post: null,
+ comment: expect.objectContaining({
+ id: 'abusive-comment-1',
+ }),
+ }),
+ ]),
+ }
+ authenticatedUser = await moderator.toJson()
+ const { data } = await query({ query: reportsQuery })
+ expect(data).toEqual(expected)
+ })
})
})
})