54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import { expect, test } from 'vitest';
|
|
|
|
import { readCreationAgentSessionFromSse } from './creationAgentSse';
|
|
|
|
function createChunkedStreamResponse(chunks: Uint8Array[]) {
|
|
const stream = new ReadableStream<Uint8Array>({
|
|
start(controller) {
|
|
for (const chunk of chunks) {
|
|
controller.enqueue(chunk);
|
|
}
|
|
controller.close();
|
|
},
|
|
});
|
|
|
|
return new Response(stream, {
|
|
headers: {
|
|
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
},
|
|
});
|
|
}
|
|
|
|
test('readCreationAgentSessionFromSse flushes decoder tail and handles CRLF boundaries', async () => {
|
|
const encoder = new TextEncoder();
|
|
const prefix = encoder.encode('event: reply_delta\r\ndata: {"text":"');
|
|
const replyTextBytes = encoder.encode('你好,潮雾列岛');
|
|
const suffix = encoder.encode(
|
|
'"}\r\n\r\nevent: session\r\ndata: {"session":{"sessionId":"session-1","title":"世界共创"}}\r\n\r\n',
|
|
);
|
|
const splitIndex = replyTextBytes.length - 1;
|
|
|
|
const chunks = [
|
|
new Uint8Array([...prefix, ...replyTextBytes.slice(0, splitIndex)]),
|
|
new Uint8Array([...replyTextBytes.slice(splitIndex), ...suffix]),
|
|
];
|
|
|
|
const updates: string[] = [];
|
|
const session = await readCreationAgentSessionFromSse<{
|
|
sessionId: string;
|
|
title: string;
|
|
}>(createChunkedStreamResponse(chunks), {
|
|
fallbackMessage: '发送失败',
|
|
incompleteMessage: '结果不完整',
|
|
onUpdate: (text) => {
|
|
updates.push(text);
|
|
},
|
|
});
|
|
|
|
expect(updates).toEqual(['你好,潮雾列岛']);
|
|
expect(session).toEqual({
|
|
sessionId: 'session-1',
|
|
title: '世界共创',
|
|
});
|
|
});
|