diff --git a/packages/api/src/services/post.ts b/packages/api/src/services/post.ts index c53df7997..32c8bfb16 100644 --- a/packages/api/src/services/post.ts +++ b/packages/api/src/services/post.ts @@ -1,5 +1,6 @@ +import { DeepPartial } from 'typeorm' import { Post } from '../entity/post' -import { getRepository } from '../repository' +import { authTrx, getRepository } from '../repository' export const findPostsByUserId = async ( userId: string, @@ -24,3 +25,14 @@ export const findPostsByUserId = async ( return posts } + +export const createPosts = async ( + userId: string, + posts: Array> +) => { + return authTrx( + async (trx) => trx.getRepository(Post).save(posts), + undefined, + userId + ) +} diff --git a/packages/api/test/resolvers/post.test.ts b/packages/api/test/resolvers/post.test.ts new file mode 100644 index 000000000..fff9eb301 --- /dev/null +++ b/packages/api/test/resolvers/post.test.ts @@ -0,0 +1,130 @@ +import { expect } from 'chai' +import { User } from '../../src/entity/user' +import { createPosts } from '../../src/services/post' +import { deleteUser } from '../../src/services/user' +import { createTestUser } from '../db' +import { graphqlRequest, loginAndGetAuthToken } from '../util' + +describe('Post Resolvers', () => { + let loginUser: User + let authToken: string + + before(async () => { + // create test user and login + loginUser = await createTestUser('loginUser') + authToken = await loginAndGetAuthToken(loginUser.email) + }) + + after(async () => { + await deleteUser(loginUser.id) + }) + + describe('postsResolver', () => { + const query = ` + query Posts($first: Int, $after: String, $userId: ID!) { + posts(first: $first, after: $after, userId: $userId) { + ... on PostsSuccess { + edges { + cursor + node { + id + title + content + ownedByViewer + } + } + pageInfo { + startCursor + endCursor + hasPreviousPage + hasNextPage + } + } + ... on PostsError { + errorCodes + } + } + } + ` + + it('should return an error if the args are invalid', async () => { + const response = await graphqlRequest(query, '', { + first: 100, + userId: loginUser.id, + }) + + expect(response.body.data.posts.errorCodes).to.eql(['BAD_REQUEST']) + }) + + context('when the user is authenticated', () => { + before(async () => { + const posts = [ + { + title: 'Post 1', + content: 'Content 1', + user: loginUser, + }, + { + title: 'Post 2', + content: 'Content 2', + user: loginUser, + }, + ] + await createPosts(loginUser.id, posts) + }) + + it('should return posts if the user is the owner', async () => { + const response = await graphqlRequest(query, authToken, { + first: 10, + userId: loginUser.id, + }) + + expect(response.body.data.posts.edges).to.be.an('array') + expect(response.body.data.posts.pageInfo).to.be.an('object') + }) + }) + + it('should return posts if the user is not authenticated and the posts are public', async () => { + const posts = [ + { + title: 'Post 1', + content: 'Content 1', + user: loginUser, + }, + { + title: 'Post 2', + content: 'Content 2', + user: loginUser, + }, + ] + await createPosts(loginUser.id, posts) + + const response = await graphqlRequest(query, '', { + first: 10, + userId: loginUser.id, + }) + + expect(response.body.data.posts.edges).to.be.an('array') + expect(response.body.data.posts.pageInfo).to.be.an('object') + }) + + it('should return empty array if the user is not authenticated and the posts are private', async () => { + const response = await graphqlRequest(query, '', { + first: 10, + userId: loginUser.id, + }) + + expect(response.body.data.posts.errorCodes).to.eql(['UNAUTHORIZED']) + }) + + it('should return posts if the user is the owner', async () => { + const response = await graphqlRequest(query, authToken, { + first: 10, + userId: loginUser.id, + }) + + expect(response.body.data.posts.edges).to.be.an('array') + expect(response.body.data.posts.pageInfo).to.be.an('object') + }) + }) +})