Skip to content

Commit 1d4b216

Browse files
committed
test(router): add streaming response test
1 parent 394fd03 commit 1d4b216

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

packages/better-call/src/router.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,4 +1124,63 @@ describe("base path", () => {
11241124
const text = await response.text();
11251125
expect(text).toBe("hello world");
11261126
});
1127+
1128+
/**
1129+
* @see https://github.com/better-auth/better-call/issues/12
1130+
*/
1131+
describe("streaming response", () => {
1132+
it("returns a Response with a ReadableStream body unchanged from the handler", async () => {
1133+
const encoder = new TextEncoder();
1134+
const messages = Array.from({ length: 5 }, (_, i) => `Message ${i}\n`);
1135+
const endpoint = createEndpoint(
1136+
"/ai/realtime",
1137+
{ method: "POST" },
1138+
async () => {
1139+
const queue = [...messages];
1140+
const stream = new ReadableStream({
1141+
pull(controller) {
1142+
const next = queue.shift();
1143+
if (next === undefined) {
1144+
controller.close();
1145+
return;
1146+
}
1147+
controller.enqueue(encoder.encode(next));
1148+
},
1149+
});
1150+
return new Response(stream, {
1151+
status: 200,
1152+
headers: {
1153+
"Content-Type": "application/x-ndjson",
1154+
"Transfer-Encoding": "chunked",
1155+
"Cache-Control": "no-cache",
1156+
Connection: "keep-alive",
1157+
},
1158+
});
1159+
},
1160+
);
1161+
const router = createRouter({ endpoint });
1162+
1163+
const res = await router.handler(
1164+
new Request("http://localhost/ai/realtime", { method: "POST" }),
1165+
);
1166+
1167+
expect(res.status).toBe(200);
1168+
expect(res.headers.get("Content-Type")).toBe("application/x-ndjson");
1169+
expect(res.headers.get("Transfer-Encoding")).toBe("chunked");
1170+
expect(res.headers.get("Cache-Control")).toBe("no-cache");
1171+
expect(res.headers.get("Connection")).toBe("keep-alive");
1172+
1173+
if (!res.body) {
1174+
throw new Error("Body is null");
1175+
}
1176+
const reader = res.body.getReader();
1177+
const decoder = new TextDecoder();
1178+
for (let i = 0; i < messages.length; i++) {
1179+
const { value } = await reader.read();
1180+
expect(decoder.decode(value)).toBe(messages[i]);
1181+
}
1182+
const tail = await reader.read();
1183+
expect(tail.done).toBe(true);
1184+
});
1185+
});
11271186
});

0 commit comments

Comments
 (0)