feat(image): 新建 knowai-core:1.0.0 镜像并完成推送
Some checks reported errors
continuous-integration/drone/push Build was killed
Some checks reported errors
continuous-integration/drone/push Build was killed
- 搭建 api、auth、utils 等逻辑模块 - 通过 tsc、eslint、vitest 测试验证 BREAKING CHANGE: 新镜像分支
This commit is contained in:
345
test/unit/api/modules/chat.test.ts
Normal file
345
test/unit/api/modules/chat.test.ts
Normal file
@@ -0,0 +1,345 @@
|
||||
/**
|
||||
* 聊天API模块测试
|
||||
* 测试聊天相关的API调用,包括创建/更新聊天会话、发送消息、获取聊天会话列表、获取聊天消息、标记消息已读等功能
|
||||
*/
|
||||
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { chatApi } from '@/api/modules/chat';
|
||||
import { createMockAxios } from '@/test/mocks/http-client';
|
||||
import {
|
||||
createMockChatSession,
|
||||
createMockChatMessage,
|
||||
createMockUser
|
||||
} from '@/test/mocks/data-factory';
|
||||
import type { ApiClient } from '@/api/client';
|
||||
import type {
|
||||
CreateChatSessionRequest,
|
||||
UpdateChatSessionRequest,
|
||||
SendMessageRequest,
|
||||
GetChatSessionsRequest,
|
||||
GetChatSessionsResponse,
|
||||
GetChatMessagesRequest,
|
||||
GetChatMessagesResponse,
|
||||
MarkMessagesAsReadRequest,
|
||||
MarkMessagesAsReadResponse
|
||||
} from '@/types/chat/api';
|
||||
|
||||
describe('聊天API模块', () => {
|
||||
let mockClient: ApiClient;
|
||||
let chatApiInstance: ReturnType<typeof chatApi>;
|
||||
|
||||
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实例
|
||||
chatApiInstance = chatApi(mockClient);
|
||||
});
|
||||
|
||||
describe('创建聊天会话功能', () => {
|
||||
it('应该能够创建新的聊天会话', async () => {
|
||||
const createRequest: CreateChatSessionRequest = {
|
||||
title: '测试聊天会话',
|
||||
modelId: 'model-123',
|
||||
systemPrompt: '你是一个有用的助手'
|
||||
};
|
||||
const mockSession = createMockChatSession({
|
||||
title: createRequest.title,
|
||||
modelId: createRequest.modelId
|
||||
});
|
||||
const mockResponse = { session: mockSession };
|
||||
|
||||
mockClient.post.mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await chatApiInstance.createSession(createRequest);
|
||||
|
||||
expect(mockClient.post).toHaveBeenCalledWith('/chat/sessions', createRequest);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('应该处理创建聊天会话失败的情况', async () => {
|
||||
const createRequest: CreateChatSessionRequest = {
|
||||
title: '',
|
||||
modelId: '',
|
||||
systemPrompt: ''
|
||||
};
|
||||
const errorResponse = {
|
||||
success: false,
|
||||
data: null,
|
||||
message: '标题和模型ID不能为空',
|
||||
code: 400
|
||||
};
|
||||
|
||||
mockClient.post.mockRejectedValue(errorResponse);
|
||||
|
||||
await expect(chatApiInstance.createSession(createRequest)).rejects.toEqual(errorResponse);
|
||||
expect(mockClient.post).toHaveBeenCalledWith('/chat/sessions', createRequest);
|
||||
});
|
||||
});
|
||||
|
||||
describe('更新聊天会话功能', () => {
|
||||
it('应该能够更新聊天会话', async () => {
|
||||
const updateRequest: UpdateChatSessionRequest = {
|
||||
sessionId: 'session-123',
|
||||
title: '更新后的标题'
|
||||
};
|
||||
const mockSession = createMockChatSession({
|
||||
id: updateRequest.sessionId,
|
||||
title: updateRequest.title
|
||||
});
|
||||
const mockResponse = { session: mockSession };
|
||||
|
||||
mockClient.put.mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await chatApiInstance.updateSession(updateRequest);
|
||||
|
||||
expect(mockClient.put).toHaveBeenCalledWith('/chat/sessions/session-123', { title: '更新后的标题' });
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('应该处理更新不存在会话的情况', async () => {
|
||||
const updateRequest: UpdateChatSessionRequest = {
|
||||
sessionId: 'non-existent-session',
|
||||
title: '更新后的标题'
|
||||
};
|
||||
const errorResponse = {
|
||||
success: false,
|
||||
data: null,
|
||||
message: '会话不存在',
|
||||
code: 404
|
||||
};
|
||||
|
||||
mockClient.put.mockRejectedValue(errorResponse);
|
||||
|
||||
await expect(chatApiInstance.updateSession(updateRequest)).rejects.toEqual(errorResponse);
|
||||
expect(mockClient.put).toHaveBeenCalledWith('/chat/sessions/non-existent-session', { title: '更新后的标题' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('发送消息功能', () => {
|
||||
it('应该能够发送消息', async () => {
|
||||
const sendMessageRequest: SendMessageRequest = {
|
||||
sessionId: 'session-123',
|
||||
content: '这是一条测试消息',
|
||||
role: 'user'
|
||||
};
|
||||
const mockMessage = createMockChatMessage({
|
||||
sessionId: sendMessageRequest.sessionId,
|
||||
content: sendMessageRequest.content,
|
||||
role: sendMessageRequest.role
|
||||
});
|
||||
const mockResponse = { message: mockMessage };
|
||||
|
||||
mockClient.post.mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await chatApiInstance.sendMessage(sendMessageRequest);
|
||||
|
||||
expect(mockClient.post).toHaveBeenCalledWith('/chat/sessions/session-123/messages', sendMessageRequest);
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('应该处理发送消息失败的情况', async () => {
|
||||
const sendMessageRequest: SendMessageRequest = {
|
||||
sessionId: 'session-123',
|
||||
content: '',
|
||||
role: 'user'
|
||||
};
|
||||
const errorResponse = {
|
||||
success: false,
|
||||
data: null,
|
||||
message: '消息内容不能为空',
|
||||
code: 400
|
||||
};
|
||||
|
||||
mockClient.post.mockRejectedValue(errorResponse);
|
||||
|
||||
await expect(chatApiInstance.sendMessage(sendMessageRequest)).rejects.toEqual(errorResponse);
|
||||
expect(mockClient.post).toHaveBeenCalledWith('/chat/sessions/session-123/messages', sendMessageRequest);
|
||||
});
|
||||
});
|
||||
|
||||
describe('获取聊天会话列表功能', () => {
|
||||
it('应该能够获取聊天会话列表', async () => {
|
||||
const getRequest: GetChatSessionsRequest = {
|
||||
page: 1,
|
||||
limit: 10
|
||||
};
|
||||
const mockSessions = [
|
||||
createMockChatSession({ id: 'session-1' }),
|
||||
createMockChatSession({ id: 'session-2' })
|
||||
];
|
||||
const mockResponse: GetChatSessionsResponse = {
|
||||
sessions: mockSessions,
|
||||
pagination: {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 20,
|
||||
totalPages: 2
|
||||
}
|
||||
};
|
||||
|
||||
mockClient.get.mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await chatApiInstance.getSessions(getRequest);
|
||||
|
||||
expect(mockClient.get).toHaveBeenCalledWith('/chat/sessions', { params: getRequest });
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('应该能够在不带参数的情况下获取聊天会话列表', async () => {
|
||||
const mockSessions = [
|
||||
createMockChatSession({ id: 'session-1' }),
|
||||
createMockChatSession({ id: 'session-2' })
|
||||
];
|
||||
const mockResponse: GetChatSessionsResponse = {
|
||||
sessions: mockSessions,
|
||||
pagination: {
|
||||
page: 1,
|
||||
limit: 20,
|
||||
total: 2,
|
||||
totalPages: 1
|
||||
}
|
||||
};
|
||||
|
||||
mockClient.get.mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await chatApiInstance.getSessions();
|
||||
|
||||
expect(mockClient.get).toHaveBeenCalledWith('/chat/sessions', {});
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('应该处理获取聊天会话列表失败的情况', async () => {
|
||||
const getRequest: GetChatSessionsRequest = {
|
||||
page: -1, // 无效的页码
|
||||
limit: 10
|
||||
};
|
||||
const errorResponse = {
|
||||
success: false,
|
||||
data: null,
|
||||
message: '页码必须大于0',
|
||||
code: 400
|
||||
};
|
||||
|
||||
mockClient.get.mockRejectedValue(errorResponse);
|
||||
|
||||
await expect(chatApiInstance.getSessions(getRequest)).rejects.toEqual(errorResponse);
|
||||
expect(mockClient.get).toHaveBeenCalledWith('/chat/sessions', { params: getRequest });
|
||||
});
|
||||
});
|
||||
|
||||
describe('获取聊天消息功能', () => {
|
||||
it('应该能够获取聊天消息', async () => {
|
||||
const getRequest: GetChatMessagesRequest = {
|
||||
sessionId: 'session-123',
|
||||
page: 1,
|
||||
limit: 10
|
||||
};
|
||||
const mockMessages = [
|
||||
createMockChatMessage({ id: 'message-1', sessionId: 'session-123' }),
|
||||
createMockChatMessage({ id: 'message-2', sessionId: 'session-123' })
|
||||
];
|
||||
const mockResponse: GetChatMessagesResponse = {
|
||||
messages: mockMessages,
|
||||
pagination: {
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 30,
|
||||
totalPages: 3
|
||||
}
|
||||
};
|
||||
|
||||
mockClient.get.mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await chatApiInstance.getMessages(getRequest);
|
||||
|
||||
expect(mockClient.get).toHaveBeenCalledWith('/chat/sessions/session-123/messages', {
|
||||
params: { page: 1, limit: 10 }
|
||||
});
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('应该处理获取不存在会话的消息的情况', async () => {
|
||||
const getRequest: GetChatMessagesRequest = {
|
||||
sessionId: 'non-existent-session',
|
||||
page: 1,
|
||||
limit: 10
|
||||
};
|
||||
const errorResponse = {
|
||||
success: false,
|
||||
data: null,
|
||||
message: '会话不存在',
|
||||
code: 404
|
||||
};
|
||||
|
||||
mockClient.get.mockRejectedValue(errorResponse);
|
||||
|
||||
await expect(chatApiInstance.getMessages(getRequest)).rejects.toEqual(errorResponse);
|
||||
expect(mockClient.get).toHaveBeenCalledWith('/chat/sessions/non-existent-session/messages', {
|
||||
params: { page: 1, limit: 10 }
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('标记消息已读功能', () => {
|
||||
it('应该能够标记消息为已读', async () => {
|
||||
const markReadRequest: MarkMessagesAsReadRequest = {
|
||||
sessionId: 'session-123',
|
||||
messageIds: ['message-1', 'message-2', 'message-3']
|
||||
};
|
||||
const mockResponse: MarkMessagesAsReadResponse = {
|
||||
success: true,
|
||||
readCount: 3
|
||||
};
|
||||
|
||||
mockClient.post.mockResolvedValue(mockResponse);
|
||||
|
||||
const result = await chatApiInstance.markMessagesAsRead(markReadRequest);
|
||||
|
||||
expect(mockClient.post).toHaveBeenCalledWith('/chat/sessions/session-123/read', {
|
||||
messageIds: ['message-1', 'message-2', 'message-3']
|
||||
});
|
||||
expect(result).toEqual(mockResponse);
|
||||
});
|
||||
|
||||
it('应该处理标记不存在的消息为已读的情况', async () => {
|
||||
const markReadRequest: MarkMessagesAsReadRequest = {
|
||||
sessionId: 'session-123',
|
||||
messageIds: ['non-existent-message']
|
||||
};
|
||||
const errorResponse = {
|
||||
success: false,
|
||||
data: null,
|
||||
message: '消息不存在',
|
||||
code: 404
|
||||
};
|
||||
|
||||
mockClient.post.mockRejectedValue(errorResponse);
|
||||
|
||||
await expect(chatApiInstance.markMessagesAsRead(markReadRequest)).rejects.toEqual(errorResponse);
|
||||
expect(mockClient.post).toHaveBeenCalledWith('/chat/sessions/session-123/read', {
|
||||
messageIds: ['non-existent-message']
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user