Refactor post spec, implement soft delete, fix bug

I think the validation for categories was too complex and the graphql
query 'PostEmotionsByCurrentUser' was erroneously allowed for
unauthenticated users.
This commit is contained in:
roschaefer 2019-09-02 00:45:09 +02:00
parent 2033b1791c
commit 1b5d91bfd2
5 changed files with 463 additions and 436 deletions

View File

@ -129,7 +129,7 @@ const permissions = shield(
isLoggedIn: allow,
Badge: allow,
PostsEmotionsCountByEmotion: allow,
PostsEmotionsByCurrentUser: allow,
PostsEmotionsByCurrentUser: isAuthenticated,
blockedUsers: isAuthenticated,
notifications: isAuthenticated,
},

View File

@ -52,29 +52,9 @@ const validatePost = async (resolve, root, args, context, info) => {
}
const validateUpdatePost = async (resolve, root, args, context, info) => {
const { id, categoryIds } = args
const session = context.driver.session()
const categoryQueryRes = await session.run(
`
MATCH (post:Post {id: $id})-[:CATEGORIZED]->(category:Category)
RETURN category`,
{ id },
)
session.close()
const [category] = categoryQueryRes.records.map(record => {
return record.get('category')
})
if (category) {
if (categoryIds && categoryIds.length > 3) {
throw new UserInputError(NO_CATEGORIES_ERR_MESSAGE)
}
} else {
if (!Array.isArray(categoryIds) || !categoryIds.length || categoryIds.length > 3) {
throw new UserInputError(NO_CATEGORIES_ERR_MESSAGE)
}
}
return resolve(root, args, context, info)
const { categoryIds } = args
if (typeof categoryIds === 'undefined') return resolve(root, args, context, info)
return validatePost(resolve, root, args, context, info)
}
export default {

View File

@ -109,8 +109,8 @@ describe('given some notifications', () => {
`
describe('unauthenticated', () => {
it('throws authorization error', async () => {
const result = await query({ query: notificationQuery })
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
const { errors } = await query({ query: notificationQuery })
expect(errors[0]).toHaveProperty('message', 'Not Authorised!')
})
})

View File

@ -73,6 +73,35 @@ export default {
},
},
Mutation: {
CreatePost: async (object, params, context, resolveInfo) => {
const { categoryIds } = params
delete params.categoryIds
params = await fileUpload(params, { file: 'imageUpload', url: 'image' })
params.id = params.id || uuid()
const createPostCypher = `CREATE (post:Post {params})
WITH post
MATCH (author:User {id: $userId})
MERGE (post)<-[:WROTE]-(author)
WITH post
UNWIND $categoryIds AS categoryId
MATCH (category:Category {id: categoryId})
MERGE (post)-[:CATEGORIZED]->(category)
RETURN post`
const createPostVariables = { userId: context.user.id, categoryIds, params }
const session = context.driver.session()
const transactionRes = await session.run(createPostCypher, createPostVariables)
const [post] = transactionRes.records.map(record => {
return record.get('post')
})
session.close()
return post.properties
},
UpdatePost: async (object, params, context, resolveInfo) => {
const { categoryIds } = params
delete params.categoryIds
@ -112,34 +141,21 @@ export default {
return post.properties
},
CreatePost: async (object, params, context, resolveInfo) => {
const { categoryIds } = params
delete params.categoryIds
params = await fileUpload(params, { file: 'imageUpload', url: 'image' })
params.id = params.id || uuid()
const createPostCypher = `CREATE (post:Post {params})
WITH post
MATCH (author:User {id: $userId})
MERGE (post)<-[:WROTE]-(author)
WITH post
UNWIND $categoryIds AS categoryId
MATCH (category:Category {id: categoryId})
MERGE (post)-[:CATEGORIZED]->(category)
RETURN post`
const createPostVariables = { userId: context.user.id, categoryIds, params }
DeletePost: async (object, args, context, resolveInfo) => {
const session = context.driver.session()
const transactionRes = await session.run(createPostCypher, createPostVariables)
const [post] = transactionRes.records.map(record => {
return record.get('post')
})
session.close()
return post.properties
const transactionRes = await session.run(
`
MATCH (post:Post {id: $postId})
SET post.deleted = TRUE
SET post.image = 'DELETED'
SET post.content = 'DELETED'
SET post.contentExcerpt = 'DELETED'
RETURN post
`,
{ postId: args.id },
)
const [post] = transactionRes.records.map(record => record.get('post').properties)
return post
},
AddPostEmotions: async (object, params, context, resolveInfo) => {
const session = context.driver.session()
@ -184,6 +200,7 @@ export default {
},
Post: {
...Resolver('Post', {
undefinedToNull: ['activityId', 'objectId', 'image', 'language'],
hasMany: {
tags: '-[:TAGGED]->(related:Tag)',
categories: '-[:CATEGORIZED]->(related:Category)',

File diff suppressed because it is too large Load Diff