import Fastify, { FastifyInstance } from 'fastify'; import { AppError } from '../../src/utils/errors.js'; import { authRoutes } from '../../src/routes/auth.js'; import type { MockDb } from '../test-utils.js'; import { createMockDb } from '../test-utils.js'; /** * Build a minimal Fastify app for auth route integration tests. * Uses mock db and rate limit options (no actual rate limiting). */ export async function buildAuthTestApp(mockDb?: MockDb): Promise { const db = mockDb ?? createMockDb(); const app = Fastify({ logger: false, requestIdHeader: 'x-request-id', requestIdLogLabel: 'requestId', }); app.setErrorHandler((err: unknown, request, reply) => { const error = err as Error & { statusCode?: number; validation?: unknown }; if (err instanceof AppError) { return reply.status(err.statusCode).send(err.toJSON()); } if (error.validation) { return reply.status(422).send({ error: { code: 'VALIDATION_ERROR', message: 'Validation failed', details: error.validation }, }); } return reply.status(500).send({ error: { code: 'INTERNAL_ERROR', message: error.message } }); }); app.decorate('db', db); app.decorate('rateLimitOptions', { login: { max: 100, timeWindow: '1 minute' }, register: { max: 100, timeWindow: '1 hour' }, forgotPassword: { max: 100, timeWindow: '1 hour' }, verifyEmail: { max: 100, timeWindow: '15 minutes' }, apiAuthed: { max: 100, timeWindow: '1 minute' }, apiGuest: { max: 100, timeWindow: '1 minute' }, }); await app.register(authRoutes, { prefix: '/auth' }); return app; }