add get post graphql api and tests

This commit is contained in:
Hongbo Wu 2024-06-18 15:07:38 +08:00
parent 81b0fc19a2
commit 12db8b6a7d
7 changed files with 158 additions and 4 deletions

View file

@ -2435,6 +2435,7 @@ export type PostError = {
export enum PostErrorCode {
BadRequest = 'BAD_REQUEST',
NotFound = 'NOT_FOUND',
Unauthorized = 'UNAUTHORIZED'
}

View file

@ -1867,6 +1867,7 @@ type PostError {
enum PostErrorCode {
BAD_REQUEST
NOT_FOUND
UNAUTHORIZED
}

View file

@ -151,7 +151,7 @@ import {
webhookResolver,
webhooksResolver,
} from './index'
import { postsResolver } from './posts'
import { postResolver, postsResolver } from './posts'
import {
markEmailAsItemResolver,
recentEmailsResolver,
@ -355,6 +355,7 @@ export const functionResolvers = {
highlights: highlightsResolver,
folderPolicies: folderPoliciesResolver,
posts: postsResolver,
post: postResolver,
},
User: {
async intercomHash(user: User) {
@ -902,4 +903,5 @@ export const functionResolvers = {
...resultResolveTypeResolver('UpdateFolderPolicy'),
...resultResolveTypeResolver('DeleteFolderPolicy'),
...resultResolveTypeResolver('Posts'),
...resultResolveTypeResolver('Post'),
}

View file

@ -1,12 +1,18 @@
import { Post } from '../../entity/post'
import {
PostEdge,
PostErrorCode,
PostResult,
PostsErrorCode,
PostsResult,
QueryPostArgs,
QueryPostsArgs,
ResolverFn,
} from '../../generated/graphql'
import { findPublicPostsByUserId } from '../../services/post'
import {
findPublicPostById,
findPublicPostsByUserId,
} from '../../services/post'
import { Merge } from '../../util'
import { ResolverContext } from '../types'
@ -39,7 +45,6 @@ export const postsResolver: ResolverFn<
}
const posts = await findPublicPostsByUserId(userId, limit + 1, offset)
console.log(posts)
const hasNextPage = posts.length > limit
if (hasNextPage) {
@ -62,3 +67,33 @@ export const postsResolver: ResolverFn<
},
}
}
export const postResolver: ResolverFn<
Merge<PostResult, { post?: Post }>,
never,
ResolverContext,
QueryPostArgs
> = async (_, { id }, { log }) => {
if (!id) {
log.error('Invalid args', { id })
return {
errorCodes: [PostErrorCode.BadRequest],
}
}
const post = await findPublicPostById(id)
if (!post) {
log.error('Post not found', { id })
return {
errorCodes: [PostErrorCode.NotFound],
}
}
return {
post,
}
}

View file

@ -3451,6 +3451,7 @@ const schema = gql`
enum PostErrorCode {
UNAUTHORIZED
BAD_REQUEST
NOT_FOUND
}
# Mutations

View file

@ -45,3 +45,14 @@ export const deletePosts = async (userId: string, postIds: string[]) => {
}
)
}
export const findPublicPostById = async (id: string) => {
return getRepository(Post).findOneBy({
id,
user: {
profile: {
private: false,
},
},
})
}

View file

@ -4,7 +4,7 @@ import { createPosts, deletePosts } from '../../src/services/post'
import { updateProfile } from '../../src/services/profile'
import { deleteUser } from '../../src/services/user'
import { createTestUser } from '../db'
import { graphqlRequest, loginAndGetAuthToken } from '../util'
import { generateFakeUuid, graphqlRequest, loginAndGetAuthToken } from '../util'
describe('Post Resolvers', () => {
let loginUser: User
@ -139,4 +139,107 @@ describe('Post Resolvers', () => {
})
})
})
describe('postResolver', () => {
const query = `
query Post($id: ID!) {
post(id: $id) {
... on PostSuccess {
post {
id
title
content
ownedByViewer
}
}
... on PostError {
errorCodes
}
}
}
`
let postId: string
before(async () => {
const post = {
title: 'Post',
content: 'Content',
user: loginUser,
}
const newPost = await createPosts(loginUser.id, [post])
postId = newPost[0].id
})
after(async () => {
await deletePosts(loginUser.id, [postId])
})
it('should return an error if the args are invalid', async () => {
const response = await graphqlRequest(query, '', {
id: '',
})
expect(response.body.data.post.errorCodes).to.eql(['BAD_REQUEST'])
})
it('should return an error if the post is not found', async () => {
const response = await graphqlRequest(query, '', {
id: generateFakeUuid(),
})
expect(response.body.data.post.errorCodes).to.eql(['NOT_FOUND'])
})
context('when the user is authenticated', () => {
it('should return the post', async () => {
const response = await graphqlRequest(query, authToken, {
id: postId,
})
expect(response.body.data.post.post.id).to.eql(postId)
expect(response.body.data.post.post.ownedByViewer).to.be.true
})
})
context('when the user is not authenticated', () => {
context('when user profile is public', () => {
before(async () => {
await updateProfile(loginUser.id, { private: false })
})
after(async () => {
await updateProfile(loginUser.id, { private: true })
})
it('should return the post', async () => {
const response = await graphqlRequest(query, '', {
id: postId,
})
expect(response.body.data.post.post.id).to.eql(postId)
expect(response.body.data.post.post.ownedByViewer).to.be.false
})
})
context('when user profile is private', () => {
before(async () => {
await updateProfile(loginUser.id, { private: true })
})
after(async () => {
await updateProfile(loginUser.id, { private: false })
})
it('should return an error', async () => {
const response = await graphqlRequest(query, '', {
id: postId,
})
expect(response.body.data.post.errorCodes).to.eql(['NOT_FOUND'])
})
})
})
})
})