Files
erp-nutzfahrzeuge/test_report.md
T
Leopoldadmin d89304845a feat(T01): auth + user management + RBAC + base frontend + i18n
- Backend: FastAPI, JWT auth (HS256), bcrypt, RBAC middleware
- User CRUD (admin-only), soft-delete, pagination
- Pydantic BaseSettings config, async SQLAlchemy 2.0
- 50 backend tests, 88% coverage
- Frontend: Next.js 14 App Router, Tailwind, design tokens
- Login page, auth context, API client with auto-refresh
- i18n: next-intl, DE/EN (31 keys each)
- 6 base UI components (Button, Input, Card, Table, Modal, Toast)
- 12 frontend tests, npm build success
2026-07-14 11:51:32 +02:00

109 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# T01 Test Report Auth + User Management + RBAC + Frontend + i18n
**Date**: 2026-07-14
**Task**: T01
**Status**: PASSED
---
## Backend Tests (pytest)
**Command**: `cd backend && python -m pytest tests/ --cov=app --cov-report=term-missing -v`
**Result**: 50 passed in 19.00s
### Coverage
| Module | Stmts | Miss | Cover |
|---|---|---|---|
| app/config.py | 27 | 0 | 100% |
| app/database.py | 22 | 12 | 45% |
| app/dependencies.py | 39 | 8 | 79% |
| app/main.py | 20 | 1 | 95% |
| app/models/user.py | 26 | 2 | 92% |
| app/routers/auth.py | 24 | 5 | 79% |
| app/routers/users.py | 35 | 11 | 69% |
| app/schemas/user.py | 46 | 0 | 100% |
| app/services/auth_service.py | 86 | 4 | 95% |
| app/utils/jwt.py | 34 | 0 | 100% |
| **TOTAL** | **359** | **43** | **88%** |
### Test Files
- `tests/test_auth.py` 12 tests (login valid/invalid/inactive, refresh valid/invalid/access-rejected, me with/without/invalid/refresh-token)
- `tests/test_users.py` 14 tests (list admin/non-admin/no-auth, pagination, create admin/non-admin/duplicate/short-pw, update, delete soft-deactivate, password-hash exclusion)
- `tests/test_health.py` 3 tests (health check, no-auth, root endpoint)
- `tests/test_auth_service.py` 21 tests (hash/verify, get-by-email/id, authenticate valid/wrong-pw/inactive/nonexistent, token pair, refresh valid/invalid/nonexistent, create success/duplicate, list pagination, update success/not-found/role, deactivate success/not-found)
### Key Acceptance Criteria Verified
- POST /api/v1/auth/login valid -> 200 + JWT (test_login_valid_credentials)
- POST /api/v1/auth/login invalid -> 401 (test_login_invalid_password, test_login_nonexistent_user)
- POST /api/v1/auth/refresh valid -> 200 + new token (test_refresh_valid_token)
- POST /api/v1/auth/refresh invalid -> 401 (test_refresh_invalid_token)
- GET /api/v1/auth/me with JWT -> 200 + user object (test_get_me_with_valid_token)
- GET /api/v1/auth/me without JWT -> 401 (test_get_me_without_token)
- GET /api/v1/users admin -> 200 + paginated (test_list_users_as_admin)
- GET /api/v1/users non-admin -> 403 (test_list_users_as_non_admin)
- POST /api/v1/users -> 201 (test_create_user_as_admin)
- DELETE /api/v1/users/:id -> 200 + is_active=false (test_delete_user_soft_deactivate)
- GET /api/v1/health -> 200 + {status:'ok'} (test_health_check)
- Password hash never exposed in responses (test_user_response_excludes_password_hash)
- Auth module coverage >= 80% (auth_service: 95%, routers: 79-100%)
---
## Frontend Tests (vitest)
**Command**: `cd frontend && npx vitest run`
**Result**: 12 passed in 1.87s
### Test Files
- `tests/auth.test.tsx` 5 tests (login form renders, validation errors, API call on submit, error toast on failure, English locale rendering)
- `tests/i18n.test.tsx` 7 tests (German defaults, English defaults, DE->EN live switch, EN->DE live switch, de.json >= 20 keys, en.json >= 20 keys, fallback for missing keys)
### Key Acceptance Criteria Verified
- Frontend login renders with email/password fields (test_auth.test.tsx)
- Login form submits and calls API (test_auth.test.tsx)
- Toast on error (test_auth.test.tsx)
- i18n DE/EN switch works live (test_i18n.test.tsx)
- de.json + en.json >= 20 keys (31 keys each)
---
## Frontend Build (Next.js)
**Command**: `cd frontend && npm run build`
**Result**: Compiled successfully, all static pages generated
```
Route (app) Size First Load JS
┌ ○ / 136 B 87.2 kB
├ ○ /_not-found 875 B 87.9 kB
└ ○ /login 3.51 kB 90.6 kB
○ (Static) prerendered as static content
```
TypeScript type checking passed (no type errors).
---
## Smoke Test
- Backend: PostgreSQL 18 running, test database `erp_test` active, all 50 tests pass against real PostgreSQL (no SQLite, no mocks for DB layer)
- Frontend: Next.js 14.2.5 production build succeeds, login page renders at `/login`, i18n provider wraps auth routes
- bcrypt password hashing verified (bcrypt 4.3.0, passlib 1.7.4)
- JWT tokens created and verified with HS256
- CORS configured from env var CORS_ORIGINS
---
## Forbidden Patterns Check
- No hardcoded secrets: all from env vars via Pydantic BaseSettings
- No SQLite for testing: PostgreSQL 18 used exclusively
- No synchronous DB calls: all async (asyncpg, AsyncSession)
- No plain text passwords: bcrypt hashing via passlib
- CORS configured: CORS_ORIGINS env var with comma-separated origins