Files
curo1305 50d2348b36 refactor: rename MERGE_CHECKLIST to ALL_TESTS + add per-service test files
- tests/MERGE_CHECKLIST.md → tests/ALL_TESTS.md (git rename, updated header + index of sub-files)
- tests/backend_tests.md — §1–9, §18 (auth, users, admin, groups, appearance, service health, plugins, AI/doc settings, infra/security)
- tests/frontend_tests.md — §19 (UI & routing)
- tests/doc-service_tests.md — §10–16 (upload/processing, list/filtering, slide-over, sharing, categories, bulk actions, watch directory)
- tests/ai-service_tests.md — §17 (AI queue & providers)
- CLAUDE.md: updated merge checklist section, file tree, and self-update checkpoint with mandatory test-file update rule
- settings.local.json: added docker inspect/ps, curl, lsof, git merge/branch/log/diff/status/config/mv permissions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 02:19:51 +02:00

11 KiB
Raw Permalink Blame History

Backend Tests

Tests covering the FastAPI gateway (backend:8000): auth, user/profile management, admin (users/groups/appearance), service health, plugin system, AI settings, document settings, and infrastructure/security.

Full combined suite: tests/ALL_TESTS.md

Test environment: Feature stack at http://localhost:$PORT (see CLAUDE.md §Feature branch workflow). Admin credentials: any superuser account created during stack setup. Regular user credentials: a second non-admin account for permission boundary tests.


Legend

Symbol Meaning
Pass
Fail
N/A for this change

1. Authentication

# Test Steps Expected
1.1 Register new account POST /api/auth/register with valid email + strong password 201; user row created; login works immediately
1.2 Password policy — too short Register with 7-char password 422 with validation error
1.3 Password policy — no uppercase Register with all-lowercase password 422 with validation error
1.4 Password policy — no special char Register without special character 422 with validation error
1.5 Password policy — common word Register with password containing "password" 422 with validation error
1.6 Duplicate email Register with an already-used email 400
1.7 Login — valid credentials POST /api/auth/login with correct email + password 200; access_token returned
1.8 Login — wrong password POST /api/auth/login with wrong password 401
1.9 Login — inactive account Admin deactivates user; attempt login 401
1.10 JWT expiry respected Manually craft token with exp in the past; call any protected route 401
1.11 Logout clears session Click Logout in UI; try navigating to / Redirected to /login
1.12 Unauthenticated redirect Open / without a token in localStorage Redirected to /login

2. User — Profile & Preferences

# Test Steps Expected
2.1 Fetch own profile GET /api/profile/me 200; profile auto-created if first request
2.2 Update profile fields PUT /api/profile/me with full_name, phone, position, address, date_of_birth 200; fields persisted; visible on /profile page
2.3 Invalid phone format PUT /api/profile/me with letters in phone field 422
2.4 Future date of birth PUT /api/profile/me with DOB = tomorrow 422
2.5 DOB before 1900 PUT /api/profile/me with DOB = 1899-12-31 422
2.6 Fetch dashboard preferences GET /api/users/me/preferences 200; app_ids list
2.7 Pin an app Dashboard → pencil button → press + on a card → save Card appears in pinned grid on next load
2.8 Unpin an app Dashboard → pencil button → press on a pinned card → save Card removed from pinned grid
2.9 Pin limit (50) PATCH /api/users/me/preferences with 51 app IDs 422
2.10 Color mode — user pref User sets mode to "dark"; reload page Dark theme applied; preference persists across sessions
2.11 Color mode — system fallback User has NULL color_mode; admin default_mode = "light" Light theme applied

3. Admin — Users

# Test Steps Expected
3.1 List all users Admin → /admin/users All registered users shown in table
3.2 Create user Admin clicks "Create user"; fills form 201; new user appears in list; can log in
3.3 Toggle user active Admin clicks toggle on active user User deactivated; login returns 401
3.4 Delete user Admin deletes a user 204; user no longer in list; their documents remain (orphaned)
3.5 Non-admin access Regular user navigates to /admin/users Redirected to /login
3.6 Admin 404 semantics Regular user calls GET /api/admin/users via curl 404 (not 403)

4. Admin — Groups

# Test Steps Expected
4.1 List groups Admin → /admin/groups All groups shown with member count
4.2 Create group Fill name + description → submit Group appears in list; {group_name}-admin bootstrap group also exists (auto-created on service start)
4.3 Edit group Click edit on group → change name → save Name updated
4.4 Delete group Delete group 204; group gone; memberships cascade-deleted
4.5 Add member Open group → search user → add 204; user appears in member list
4.6 Remove member Click remove on a member User removed from group
4.7 Duplicate group name Create group with name that already exists 400 / validation error shown
4.8 Non-admin access Regular user calls GET /api/admin/groups 404
4.9 Set group admin role Admin → group detail → tick "Group admin" checkbox on a member → save PATCH /api/admin/groups/{id}/members/{user_id}/admin with {"is_group_admin": true} returns 200; badge shown in member list
4.10 Unset group admin role Admin unticks "Group admin" on an existing group admin member Returns 200; badge removed; user loses group-admin privileges

