# Plan: Add Testing to Eyrun Auth System ## Context The project has zero test infrastructure. We need to add a test framework and write tests covering the auth system we just built, plus the lib utilities. The `buildApp()` factory pattern in `src/app.ts` is ideal for integration testing with Fastify's `.inject()` method. ## Setup **Install dependencies:** - `vitest` — test runner (ESM + TypeScript native support, no config hassle) **Config files:** - `vitest.config.ts` at project root (minimal — just point at src) - Add `"test": "vitest run"` script to `package.json` ## Test Structure ``` src/ ├── lib/ │ ├── jwt.test.ts # Unit tests │ ├── otp.test.ts # Unit tests │ └── tokens.test.ts # Unit tests └── routes/ └── auth.test.ts # Integration tests (full auth flow) ``` ## Unit Tests **`src/lib/jwt.test.ts`** — sign returns JWT string, verify decodes correct `sub`, verify throws on invalid/expired tokens **`src/lib/otp.test.ts`** — generates 6-digit string, produces varying codes **`src/lib/tokens.test.ts`** — returns non-empty string, produces unique tokens ## Integration Tests — `src/routes/auth.test.ts` Uses `buildApp()` + `app.inject()` against the real local DB. Cleans up test data (otp_codes, sessions, users by test email) in afterAll. **Test cases:** 1. `POST /auth/login` — returns message, creates OTP row in DB 2. `POST /auth/login` — rate limits after 3 requests per email/hour 3. `POST /auth/verify` — valid code → returns accessToken + refreshToken 4. `POST /auth/verify` — wrong code → 400 5. `POST /auth/verify` — creates user if email not in users table 6. `POST /auth/refresh` — valid refresh token → rotated tokens 7. `POST /auth/refresh` — reuse old token → theft detection, all sessions revoked 8. `GET /auth/me` — valid Bearer → returns user 9. `GET /auth/me` — no token → 401 10. `POST /auth/logout` — revokes sessions, refresh afterward fails ## Files to Create/Modify - `package.json` — add vitest devDep + `test` script - `vitest.config.ts` — new - `src/lib/jwt.test.ts` — new - `src/lib/otp.test.ts` — new - `src/lib/tokens.test.ts` — new - `src/routes/auth.test.ts` — new ## Verification - `pnpm test` passes all tests - `pnpm build` still compiles