test(server): 补充 checkpoints/mcp/sse/adapter 测试
- 新增 checkpoints.test.ts: 29 个测试覆盖 Checkpoint 管理 API - 新增 mcp.test.ts: 15 个测试覆盖 MCP 服务器管理 API - 扩展 sse.test.ts: 添加 handleSSE 路由测试 - 扩展 adapter.test.ts: 添加 cancelProcessing, getContextUsage, compressContext, processMessage 测试 覆盖率提升: 60% -> 80.82% 测试数量: 288 -> 344
This commit is contained in:
@@ -338,4 +338,221 @@ describe('Agent Adapter', () => {
|
||||
expect(stats.contextUsage).toBe('10k / 200k');
|
||||
});
|
||||
});
|
||||
|
||||
describe('cancelProcessing - 取消处理', () => {
|
||||
it('更新会话状态为 idle', async () => {
|
||||
const mockSessionManager = {
|
||||
exists: vi.fn().mockReturnValue(true),
|
||||
updateStatus: vi.fn(),
|
||||
};
|
||||
|
||||
vi.doMock('../../../src/session/manager.js', () => ({
|
||||
getSessionManager: vi.fn().mockReturnValue(mockSessionManager),
|
||||
}));
|
||||
|
||||
vi.doMock('../../../src/sse.js', () => ({
|
||||
emitStatusEvent: vi.fn(),
|
||||
emitLogEvent: vi.fn(),
|
||||
}));
|
||||
|
||||
const { cancelProcessing } = await import('../../../src/agent/adapter.js');
|
||||
cancelProcessing('session-1');
|
||||
|
||||
expect(mockSessionManager.updateStatus).toHaveBeenCalledWith('session-1', 'idle');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getContextUsage - 获取上下文使用情况', () => {
|
||||
it('Core 未初始化时返回 null', async () => {
|
||||
vi.resetModules();
|
||||
const { getContextUsage } = await import('../../../src/agent/adapter.js');
|
||||
const usage = getContextUsage('session-1');
|
||||
expect(usage).toBeNull();
|
||||
});
|
||||
|
||||
it('Agent 不存在时返回 null', async () => {
|
||||
const mockCore = createMockCoreModule();
|
||||
vi.doMock('@ai-assistant/core', () => mockCore);
|
||||
|
||||
const { initCore, getContextUsage } = await import('../../../src/agent/adapter.js');
|
||||
await initCore();
|
||||
|
||||
const usage = getContextUsage('non-existent-session');
|
||||
expect(usage).toBeNull();
|
||||
});
|
||||
|
||||
it('Agent 存在时返回使用情况', async () => {
|
||||
const mockCore = createMockCoreModule();
|
||||
vi.doMock('@ai-assistant/core', () => mockCore);
|
||||
|
||||
vi.doMock('../../../src/session/manager.js', () => ({
|
||||
getSessionManager: vi.fn().mockReturnValue({
|
||||
exists: vi.fn().mockReturnValue(true),
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.doMock('../../../src/permission/handler.js', () => ({
|
||||
createServerPermissionCallback: vi.fn().mockReturnValue(async () => ({ allow: true })),
|
||||
}));
|
||||
|
||||
const { initCore, getOrCreateAgent, getContextUsage } = await import('../../../src/agent/adapter.js');
|
||||
await initCore();
|
||||
|
||||
getOrCreateAgent('session-1');
|
||||
|
||||
const usage = getContextUsage('session-1');
|
||||
expect(usage).not.toBeNull();
|
||||
expect(usage?.formatted).toBe('10k / 200k');
|
||||
expect(usage?.input).toBe(10000);
|
||||
});
|
||||
});
|
||||
|
||||
describe('compressContext - 上下文压缩', () => {
|
||||
it('Core 未初始化时返回 null', async () => {
|
||||
vi.resetModules();
|
||||
const { compressContext } = await import('../../../src/agent/adapter.js');
|
||||
const result = await compressContext('session-1');
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('Agent 不存在时返回 null', async () => {
|
||||
const mockCore = createMockCoreModule();
|
||||
vi.doMock('@ai-assistant/core', () => mockCore);
|
||||
|
||||
const { initCore, compressContext } = await import('../../../src/agent/adapter.js');
|
||||
await initCore();
|
||||
|
||||
const result = await compressContext('non-existent-session');
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('压缩成功时返回结果', async () => {
|
||||
const mockCore = createMockCoreModule();
|
||||
vi.doMock('@ai-assistant/core', () => mockCore);
|
||||
|
||||
vi.doMock('../../../src/session/manager.js', () => ({
|
||||
getSessionManager: vi.fn().mockReturnValue({
|
||||
exists: vi.fn().mockReturnValue(true),
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.doMock('../../../src/permission/handler.js', () => ({
|
||||
createServerPermissionCallback: vi.fn().mockReturnValue(async () => ({ allow: true })),
|
||||
}));
|
||||
|
||||
const { initCore, getOrCreateAgent, compressContext } = await import('../../../src/agent/adapter.js');
|
||||
await initCore();
|
||||
|
||||
getOrCreateAgent('session-1');
|
||||
|
||||
const result = await compressContext('session-1');
|
||||
expect(result).not.toBeNull();
|
||||
expect(result?.type).toBe('prune');
|
||||
expect(result?.freedTokens).toBe(1000);
|
||||
});
|
||||
|
||||
it('压缩失败时返回错误信息', async () => {
|
||||
const mockCore = createMockCoreModule({
|
||||
agent: {
|
||||
compactHistory: vi.fn().mockRejectedValue(new Error('Compression failed')),
|
||||
},
|
||||
});
|
||||
|
||||
vi.doMock('@ai-assistant/core', () => mockCore);
|
||||
|
||||
vi.doMock('../../../src/session/manager.js', () => ({
|
||||
getSessionManager: vi.fn().mockReturnValue({
|
||||
exists: vi.fn().mockReturnValue(true),
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.doMock('../../../src/permission/handler.js', () => ({
|
||||
createServerPermissionCallback: vi.fn().mockReturnValue(async () => ({ allow: true })),
|
||||
}));
|
||||
|
||||
const { initCore, getOrCreateAgent, compressContext } = await import('../../../src/agent/adapter.js');
|
||||
await initCore();
|
||||
|
||||
getOrCreateAgent('session-1');
|
||||
|
||||
const result = await compressContext('session-1');
|
||||
expect(result).not.toBeNull();
|
||||
expect(result?.status).toBe('failed_error');
|
||||
expect(result?.error).toBe('Compression failed');
|
||||
});
|
||||
});
|
||||
|
||||
describe('processMessage - 消息处理', () => {
|
||||
it('Agent 不可用时发送占位消息', async () => {
|
||||
const mockSessionManager = {
|
||||
exists: vi.fn().mockReturnValue(true),
|
||||
updateStatus: vi.fn(),
|
||||
addMessage: vi.fn().mockResolvedValue({ id: 'msg-1', role: 'assistant', content: 'placeholder' }),
|
||||
};
|
||||
|
||||
vi.doMock('../../../src/session/manager.js', () => ({
|
||||
getSessionManager: vi.fn().mockReturnValue(mockSessionManager),
|
||||
}));
|
||||
|
||||
const mockBroadcast = vi.fn();
|
||||
vi.doMock('../../../src/ws.js', () => ({
|
||||
broadcastToSession: mockBroadcast,
|
||||
}));
|
||||
|
||||
vi.doMock('../../../src/sse.js', () => ({
|
||||
emitStatusEvent: vi.fn(),
|
||||
emitLogEvent: vi.fn(),
|
||||
}));
|
||||
|
||||
// 不初始化 core,使 agent 为 null
|
||||
vi.resetModules();
|
||||
const { processMessage } = await import('../../../src/agent/adapter.js');
|
||||
await processMessage('session-1', 'Hello');
|
||||
|
||||
// 应该发送占位消息
|
||||
expect(mockBroadcast).toHaveBeenCalledWith('session-1', expect.objectContaining({
|
||||
type: 'chunk',
|
||||
}));
|
||||
});
|
||||
|
||||
it('成功处理消息并返回响应', async () => {
|
||||
const mockCore = createMockCoreModule();
|
||||
vi.doMock('@ai-assistant/core', () => mockCore);
|
||||
|
||||
const mockSessionManager = {
|
||||
exists: vi.fn().mockReturnValue(true),
|
||||
get: vi.fn().mockReturnValue({ id: 'session-1', name: 'Test' }),
|
||||
updateStatus: vi.fn(),
|
||||
addMessage: vi.fn().mockResolvedValue({ id: 'msg-1', role: 'assistant', content: 'response' }),
|
||||
getMessages: vi.fn().mockReturnValue([]),
|
||||
};
|
||||
|
||||
vi.doMock('../../../src/session/manager.js', () => ({
|
||||
getSessionManager: vi.fn().mockReturnValue(mockSessionManager),
|
||||
}));
|
||||
|
||||
vi.doMock('../../../src/permission/handler.js', () => ({
|
||||
createServerPermissionCallback: vi.fn().mockReturnValue(async () => ({ allow: true })),
|
||||
}));
|
||||
|
||||
const mockBroadcast = vi.fn();
|
||||
vi.doMock('../../../src/ws.js', () => ({
|
||||
broadcastToSession: mockBroadcast,
|
||||
}));
|
||||
|
||||
vi.doMock('../../../src/sse.js', () => ({
|
||||
emitStatusEvent: vi.fn(),
|
||||
emitLogEvent: vi.fn(),
|
||||
}));
|
||||
|
||||
const { initCore, processMessage } = await import('../../../src/agent/adapter.js');
|
||||
await initCore();
|
||||
await processMessage('session-1', 'Hello');
|
||||
|
||||
// 应该发送 done 消息
|
||||
expect(mockBroadcast).toHaveBeenCalledWith('session-1', expect.objectContaining({
|
||||
type: 'done',
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user