import { describe, it, expect, beforeEach } from "bun:test"; import { Hono } from "hono"; import { createTestDb } from "../helpers/db.ts"; import { categoryRoutes } from "../../src/server/routes/categories.ts"; import { itemRoutes } from "../../src/server/routes/items.ts"; function createTestApp() { const db = createTestDb(); const app = new Hono(); // Inject test DB into context for all routes app.use("*", async (c, next) => { c.set("db", db); await next(); }); app.route("/api/categories", categoryRoutes); app.route("/api/items", itemRoutes); return { app, db }; } describe("Category Routes", () => { let app: Hono; beforeEach(() => { const testApp = createTestApp(); app = testApp.app; }); it("POST /api/categories creates category", async () => { const res = await app.request("/api/categories", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "Shelter", icon: "tent" }), }); expect(res.status).toBe(201); const body = await res.json(); expect(body.name).toBe("Shelter"); expect(body.icon).toBe("tent"); expect(body.id).toBeGreaterThan(0); }); it("GET /api/categories returns all categories", async () => { const res = await app.request("/api/categories"); expect(res.status).toBe(200); const body = await res.json(); expect(Array.isArray(body)).toBe(true); // At minimum, Uncategorized is seeded expect(body.length).toBeGreaterThanOrEqual(1); }); it("DELETE /api/categories/:id reassigns items", async () => { // Create category const catRes = await app.request("/api/categories", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "Shelter", icon: "tent" }), }); const cat = await catRes.json(); // Create item in that category await app.request("/api/items", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name: "Tent", categoryId: cat.id }), }); // Delete the category const delRes = await app.request(`/api/categories/${cat.id}`, { method: "DELETE", }); expect(delRes.status).toBe(200); // Verify items are now in Uncategorized const itemsRes = await app.request("/api/items"); const items = await itemsRes.json(); const tent = items.find((i: any) => i.name === "Tent"); expect(tent.categoryId).toBe(1); }); it("DELETE /api/categories/1 returns 400 (cannot delete Uncategorized)", async () => { const res = await app.request("/api/categories/1", { method: "DELETE", }); expect(res.status).toBe(400); const body = await res.json(); expect(body.error).toContain("Uncategorized"); }); });