Some checks reported errors
continuous-integration/drone/push Build was killed
- 搭建 api、auth、utils 等逻辑模块 - 通过 tsc、eslint、vitest 测试验证 BREAKING CHANGE: 新镜像分支
408 lines
12 KiB
TypeScript
408 lines
12 KiB
TypeScript
/**
|
||
* 帖子API模块测试
|
||
* 测试帖子相关的API调用,包括创建帖子、获取帖子列表、点赞、评论等功能
|
||
*/
|
||
|
||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||
import { postApi } from '@/api/modules/post';
|
||
import { createMockAxios } from '@/test/mocks/http-client';
|
||
import {
|
||
createMockPost,
|
||
createMockUser,
|
||
createMockPostComment
|
||
} from '@/test/mocks/data-factory';
|
||
import type { ApiClient } from '@/api/client';
|
||
import type {
|
||
CreatePostRequest,
|
||
CreatePostResponse,
|
||
GetPostsRequest,
|
||
GetPostsResponse,
|
||
GetPostRequest,
|
||
GetPostResponse,
|
||
LikePostRequest,
|
||
LikePostResponse,
|
||
BookmarkPostRequest,
|
||
BookmarkPostResponse,
|
||
CreateCommentRequest,
|
||
CreateCommentResponse,
|
||
GetCommentsRequest,
|
||
GetCommentsResponse,
|
||
LikeCommentRequest,
|
||
LikeCommentResponse
|
||
} from '@/types/post/api';
|
||
|
||
describe('帖子API模块', () => {
|
||
let mockClient: ApiClient;
|
||
let postApiInstance: ReturnType<typeof postApi>;
|
||
|
||
beforeEach(() => {
|
||
// 创建模拟的API客户端
|
||
mockClient = {
|
||
get: vi.fn(),
|
||
post: vi.fn(),
|
||
put: vi.fn(),
|
||
delete: vi.fn(),
|
||
patch: vi.fn(),
|
||
request: vi.fn(),
|
||
getWithResponse: vi.fn(),
|
||
postWithResponse: vi.fn(),
|
||
putWithResponse: vi.fn(),
|
||
deleteWithResponse: vi.fn(),
|
||
patchWithResponse: vi.fn(),
|
||
requestWithResponse: vi.fn(),
|
||
addRequestInterceptor: vi.fn(),
|
||
addResponseInterceptor: vi.fn(),
|
||
removeRequestInterceptor: vi.fn(),
|
||
removeResponseInterceptor: vi.fn(),
|
||
setDefaults: vi.fn(),
|
||
setBaseURL: vi.fn(),
|
||
createInstance: vi.fn(),
|
||
} as unknown as ApiClient;
|
||
|
||
// 创建帖子API实例
|
||
postApiInstance = postApi(mockClient);
|
||
});
|
||
|
||
describe('创建帖子功能', () => {
|
||
it('应该能够创建新帖子', async () => {
|
||
const createRequest: CreatePostRequest = {
|
||
title: '测试帖子标题',
|
||
content: '这是一个测试帖子的内容',
|
||
tags: ['测试', 'API'],
|
||
isPublic: true
|
||
};
|
||
const mockPost = createMockPost({
|
||
title: createRequest.title,
|
||
content: createRequest.content,
|
||
tags: createRequest.tags
|
||
});
|
||
const mockResponse: CreatePostResponse = {
|
||
success: true,
|
||
data: mockPost,
|
||
message: '帖子创建成功',
|
||
code: 201
|
||
};
|
||
|
||
mockClient.post.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.createPost(createRequest);
|
||
|
||
expect(mockClient.post).toHaveBeenCalledWith('/posts', createRequest);
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理创建帖子失败的情况', async () => {
|
||
const createRequest: CreatePostRequest = {
|
||
title: '',
|
||
content: '',
|
||
tags: [],
|
||
isPublic: true
|
||
};
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '标题和内容不能为空',
|
||
code: 400
|
||
};
|
||
|
||
mockClient.post.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.createPost(createRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.post).toHaveBeenCalledWith('/posts', createRequest);
|
||
});
|
||
});
|
||
|
||
describe('获取帖子列表功能', () => {
|
||
it('应该能够获取帖子列表', async () => {
|
||
const getRequest: GetPostsRequest = {
|
||
page: 1,
|
||
limit: 10,
|
||
tag: '测试'
|
||
};
|
||
const mockPosts = [
|
||
createMockPost({ id: 'post-1' }),
|
||
createMockPost({ id: 'post-2' })
|
||
];
|
||
const mockResponse: GetPostsResponse = {
|
||
success: true,
|
||
data: {
|
||
posts: mockPosts,
|
||
pagination: {
|
||
page: 1,
|
||
limit: 10,
|
||
total: 100,
|
||
totalPages: 10
|
||
}
|
||
},
|
||
message: '获取帖子列表成功',
|
||
code: 200
|
||
};
|
||
|
||
mockClient.get.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.getPosts(getRequest);
|
||
|
||
expect(mockClient.get).toHaveBeenCalledWith('/posts', { params: getRequest });
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理获取帖子列表失败的情况', async () => {
|
||
const getRequest: GetPostsRequest = {
|
||
page: -1, // 无效的页码
|
||
limit: 10
|
||
};
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '页码必须大于0',
|
||
code: 400
|
||
};
|
||
|
||
mockClient.get.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.getPosts(getRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.get).toHaveBeenCalledWith('/posts', { params: getRequest });
|
||
});
|
||
});
|
||
|
||
describe('获取帖子详情功能', () => {
|
||
it('应该能够获取帖子详情', async () => {
|
||
const getRequest: GetPostRequest = { postId: 'post-123' };
|
||
const mockPost = createMockPost({ id: 'post-123' });
|
||
const mockResponse: GetPostResponse = {
|
||
success: true,
|
||
data: mockPost,
|
||
message: '获取帖子详情成功',
|
||
code: 200
|
||
};
|
||
|
||
mockClient.get.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.getPost(getRequest);
|
||
|
||
expect(mockClient.get).toHaveBeenCalledWith('/posts/post-123');
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理获取不存在帖子的情况', async () => {
|
||
const getRequest: GetPostRequest = { postId: 'non-existent-post' };
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '帖子不存在',
|
||
code: 404
|
||
};
|
||
|
||
mockClient.get.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.getPost(getRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.get).toHaveBeenCalledWith('/posts/non-existent-post');
|
||
});
|
||
});
|
||
|
||
describe('点赞帖子功能', () => {
|
||
it('应该能够点赞帖子', async () => {
|
||
const likeRequest: LikePostRequest = { postId: 'post-123' };
|
||
const mockResponse: LikePostResponse = {
|
||
success: true,
|
||
message: '点赞成功',
|
||
code: 200
|
||
};
|
||
|
||
mockClient.put.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.likePost(likeRequest);
|
||
|
||
expect(mockClient.put).toHaveBeenCalledWith('/posts/post-123/like');
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理点赞不存在帖子的情况', async () => {
|
||
const likeRequest: LikePostRequest = { postId: 'non-existent-post' };
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '帖子不存在',
|
||
code: 404
|
||
};
|
||
|
||
mockClient.put.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.likePost(likeRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.put).toHaveBeenCalledWith('/posts/non-existent-post/like');
|
||
});
|
||
});
|
||
|
||
describe('收藏帖子功能', () => {
|
||
it('应该能够收藏帖子', async () => {
|
||
const bookmarkRequest: BookmarkPostRequest = { postId: 'post-123' };
|
||
const mockResponse: BookmarkPostResponse = {
|
||
success: true,
|
||
message: '收藏成功',
|
||
code: 200
|
||
};
|
||
|
||
mockClient.put.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.bookmarkPost(bookmarkRequest);
|
||
|
||
expect(mockClient.put).toHaveBeenCalledWith('/posts/post-123/bookmark');
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理收藏不存在帖子的情况', async () => {
|
||
const bookmarkRequest: BookmarkPostRequest = { postId: 'non-existent-post' };
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '帖子不存在',
|
||
code: 404
|
||
};
|
||
|
||
mockClient.put.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.bookmarkPost(bookmarkRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.put).toHaveBeenCalledWith('/posts/non-existent-post/bookmark');
|
||
});
|
||
});
|
||
|
||
describe('创建评论功能', () => {
|
||
it('应该能够创建评论', async () => {
|
||
const commentRequest: CreateCommentRequest = {
|
||
postId: 'post-123',
|
||
content: '这是一个测试评论',
|
||
parentId: 'parent-comment-123'
|
||
};
|
||
const mockComment = createMockPostComment({
|
||
postId: commentRequest.postId,
|
||
content: commentRequest.content,
|
||
parentId: commentRequest.parentId
|
||
});
|
||
const mockResponse: CreateCommentResponse = {
|
||
success: true,
|
||
data: mockComment,
|
||
message: '评论创建成功',
|
||
code: 201
|
||
};
|
||
|
||
mockClient.post.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.createComment(commentRequest);
|
||
|
||
expect(mockClient.post).toHaveBeenCalledWith('/posts/post-123/comments', commentRequest);
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理创建评论失败的情况', async () => {
|
||
const commentRequest: CreateCommentRequest = {
|
||
postId: 'post-123',
|
||
content: '', // 空评论内容
|
||
parentId: 'parent-comment-123'
|
||
};
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '评论内容不能为空',
|
||
code: 400
|
||
};
|
||
|
||
mockClient.post.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.createComment(commentRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.post).toHaveBeenCalledWith('/posts/post-123/comments', commentRequest);
|
||
});
|
||
});
|
||
|
||
describe('获取评论列表功能', () => {
|
||
it('应该能够获取评论列表', async () => {
|
||
const commentsRequest: GetCommentsRequest = {
|
||
postId: 'post-123',
|
||
page: 1,
|
||
limit: 10,
|
||
sortBy: 'createdAt',
|
||
sortOrder: 'desc'
|
||
};
|
||
const mockComments = [
|
||
createMockPostComment({ id: 'comment-1', postId: 'post-123' }),
|
||
createMockPostComment({ id: 'comment-2', postId: 'post-123' })
|
||
];
|
||
const mockResponse: GetCommentsResponse = {
|
||
success: true,
|
||
data: {
|
||
comments: mockComments,
|
||
pagination: {
|
||
page: 1,
|
||
limit: 10,
|
||
total: 50,
|
||
totalPages: 5
|
||
}
|
||
},
|
||
message: '获取评论列表成功',
|
||
code: 200
|
||
};
|
||
|
||
mockClient.get.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.getComments(commentsRequest);
|
||
|
||
expect(mockClient.get).toHaveBeenCalledWith('/posts/post-123/comments', {
|
||
params: { page: 1, limit: 10, sortBy: 'createdAt', sortOrder: 'desc' }
|
||
});
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理获取评论列表失败的情况', async () => {
|
||
const commentsRequest: GetCommentsRequest = {
|
||
postId: 'post-123',
|
||
page: -1, // 无效的页码
|
||
limit: 10
|
||
};
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '页码必须大于0',
|
||
code: 400
|
||
};
|
||
|
||
mockClient.get.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.getComments(commentsRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.get).toHaveBeenCalledWith('/posts/post-123/comments', {
|
||
params: { page: -1, limit: 10 }
|
||
});
|
||
});
|
||
});
|
||
|
||
describe('点赞评论功能', () => {
|
||
it('应该能够点赞评论', async () => {
|
||
const likeCommentRequest: LikeCommentRequest = { commentId: 'comment-123' };
|
||
const mockResponse: LikeCommentResponse = {
|
||
success: true,
|
||
message: '点赞评论成功',
|
||
code: 200
|
||
};
|
||
|
||
mockClient.put.mockResolvedValue(mockResponse);
|
||
|
||
const result = await postApiInstance.likeComment(likeCommentRequest);
|
||
|
||
expect(mockClient.put).toHaveBeenCalledWith('/comments/comment-123/like');
|
||
expect(result).toEqual(mockResponse);
|
||
});
|
||
|
||
it('应该处理点赞不存在评论的情况', async () => {
|
||
const likeCommentRequest: LikeCommentRequest = { commentId: 'non-existent-comment' };
|
||
const errorResponse = {
|
||
success: false,
|
||
data: null,
|
||
message: '评论不存在',
|
||
code: 404
|
||
};
|
||
|
||
mockClient.put.mockRejectedValue(errorResponse);
|
||
|
||
await expect(postApiInstance.likeComment(likeCommentRequest)).rejects.toEqual(errorResponse);
|
||
expect(mockClient.put).toHaveBeenCalledWith('/comments/non-existent-comment/like');
|
||
});
|
||
});
|
||
}) |