Files
gongxue-base/apps/admin/src/components/AiChat/message-mappers.integration.test.ts

143 lines
4.2 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { mapHistoryMessage } from './message-mappers';
describe('AI chat history mapper', () => {
it('restores reasoning, tool summaries and completed status', () => {
const mapped = mapHistoryMessage({
id: 3,
role: 'assistant',
content: '回答',
reasoningContent: '思考',
status: 'completed',
errorCode: null,
createdAt: '2026-07-23T00:00:00.000Z',
attachments: [
{
id: 8,
name: '考勤.pdf',
mimeType: 'application/pdf',
size: 100,
status: 'ready',
url: '/api/ai/chat/attachments/8',
createdAt: '2026-07-24T00:00:00.000Z',
},
],
toolRuns: [
{
toolCallId: 'tool-1',
toolName: 'search_rooms',
status: 'success',
resultSummary: '共 4 间',
},
],
});
expect(mapped.status).toBe('success');
expect(mapped.message.reasoningContent).toBe('思考');
expect(mapped.message.toolRuns[0].summary).toBe('共 4 间');
expect(mapped.message.attachments).toHaveLength(1);
});
it('maps failed and cancelled history to X SDK statuses', () => {
const base = {
id: 4,
role: 'assistant' as const,
content: '',
reasoningContent: null,
errorCode: 'UPSTREAM_ERROR',
createdAt: '2026-07-23T00:00:00.000Z',
};
expect(mapHistoryMessage({ ...base, status: 'failed' }).status).toBe('error');
expect(mapHistoryMessage({ ...base, status: 'cancelled' }).status).toBe('abort');
});
it('restores a persisted A2UI form from message metadata', () => {
const mapped = mapHistoryMessage({
id: 5,
role: 'assistant',
content: '请填写表单',
reasoningContent: null,
status: 'completed',
errorCode: null,
createdAt: '2026-07-23T00:00:00.000Z',
metadata: {
a2uiForm: {
id: 'form-9',
title: '新增学生',
submitLabel: '提交创建',
status: 'pending',
fields: [
{ name: 'name', label: '姓名', type: 'input', required: true },
{ name: 'gender', label: '性别', type: 'select', options: [{ label: '男', value: 'male' }] },
],
},
},
});
expect(mapped.message.forms).toHaveLength(1);
expect(mapped.message.forms?.[0]).toMatchObject({ id: 'form-9', title: '新增学生' });
});
it('restores a persisted A2UI review from message metadata', () => {
const mapped = mapHistoryMessage({
id: 6,
role: 'assistant',
content: '请审阅导入预览',
reasoningContent: null,
status: 'completed',
errorCode: null,
createdAt: '2026-07-23T00:00:00.000Z',
metadata: {
a2uiReview: {
id: 'review-9',
title: '批量导入',
status: 'pending',
sections: [
{
key: 'transfers',
type: 'transfers',
title: '换宿',
kind: 'table',
columns: [{ key: 'newRoom', title: '目标宿舍' }],
rows: [{ newRoom: '3-301' }],
issues: [],
},
],
},
},
});
expect(mapped.message.reviews).toHaveLength(1);
expect(mapped.message.reviews?.[0]).toMatchObject({ id: 'review-9', title: '批量导入' });
});
it('restores persisted A2UI charts from message metadata', () => {
const mapped = mapHistoryMessage({
id: 7,
role: 'assistant',
content: '这是图表',
reasoningContent: null,
status: 'completed',
errorCode: null,
createdAt: '2026-07-23T00:00:00.000Z',
metadata: {
a2uiChart: [
{
id: 'chart-9',
title: '各班级人数',
chartType: 'bar',
columns: [
{ key: 'className', title: '班级' },
{ key: 'count', title: '人数' },
],
rows: [{ className: '一班', count: 20 }],
},
],
},
});
expect(mapped.message.charts).toHaveLength(1);
expect(mapped.message.charts?.[0]).toMatchObject({ id: 'chart-9', chartType: 'bar' });
});
});