Ocelot-Social/backend/src/schema/resolvers/notifications.spec.js
2020-03-11 11:03:03 +01:00

665 lines
20 KiB
JavaScript

import Factory, { cleanDatabase } from '../../db/factories'
import { gql } from '../../helpers/jest'
import { getDriver } from '../../db/neo4j'
import { createTestClient } from 'apollo-server-testing'
import createServer from '../.././server'
const driver = getDriver()
let authenticatedUser
let user
let author
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 () => {
authenticatedUser = null
variables = { orderBy: 'updatedAt_desc' }
})
afterEach(async () => {
await cleanDatabase()
})
describe('given some notifications', () => {
beforeEach(async () => {
const categoryIds = ['cat1']
author = await Factory.build('user', { id: 'author' })
user = await Factory.build('user', { id: 'you' })
const [neighbor, badWomen] = await Promise.all([
Factory.build('user', { id: 'neighbor' }),
Factory.build('user', { id: 'badWomen', name: 'Mrs. Badwomen' }),
Factory.build('category', { id: 'cat1' }),
])
const [post1, post2, post3, post4] = await Promise.all([
Factory.build('post', { id: 'p1', content: 'Not for you' }, { author, categoryIds }),
Factory.build(
'post',
{
id: 'p2',
content: 'Already seen post mention',
},
{
author,
categoryIds,
},
),
Factory.build(
'post',
{
id: 'p3',
content: 'You have been mentioned in a post',
},
{
author,
categoryIds,
},
),
Factory.build(
'post',
{
id: 'p4',
title: 'Bad Post',
content: 'I am bad content !!!',
},
{
author,
categoryIds,
},
),
])
const [comment1, comment2, comment3, comment4] = await Promise.all([
Factory.build(
'comment',
{
id: 'c1',
content: 'You have seen this comment mentioning already',
},
{
author,
postId: 'p3',
},
),
Factory.build(
'comment',
{
id: 'c2',
content: 'You have been mentioned in a comment',
},
{
author,
postId: 'p3',
},
),
Factory.build(
'comment',
{
id: 'c3',
content: 'Somebody else was mentioned in a comment',
},
{
author,
postId: 'p3',
},
),
Factory.build(
'comment',
{
id: 'c4',
content: 'I am harassing content in a harassing comment to a bad post !!!',
},
{
author,
postId: 'p4',
},
),
])
await Promise.all([
neighbor.relateTo(post1, 'notified', {
createdAt: '2019-08-29T17:33:48.651Z',
updatedAt: '2019-08-29T17:33:48.651Z',
read: false,
reason: 'mentioned_in_post',
}),
user.relateTo(post2, 'notified', {
createdAt: '2019-08-30T17:33:48.651Z',
updatedAt: '2019-08-30T17:33:48.651Z',
read: true,
reason: 'mentioned_in_post',
}),
user.relateTo(post3, 'notified', {
createdAt: '2019-08-31T17:33:48.651Z',
updatedAt: '2019-08-31T17:33:48.651Z',
read: false,
reason: 'mentioned_in_post',
}),
user.relateTo(comment1, 'notified', {
createdAt: '2019-08-30T15:33:48.651Z',
updatedAt: '2019-08-30T15:33:48.651Z',
read: true,
reason: 'mentioned_in_comment',
}),
user.relateTo(comment2, 'notified', {
createdAt: '2019-08-30T19:33:48.651Z',
updatedAt: '2019-08-30T19:33:48.651Z',
read: false,
reason: 'mentioned_in_comment',
}),
neighbor.relateTo(comment3, 'notified', {
createdAt: '2019-09-01T17:33:48.651Z',
updatedAt: '2019-09-01T17:33:48.651Z',
read: false,
reason: 'mentioned_in_comment',
}),
])
// report notifications
const [reportOnUser, reportOnPost, reportOnComment] = await Promise.all([
Factory.build('report', { id: 'reportOnUser' }),
Factory.build('report', { id: 'reportOnPost' }),
Factory.build('report', { id: 'reportOnComment' }),
])
await Promise.all([
reportOnUser.relateTo(user, 'filed', {
resourceId: 'badWomen',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
}),
reportOnUser.relateTo(badWomen, 'belongsTo'),
reportOnPost.relateTo(user, 'filed', {
resourceId: 'p4',
reasonCategory: 'other',
reasonDescription: "This shouldn't be shown to anybody else! It's my private thing!",
}),
reportOnPost.relateTo(post4, 'belongsTo'),
reportOnComment.relateTo(user, 'filed', {
resourceId: 'c4',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me!',
}),
reportOnComment.relateTo(comment4, 'belongsTo'),
])
await Promise.all([
user.relateTo(reportOnUser, 'notified', {
createdAt: '2020-01-15T16:33:48.651Z',
updatedAt: '2020-01-15T16:33:48.651Z',
read: false,
reason: 'filed_report_on_resource',
}),
user.relateTo(reportOnPost, 'notified', {
createdAt: '2020-01-16T10:33:48.651Z',
updatedAt: '2020-01-16T10:33:48.651Z',
read: true,
reason: 'filed_report_on_resource',
}),
user.relateTo(reportOnComment, 'notified', {
createdAt: '2020-01-14T12:33:48.651Z',
updatedAt: '2020-01-14T12:33:48.651Z',
read: false,
reason: 'filed_report_on_resource',
}),
])
})
describe('notifications', () => {
const notificationQuery = gql`
query($read: Boolean, $orderBy: NotificationOrdering) {
notifications(read: $read, orderBy: $orderBy) {
createdAt
updatedAt
read
reason
from {
__typename
... on Post {
content
}
... on Comment {
content
}
# Wolle ... on Report {
# id
# filed {
# reasonCategory
# reasonDescription
# reportedResource {
# __typename
# ... on User {
# id
# name
# }
# ... on Post {
# id
# title
# content
# }
# ... on Comment {
# id
# content
# }
# }
# }
# }
... on FiledReport {
reportId
reasonCategory
reasonDescription
resource {
__typename
... on User {
id
name
}
... on Post {
id
title
content
}
... on Comment {
id
content
}
}
}
}
}
}
`
describe('unauthenticated', () => {
it('throws authorization error', async () => {
const { errors } = await query({ query: notificationQuery })
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
})
})
describe('authenticated', () => {
beforeEach(async () => {
authenticatedUser = await user.toJson()
})
describe('no filters', () => {
it('returns all notifications of current user', async () => {
const expected = {
data: {
notifications: [
{
createdAt: '2020-01-16T10:33:48.651Z',
updatedAt: '2020-01-16T10:33:48.651Z',
read: true,
reason: 'filed_report_on_resource',
from: {
__typename: 'FiledReport',
reportId: 'reportOnPost',
reasonCategory: 'other',
reasonDescription:
"This shouldn't be shown to anybody else! It's my private thing!",
resource: {
__typename: 'Post',
id: 'p4',
title: 'Bad Post',
content: 'I am bad content !!!',
},
},
},
{
createdAt: '2020-01-15T16:33:48.651Z',
updatedAt: '2020-01-15T16:33:48.651Z',
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'FiledReport',
reportId: 'reportOnUser',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
resource: {
__typename: 'User',
id: 'badWomen',
name: 'Mrs. Badwomen',
},
},
},
{
createdAt: '2020-01-14T12:33:48.651Z',
updatedAt: '2020-01-14T12:33:48.651Z',
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'FiledReport',
reportId: 'reportOnComment',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me!',
resource: {
__typename: 'Comment',
id: 'c4',
content:
'I am harassing content in a harassing comment to a bad post !!!',
},
},
},
expect.objectContaining({
createdAt: '2019-08-31T17:33:48.651Z',
updatedAt: '2019-08-31T17:33:48.651Z',
read: false,
from: {
__typename: 'Post',
content: 'You have been mentioned in a post',
},
}),
expect.objectContaining({
createdAt: '2019-08-30T19:33:48.651Z',
updatedAt: '2019-08-30T19:33:48.651Z',
read: false,
from: {
__typename: 'Comment',
content: 'You have been mentioned in a comment',
},
}),
expect.objectContaining({
createdAt: '2019-08-30T17:33:48.651Z',
updatedAt: '2019-08-30T17:33:48.651Z',
read: true,
from: {
__typename: 'Post',
content: 'Already seen post mention',
},
}),
expect.objectContaining({
createdAt: '2019-08-30T15:33:48.651Z',
updatedAt: '2019-08-30T15:33:48.651Z',
read: true,
from: {
__typename: 'Comment',
content: 'You have seen this comment mentioning already',
},
}),
],
},
errors: undefined,
}
const response = await query({ query: notificationQuery, variables })
await expect(response).toMatchObject(expected)
await expect(response.data.notifications.length).toEqual(7) // has to be checked, because of 'arrayContaining'
})
})
describe('filter for read: false', () => {
it('returns only unread notifications of current user', async () => {
const expected = {
data: {
notifications: [
{
createdAt: '2020-01-15T16:33:48.651Z',
updatedAt: '2020-01-15T16:33:48.651Z',
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'FiledReport',
reportId: 'reportOnUser',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me with bigoted remarks!',
resource: {
__typename: 'User',
id: 'badWomen',
name: 'Mrs. Badwomen',
},
},
},
{
createdAt: '2020-01-14T12:33:48.651Z',
updatedAt: '2020-01-14T12:33:48.651Z',
read: false,
reason: 'filed_report_on_resource',
from: {
__typename: 'FiledReport',
reportId: 'reportOnComment',
reasonCategory: 'discrimination_etc',
reasonDescription: 'This user is harassing me!',
resource: {
__typename: 'Comment',
id: 'c4',
content:
'I am harassing content in a harassing comment to a bad post !!!',
},
},
},
{
createdAt: '2019-08-31T17:33:48.651Z',
updatedAt: '2019-08-31T17:33:48.651Z',
read: false,
reason: 'mentioned_in_post',
from: {
__typename: 'Post',
content: 'You have been mentioned in a post',
},
},
{
createdAt: '2019-08-30T19:33:48.651Z',
updatedAt: '2019-08-30T19:33:48.651Z',
read: false,
reason: 'mentioned_in_comment',
from: {
__typename: 'Comment',
content: 'You have been mentioned in a comment',
},
},
],
},
errors: undefined,
}
const response = await query({
query: notificationQuery,
variables: { ...variables, read: false },
})
await expect(response).toMatchObject(expected)
await expect(response.data.notifications.length).toEqual(4) // has to be checked, because of 'arrayContaining'
})
describe('if a resource gets deleted', () => {
const deletePostAction = async () => {
authenticatedUser = await author.toJson()
const deletePostMutation = gql`
mutation($id: ID!) {
DeletePost(id: $id) {
id
deleted
}
}
`
await expect(
mutate({ mutation: deletePostMutation, variables: { id: 'p3' } }),
).resolves.toMatchObject({
data: { DeletePost: { id: 'p3', deleted: true } },
errors: undefined,
})
authenticatedUser = await user.toJson()
}
it('reduces notifications list', async () => {
let response
response = await query({
query: notificationQuery,
variables: { ...variables, read: false },
})
await expect(response).toMatchObject({
data: { notifications: expect.any(Array) },
errors: undefined,
})
await expect(response.data.notifications.length).toEqual(4)
await deletePostAction()
response = await query({
query: notificationQuery,
variables: { ...variables, read: false },
})
await expect(response).toMatchObject({
data: { notifications: expect.any(Array) },
errors: undefined,
})
await expect(response.data.notifications.length).toEqual(2)
})
})
})
})
})
describe('markAsRead', () => {
const markAsReadMutation = gql`
mutation($id: ID!) {
markAsRead(id: $id) {
createdAt
read
from {
__typename
... on Post {
content
}
... on Comment {
content
}
... on Report {
id
}
}
}
}
`
describe('unauthenticated', () => {
it('throws authorization error', async () => {
const result = await mutate({
mutation: markAsReadMutation,
variables: { ...variables, id: 'p1' },
})
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
})
})
describe('authenticated', () => {
beforeEach(async () => {
authenticatedUser = await user.toJson()
})
describe('not being notified at all', () => {
beforeEach(async () => {
variables = {
id: 'p1',
}
})
it('returns null', async () => {
const response = await mutate({ mutation: markAsReadMutation, variables })
expect(response.data.markAsRead).toEqual(null)
expect(response.errors).toBeUndefined()
})
})
describe('being notified', () => {
describe('on a post', () => {
beforeEach(async () => {
variables = {
id: 'p3',
}
})
it('updates `read` attribute and returns NOTIFIED relationship', async () => {
const response = await mutate({ mutation: markAsReadMutation, variables })
expect(response).toMatchObject({
data: {
markAsRead: {
createdAt: '2019-08-31T17:33:48.651Z',
read: true,
from: {
__typename: 'Post',
content: 'You have been mentioned in a post',
},
},
},
errors: undefined,
})
})
describe('but notification was already marked as read', () => {
beforeEach(async () => {
variables = {
id: 'p2',
}
})
it('returns null', async () => {
const response = await mutate({ mutation: markAsReadMutation, variables })
expect(response.data.markAsRead).toEqual(null)
expect(response.errors).toBeUndefined()
})
})
})
describe('on a comment', () => {
beforeEach(async () => {
variables = {
id: 'c2',
}
})
it('updates `read` attribute and returns NOTIFIED relationship', async () => {
const response = await mutate({ mutation: markAsReadMutation, variables })
expect(response).toMatchObject({
data: {
markAsRead: {
createdAt: '2019-08-30T19:33:48.651Z',
read: true,
from: {
__typename: 'Comment',
content: 'You have been mentioned in a comment',
},
},
},
errors: undefined,
})
})
})
describe('on a report', () => {
beforeEach(async () => {
variables = {
id: 'reportOnComment',
}
})
it('updates `read` attribute and returns NOTIFIED relationship', async () => {
const response = await mutate({ mutation: markAsReadMutation, variables })
expect(response).toMatchObject({
data: {
markAsRead: {
createdAt: '2020-01-14T12:33:48.651Z',
read: true,
from: {
__typename: 'FiledReport',
reportId: 'reportOnComment',
},
},
},
errors: undefined,
})
})
})
})
})
})
})