import { describe, test, expect } from "bun:test"; import { createRoute } from "../../src/modules/api-utils/createRoute"; import { Hono } from "hono"; describe("createRoute", () => { test("returns a Hono instance", () => { const route = createRoute("get", ["/test"], (c) => c.text("ok")); expect(route).toBeInstanceOf(Hono); }); test("GET route responds correctly", async () => { const route = createRoute("get", ["/hello"], (c) => c.json({ message: "Hello" }), ); const res = await route.request("/hello"); expect(res.status).toBe(200); const body: any = await res.json(); expect(body.message).toBe("Hello"); }); test("POST route responds correctly", async () => { const route = createRoute("post", ["/items"], async (c) => { const body = await c.req.json(); return c.json({ received: body }); }); const res = await route.request("/items", { method: "POST", body: JSON.stringify({ name: "test" }), headers: { "Content-Type": "application/json" }, }); expect(res.status).toBe(200); const data: any = await res.json(); expect(data.received.name).toBe("test"); }); test("supports multiple paths", async () => { const route = createRoute("get", ["/a", "/b"], (c) => c.json({ path: c.req.path }), ); const resA = await route.request("/a"); const resB = await route.request("/b"); expect(resA.status).toBe(200); expect(resB.status).toBe(200); }); test("applies middleware", async () => { let middlewareRan = false; const route = createRoute( "get", ["/protected"], (c) => c.json({ ok: true }), async (c, next) => { middlewareRan = true; await next(); }, ); await route.request("/protected"); expect(middlewareRan).toBe(true); }); test("middleware can block handler", async () => { const route = createRoute( "get", ["/blocked"], (c) => c.json({ ok: true }), async (c, _next) => { return c.json({ blocked: true }, 403); }, ); const res = await route.request("/blocked"); expect(res.status).toBe(403); const body: any = await res.json(); expect(body.blocked).toBe(true); }); test("supports multiple middleware functions", async () => { const order: number[] = []; const route = createRoute( "get", ["/multi"], (c) => c.json({ order }), async (_c, next) => { order.push(1); await next(); }, async (_c, next) => { order.push(2); await next(); }, ); await route.request("/multi"); expect(order).toEqual([1, 2]); }); test("returns 404 for unmatched paths", async () => { const route = createRoute("get", ["/exists"], (c) => c.text("ok")); const res = await route.request("/not-exists"); expect(res.status).toBe(404); }); test("method mismatch returns 404 or 405", async () => { const route = createRoute("get", ["/only-get"], (c) => c.text("ok")); const res = await route.request("/only-get", { method: "POST" }); // Hono returns 404 for method mismatch by default expect([404, 405]).toContain(res.status); }); });