Files
GearBox/tests/routes/categories.test.ts
Jean-Luc Makiola f30d375544 feat(14-06): convert route tests + MCP tests to async PGlite
- All 8 route test files: async createTestApp(), async beforeEach
- MCP tools test: await createTestDb(), await getCollectionSummary()
- Fixed MCP tool files: added await to all service calls in items, categories, threads, setups tools
- Fixed MCP collection resource: made getCollectionSummary async
- Fixed MCP index.ts: await getCollectionSummary call
- Increased test timeout to 30s in bunfig.toml for PGlite WASM overhead
- Zero SQLite references remain in tests/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 15:40:14 +02:00

92 lines
2.6 KiB
TypeScript

import { beforeEach, describe, expect, it } from "bun:test";
import { Hono } from "hono";
import { categoryRoutes } from "../../src/server/routes/categories.ts";
import { itemRoutes } from "../../src/server/routes/items.ts";
import { createTestDb } from "../helpers/db.ts";
async function createTestApp() {
const db = await 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(async () => {
const testApp = await 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");
});
});