import { describe, test, expect } from "bun:test"; import { Hono } from "hono"; /** * Tests for the router aggregation pattern used throughout the app. * Each router imports route modules and mounts them. */ describe("Router pattern", () => { test("mounting multiple routes via Object.values pattern", () => { // Simulate the pattern used in companyRouter.ts const route1 = new Hono().get("/items", (c) => c.json({ route: "items" })); const route2 = new Hono().get("/count", (c) => c.json({ route: "count" })); const routes = { route1, route2 }; const router = new Hono(); Object.values(routes).map((r) => router.route("/", r)); // Mount router under a prefix const app = new Hono(); app.route("/v1/resource", router); return Promise.all([ (async () => { const res = await app.request("/v1/resource/items"); expect(res.status).toBe(200); const body: any = await res.json(); expect(body.route).toBe("items"); })(), (async () => { const res = await app.request("/v1/resource/count"); expect(res.status).toBe(200); const body: any = await res.json(); expect(body.route).toBe("count"); })(), ]); }); test("nested route parameters work correctly", async () => { const route = new Hono().get("/items/:id", (c) => c.json({ id: c.req.param("id") }), ); const router = new Hono(); router.route("/", route); const app = new Hono(); app.route("/v1/test", router); const res = await app.request("/v1/test/items/abc-123"); expect(res.status).toBe(200); const body: any = await res.json(); expect(body.id).toBe("abc-123"); }); test("error propagation through router chain", async () => { const route = new Hono().get("/fail", () => { throw new Error("Boom!"); }); const router = new Hono(); router.route("/", route); const app = new Hono(); app.onError((err, c) => c.json({ error: err.message, caught: true }, 500)); app.route("/v1", router); const res = await app.request("/v1/fail"); expect(res.status).toBe(500); const body: any = await res.json(); expect(body.caught).toBe(true); expect(body.error).toBe("Boom!"); }); });