import { afterEach, expect, test } from "bun:test"; import express from "express"; import type { Server } from "node:http"; import { buildChatRouter } from "../../src/routes/chat.js"; const originalFetch = globalThis.fetch; let server: Server | undefined; afterEach(async () => { globalThis.fetch = originalFetch; if (server) await new Promise((resolve) => server!.close(() => resolve())); server = undefined; }); test("suggestions inherit verified identity and project scope and reject unsupported requests before inference", async () => { globalThis.fetch = (async (_input, init) => { const headers = new Headers(init?.headers); if (headers.get("Authorization") === "Bearer denied") return Response.json({ detail: "denied" }, { status: 403 }); return Response.json({ user_id: headers.get("Authorization") === "Bearer user-a" ? "user-a" : "user-b", project_id: headers.get("X-Project-Id"), network: "supply" }); }) as typeof fetch; let generations = 0; const app = express(); app.use(express.json()); app.use("/api/v1", buildChatRouter({ runtime: { generateText: async () => { generations += 1; return '{"suggestions":[{"question":"核对供水监测数据的完整性","activity_id":null}]}'; } }, frontendActionCoordinator: {}, learningOrchestrator: {}, memoryStore: {}, sessionBridge: {}, sessionMetadataStore: {}, sessionTranscriptStore: {}, sessionUiStateStore: {}, } as never)); server = app.listen(0, "127.0.0.1"); await new Promise((resolve) => server!.once("listening", resolve)); const address = server.address(); if (!address || typeof address === "string") throw new Error("missing test server address"); const post = (user: string, project = "10000000-0000-4000-8000-000000000001", body: unknown = { activities: [] }) => originalFetch(`http://127.0.0.1:${address.port}/api/v1/suggestions`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${user}`, "X-Project-Id": project, Connection: "close" }, body: JSON.stringify(body), }); expect((await post("user-a")).status).toBe(200); expect((await post("user-a")).status).toBe(200); expect(generations).toBe(1); expect((await post("user-b")).status).toBe(200); expect((await post("user-a", "10000000-0000-4000-8000-000000000002")).status).toBe(200); expect(generations).toBe(3); expect((await post("denied")).status).toBe(403); expect((await post("user-a", undefined, { activities: [], model: "unknown/model" })).status).toBe(400); expect((await post("user-a", undefined, { activities: [], unexpected: "field" })).status).toBe(400); expect(generations).toBe(3); });