import { describe, expect, it } from "vitest"; import type { RouteDefinition, RouteModule } from "../../src/routes/types.js"; import { ApplicationError } from "../../src/errors/index.js"; import { ApplicationRouter } from "../../src/services/router.js"; import { TestConnection } from "../helpers/test-connection.js"; function moduleWith(routes: RouteDefinition[]): RouteModule { return { async getRoutes() { return routes; }, }; } describe("ApplicationRouter initialization", () => { it("rejects duplicate exact paths during startup", async () => { const route = { url: "/echo", handler: () => undefined }; await expect( ApplicationRouter.create([moduleWith([route]), moduleWith([route])]), ).rejects.toThrow("Duplicate application route: /echo"); }); it.each(["echo", "/", "/items/:id", "/items?active=true", "/items#active"])( "rejects the invalid route path %s", async (url) => { await expect( ApplicationRouter.create([ moduleWith([{ url, handler: () => undefined }]), ]), ).rejects.toThrow("Invalid application route"); }, ); }); describe("ApplicationRouter dispatch", () => { it("binds the connection, body, and request ID to one route stream", async () => { const connection = new TestConnection(false, false); const router = await ApplicationRouter.create([ moduleWith([ { url: "/echo", handler: async (stream) => { expect(stream.connection).toBe(connection); await stream.send(stream.body); }, }, ]), ]); await router.dispatch( { path: "/echo", body: { value: 1 }, requestId: "request-1" }, connection, ); expect(connection.messages).toEqual([ { id: "request-1", type: "response", statusCode: 200, body: { value: 1 }, }, ]); await expect( router.dispatch({ path: "/echo/other", body: {} }, connection), ).rejects.toMatchObject({ statusCode: 404 }); }); it("preserves correlation when concurrent requests finish out of order", async () => { const completions = new Map void>(); const router = await ApplicationRouter.create([ moduleWith([ { url: "/delayed", handler: async (stream) => { const key = (stream.body as { key: string }).key; await new Promise((resolve) => completions.set(key, resolve)); await stream.send({ key }); }, }, ]), ]); const connection = new TestConnection(true, true); const first = router.dispatch( { path: "/delayed", body: { key: "A" }, requestId: "A" }, connection, ); const second = router.dispatch( { path: "/delayed", body: { key: "B" }, requestId: "B" }, connection, ); completions.get("B")?.(); await second; completions.get("A")?.(); await first; expect(connection.messages).toEqual([ { id: "B", type: "response", statusCode: 200, body: { key: "B" }, }, { id: "A", type: "response", statusCode: 200, body: { key: "A" }, }, ]); }); it("propagates route failures without infrastructure-specific cleanup", async () => { const error = new Error("route failed"); const router = await ApplicationRouter.create([ moduleWith([ { url: "/failure", handler: () => { throw error; }, }, ]), ]); await expect( router.dispatch({ path: "/failure" }, new TestConnection(false, false)), ).rejects.toBe(error); }); });