Throw error if no categories on post creation

Co-authored-by: mattwr18 <mattwr18@gmail.com>
This commit is contained in:
kachulio1 2019-08-15 17:55:02 +03:00
parent 544fd0d84c
commit 314dfcf413
4 changed files with 91 additions and 89 deletions

View File

@ -40,9 +40,18 @@ const validateUpdateComment = async (resolve, root, args, context, info) => {
return resolve(root, args, context, info) return resolve(root, args, context, info)
} }
const validateCreatePost = async (resolve, root, args, context, info) => {
const { categoryIds } = args
if (!Array.isArray(categoryIds) || !categoryIds.length) {
throw new UserInputError('You cannot create a post without at least one category')
}
return resolve(root, args, context, info)
}
export default { export default {
Mutation: { Mutation: {
CreateComment: validateCommentCreation, CreateComment: validateCommentCreation,
UpdateComment: validateUpdateComment, UpdateComment: validateUpdateComment,
CreatePost: validateCreatePost,
}, },
} }

View File

@ -110,6 +110,7 @@ export default {
const { categoryIds } = params const { categoryIds } = params
delete params.categoryIds delete params.categoryIds
params = await fileUpload(params, { file: 'imageUpload', url: 'image' }) params = await fileUpload(params, { file: 'imageUpload', url: 'image' })
params.id = params.id || uuid() params.id = params.id || uuid()
let createPostCypher = `CREATE (post:Post {params}) let createPostCypher = `CREATE (post:Post {params})

View File

@ -19,20 +19,9 @@ const oldTitle = 'Old title'
const oldContent = 'Old content' const oldContent = 'Old content'
const newTitle = 'New title' const newTitle = 'New title'
const newContent = 'New content' const newContent = 'New content'
const createPostVariables = { title: postTitle, content: postContent } const categoryIds = ['cat9', 'cat4', 'cat15']
const createPostWithCategoriesMutation = gql` let createPostVariables
mutation($title: String!, $content: String!, $categoryIds: [ID]) {
CreatePost(title: $title, content: $content, categoryIds: $categoryIds) {
id
title
}
}
`
const createPostWithCategoriesVariables = {
title: postTitle,
content: postContent,
categoryIds: ['cat9', 'cat4', 'cat15'],
}
const postQueryWithCategories = gql` const postQueryWithCategories = gql`
query($id: ID) { query($id: ID) {
Post(id: $id) { Post(id: $id) {
@ -42,11 +31,6 @@ const postQueryWithCategories = gql`
} }
} }
` `
const createPostWithoutCategoriesVariables = {
title: 'This is a post without categories',
content: 'I should be able to filter it out',
categoryIds: null,
}
const postQueryFilteredByCategory = gql` const postQueryFilteredByCategory = gql`
query Post($filter: _PostFilter) { query Post($filter: _PostFilter) {
Post(filter: $filter) { Post(filter: $filter) {
@ -58,14 +42,14 @@ const postQueryFilteredByCategory = gql`
} }
} }
` `
const postCategoriesFilterParam = { categories_some: { id_in: ['cat4'] } } const postCategoriesFilterParam = { categories_some: { id_in: categoryIds } }
const postQueryFilteredByCategoryVariables = { const postQueryFilteredByCategoryVariables = {
filter: postCategoriesFilterParam, filter: postCategoriesFilterParam,
} }
const createPostMutation = gql` const createPostMutation = gql`
mutation($title: String!, $content: String!) { mutation($id: ID, $title: String!, $content: String!, $categoryIds: [ID]) {
CreatePost(title: $title, content: $content) { CreatePost(id: $id, title: $title, content: $content, categoryIds: $categoryIds) {
id id
title title
content content
@ -88,6 +72,29 @@ beforeEach(async () => {
password: '1234', password: '1234',
} }
await factory.create('User', userParams) await factory.create('User', userParams)
await Promise.all([
factory.create('Category', {
id: 'cat9',
name: 'Democracy & Politics',
icon: 'university',
}),
factory.create('Category', {
id: 'cat4',
name: 'Environment & Nature',
icon: 'tree',
}),
factory.create('Category', {
id: 'cat15',
name: 'Consumption & Sustainability',
icon: 'shopping-cart',
}),
])
createPostVariables = {
id: 'p3589',
title: postTitle,
content: postContent,
categoryIds,
}
}) })
afterEach(async () => { afterEach(async () => {
@ -152,8 +159,13 @@ describe('CreatePost', () => {
describe('language', () => { describe('language', () => {
it('allows a user to set the language of the post', async () => { it('allows a user to set the language of the post', async () => {
const createPostWithLanguageMutation = gql` const createPostWithLanguageMutation = gql`
mutation($title: String!, $content: String!, $language: String) { mutation($title: String!, $content: String!, $language: String, $categoryIds: [ID]) {
CreatePost(title: $title, content: $content, language: $language) { CreatePost(
title: $title
content: $content
language: $language
categoryIds: $categoryIds
) {
language language
} }
} }
@ -162,6 +174,7 @@ describe('CreatePost', () => {
title: postTitle, title: postTitle,
content: postContent, content: postContent,
language: 'en', language: 'en',
categoryIds,
} }
const expected = { CreatePost: { language: 'en' } } const expected = { CreatePost: { language: 'en' } }
await expect( await expect(
@ -171,51 +184,29 @@ describe('CreatePost', () => {
}) })
describe('categories', () => { describe('categories', () => {
let postWithCategories it('throws an error if categoryIds is not an array', async () => {
beforeEach(async () => { createPostVariables.categoryIds = null
await Promise.all([ await expect(client.request(createPostMutation, createPostVariables)).rejects.toThrow(
factory.create('Category', { 'You cannot create a post without at least one category',
id: 'cat9',
name: 'Democracy & Politics',
icon: 'university',
}),
factory.create('Category', {
id: 'cat4',
name: 'Environment & Nature',
icon: 'tree',
}),
factory.create('Category', {
id: 'cat15',
name: 'Consumption & Sustainability',
icon: 'shopping-cart',
}),
])
postWithCategories = await client.request(
createPostWithCategoriesMutation,
createPostWithCategoriesVariables,
) )
}) })
it('allows a user to set the categories of the post', async () => { it('requires at least one category for successful creation', async () => {
const expected = [{ id: 'cat9' }, { id: 'cat4' }, { id: 'cat15' }] createPostVariables.categoryIds = []
const postQueryWithCategoriesVariables = { await expect(client.request(createPostMutation, createPostVariables)).rejects.toThrow(
id: postWithCategories.CreatePost.id, 'You cannot create a post without at least one category',
} )
await expect(
client.request(postQueryWithCategories, postQueryWithCategoriesVariables),
).resolves.toEqual({ Post: [{ categories: expect.arrayContaining(expected) }] })
}) })
it('allows a user to filter for posts by category', async () => { it('allows a user to filter for posts by category', async () => {
await client.request(createPostWithCategoriesMutation, createPostWithoutCategoriesVariables) await client.request(createPostMutation, createPostVariables)
const categoryIds = [{ id: 'cat4' }, { id: 'cat15' }, { id: 'cat9' }] const categoryIdsArray = [{ id: 'cat4' }, { id: 'cat15' }, { id: 'cat9' }]
const expected = { const expected = {
Post: [ Post: [
{ {
title: postTitle, title: postTitle,
id: postWithCategories.CreatePost.id, id: 'p3589',
categories: expect.arrayContaining(categoryIds), categories: expect.arrayContaining(categoryIdsArray),
}, },
], ],
} }
@ -231,6 +222,28 @@ describe('UpdatePost', () => {
let updatePostMutation let updatePostMutation
let updatePostVariables let updatePostVariables
beforeEach(async () => { beforeEach(async () => {
await Promise.all([
factory.create('Category', {
id: 'cat9',
name: 'Democracy & Politics',
icon: 'university',
}),
factory.create('Category', {
id: 'cat4',
name: 'Environment & Nature',
icon: 'tree',
}),
factory.create('Category', {
id: 'cat15',
name: 'Consumption & Sustainability',
icon: 'shopping-cart',
}),
factory.create('Category', {
id: 'cat27',
name: 'Animal Protection',
icon: 'paw',
}),
])
const asAuthor = Factory() const asAuthor = Factory()
await asAuthor.create('User', authorParams) await asAuthor.create('User', authorParams)
await asAuthor.authenticateAs(authorParams) await asAuthor.authenticateAs(authorParams)
@ -238,6 +251,7 @@ describe('UpdatePost', () => {
id: 'p1', id: 'p1',
title: oldTitle, title: oldTitle,
content: oldContent, content: oldContent,
categoryIds,
}) })
updatePostMutation = gql` updatePostMutation = gql`
mutation($id: ID!, $title: String!, $content: String!, $categoryIds: [ID]) { mutation($id: ID!, $title: String!, $content: String!, $categoryIds: [ID]) {
@ -294,36 +308,10 @@ describe('UpdatePost', () => {
}) })
describe('categories', () => { describe('categories', () => {
let postWithCategories
beforeEach(async () => { beforeEach(async () => {
await Promise.all([ await client.request(createPostMutation, createPostVariables)
factory.create('Category', {
id: 'cat9',
name: 'Democracy & Politics',
icon: 'university',
}),
factory.create('Category', {
id: 'cat4',
name: 'Environment & Nature',
icon: 'tree',
}),
factory.create('Category', {
id: 'cat15',
name: 'Consumption & Sustainability',
icon: 'shopping-cart',
}),
factory.create('Category', {
id: 'cat27',
name: 'Animal Protection',
icon: 'paw',
}),
])
postWithCategories = await client.request(
createPostWithCategoriesMutation,
createPostWithCategoriesVariables,
)
updatePostVariables = { updatePostVariables = {
id: postWithCategories.CreatePost.id, id: 'p3589',
title: newTitle, title: newTitle,
content: newContent, content: newContent,
categoryIds: ['cat27'], categoryIds: ['cat27'],
@ -334,7 +322,7 @@ describe('UpdatePost', () => {
await client.request(updatePostMutation, updatePostVariables) await client.request(updatePostMutation, updatePostVariables)
const expected = [{ id: 'cat27' }] const expected = [{ id: 'cat27' }]
const postQueryWithCategoriesVariables = { const postQueryWithCategoriesVariables = {
id: postWithCategories.CreatePost.id, id: 'p3589',
} }
await expect( await expect(
client.request(postQueryWithCategories, postQueryWithCategoriesVariables), client.request(postQueryWithCategories, postQueryWithCategoriesVariables),
@ -365,6 +353,7 @@ describe('DeletePost', () => {
await asAuthor.create('Post', { await asAuthor.create('Post', {
id: 'p1', id: 'p1',
content: 'To be deleted', content: 'To be deleted',
categoryIds,
}) })
}) })

View File

@ -16,6 +16,7 @@ export default function(params) {
image = faker.image.unsplash.imageUrl(), image = faker.image.unsplash.imageUrl(),
visibility = 'public', visibility = 'public',
deleted = false, deleted = false,
categoryIds,
} = params } = params
return { return {
@ -28,6 +29,7 @@ export default function(params) {
$image: String $image: String
$visibility: Visibility $visibility: Visibility
$deleted: Boolean $deleted: Boolean
$categoryIds: [ID]
) { ) {
CreatePost( CreatePost(
id: $id id: $id
@ -37,12 +39,13 @@ export default function(params) {
image: $image image: $image
visibility: $visibility visibility: $visibility
deleted: $deleted deleted: $deleted
categoryIds: $categoryIds
) { ) {
title title
content content
} }
} }
`, `,
variables: { id, slug, title, content, image, visibility, deleted }, variables: { id, slug, title, content, image, visibility, deleted, categoryIds },
} }
} }