Files
zhuangang/topics/backend/nodejs/examples/express-bff/app.test.ts
T

54 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 不自动运行(需要 npm install 后执行 node --test app.test.ts)
import assert from "node:assert/strict";
import type { AddressInfo } from "node:net";
import { after, before, test } from "node:test";
import { createApp } from "./app.ts";
let base = "";
let close: () => void = () => {};
before(async () => {
const app = createApp({
async *askLLM(q) {
if (q === "boom") throw new Error("upstream down");
yield "你好";
yield q;
},
findOrder: async (id) => (id === "A001" ? { id, status: "paid" } : null),
});
const server = app.listen(0);
await new Promise((r) => server.once("listening", r));
base = `http://127.0.0.1:${(server.address() as AddressInfo).port}`;
close = () => server.close();
});
after(() => close());
test("查询订单:正常 / 格式错误 / 不存在", async () => {
assert.deepEqual(await (await fetch(`${base}/orders/A001`)).json(), { id: "A001", status: "paid" });
const bad = await fetch(`${base}/orders/xx`);
assert.equal(bad.status, 400);
assert.equal((await bad.json()).code, "BAD_ORDER_ID");
const missing = await fetch(`${base}/orders/A999`);
assert.equal(missing.status, 404);
assert.ok(missing.headers.get("x-request-id"));
});
test("请求体不是合法 JSON 时返回 400 而不是 500", async () => {
const r = await fetch(`${base}/chat`, { method: "POST", headers: { "content-type": "application/json" }, body: "{bad" });
assert.equal(r.status, 400);
});
test("流式对话:逐条 SSE 事件,最后是 done", async () => {
const r = await fetch(`${base}/chat`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ question: "退货" }) });
assert.match(r.headers.get("content-type") ?? "", /^text\/event-stream/); // express 会追加 charset
const text = await r.text();
assert.match(text, /data: \{"token":"你好"\}/);
assert.match(text, /data: \{"token":"退货"\}/);
assert.match(text, /event: done/);
});
test("上游失败:用 error 事件通知,而不是挂起连接", async () => {
const r = await fetch(`${base}/chat`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ question: "boom" }) });
assert.match(await r.text(), /event: error/);
});