mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
Merge branch 'event-master' into 6044-Add-create-New-Event
This commit is contained in:
commit
2c9084a185
@ -0,0 +1,53 @@
|
||||
import { getDriver } from '../../db/neo4j'
|
||||
|
||||
export const description = ''
|
||||
|
||||
export async function up(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
await transaction.run(`
|
||||
MATCH (post:Post)
|
||||
SET post:Article
|
||||
RETURN post
|
||||
`)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
|
||||
export async function down(next) {
|
||||
const driver = getDriver()
|
||||
const session = driver.session()
|
||||
const transaction = session.beginTransaction()
|
||||
|
||||
try {
|
||||
await transaction.run(`
|
||||
MATCH (post:Post)
|
||||
REMOVE post:Article
|
||||
RETURN post
|
||||
`)
|
||||
await transaction.commit()
|
||||
next()
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(error)
|
||||
await transaction.rollback()
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('rolled back')
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
session.close()
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,8 @@ export const createPostMutation = () => {
|
||||
$content: String!
|
||||
$categoryIds: [ID]
|
||||
$groupId: ID
|
||||
$postType: PostType
|
||||
$eventInput: _EventInput
|
||||
) {
|
||||
CreatePost(
|
||||
id: $id
|
||||
@ -19,11 +21,29 @@ export const createPostMutation = () => {
|
||||
content: $content
|
||||
categoryIds: $categoryIds
|
||||
groupId: $groupId
|
||||
postType: $postType
|
||||
eventInput: $eventInput
|
||||
) {
|
||||
id
|
||||
slug
|
||||
title
|
||||
content
|
||||
disabled
|
||||
deleted
|
||||
postType
|
||||
author {
|
||||
name
|
||||
}
|
||||
categories {
|
||||
id
|
||||
}
|
||||
eventStart
|
||||
eventLocationName
|
||||
eventVenue
|
||||
eventLocation {
|
||||
lng
|
||||
lat
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
35
backend/src/schema/resolvers/helpers/events.js
Normal file
35
backend/src/schema/resolvers/helpers/events.js
Normal file
@ -0,0 +1,35 @@
|
||||
import { UserInputError } from 'apollo-server'
|
||||
|
||||
export const validateEventParams = (params) => {
|
||||
if (params.postType && params.postType === 'Event') {
|
||||
const { eventInput } = params
|
||||
validateEventDate(eventInput.eventStart)
|
||||
params.eventStart = eventInput.eventStart
|
||||
if (eventInput.eventLocation && !eventInput.eventVenue) {
|
||||
throw new UserInputError('Event venue must be present if event location is given!')
|
||||
}
|
||||
params.eventVenue = eventInput.eventVenue
|
||||
params.eventLocation = eventInput.eventLocation
|
||||
}
|
||||
delete params.eventInput
|
||||
let locationName
|
||||
if (params.eventLocation) {
|
||||
params.eventLocationName = params.eventLocation
|
||||
locationName = params.eventLocation
|
||||
} else {
|
||||
params.eventLocationName = null
|
||||
locationName = null
|
||||
}
|
||||
delete params.eventLocation
|
||||
return locationName
|
||||
}
|
||||
|
||||
const validateEventDate = (dateString) => {
|
||||
const date = new Date(dateString)
|
||||
if (date.toString() === 'Invalid Date')
|
||||
throw new UserInputError('Event start date must be a valid date!')
|
||||
const now = new Date()
|
||||
if (date.getTime() < now.getTime()) {
|
||||
throw new UserInputError('Event start date must be in the future!')
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,8 @@ import Resolver from './helpers/Resolver'
|
||||
import { filterForMutedUsers } from './helpers/filterForMutedUsers'
|
||||
import { filterInvisiblePosts } from './helpers/filterInvisiblePosts'
|
||||
import { filterPostsOfMyGroups } from './helpers/filterPostsOfMyGroups'
|
||||
import { validateEventParams } from './helpers/events'
|
||||
import { createOrUpdateLocations } from './users/location'
|
||||
import CONFIG from '../../config'
|
||||
|
||||
const maintainPinnedPosts = (params) => {
|
||||
@ -81,6 +83,9 @@ export default {
|
||||
CreatePost: async (_parent, params, context, _resolveInfo) => {
|
||||
const { categoryIds, groupId } = params
|
||||
const { image: imageInput } = params
|
||||
|
||||
const locationName = validateEventParams(params)
|
||||
|
||||
delete params.categoryIds
|
||||
delete params.image
|
||||
delete params.groupId
|
||||
@ -125,12 +130,13 @@ export default {
|
||||
SET post.updatedAt = toString(datetime())
|
||||
SET post.clickedCount = 0
|
||||
SET post.viewedTeaserCount = 0
|
||||
SET post:${params.postType}
|
||||
WITH post
|
||||
MATCH (author:User {id: $userId})
|
||||
MERGE (post)<-[:WROTE]-(author)
|
||||
${categoriesCypher}
|
||||
${groupCypher}
|
||||
RETURN post {.*}
|
||||
RETURN post {.*, postType: filter(l IN labels(post) WHERE NOT l = "Post") }
|
||||
`,
|
||||
{ userId: context.user.id, categoryIds, groupId, params },
|
||||
)
|
||||
@ -142,6 +148,9 @@ export default {
|
||||
})
|
||||
try {
|
||||
const post = await writeTxResultPromise
|
||||
if (locationName) {
|
||||
await createOrUpdateLocations('Post', post.id, locationName, session)
|
||||
}
|
||||
return post
|
||||
} catch (e) {
|
||||
if (e.code === 'Neo.ClientError.Schema.ConstraintValidationFailed')
|
||||
@ -154,6 +163,9 @@ export default {
|
||||
UpdatePost: async (_parent, params, context, _resolveInfo) => {
|
||||
const { categoryIds } = params
|
||||
const { image: imageInput } = params
|
||||
|
||||
const locationName = validateEventParams(params)
|
||||
|
||||
delete params.categoryIds
|
||||
delete params.image
|
||||
const session = context.driver.session()
|
||||
@ -183,7 +195,16 @@ export default {
|
||||
`
|
||||
}
|
||||
|
||||
updatePostCypher += `RETURN post {.*}`
|
||||
if (params.postType) {
|
||||
updatePostCypher += `
|
||||
REMOVE post:Article
|
||||
REMOVE post:Event
|
||||
SET post:${params.postType}
|
||||
WITH post
|
||||
`
|
||||
}
|
||||
|
||||
updatePostCypher += `RETURN post {.*, postType: filter(l IN labels(post) WHERE NOT l = "Post")}`
|
||||
const updatePostVariables = { categoryIds, params }
|
||||
try {
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
@ -196,6 +217,9 @@ export default {
|
||||
return post
|
||||
})
|
||||
const post = await writeTxResultPromise
|
||||
if (locationName) {
|
||||
await createOrUpdateLocations('Post', post.id, locationName, session)
|
||||
}
|
||||
return post
|
||||
} finally {
|
||||
session.close()
|
||||
@ -382,7 +406,17 @@ export default {
|
||||
},
|
||||
Post: {
|
||||
...Resolver('Post', {
|
||||
undefinedToNull: ['activityId', 'objectId', 'language', 'pinnedAt', 'pinned'],
|
||||
undefinedToNull: [
|
||||
'activityId',
|
||||
'objectId',
|
||||
'language',
|
||||
'pinnedAt',
|
||||
'pinned',
|
||||
'eventVenue',
|
||||
'eventLocation',
|
||||
'eventLocationName',
|
||||
'eventStart',
|
||||
],
|
||||
hasMany: {
|
||||
tags: '-[:TAGGED]->(related:Tag)',
|
||||
categories: '-[:CATEGORIZED]->(related:Category)',
|
||||
@ -395,6 +429,7 @@ export default {
|
||||
pinnedBy: '<-[:PINNED]-(related:User)',
|
||||
image: '-[:HERO_IMAGE]->(related:Image)',
|
||||
group: '-[:IN]->(related:Group)',
|
||||
eventLocation: '-[:IS_IN]->(related:Location)',
|
||||
},
|
||||
count: {
|
||||
commentsCount:
|
||||
|
||||
@ -3,6 +3,10 @@ import Factory, { cleanDatabase } from '../../db/factories'
|
||||
import gql from 'graphql-tag'
|
||||
import { getNeode, getDriver } from '../../db/neo4j'
|
||||
import createServer from '../../server'
|
||||
import { createPostMutation } from '../../graphql/posts'
|
||||
import CONFIG from '../../config'
|
||||
|
||||
CONFIG.CATEGORIES_ACTIVE = true
|
||||
|
||||
const driver = getDriver()
|
||||
const neode = getNeode()
|
||||
@ -15,29 +19,6 @@ let user
|
||||
const categoryIds = ['cat9', 'cat4', 'cat15']
|
||||
let variables
|
||||
|
||||
const createPostMutation = gql`
|
||||
mutation ($id: ID, $title: String!, $content: String!, $language: String, $categoryIds: [ID]) {
|
||||
CreatePost(
|
||||
id: $id
|
||||
title: $title
|
||||
content: $content
|
||||
language: $language
|
||||
categoryIds: $categoryIds
|
||||
) {
|
||||
id
|
||||
title
|
||||
content
|
||||
slug
|
||||
disabled
|
||||
deleted
|
||||
language
|
||||
author {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
beforeAll(async () => {
|
||||
await cleanDatabase()
|
||||
|
||||
@ -281,7 +262,7 @@ describe('CreatePost', () => {
|
||||
|
||||
describe('unauthenticated', () => {
|
||||
it('throws authorization error', async () => {
|
||||
const { errors } = await mutate({ mutation: createPostMutation, variables })
|
||||
const { errors } = await mutate({ mutation: createPostMutation(), variables })
|
||||
expect(errors[0]).toHaveProperty('message', 'Not Authorized!')
|
||||
})
|
||||
})
|
||||
@ -296,7 +277,7 @@ describe('CreatePost', () => {
|
||||
data: { CreatePost: { title: 'I am a title', content: 'Some content' } },
|
||||
errors: undefined,
|
||||
}
|
||||
await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject(
|
||||
await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject(
|
||||
expected,
|
||||
)
|
||||
})
|
||||
@ -313,25 +294,219 @@ describe('CreatePost', () => {
|
||||
},
|
||||
errors: undefined,
|
||||
}
|
||||
await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject(
|
||||
await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject(
|
||||
expected,
|
||||
)
|
||||
})
|
||||
|
||||
it('`disabled` and `deleted` default to `false`', async () => {
|
||||
const expected = { data: { CreatePost: { disabled: false, deleted: false } } }
|
||||
await expect(mutate({ mutation: createPostMutation, variables })).resolves.toMatchObject(
|
||||
await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject(
|
||||
expected,
|
||||
)
|
||||
})
|
||||
|
||||
it('has label "Article" as default', async () => {
|
||||
await expect(mutate({ mutation: createPostMutation(), variables })).resolves.toMatchObject({
|
||||
data: { CreatePost: { postType: ['Article'] } },
|
||||
})
|
||||
})
|
||||
|
||||
describe('with invalid post type', () => {
|
||||
it('throws an error', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: { ...variables, postType: 'not-valid' },
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message:
|
||||
'Variable "$postType" got invalid value "not-valid"; Expected type PostType.',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with post type "Event"', () => {
|
||||
describe('without event start date', () => {
|
||||
it('throws an error', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: "Cannot read properties of undefined (reading 'eventStart')",
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with invalid event start date', () => {
|
||||
it('throws an error', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: 'no date',
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: 'Event start date must be a valid date!',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with event start date in the past', () => {
|
||||
it('throws an error', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() - 1).toISOString(),
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: 'Event start date must be in the future!',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('event location is given but event venue is missing', () => {
|
||||
it('throws an error', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
eventLocation: 'Berlin',
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: 'Event venue must be present if event location is given!',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('valid event input without location', () => {
|
||||
it('has label "Event" set', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
CreatePost: {
|
||||
postType: ['Event'],
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('valid event input with location', () => {
|
||||
it('has label "Event" set', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
eventLocation: 'Leipzig',
|
||||
eventVenue: 'Connewitzer Kreuz',
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
CreatePost: {
|
||||
postType: ['Event'],
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
eventLocationName: 'Leipzig',
|
||||
eventVenue: 'Connewitzer Kreuz',
|
||||
eventLocation: {
|
||||
lng: 12.374733,
|
||||
lat: 51.340632,
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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) {
|
||||
mutation (
|
||||
$id: ID!
|
||||
$title: String!
|
||||
$content: String!
|
||||
$image: ImageInput
|
||||
$categoryIds: [ID]
|
||||
$postType: PostType
|
||||
$eventInput: _EventInput
|
||||
) {
|
||||
UpdatePost(
|
||||
id: $id
|
||||
title: $title
|
||||
content: $content
|
||||
image: $image
|
||||
categoryIds: $categoryIds
|
||||
postType: $postType
|
||||
eventInput: $eventInput
|
||||
) {
|
||||
id
|
||||
title
|
||||
content
|
||||
@ -341,26 +516,34 @@ describe('UpdatePost', () => {
|
||||
}
|
||||
createdAt
|
||||
updatedAt
|
||||
categories {
|
||||
id
|
||||
}
|
||||
postType
|
||||
eventStart
|
||||
eventLocationName
|
||||
eventVenue
|
||||
eventLocation {
|
||||
lng
|
||||
lat
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
beforeEach(async () => {
|
||||
author = await Factory.build('user', { slug: 'the-author' })
|
||||
newlyCreatedPost = await Factory.build(
|
||||
'post',
|
||||
{
|
||||
id: 'p9876',
|
||||
authenticatedUser = await author.toJson()
|
||||
const { data } = await mutate({
|
||||
mutation: createPostMutation(),
|
||||
variables: {
|
||||
title: 'Old title',
|
||||
content: 'Old content',
|
||||
},
|
||||
{
|
||||
author,
|
||||
categoryIds,
|
||||
},
|
||||
)
|
||||
|
||||
})
|
||||
newlyCreatedPost = data.CreatePost
|
||||
variables = {
|
||||
id: 'p9876',
|
||||
id: newlyCreatedPost.id,
|
||||
title: 'New title',
|
||||
content: 'New content',
|
||||
}
|
||||
@ -394,7 +577,7 @@ describe('UpdatePost', () => {
|
||||
|
||||
it('updates a post', async () => {
|
||||
const expected = {
|
||||
data: { UpdatePost: { id: 'p9876', content: 'New content' } },
|
||||
data: { UpdatePost: { id: newlyCreatedPost.id, content: 'New content' } },
|
||||
errors: undefined,
|
||||
}
|
||||
await expect(mutate({ mutation: updatePostMutation, variables })).resolves.toMatchObject(
|
||||
@ -405,7 +588,11 @@ describe('UpdatePost', () => {
|
||||
it('updates a post, but maintains non-updated attributes', async () => {
|
||||
const expected = {
|
||||
data: {
|
||||
UpdatePost: { id: 'p9876', content: 'New content', createdAt: expect.any(String) },
|
||||
UpdatePost: {
|
||||
id: newlyCreatedPost.id,
|
||||
content: 'New content',
|
||||
createdAt: expect.any(String),
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
}
|
||||
@ -415,23 +602,20 @@ describe('UpdatePost', () => {
|
||||
})
|
||||
|
||||
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', () => {
|
||||
describe('no new category ids provided for update', () => {
|
||||
it('resolves and keeps current categories', async () => {
|
||||
const expected = {
|
||||
data: {
|
||||
UpdatePost: {
|
||||
id: 'p9876',
|
||||
id: newlyCreatedPost.id,
|
||||
categories: expect.arrayContaining([{ id: 'cat9' }, { id: 'cat4' }, { id: 'cat15' }]),
|
||||
},
|
||||
},
|
||||
@ -441,9 +625,9 @@ describe('UpdatePost', () => {
|
||||
expected,
|
||||
)
|
||||
})
|
||||
}) */
|
||||
})
|
||||
|
||||
/* describe('given category ids', () => {
|
||||
describe('given category ids', () => {
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, categoryIds: ['cat27'] }
|
||||
})
|
||||
@ -452,7 +636,7 @@ describe('UpdatePost', () => {
|
||||
const expected = {
|
||||
data: {
|
||||
UpdatePost: {
|
||||
id: 'p9876',
|
||||
id: newlyCreatedPost.id,
|
||||
categories: expect.arrayContaining([{ id: 'cat27' }]),
|
||||
},
|
||||
},
|
||||
@ -462,9 +646,160 @@ describe('UpdatePost', () => {
|
||||
expected,
|
||||
)
|
||||
})
|
||||
}) */
|
||||
})
|
||||
|
||||
describe('params.image', () => {
|
||||
describe('change post type to event', () => {
|
||||
describe('with missing event start date', () => {
|
||||
it('throws an error', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: updatePostMutation,
|
||||
variables: { ...variables, postType: 'Event' },
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: "Cannot read properties of undefined (reading 'eventStart')",
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with invalid event start date', () => {
|
||||
it('throws an error', async () => {
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: updatePostMutation,
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: 'no-date',
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: 'Event start date must be a valid date!',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with event start date in the past', () => {
|
||||
it('throws an error', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: updatePostMutation,
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() - 1).toISOString(),
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: 'Event start date must be in the future!',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('event location is given but event venue is missing', () => {
|
||||
it('throws an error', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: updatePostMutation,
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
eventLocation: 'Berlin',
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
errors: [
|
||||
{
|
||||
message: 'Event venue must be present if event location is given!',
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('valid event input without location', () => {
|
||||
it('has label "Event" set', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: updatePostMutation,
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
UpdatePost: {
|
||||
postType: ['Event'],
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('valid event input with location', () => {
|
||||
it('has label "Event" set', async () => {
|
||||
const now = new Date()
|
||||
await expect(
|
||||
mutate({
|
||||
mutation: updatePostMutation,
|
||||
variables: {
|
||||
...variables,
|
||||
postType: 'Event',
|
||||
eventInput: {
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
eventLocation: 'Leipzig',
|
||||
eventVenue: 'Connewitzer Kreuz',
|
||||
},
|
||||
},
|
||||
}),
|
||||
).resolves.toMatchObject({
|
||||
data: {
|
||||
UpdatePost: {
|
||||
postType: ['Event'],
|
||||
eventStart: new Date(now.getFullYear(), now.getMonth() + 1).toISOString(),
|
||||
eventLocationName: 'Leipzig',
|
||||
eventVenue: 'Connewitzer Kreuz',
|
||||
eventLocation: {
|
||||
lng: 12.374733,
|
||||
lat: 51.340632,
|
||||
},
|
||||
},
|
||||
},
|
||||
errors: undefined,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe.skip('params.image', () => {
|
||||
describe('is object', () => {
|
||||
beforeEach(() => {
|
||||
variables = { ...variables, image: { sensitive: true } }
|
||||
|
||||
4
backend/src/schema/types/enum/PostType.gql
Normal file
4
backend/src/schema/types/enum/PostType.gql
Normal file
@ -0,0 +1,4 @@
|
||||
enum PostType {
|
||||
Article
|
||||
Event
|
||||
}
|
||||
@ -171,12 +171,26 @@ type Post {
|
||||
@cypher(statement: "MATCH (this)<-[emoted:EMOTED]-(:User) RETURN COUNT(DISTINCT emoted)")
|
||||
|
||||
group: Group @relation(name: "IN", direction: "OUT")
|
||||
|
||||
postType: [PostType]
|
||||
@cypher(statement: "RETURN filter(l IN labels(this) WHERE NOT l = 'Post')")
|
||||
|
||||
eventLocationName: String
|
||||
eventLocation: Location @cypher(statement: "MATCH (this)-[:IS_IN]->(l:Location) RETURN l")
|
||||
eventVenue: String
|
||||
eventStart: String
|
||||
}
|
||||
|
||||
input _PostInput {
|
||||
id: ID!
|
||||
}
|
||||
|
||||
input _EventInput {
|
||||
eventStart: String!
|
||||
eventLocation: String
|
||||
eventVenue: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
CreatePost(
|
||||
id: ID
|
||||
@ -189,6 +203,8 @@ type Mutation {
|
||||
categoryIds: [ID]
|
||||
contentExcerpt: String
|
||||
groupId: ID
|
||||
postType: PostType = Article
|
||||
eventInput: _EventInput
|
||||
): Post
|
||||
UpdatePost(
|
||||
id: ID!
|
||||
@ -200,6 +216,8 @@ type Mutation {
|
||||
visibility: Visibility
|
||||
language: String
|
||||
categoryIds: [ID]
|
||||
postType: PostType
|
||||
eventInput: _EventInput
|
||||
): Post
|
||||
DeletePost(id: ID!): Post
|
||||
AddPostEmotions(to: _PostInput!, data: _EMOTEDInput!): EMOTED
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user