const Fastify = require("fastify"); const todosRoutes = require("../../../src/routes/todos"); const { AppError } = require("../../../src/utils/AppError"); async function buildApp({ featureEnabled = true } = {}) { const app = Fastify(); const prisma = { featureFlag: { findUnique: vi.fn(async () => ({ flag_key: "todo_board_v1", override_mode: featureEnabled ? "force_on" : "force_off", rollout_type: "global", department_ids: [], })), }, todoItem: { findMany: vi.fn(async () => []), create: vi.fn(), findUnique: vi.fn(), update: vi.fn(), }, }; app.decorate("prisma", prisma); app.decorate("config", { todoBoardEnabled: true }); app.decorate("authenticate", async (request) => { request.employee = { id: "employee-1", department_id: "department-1", permissionCodes: [] }; }); app.decorate("hasPermission", () => false); app.setErrorHandler((error, request, reply) => { if (error instanceof AppError) { return reply.code(error.statusCode).send({ error: { code: error.code, details: error.details ?? {} } }); } return reply.code(500).send({ error: { code: "SYS_001" } }); }); await app.register(todosRoutes, { prefix: "/api" }); return { app, prisma }; } describe("todos feature gate", () => { it("returns a precise reasonCode and skips todo reads when the board is disabled", async () => { const { app, prisma } = await buildApp({ featureEnabled: false }); try { const getResponse = await app.inject({ method: "GET", url: "/api/todos" }); expect(getResponse.statusCode).toBe(409); expect(getResponse.json()).toEqual({ error: { code: "VALID_001", details: { featureFlag: "todo_board_v1_disabled", reason: "flag_force_off", reasonCode: "todo.feature_disabled" }, }, }); expect(prisma.todoItem.findMany).not.toHaveBeenCalled(); const postResponse = await app.inject({ method: "POST", url: "/api/todos", payload: { title: "εˆζˆεΎ…εŠž" }, }); expect(postResponse.statusCode).toBe(409); expect(postResponse.json().error.details.reasonCode).toBe("todo.feature_disabled"); expect(prisma.todoItem.create).not.toHaveBeenCalled(); } finally { await app.close(); } }); it("lists todos normally without leaking a reasonCode when the board is enabled", async () => { const { app, prisma } = await buildApp({ featureEnabled: true }); try { const response = await app.inject({ method: "GET", url: "/api/todos" }); expect(response.statusCode).toBe(200); expect(response.json().data).toEqual({ items: [] }); expect(prisma.todoItem.findMany).toHaveBeenCalledTimes(1); } finally { await app.close(); } }); });