5. Admin — Appearance

# Test Steps Expected
5.1 List themes Admin → /admin/appearance Built-in themes + any custom themes shown
5.2 Switch active theme Select a different theme → save All users see the new theme on next load
5.3 Create custom theme Admin → create theme. Required fields: id (slug), label, light (CSS vars object), dark (CSS vars object) 201; theme appears in selector; can be activated
5.4 Edit custom theme Admin edits colour values on a custom theme Colours update live after activation
5.5 Delete custom theme Admin deletes a custom theme 204; theme gone from selector; active theme reverts to default
5.6 Set default mode PATCH /api/settings/appearance with {"theme": "<id>", "default_mode": "dark"} (both fields required) 200; new users without a personal preference see dark mode

6. Service Health & Dashboard

# Test Steps Expected
6.1 Services endpoint GET /api/services (authenticated) Returns health status for doc-service and ai-service
6.2 Healthy service card Both services running → /apps page. API response uses healthy: true (boolean), not status: "healthy" Cards show "Available" badge; clicking navigates to the app
6.3 Unhealthy service card Stop doc-service container → wait 30s → /apps Doc-service card dimmed, "Unavailable", not clickable
6.4 Service recovery Restart stopped container → wait 30s Card returns to "Available"
6.5 Dashboard pinned cards Pin a service → go to / Pinned card appears in home grid
6.6 Customize mode Click pencil on dashboard → toggle cards Pinned list updates after save

7. Plugin System

# Test Steps Expected
7.1 List plugins GET /api/plugins (authenticated) Returns accessible plugins for current user
7.2 Superuser sees all plugins Log in as admin → GET /api/plugins All registered service plugins returned
7.3 Group member sees plugin Add user to doc-service-admin group → GET /api/plugins doc-service plugin returned
7.4 Unpermitted user hidden Regular user not in any admin group → GET /api/plugins Empty list (plugins hidden, not 403)
7.5 Manifest fetch GET /api/plugins/doc-service/manifest as permitted user JSON Schema + access rules returned
7.6 Settings read GET /api/plugins/doc-service/settings Current doc-service plugin settings returned
7.7 Settings write PATCH /api/plugins/doc-service/settings with valid payload 200; setting persisted to volume
7.8 Unpermitted settings access Regular user GET /api/plugins/doc-service/settings 404

8. AI Service Settings

# Test Steps Expected
8.1 Read AI config Admin (or ai-service-admin member) → GET /api/settings/ai Config returned; API keys masked
8.2 Update provider PATCH /api/settings/ai with provider = "anthropic" + valid key 200; config persisted
8.3 Test connection POST /api/settings/ai/test with valid config 200; success response from provider
8.4 Test connection — bad key POST /api/settings/ai/test with wrong API key 502 or error detail
8.5 Read system prompts GET /api/settings/system-prompts All registered service prompts returned
8.6 Update system prompt PATCH /api/settings/system-prompts/doc-service with new prompt text 200; doc-service picks up new prompt within 30s
8.7 Non-admin access Regular user calls any /api/settings/ai endpoint 404
8.8 ai-service-admin delegation Non-superuser added to ai-service-admin group → accesses AI settings page Page loads; can read and write settings

9. Document Service Settings

# Test Steps Expected
9.1 Read upload limits GET /api/settings/documents/limits (admin or doc-service-admin) max_pdf_bytes returned
9.2 Update upload limit PATCH /api/settings/documents/limits with new value 200; upload of oversized PDF now rejected with 413
9.3 Non-admin access Regular user calls GET /api/settings/documents/limits 404
9.4 Settings page loads Admin navigates to /apps/documents/settings Upload limits section + watch directory config visible
9.5 doc-service-admin delegation Non-superuser added to doc-service-admin → navigates to settings page Page loads; settings editable

18. Infrastructure & Security

# Test Steps Expected
18.1 Non-root containers docker inspect <container> --format '{{.Config.User}}' for each service Returns 1001 (or 70 for db)
18.2 No host ports in prod docker compose up --build -ddocker ps Only port 80 (frontend) exposed; no 8000/8001/8010/5432
18.3 backend-net isolation curl http://localhost:8000 from host in prod Connection refused
18.4 Pre-commit hook runs Stage a file with eval("x")git commit Commit blocked; security_check.py output shown
18.5 Pre-commit hook — clean code Normal commit Hook passes; commit succeeds
18.6 JWT algorithm none rejected Craft token with "alg": "none" → call protected route 401
18.7 XSS — input sanitation Enter <script>alert(1)</script> in title/name fields Value stored as plain text; not executed in UI
18.8 SQL injection attempt Pass '; DROP TABLE documents; -- as search param 200 with empty results; no DB error
18.9 CORS curl -H "Origin: http://evil.com" http://localhost/api/users/me Request blocked or access-control-allow-origin not set for that origin
18.10 Config volume persistence Restart all containers AI provider config + doc limits survive restart
18.11 Migration auto-apply Start fresh stack Both alembic upgrade head chains run without error; all tables created