2026-08-21 21:21:33 +02:00
|
|
|
# LeoCRM — Kompletter Test-Plan
|
|
|
|
|
|
|
|
|
|
> **Erstellt:** 2026-08-21
|
|
|
|
|
> **Prinzip:** Echte Tests gegen Produktion — keine Mocks
|
|
|
|
|
> **Ziel:** 100% Abdeckung aller Module, Plugins, Verbindungen, Rechte, Security
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 1. Smoke Tests (Basis-Funktionalität)
|
|
|
|
|
|
|
|
|
|
### 1.1 System Health
|
|
|
|
|
- [ ] `GET /api/v1/health` → 200, status=healthy
|
|
|
|
|
- [ ] DB Verbindung → up
|
|
|
|
|
- [ ] Redis Verbindung → up
|
|
|
|
|
- [ ] Storage → up
|
|
|
|
|
- [ ] Worker → up, queue_length=0
|
|
|
|
|
|
|
|
|
|
### 1.2 Auth & Login
|
|
|
|
|
- [ ] `POST /api/v1/auth/login` (admin) → 200, csrf_token
|
|
|
|
|
- [ ] `POST /api/v1/auth/login` (falsches Passwort) → 401
|
|
|
|
|
- [ ] `POST /api/v1/auth/login` (nicht existierender User) → 401
|
|
|
|
|
- [ ] Session-Cookie ist HttpOnly
|
|
|
|
|
- [ ] CSRF-Token wird zurückgegeben
|
|
|
|
|
- [ ] `POST /api/v1/auth/logout` → 200
|
|
|
|
|
|
|
|
|
|
### 1.3 Frontend laden
|
|
|
|
|
- [ ] `GET /` → index.html mit JS-Referenzen
|
|
|
|
|
- [ ] `GET /login` → Login-Seite rendert
|
|
|
|
|
- [ ] `GET /assets/index-*.js` → 200
|
|
|
|
|
- [ ] Service Worker Kill-Switch aktiv auf /sw.js
|
|
|
|
|
- [ ] Cache-Control: no-cache auf index.html
|
|
|
|
|
|
|
|
|
|
### 1.4 Plugins aktiv
|
|
|
|
|
- [ ] `GET /api/v1/plugins` → 200, alle 25 Plugins aktiv
|
|
|
|
|
- [ ] Jedes Plugin hat Routes registriert
|
|
|
|
|
- [ ] Jedes Plugin hat Models in DB
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 2. Backend API Tests (alle 480+ Endpunkte)
|
|
|
|
|
|
|
|
|
|
### 2.1 Contacts
|
|
|
|
|
- [ ] `GET /api/v1/contacts` → 200, PaginatedResponse
|
|
|
|
|
- [ ] `GET /api/v1/contacts?page=1&page_size=25` → 200
|
|
|
|
|
- [ ] `GET /api/v1/contacts?search=test` → 200
|
|
|
|
|
- [ ] `GET /api/v1/contacts?type=company` → 200
|
|
|
|
|
- [ ] `GET /api/v1/contacts?type=person` → 200
|
|
|
|
|
- [ ] `GET /api/v1/contacts?folder_id={id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/contacts?sort_by=displayname&sort_order=asc` → 200
|
|
|
|
|
- [ ] `POST /api/v1/contacts` (person) → 201, id
|
|
|
|
|
- [ ] `POST /api/v1/contacts` (company) → 201, id
|
|
|
|
|
- [ ] `POST /api/v1/contacts` (missing required fields) → 422
|
|
|
|
|
- [ ] `GET /api/v1/contacts/{id}` → 200, contact detail
|
|
|
|
|
- [ ] `GET /api/v1/contacts/{id}` (non-existent) → 404
|
|
|
|
|
- [ ] `PUT /api/v1/contacts/{id}` → 200, updated
|
|
|
|
|
- [ ] `PUT /api/v1/contacts/{id}` (invalid data) → 422
|
|
|
|
|
- [ ] `DELETE /api/v1/contacts/{id}` → 204
|
|
|
|
|
- [ ] `DELETE /api/v1/contacts/{id}?hard=true` → 204
|
|
|
|
|
- [ ] `GET /api/v1/contacts/{id}/persons` → 200
|
|
|
|
|
- [ ] `POST /api/v1/contacts/{id}/persons` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/contacts/{id}/persons/{pid}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/contacts/{id}/persons/{pid}` → 204
|
|
|
|
|
|
|
|
|
|
### 2.2 Contact Folders
|
|
|
|
|
- [ ] `GET /api/v1/contact-folders` → 200
|
|
|
|
|
- [ ] `POST /api/v1/contact-folders` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/contact-folders/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/contact-folders/{id}` → 204
|
|
|
|
|
- [ ] `PUT /api/v1/contact-folders/contacts/{cid}/move` → 200
|
|
|
|
|
- [ ] `GET /api/v1/contact-folders/{id}/permissions` → 200
|
|
|
|
|
- [ ] `POST /api/v1/contact-folders/{id}/permissions` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/contact-folders/{id}/permissions/{pid}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/contact-folders/{id}/permissions/{pid}` → 204
|
|
|
|
|
|
|
|
|
|
### 2.3 Mail
|
|
|
|
|
- [ ] `GET /api/v1/mail/accounts` → 200
|
|
|
|
|
- [ ] `POST /api/v1/mail/accounts` → 201 (IMAP account)
|
|
|
|
|
- [ ] `PUT /api/v1/mail/accounts/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/mail/accounts/{id}` → 204
|
|
|
|
|
- [ ] `POST /api/v1/mail/accounts/{id}/sync` → 200, synced count
|
|
|
|
|
- [ ] `GET /api/v1/mail/accounts/{id}/folders` → 200
|
|
|
|
|
- [ ] `GET /api/v1/mail/messages?account_id={id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/mail/messages/{id}` → 200
|
|
|
|
|
- [ ] `POST /api/v1/mail/messages` (send) → 201
|
|
|
|
|
- [ ] `PATCH /api/v1/mail/messages/{id}` (mark read/unread) → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/mail/messages/{id}` → 204
|
|
|
|
|
- [ ] `POST /api/v1/mail/accounts/{id}/folders` (IMAP create) → 201
|
|
|
|
|
|
|
|
|
|
### 2.4 Calendar
|
|
|
|
|
- [ ] `GET /api/v1/calendars` → 200
|
|
|
|
|
- [ ] `POST /api/v1/calendars` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/calendars/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/calendars/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/calendar/entries?start=...&end=...` → 200
|
|
|
|
|
- [ ] `POST /api/v1/calendar/entries` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/calendar/entries/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/calendar/entries/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/calendar/entries?calendar_id={id}` → 200
|
|
|
|
|
|
|
|
|
|
### 2.5 Tasks
|
|
|
|
|
- [ ] `GET /api/v1/tasks?page=1&page_size=25` → 200
|
|
|
|
|
- [ ] `GET /api/v1/tasks?status=open` → 200
|
|
|
|
|
- [ ] `GET /api/v1/tasks?priority=high` → 200
|
|
|
|
|
- [ ] `POST /api/v1/tasks` → 201
|
|
|
|
|
- [ ] `GET /api/v1/tasks/{id}` → 200
|
|
|
|
|
- [ ] `PATCH /api/v1/tasks/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/tasks/{id}` → 204
|
|
|
|
|
- [ ] `PATCH /api/v1/tasks/{id}/status` → 200
|
|
|
|
|
|
|
|
|
|
### 2.6 Wiki
|
|
|
|
|
- [ ] `GET /api/v1/wiki/articles?page_size=100` → 200
|
|
|
|
|
- [ ] `GET /api/v1/wiki/articles?category_id={id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/wiki/articles?search=test` → 200
|
|
|
|
|
- [ ] `POST /api/v1/wiki/articles` (with slug) → 201
|
|
|
|
|
- [ ] `GET /api/v1/wiki/articles/{id}` → 200
|
|
|
|
|
- [ ] `PATCH /api/v1/wiki/articles/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/wiki/articles/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/wiki/articles/{id}/versions` → 200
|
|
|
|
|
- [ ] `POST /api/v1/wiki/articles/{id}/versions/{ver}/restore` → 200
|
|
|
|
|
- [ ] `GET /api/v1/wiki/categories` → 200
|
|
|
|
|
- [ ] `POST /api/v1/wiki/categories` → 201
|
|
|
|
|
|
|
|
|
|
### 2.7 Tags
|
|
|
|
|
- [ ] `GET /api/v1/tags` → 200 (with parent_id, applicable_to, icon)
|
|
|
|
|
- [ ] `POST /api/v1/tags` (with new fields) → 201
|
|
|
|
|
- [ ] `PATCH /api/v1/tags/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/tags/{id}` → 204
|
|
|
|
|
- [ ] `POST /api/v1/tags/assign` → 201
|
|
|
|
|
- [ ] `DELETE /api/v1/tags/assign` → 204
|
|
|
|
|
- [ ] `POST /api/v1/tags/bulk-assign` → 200
|
|
|
|
|
- [ ] `GET /api/v1/tags/{id}/entities` → 200
|
|
|
|
|
|
|
|
|
|
### 2.8 DMS
|
|
|
|
|
- [ ] `GET /api/v1/dms/files?page=1&page_size=25` → 200
|
|
|
|
|
- [ ] `POST /api/v1/dms/files` (upload) → 201
|
|
|
|
|
- [ ] `GET /api/v1/dms/files/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/dms/files/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/dms/folders` → 200
|
|
|
|
|
- [ ] `POST /api/v1/dms/folders` → 201
|
|
|
|
|
- [ ] `GET /api/v1/dms/trash` → 200
|
|
|
|
|
|
|
|
|
|
### 2.9 Reports
|
|
|
|
|
- [ ] `GET /api/v1/reports/templates` → 200
|
|
|
|
|
- [ ] `POST /api/v1/reports/templates` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/reports/templates/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/reports/templates/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/reports/presets` → 200
|
|
|
|
|
- [ ] `POST /api/v1/reports/generate` → 200 (blob)
|
|
|
|
|
- [ ] `POST /api/v1/reports/presets/{key}/generate` → 200 (blob)
|
|
|
|
|
|
|
|
|
|
### 2.10 Kommunikation
|
|
|
|
|
- [ ] `GET /api/v1/comm/conversations` → 200
|
|
|
|
|
- [ ] `POST /api/v1/comm/conversations` (with metadata) → 200
|
|
|
|
|
- [ ] `GET /api/v1/comm/conversations/{id}` → 200
|
|
|
|
|
- [ ] `PATCH /api/v1/comm/conversations/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/comm/conversations/{id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/comm/conversations/{id}/messages` → 200
|
|
|
|
|
- [ ] `POST /api/v1/comm/conversations/{id}/messages` → 200
|
|
|
|
|
- [ ] `POST /api/v1/comm/conversations/{id}/pin` → 200
|
|
|
|
|
- [ ] `POST /api/v1/comm/conversations/{id}/mark-read` → 200
|
|
|
|
|
- [ ] `GET /api/v1/comm/block-types` → 200
|
|
|
|
|
- [ ] `GET /api/v1/comm/miniapps` → 200
|
|
|
|
|
- [ ] WebSocket `/api/v1/comm/ws` → connect + receive messages
|
|
|
|
|
|
|
|
|
|
### 2.11 AI Assistant
|
|
|
|
|
- [ ] `GET /api/v1/ai/providers` → 200
|
|
|
|
|
- [ ] `POST /api/v1/ai/providers` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/ai/providers/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/ai/providers/{id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/ai/models` → 200
|
|
|
|
|
- [ ] `POST /api/v1/ai/models` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/ai/models/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/ai/models/{id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/ai/presets` → 200
|
|
|
|
|
- [ ] `POST /api/v1/ai/presets` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/ai/presets/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/ai/presets/{id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/ai/agents` → 200
|
|
|
|
|
- [ ] `POST /api/v1/ai/agents` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/ai/agents/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/ai/agents/{id}` → 200
|
|
|
|
|
- [ ] `GET /api/v1/ai/tools` → 200
|
|
|
|
|
- [ ] `GET /api/v1/ai/folders` → 200
|
|
|
|
|
- [ ] `POST /api/v1/ai/folders` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/ai/folders/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/ai/folders/{id}` → 200
|
|
|
|
|
- [ ] `POST /api/v1/ai/conversations/{id}/stream` → SSE stream with GLM 5.2 response
|
|
|
|
|
- [ ] `GET /api/v1/ai/conversations/{id}/messages` → 200
|
|
|
|
|
- [ ] `GET /api/v1/ai/sessions` → 404 (removed in Phase 2)
|
|
|
|
|
|
|
|
|
|
### 2.12 Workflows
|
|
|
|
|
- [ ] `GET /api/v1/workflows` → 200
|
|
|
|
|
- [ ] `POST /api/v1/workflows` → 201
|
|
|
|
|
- [ ] `GET /api/v1/workflows/{id}` → 200
|
|
|
|
|
- [ ] `PUT /api/v1/workflows/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/workflows/{id}` → 204
|
|
|
|
|
- [ ] `POST /api/v1/workflows/{id}/execute` → 200
|
|
|
|
|
- [ ] `GET /api/v1/workflows/{id}/instances` → 200
|
|
|
|
|
|
|
|
|
|
### 2.13 Search
|
|
|
|
|
- [ ] `GET /api/v1/search?q=test` → 200, results array
|
|
|
|
|
- [ ] `GET /api/v1/search?q=test&entity_type=contact` → 200
|
|
|
|
|
- [ ] `GET /api/v1/search?q=test&entity_type=wiki` → 200
|
|
|
|
|
- [ ] `GET /api/v1/search?q=test&entity_type=ai_chat` → 200 (searches comm_messages)
|
|
|
|
|
- [ ] `GET /api/v1/search/providers` → 200
|
|
|
|
|
|
|
|
|
|
### 2.14 Notifications
|
|
|
|
|
- [ ] `GET /api/v1/notifications` → 200
|
|
|
|
|
- [ ] `PATCH /api/v1/notifications/{id}` (mark read) → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/notifications/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/notifications/types` → 200
|
|
|
|
|
|
|
|
|
|
### 2.15 Audit Log
|
|
|
|
|
- [ ] `GET /api/v1/audit-log?page=1&page_size=25` → 200
|
|
|
|
|
- [ ] `GET /api/v1/audit-log?entity_type=contact` → 200
|
|
|
|
|
- [ ] `GET /api/v1/audit-log?action=create` → 200
|
|
|
|
|
- [ ] Audit-Eintrag wird bei jeder Mutation erstellt
|
|
|
|
|
|
|
|
|
|
### 2.16 Users & Roles & Groups
|
|
|
|
|
- [ ] `GET /api/v1/users` → 200
|
|
|
|
|
- [ ] `POST /api/v1/users` → 201
|
|
|
|
|
- [ ] `PATCH /api/v1/users/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/users/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/roles` → 200
|
|
|
|
|
- [ ] `POST /api/v1/roles` → 201 (with permissions dict)
|
|
|
|
|
- [ ] `PUT /api/v1/roles/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/roles/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/groups` → 200
|
|
|
|
|
- [ ] `POST /api/v1/groups` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/groups/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/groups/{id}` → 204
|
|
|
|
|
|
|
|
|
|
### 2.17 Plugins
|
|
|
|
|
- [ ] `GET /api/v1/plugins` → 200, 25 plugins
|
|
|
|
|
- [ ] `GET /api/v1/plugins/{name}` → 200
|
|
|
|
|
- [ ] `POST /api/v1/plugins/{name}/activate` → 200
|
|
|
|
|
- [ ] `POST /api/v1/plugins/{name}/deactivate` → 200
|
|
|
|
|
|
|
|
|
|
### 2.18 Settings
|
|
|
|
|
- [ ] `GET /api/v1/system-settings` → 200
|
|
|
|
|
- [ ] `PUT /api/v1/system-settings` → 200
|
|
|
|
|
- [ ] `GET /api/v1/users/me/preferences` → 200
|
|
|
|
|
- [ ] `PUT /api/v1/users/me/preferences` → 200
|
|
|
|
|
|
|
|
|
|
### 2.19 Entity Permissions
|
|
|
|
|
- [ ] `GET /api/v1/entity-permissions?entity_type=contact` → 200
|
|
|
|
|
- [ ] `POST /api/v1/entity-permissions` → 201
|
|
|
|
|
- [ ] `DELETE /api/v1/entity-permissions/{id}` → 204
|
|
|
|
|
|
|
|
|
|
### 2.20 Webhooks
|
|
|
|
|
- [ ] `GET /api/v1/webhooks` → 200
|
|
|
|
|
- [ ] `POST /api/v1/webhooks` → 201
|
|
|
|
|
- [ ] `DELETE /api/v1/webhooks/{id}` → 204
|
|
|
|
|
- [ ] `POST /api/v1/webhooks/{id}/test` → 200
|
|
|
|
|
|
|
|
|
|
### 2.21 Saved Views & Filters
|
|
|
|
|
- [ ] `GET /api/v1/saved-views` → 200
|
|
|
|
|
- [ ] `POST /api/v1/saved-views` → 201
|
|
|
|
|
- [ ] `DELETE /api/v1/saved-views/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/saved-filters` → 200
|
|
|
|
|
- [ ] `POST /api/v1/saved-filters` → 201
|
|
|
|
|
|
|
|
|
|
### 2.22 Custom Fields
|
|
|
|
|
- [ ] `GET /api/v1/custom-field-definitions?entity=contact` → 200
|
|
|
|
|
- [ ] `POST /api/v1/custom-field-definitions` → 201
|
|
|
|
|
- [ ] `PUT /api/v1/custom-field-definitions/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/custom-field-definitions/{id}` → 204
|
|
|
|
|
- [ ] `GET /api/v1/contacts/{id}/custom-fields` → 200
|
|
|
|
|
- [ ] `PUT /api/v1/contacts/{id}/custom-fields` → 200
|
|
|
|
|
|
|
|
|
|
### 2.23 Compliance
|
|
|
|
|
- [ ] `GET /api/v1/compliance/incidents` → 200
|
|
|
|
|
- [ ] `POST /api/v1/compliance/incidents` → 201
|
|
|
|
|
|
|
|
|
|
### 2.24 Attachments
|
|
|
|
|
- [ ] `GET /api/v1/attachments` → 200
|
|
|
|
|
- [ ] `POST /api/v1/attachments` (upload) → 201
|
|
|
|
|
- [ ] `GET /api/v1/attachments/{id}` → 200
|
|
|
|
|
- [ ] `DELETE /api/v1/attachments/{id}` → 204
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 3. Frontend Tests
|
|
|
|
|
|
|
|
|
|
### 3.1 TypeScript
|
|
|
|
|
- [ ] `npx tsc --noEmit` → clean (0 errors)
|
|
|
|
|
|
|
|
|
|
### 3.2 Build
|
|
|
|
|
- [ ] `npm run build` → successful
|
|
|
|
|
|
|
|
|
|
### 3.3 vitest Unit Tests
|
|
|
|
|
- [ ] Alle `src/__tests__/` Dateien ausführen
|
|
|
|
|
- [ ] DmsPage Tests → passed
|
|
|
|
|
- [ ] Alle anderen Test-Dateien → passed
|
|
|
|
|
|
|
|
|
|
### 3.4 Playwright E2E Tests
|
|
|
|
|
- [ ] Alle `e2e/` Dateien ausführen
|
|
|
|
|
- [ ] Login Flow → passed
|
|
|
|
|
- [ ] Navigation → passed
|
|
|
|
|
- [ ] Contact CRUD → passed
|
|
|
|
|
- [ ] Mail → passed
|
|
|
|
|
|
|
|
|
|
### 3.5 Browser UI Tests (live)
|
|
|
|
|
- [ ] Login-Seite rendert mit Formular
|
|
|
|
|
- [ ] Dashboard lädt nach Login
|
|
|
|
|
- [ ] Contacts-Seite lädt mit 3-Spalten Layout
|
|
|
|
|
- [ ] Mail-Seite lädt mit IMAP-Mails
|
|
|
|
|
- [ ] Calendar-Seite lädt mit Kalender
|
|
|
|
|
- [ ] Tasks-Seite lädt mit 3-Spalten Layout
|
|
|
|
|
- [ ] Wiki-Seite lädt mit WYSIWYG Editor
|
|
|
|
|
- [ ] Tags-Seite lädt (unter Settings)
|
|
|
|
|
- [ ] Reports-Seite lädt
|
|
|
|
|
- [ ] Communication-Seite lädt mit AI Chat
|
|
|
|
|
- [ ] Settings-Seite lädt
|
|
|
|
|
- [ ] System Dashboard lädt
|
|
|
|
|
- [ ] Keine Console-Fehler auf irgendeiner Seite
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 4. Datenbank Tests
|
|
|
|
|
|
|
|
|
|
### 4.1 Schema
|
|
|
|
|
- [ ] Alembic Version: 0140
|
|
|
|
|
- [ ] Alle Tabellen existieren (130+)
|
|
|
|
|
- [ ] Alle Foreign Keys existieren (159+)
|
|
|
|
|
- [ ] Alle Indexes existieren (590+)
|
|
|
|
|
- [ ] Alle Unique Constraints existieren
|
|
|
|
|
- [ ] JSONB Spalten: metadata, applicable_to, config
|
|
|
|
|
- [ ] TSVECTOR Spalten: search_tsv
|
|
|
|
|
- [ ] Vector Spalten: embedding (768)
|
|
|
|
|
|
|
|
|
|
### 4.2 RLS (Row Level Security)
|
|
|
|
|
- [ ] 109 Tabellen mit RLS aktiviert
|
|
|
|
|
- [ ] `app.current_tenant_id` wird von `set_tenant_context()` gesetzt
|
|
|
|
|
- [ ] User sieht nur eigene Tenant-Daten
|
|
|
|
|
- [ ] Cross-Tenant Query gibt leere Ergebnisse
|
|
|
|
|
|
|
|
|
|
### 4.3 Migrationen
|
|
|
|
|
- [ ] Alle 140 Migrationen angewendet
|
|
|
|
|
- [ ] Migration Hashes korrekt (migration_hashes.txt)
|
|
|
|
|
- [ ] 0137: AI Chat Tables entfernt
|
|
|
|
|
- [ ] 0138: Tags parent_id, applicable_to, icon
|
|
|
|
|
- [ ] 0139: Report templates folder_id
|
|
|
|
|
- [ ] 0140: Comm conversations folder_id
|
|
|
|
|
|
|
|
|
|
### 4.4 Daten-Integrität
|
|
|
|
|
- [ ] AI Provider: Ollama Cloud (is_default=true)
|
|
|
|
|
- [ ] AI Model: GLM 5.2 (is_active=true)
|
|
|
|
|
- [ ] AI Preset: GLM 5.2 Default (is_active=true)
|
|
|
|
|
- [ ] AI Agent: LeoCRM Assistant (is_default=true, is_active=true)
|
|
|
|
|
- [ ] Mail Account: admin@media-on.de (is_active=true)
|
|
|
|
|
- [ ] Sales Role: erstellt mit Berechtigungen
|
|
|
|
|
- [ ] AI Chat Tables: entfernt (0 Einträge)
|
|
|
|
|
- [ ] Comm Conversations mit conversation_type=ai: vorhanden
|
|
|
|
|
- [ ] Mail Messages: synchronisiert (>0)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 5. Rechte-System Tests
|
|
|
|
|
|
|
|
|
|
### 5.1 Admin User (volle Rechte)
|
|
|
|
|
- [ ] Contacts: GET=200, POST=201, PUT=200, DELETE=204
|
|
|
|
|
- [ ] Mail: GET=200, POST=201
|
|
|
|
|
- [ ] Calendar: GET=200, POST=201
|
|
|
|
|
- [ ] Tasks: GET=200, POST=201
|
|
|
|
|
- [ ] Wiki: GET=200, POST=201
|
|
|
|
|
- [ ] Tags: GET=200, POST=201
|
|
|
|
|
- [ ] DMS: GET=200, POST=201
|
|
|
|
|
- [ ] Reports: GET=200, POST=201
|
|
|
|
|
- [ ] Comm: GET=200, POST=200
|
|
|
|
|
- [ ] AI Providers: GET=200, POST=201
|
|
|
|
|
- [ ] AI Agents: GET=200, POST=201
|
|
|
|
|
- [ ] Users: GET=200, POST=201
|
|
|
|
|
- [ ] Roles: GET=200, POST=201
|
|
|
|
|
- [ ] Groups: GET=200, POST=201
|
|
|
|
|
- [ ] Plugins: GET=200
|
|
|
|
|
- [ ] Workflows: GET=200, POST=201
|
|
|
|
|
- [ ] Settings: GET=200, PUT=200
|
|
|
|
|
- [ ] Audit: GET=200
|
|
|
|
|
- [ ] Webhooks: GET=200, POST=201
|
|
|
|
|
- [ ] Notifications: GET=200
|
|
|
|
|
- [ ] Search: GET=200
|
|
|
|
|
|
|
|
|
|
### 5.2 Sales User (Sales-Rolle: contacts:read+write, mail:read, calendar:read, tags:read, tasks:read+write, wiki:read, communication:read+write, dms:read, reports:read)
|
|
|
|
|
- [ ] Contacts: GET=200, POST=201 (write erlaubt)
|
|
|
|
|
- [ ] Mail: GET=200 (read erlaubt)
|
|
|
|
|
- [ ] Calendar: GET=200 (read erlaubt)
|
|
|
|
|
- [ ] Tags: GET=200 (read erlaubt)
|
|
|
|
|
- [ ] Tasks: GET=200, POST=201 (write erlaubt)
|
|
|
|
|
- [ ] Wiki: GET=200 (read erlaubt)
|
|
|
|
|
- [ ] Comm: GET=200, POST=200 (write erlaubt)
|
|
|
|
|
- [ ] DMS: GET=200 (read erlaubt)
|
|
|
|
|
- [ ] Reports: GET=200 (read erlaubt)
|
|
|
|
|
- [ ] AI Providers: GET=403 (kein ai:config)
|
|
|
|
|
- [ ] AI Agents: GET=403 (kein ai:agents)
|
|
|
|
|
- [ ] Users: GET=403 (kein settings:read)
|
|
|
|
|
- [ ] Roles: GET=403 (kein settings:read)
|
|
|
|
|
- [ ] Plugins: GET=403 (kein settings:read)
|
|
|
|
|
- [ ] Settings: GET=403 (kein settings:read)
|
|
|
|
|
- [ ] Audit: GET=403 (kein audit:read)
|
|
|
|
|
- [ ] Webhooks: GET=403 (kein settings:read)
|
|
|
|
|
|
|
|
|
|
### 5.3 Reader User (keine Berechtigungen)
|
|
|
|
|
- [ ] Contacts: GET=403, POST=403
|
|
|
|
|
- [ ] Mail: GET=403
|
|
|
|
|
- [ ] Calendar: GET=403
|
|
|
|
|
- [ ] Tags: GET=403, POST=403
|
|
|
|
|
- [ ] Tasks: GET=403, POST=403
|
|
|
|
|
- [ ] Wiki: GET=403, POST=403
|
|
|
|
|
- [ ] AI Providers: GET=403
|
|
|
|
|
- [ ] Users: GET=403
|
|
|
|
|
|
|
|
|
|
### 5.4 Field-Level Permissions
|
|
|
|
|
- [ ] Feld `contacts.email_1` auf 'readonly' → User kann lesen aber nicht ändern
|
|
|
|
|
- [ ] Feld `contacts.phone_1` auf 'hidden' → User kann nicht sehen
|
|
|
|
|
|
|
|
|
|
### 5.5 Entity-Permissions
|
|
|
|
|
- [ ] User A hat 'read' auf Contact X → kann lesen
|
|
|
|
|
- [ ] User B hat keine Permission auf Contact X → kann nicht lesen
|
|
|
|
|
- [ ] User A hat 'write' auf Contact X → kann ändern
|
|
|
|
|
|
|
|
|
|
### 5.6 Gruppen-Permissions
|
|
|
|
|
- [ ] Gruppe 'Sales' hat contacts:read → alle Gruppen-Mitglieder können Contacts lesen
|
|
|
|
|
- [ ] User wird Gruppe hinzugefügt → bekommt Gruppen-Berechtigungen
|
|
|
|
|
- [ ] User wird aus Gruppe entfernt → verliert Gruppen-Berechtigungen
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 6. Cross-Tenant Security Tests
|
|
|
|
|
|
|
|
|
|
- [ ] Tenant A User fragt Contacts ab → sieht nur Tenant A Contacts
|
|
|
|
|
- [ ] Tenant A User fragt Contact ID aus Tenant B ab → 404
|
|
|
|
|
- [ ] Tenant A User versucht Contact aus Tenant B zu ändern → 404
|
|
|
|
|
- [ ] Tenant A User versucht Contact aus Tenant B zu löschen → 404
|
|
|
|
|
- [ ] RLS Policy aktiv auf allen 109 Tabellen
|
|
|
|
|
- [ ] `set_tenant_context()` wird bei jedem Request aufgerufen
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 7. Plugin-Verbindungen Tests
|
|
|
|
|
|
|
|
|
|
### 7.1 AI ↔ Kommunikation
|
|
|
|
|
- [ ] AI Chat erstellt comm_conversation mit metadata.conversation_type=ai
|
|
|
|
|
- [ ] AI Streaming schreibt Messages in comm_messages
|
|
|
|
|
- [ ] AI Messages werden in Kommunikation angezeigt
|
|
|
|
|
- [ ] categorizeConversation erkennt AI Chats an metadata
|
|
|
|
|
|
|
|
|
|
### 7.2 AI ↔ Search (Unified Search)
|
|
|
|
|
- [ ] AI Chat Provider sucht in comm_messages (nicht ai_chat_messages)
|
|
|
|
|
- [ ] Search Results zeigen AI Chat Messages
|
|
|
|
|
- [ ] Search filtert nach conversation_type=ai
|
|
|
|
|
|
|
|
|
|
### 7.3 Tags ↔ Contacts
|
|
|
|
|
- [ ] Tag wird Contact zugewiesen (POST /tags/assign)
|
|
|
|
|
- [ ] Contact hat Tag in tags Feld
|
|
|
|
|
- [ ] Contact kann nach Tag gefiltert werden
|
|
|
|
|
- [ ] Tag wird von Contact entfernt (DELETE /tags/assign)
|
|
|
|
|
|
|
|
|
|
### 7.4 Tags ↔ andere Module
|
|
|
|
|
- [ ] Tags mit applicable_to=['contact'] → nur für Contacts verfügbar
|
|
|
|
|
- [ ] Tags mit applicable_to=['file'] → nur für DMS verfügbar
|
|
|
|
|
- [ ] Tags mit applicable_to=['calendar_entry'] → nur für Calendar verfügbar
|
|
|
|
|
|
|
|
|
|
### 7.5 Wiki ↔ Search
|
|
|
|
|
- [ ] Wiki Artikel erscheint in Unified Search
|
|
|
|
|
- [ ] Search nach Wiki Artikel Titel → gefunden
|
|
|
|
|
- [ ] Search nach Wiki Artikel Content → gefunden
|
|
|
|
|
|
|
|
|
|
### 7.6 DMS ↔ Contacts
|
|
|
|
|
- [ ] Datei wird mit Contact verknüpft (entity_link)
|
|
|
|
|
- [ ] Contact Detail zeigt verknüpfte Dateien
|
|
|
|
|
- [ ] Datei wird von Contact entknüpft
|
|
|
|
|
|
|
|
|
|
### 7.7 Mail ↔ Contacts
|
|
|
|
|
- [ ] E-Mail wird mit Contact verknüpft
|
|
|
|
|
- [ ] Contact Detail zeigt verknüpfte E-Mails
|
|
|
|
|
|
|
|
|
|
### 7.8 Calendar ↔ Tasks
|
|
|
|
|
- [ ] Task mit due_date erscheint im Calendar
|
|
|
|
|
- [ ] Calendar Entry kann mit Task verknüpft werden
|
|
|
|
|
|
|
|
|
|
### 7.9 Permissions ↔ alle Plugins
|
|
|
|
|
- [ ] Jedes Plugin nutzt require_permission Dependency
|
|
|
|
|
- [ ] Plugin Route ohne Berechtigung → 403
|
|
|
|
|
- [ ] Plugin Route mit Berechtigung → 200
|
|
|
|
|
|
|
|
|
|
### 7.10 Notifications ↔ alle Plugins
|
|
|
|
|
- [ ] Contact erstellt → Notification generiert
|
|
|
|
|
- [ ] Task erstellt → Notification generiert
|
|
|
|
|
- [ ] Mail empfangen → Notification generiert
|
|
|
|
|
- [ ] AI Chat Message → Notification generiert
|
|
|
|
|
|
|
|
|
|
### 7.11 Audit ↔ alle Plugins
|
|
|
|
|
- [ ] Contact Create → Audit Log Eintrag
|
|
|
|
|
- [ ] Contact Update → Audit Log Eintrag
|
|
|
|
|
- [ ] Contact Delete → Audit Log Eintrag
|
|
|
|
|
- [ ] Tag Create → Audit Log Eintrag
|
|
|
|
|
- [ ] Task Create → Audit Log Eintrag
|
|
|
|
|
- [ ] Wiki Create → Audit Log Eintrag
|
|
|
|
|
- [ ] Mail Send → Audit Log Eintrag
|
|
|
|
|
|
|
|
|
|
### 7.12 Workflows ↔ Plugins
|
|
|
|
|
- [ ] Workflow kann Contact erstellen (Step Handler)
|
|
|
|
|
- [ ] Workflow kann Task erstellen (Step Handler)
|
|
|
|
|
- [ ] Workflow kann Notification senden (Step Handler)
|
|
|
|
|
|
|
|
|
|
### 7.13 AI ↔ CRM API Tool
|
|
|
|
|
- [ ] AI Agent kann call_crm_api Tool verwenden
|
|
|
|
|
- [ ] AI Agent ruft Contacts API auf → bekommt Ergebnisse
|
|
|
|
|
- [ ] AI Agent erstellt Contact über Tool → Contact existiert
|
|
|
|
|
|
|
|
|
|
### 7.14 Search ↔ alle Provider
|
|
|
|
|
- [ ] Contact Search Provider → findet Contacts
|
|
|
|
|
- [ ] DMS Search Provider → findet Dateien
|
|
|
|
|
- [ ] Wiki Search Provider → findet Artikel
|
|
|
|
|
- [ ] AI Chat Search Provider → findet AI Chat Messages
|
|
|
|
|
- [ ] Tag Search Provider → findet Tags
|
|
|
|
|
- [ ] Mail Search Provider → findet E-Mails
|
|
|
|
|
- [ ] Calendar Search Provider → findet Termine
|
|
|
|
|
- [ ] Task Search Provider → findet Tasks
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 8. Code-Logik Tests
|
|
|
|
|
|
|
|
|
|
### 8.1 Python Imports
|
|
|
|
|
- [ ] `from app.main import app` → OK
|
|
|
|
|
- [ ] `from app.models import *` → OK (keine AIChatSession/AIChatMessage)
|
|
|
|
|
- [ ] Alle Plugin Routes importierbar
|
|
|
|
|
- [ ] Alle Services importierbar
|
|
|
|
|
- [ ] Keine ImportError in irgend einem Modul
|
|
|
|
|
|
|
|
|
|
### 8.2 Model Validierung
|
|
|
|
|
- [ ] Tag Model hat parent_id, applicable_to, icon
|
|
|
|
|
- [ ] CommConversation Model hat folder_id
|
|
|
|
|
- [ ] ReportTemplate Model hat folder_id
|
|
|
|
|
- [ ] AIChatSession/AIChatMessage/AIChatAttachment entfernt
|
|
|
|
|
- [ ] AIConversation/AIMessage entfernt
|
|
|
|
|
|
|
|
|
|
### 8.3 Schema Validierung
|
|
|
|
|
- [ ] TagCreate akzeptiert parent_id, applicable_to, icon
|
|
|
|
|
- [ ] TagUpdate akzeptiert parent_id, applicable_to, icon
|
|
|
|
|
- [ ] ConversationCreate akzeptiert metadata
|
|
|
|
|
- [ ] WikiArticleCreate benötigt slug
|
|
|
|
|
|
|
|
|
|
### 8.4 Service Logik
|
|
|
|
|
- [ ] create_conversation speichert metadata
|
|
|
|
|
- [ ] stream_chat_comm schreibt in comm_messages
|
|
|
|
|
- [ ] get_comm_messages liest aus comm_messages
|
|
|
|
|
- [ ] AI Chat Search Provider sucht in comm_messages
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 9. Performance Tests
|
|
|
|
|
|
|
|
|
|
- [ ] `GET /api/v1/contacts?page=1&page_size=25` → < 200ms
|
|
|
|
|
- [ ] `GET /api/v1/search?q=test` → < 500ms
|
|
|
|
|
- [ ] `GET /api/v1/health` → < 50ms
|
|
|
|
|
- [ ] Frontend Load Time → < 3s
|
|
|
|
|
- [ ] DB Query für Contacts mit RLS → < 100ms
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 10. Security Tests
|
|
|
|
|
|
|
|
|
|
### 10.1 CSRF
|
|
|
|
|
- [ ] POST ohne X-CSRF-Token → 403
|
|
|
|
|
- [ ] POST mit gültigem X-CSRF-Token → 200/201
|
|
|
|
|
- [ ] POST mit falschem X-CSRF-Token → 403
|
|
|
|
|
|
|
|
|
|
### 10.2 Auth
|
|
|
|
|
- [ ] GET ohne Session-Cookie → 401
|
|
|
|
|
- [ ] GET mit abgelaufener Session → 401
|
|
|
|
|
- [ ] Session-Cookie ist HttpOnly
|
|
|
|
|
- [ ] Session-Cookie ist Secure (HTTPS)
|
|
|
|
|
|
|
|
|
|
### 10.3 Input Validation
|
|
|
|
|
- [ ] POST mit invalid JSON → 422
|
|
|
|
|
- [ ] POST mit SQL Injection (`'; DROP TABLE--`) → 422 oder safe
|
|
|
|
|
- [ ] POST mit XSS (`<script>alert(1)</script>`) → sanitized
|
|
|
|
|
- [ ] GET mit Path Traversal (`../../../etc/passwd`) → 404
|
|
|
|
|
|
|
|
|
|
### 10.4 Rate Limiting
|
|
|
|
|
- [ ] AI Chat Streaming hat Rate Limit
|
|
|
|
|
- [ ] Login hat Rate Limit
|
|
|
|
|
- [ ] API hat General Rate Limit
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## 11. Cleanup Tests
|
|
|
|
|
|
|
|
|
|
- [ ] Test-User (sales@test.com, reader@test.com) werden nach Tests gelöscht
|
|
|
|
|
- [ ] Test-Daten (Contacts, Tags, Tasks, Wiki Articles) werden nach Tests gelöscht
|
|
|
|
|
- [ ] Test-Role (Sales) wird nach Tests gelöscht
|
|
|
|
|
- [ ] Keine Test-Daten bleiben in Produktion
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-08-21 21:28:11 +02:00
|
|
|
## 12. Frontend Component Tests (169 Components)
|
|
|
|
|
- [ ] Jede Component rendert ohne Fehler
|
|
|
|
|
- [ ] Props werden korrekt übergeben
|
|
|
|
|
- [ ] State changes funktionieren
|
|
|
|
|
- [ ] Event handlers reagieren
|
|
|
|
|
- [ ] Loading states zeigen Skeleton
|
|
|
|
|
- [ ] Error states zeigen Fehlermeldung
|
|
|
|
|
- [ ] Empty states zeigen EmptyState
|
|
|
|
|
|
|
|
|
|
## 13. Frontend Store Tests (19 Stores)
|
|
|
|
|
- [ ] authStore — Login/Logout/Session state
|
|
|
|
|
- [ ] commStore — Conversations/Messages/WebSocket
|
|
|
|
|
- [ ] calendarStore — Calendars/Events/Visibility
|
|
|
|
|
- [ ] uiStore — Sidebar/Theme/Notifications
|
|
|
|
|
- [ ] pluginStore — Plugin activation/deactivation
|
|
|
|
|
- [ ] workspaceStore — Workspace switching
|
|
|
|
|
- [ ] windowStore — Window management
|
|
|
|
|
- [ ] themeStore — Theme switching
|
|
|
|
|
- [ ] commandPaletteStore — Command palette
|
|
|
|
|
- [ ] onboardingStore — Onboarding tour
|
|
|
|
|
|
|
|
|
|
## 14. Frontend Hook Tests (11 Hooks)
|
|
|
|
|
- [ ] useAuth — Auth state management
|
|
|
|
|
- [ ] usePermission — Permission checking
|
|
|
|
|
- [ ] useCommWebSocket — WebSocket connection
|
|
|
|
|
- [ ] useAIContext — AI context building
|
|
|
|
|
- [ ] useWorkspace — Workspace management
|
|
|
|
|
- [ ] useUserPermissions — Permission loading
|
|
|
|
|
- [ ] useUserPreferences — Preferences loading
|
|
|
|
|
- [ ] useCommandPalette — Command palette
|
|
|
|
|
- [ ] useOnlineStatus — Online/offline detection
|
|
|
|
|
- [ ] useAIUIControl — AI UI control
|
|
|
|
|
- [ ] useTenant — Tenant context
|
|
|
|
|
|
|
|
|
|
## 15. Frontend API Client Tests (52 Clients)
|
|
|
|
|
- [ ] Jeder API Client function testen
|
|
|
|
|
- [ ] Request/Response handling
|
|
|
|
|
- [ ] Error handling
|
|
|
|
|
- [ ] Retry logic
|
|
|
|
|
- [ ] Cache invalidation (TanStack Query)
|
|
|
|
|
- [ ] Optimistic updates
|
|
|
|
|
|
|
|
|
|
## 16. WebSocket Tests
|
|
|
|
|
- [ ] `/api/v1/comm/ws` — Chat WebSocket
|
|
|
|
|
- [ ] Connection/Disconnection
|
|
|
|
|
- [ ] Message broadcasting
|
|
|
|
|
- [ ] Room joining/leaving
|
|
|
|
|
- [ ] Reconnection on disconnect
|
|
|
|
|
|
|
|
|
|
## 17. Background Worker Tests (ARQ)
|
|
|
|
|
- [ ] Mail IMAP Sync Job
|
|
|
|
|
- [ ] Notification Job
|
|
|
|
|
- [ ] Workflow Execution Job
|
|
|
|
|
- [ ] Backup Job
|
|
|
|
|
- [ ] Outbox Delivery Job
|
|
|
|
|
- [ ] Worker Queue processing
|
|
|
|
|
- [ ] Job retry logic
|
|
|
|
|
- [ ] Job failure handling
|
|
|
|
|
|
|
|
|
|
## 18. Plugin Lifecycle Tests
|
|
|
|
|
- [ ] Plugin aktivieren → Routes registriert
|
|
|
|
|
- [ ] Plugin deaktivieren → Routes entfernt
|
|
|
|
|
- [ ] Plugin neu aktivieren → State wiederhergestellt
|
|
|
|
|
- [ ] Plugin Migration Runner
|
|
|
|
|
- [ ] Plugin Signature Validation
|
|
|
|
|
- [ ] Plugin Quarantine Mode
|
|
|
|
|
|
|
|
|
|
## 19. Workflow Engine Tests
|
|
|
|
|
- [ ] Workflow erstellen mit Steps
|
|
|
|
|
- [ ] Workflow ausführen → Instance erstellt
|
|
|
|
|
- [ ] Step Handler: contact_create
|
|
|
|
|
- [ ] Step Handler: task_create
|
|
|
|
|
- [ ] Step Handler: send_notification
|
|
|
|
|
- [ ] Step Handler: send_mail
|
|
|
|
|
- [ ] Decision Steps (if/else)
|
|
|
|
|
- [ ] Loop Steps
|
|
|
|
|
- [ ] Parallel Steps
|
|
|
|
|
- [ ] Workflow Pause/Resume
|
|
|
|
|
- [ ] Workflow Cancel
|
|
|
|
|
|
|
|
|
|
## 20. AI System Tests (detailliert)
|
|
|
|
|
- [ ] AI Provider CRUD
|
|
|
|
|
- [ ] AI Model CRUD
|
|
|
|
|
- [ ] AI Preset CRUD
|
|
|
|
|
- [ ] AI Agent CRUD
|
|
|
|
|
- [ ] AI Agent mit Tools
|
|
|
|
|
- [ ] AI Streaming (SSE format validieren)
|
|
|
|
|
- [ ] AI Streaming mit langen Antworten
|
|
|
|
|
- [ ] AI Streaming mit Tool Calls
|
|
|
|
|
- [ ] AI Memory (speichern/abrufen/löschen)
|
|
|
|
|
- [ ] AI Context Builder
|
|
|
|
|
- [ ] AI Permission checks
|
|
|
|
|
- [ ] AI Cost tracking
|
|
|
|
|
- [ ] AI Rate limiting
|
|
|
|
|
|
|
|
|
|
## 21. Mail System Tests (detailliert)
|
|
|
|
|
- [ ] IMAP Sync (neue E-Mails abrufen)
|
|
|
|
|
- [ ] IMAP Sync (gelöschte E-Mails synchronisieren)
|
|
|
|
|
- [ ] SMTP Senden (mit Anhang)
|
|
|
|
|
- [ ] SMTP Senden (an mehrere Empfänger)
|
|
|
|
|
- [ ] Mail Ordner erstellen (IMAP)
|
|
|
|
|
- [ ] Mail Ordner umbenennen
|
|
|
|
|
- [ ] Mail als gelesen/ungelesen markieren
|
|
|
|
|
- [ ] Mail weiterleiten
|
|
|
|
|
- [ ] Mail mit Contact verknüpfen
|
|
|
|
|
- [ ] Mail Search
|
|
|
|
|
|
|
|
|
|
## 22. DMS Tests (detailliert)
|
|
|
|
|
- [ ] Datei Upload (PDF, DOCX, XLSX, Bild)
|
|
|
|
|
- [ ] Datei Download
|
|
|
|
|
- [ ] Datei Vorschau (PDF viewer)
|
|
|
|
|
- [ ] Ordner erstellen
|
|
|
|
|
- [ ] Datei verschieben
|
|
|
|
|
- [ ] Datei umbenennen
|
|
|
|
|
- [ ] Datei löschen (Trash)
|
|
|
|
|
- [ ] Trash wiederherstellen
|
|
|
|
|
- [ ] Datei teilen (Share Link)
|
|
|
|
|
- [ ] Datei Berechtigungen
|
|
|
|
|
- [ ] Dedup (gleiche Datei erkennen)
|
|
|
|
|
- [ ] Volltext-Suche in Dateien
|
|
|
|
|
|
|
|
|
|
## 23. Calendar Tests (detailliert)
|
|
|
|
|
- [ ] Kalender erstellen (verschiedene Farben)
|
|
|
|
|
- [ ] Termin erstellen (einmalig)
|
|
|
|
|
- [ ] Termin erstellen (wiederkehrend: täglich/wöchentlich/monatlich)
|
|
|
|
|
- [ ] Termin bearbeiten
|
|
|
|
|
- [ ] Termin löschen
|
|
|
|
|
- [ ] Kalender teilen (mit User/Group)
|
|
|
|
|
- [ ] ICS Export
|
|
|
|
|
- [ ] ICS Import
|
|
|
|
|
- [ ] Kalender Visibility Toggle
|
|
|
|
|
- [ ] Drag & Drop Termin verschieben
|
|
|
|
|
|
|
|
|
|
## 24. Search Tests (alle 14 Provider)
|
|
|
|
|
- [ ] Contact Search Provider
|
|
|
|
|
- [ ] Company Search Provider
|
|
|
|
|
- [ ] DMS Search Provider
|
|
|
|
|
- [ ] Wiki Search Provider
|
|
|
|
|
- [ ] AI Chat Search Provider (comm_messages)
|
|
|
|
|
- [ ] Tag Search Provider
|
|
|
|
|
- [ ] Mail Search Provider
|
|
|
|
|
- [ ] Calendar Search Provider
|
|
|
|
|
- [ ] Task Search Provider
|
|
|
|
|
- [ ] Audit Search Provider
|
|
|
|
|
- [ ] Notification Search Provider
|
|
|
|
|
- [ ] Workflow Search Provider
|
|
|
|
|
- [ ] Agent Search Provider
|
|
|
|
|
- [ ] Report Search Provider
|
|
|
|
|
|
|
|
|
|
## 25. Compliance Tests
|
|
|
|
|
- [ ] Incident erstellen
|
|
|
|
|
- [ ] Incident Status ändern
|
|
|
|
|
- [ ] Incident Report generieren
|
|
|
|
|
- [ ] Compliance Check
|
|
|
|
|
- [ ] GDPR Delete (hard delete mit ?gdpr=true)
|
|
|
|
|
- [ ] Audit Trail Integrität
|
|
|
|
|
|
|
|
|
|
## 26. Backup/Restore Tests
|
|
|
|
|
- [ ] Backup erstellen (pg_dump)
|
|
|
|
|
- [ ] Backup mit Files
|
|
|
|
|
- [ ] Backup auf S3
|
|
|
|
|
- [ ] Backup auf Nextcloud
|
|
|
|
|
- [ ] Restore (DB + Files)
|
|
|
|
|
- [ ] Backup Retention
|
|
|
|
|
|
|
|
|
|
## 27. MCP (Model Context Protocol) Tests
|
|
|
|
|
- [ ] MCP Server starten
|
|
|
|
|
- [ ] MCP Client verbinden
|
|
|
|
|
- [ ] MCP Tool aufrufen
|
|
|
|
|
- [ ] MCP Resource abrufen
|
|
|
|
|
|
|
|
|
|
## 28. Dedup/Merge Tests
|
|
|
|
|
- [ ] Duplicate Contacts erkennen
|
|
|
|
|
- [ ] Merge Contacts
|
|
|
|
|
- [ ] Merge Preview
|
|
|
|
|
- [ ] Merge Rollback
|
|
|
|
|
|
|
|
|
|
## 29. Import/Export Tests
|
|
|
|
|
- [ ] Contacts CSV Import
|
|
|
|
|
- [ ] Contacts CSV Export
|
|
|
|
|
- [ ] Companies Import
|
|
|
|
|
- [ ] Tasks Import
|
|
|
|
|
- [ ] Mail Export
|
|
|
|
|
|
|
|
|
|
## 30. Custom Fields Tests
|
|
|
|
|
- [ ] Custom Field Definition erstellen (text/number/date/select/multiselect)
|
|
|
|
|
- [ ] Custom Field zu Contact hinzufügen
|
|
|
|
|
- [ ] Custom Field validieren
|
|
|
|
|
- [ ] Custom Field suchen/filtern
|
|
|
|
|
|
|
|
|
|
## 31. Onboarding/Tour Tests
|
|
|
|
|
- [ ] Onboarding Tour starten
|
|
|
|
|
- [ ] Tour Steps durchlaufen
|
|
|
|
|
- [ ] Tour abschließen
|
|
|
|
|
- [ ] Tour überspringen
|
|
|
|
|
- [ ] Welcome Dialog
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
docs: Test-Plan erweitert auf 42 Kategorien (Edge Cases, Concurrency, Error Handling, File Upload, Session, Data Consistency, Accessibility, API Docs, Infrastructure, Monitoring, Deployment)
2026-08-21 21:33:21 +02:00
|
|
|
## 32. Edge Cases & Boundary Tests
|
|
|
|
|
- [ ] Leere Datenbank (0 Einträge) → alle Listen zeigen EmptyState
|
|
|
|
|
- [ ] Sehr viele Daten (10.000+ Contacts) → Pagination funktioniert, Performance OK
|
|
|
|
|
- [ ] Unicode/Sonderzeichen in allen Textfeldern (Emojis, Umlaute, Chinesisch, Arabisch)
|
|
|
|
|
- [ ] Sehr lange Strings (10.000 Zeichen Name)
|
|
|
|
|
- [ ] Null/Empty Werte in Pflichtfeldern
|
|
|
|
|
- [ ] Negative Zahlen in positiven Feldern
|
|
|
|
|
- [ ] Datumsrandfälle: 29.02.2024 (Schaltjahr), 31.12.9999, 01.01.0001
|
|
|
|
|
- [ ] Zeitzone-Wechsel (UTC vs CEST)
|
|
|
|
|
|
|
|
|
|
## 33. Concurrency & Race Conditions
|
|
|
|
|
- [ ] Zwei User erstellen gleichzeitig einen Contact mit gleicher E-Mail
|
|
|
|
|
- [ ] User A löscht Contact während User B ihn bearbeitet
|
|
|
|
|
- [ ] Gleichzeitige IMAP Sync auf gleichem Account
|
|
|
|
|
- [ ] Gleichzeitige Workflow-Ausführung
|
|
|
|
|
- [ ] Optimistic Locking Tests
|
|
|
|
|
|
|
|
|
|
## 34. API Error Handling
|
|
|
|
|
- [ ] Invalid JSON Body → 422
|
|
|
|
|
- [ ] Sehr große Request Body (> 10MB) → 413
|
|
|
|
|
- [ ] Fehlende Content-Type Header → 422
|
|
|
|
|
- [ ] Falsche HTTP Method (GET statt POST) → 405
|
|
|
|
|
- [ ] Nicht existierende Endpoint-Pfade → 404
|
|
|
|
|
- [ ] Rate Limit überschritten → 429
|
|
|
|
|
|
|
|
|
|
## 35. File Upload Tests
|
|
|
|
|
- [ ] Upload 0 Byte Datei
|
|
|
|
|
- [ ] Upload 100MB Datei
|
|
|
|
|
- [ ] Upload ausführbare Datei (.exe, .sh, .php)
|
|
|
|
|
- [ ] Upload Datei mit doppelten Extension (.pdf.exe)
|
|
|
|
|
- [ ] Upload ohne Dateiname
|
|
|
|
|
- [ ] Upload mit Sonderzeichen im Dateinamen
|
|
|
|
|
- [ ] Upload mehrere Dateien gleichzeitig
|
|
|
|
|
- [ ] Upload Abbruch (Network Error)
|
|
|
|
|
|
|
|
|
|
## 36. Session & Auth Edge Cases
|
|
|
|
|
- [ ] Session nach Neustart des Backends → noch gültig?
|
|
|
|
|
- [ ] Gleichzeitige Sessions von verschiedenen Browsern
|
|
|
|
|
- [ ] Session Timeout → automatischer Logout
|
|
|
|
|
- [ ] CSRF Token nach Session Timeout → ungültig
|
|
|
|
|
- [ ] Login mit deaktiviertem User → 403
|
|
|
|
|
- [ ] Login mit gelöschtem User → 401
|
|
|
|
|
- [ ] Password Reset Flow komplett
|
|
|
|
|
|
|
|
|
|
## 37. Data Consistency Tests
|
|
|
|
|
- [ ] Contact löschen → alle Tags, Custom Fields, Attachments, Entity Links werden gelöscht
|
|
|
|
|
- [ ] User löschen → seine Daten werden auf admin übertragen oder gelöscht
|
|
|
|
|
- [ ] Tenant löschen → alle Tenant-Daten werden gelöscht
|
|
|
|
|
- [ ] Soft-Delete → deleted_at wird gesetzt, Daten nicht in Queries
|
|
|
|
|
- [ ] Hard-Delete (?gdpr=true) → Daten physisch gelöscht
|
|
|
|
|
- [ ] Restore aus Trash → Daten wiederhergestellt
|
|
|
|
|
|
|
|
|
|
## 38. Frontend Accessibility Tests
|
|
|
|
|
- [ ] Tastatur-Navigation (Tab, Enter, Escape)
|
|
|
|
|
- [ ] Screen Reader Kompatibilität (ARIA Labels)
|
|
|
|
|
- [ ] Color Contrast (WCAG AA)
|
|
|
|
|
- [ ] Touch Targets ≥ 44px
|
|
|
|
|
- [ ] Focus Indicators sichtbar
|
|
|
|
|
- [ ] i18n: Alle Strings übersetzt (keine hardcoded Strings)
|
|
|
|
|
|
|
|
|
|
## 39. API Documentation Tests
|
|
|
|
|
- [ ] OpenAPI Schema ist aktuell (`GET /openapi.json`)
|
|
|
|
|
- [ ] Alle Endpunkte haben Beschreibungen
|
|
|
|
|
- [ ] Alle Schemas haben Beispiele
|
|
|
|
|
- [ ] Response Codes sind dokumentiert
|
|
|
|
|
|
|
|
|
|
## 40. Infrastructure Tests
|
|
|
|
|
- [ ] Docker Health Check funktioniert
|
|
|
|
|
- [ ] Redis Persistence (dump.rdb)
|
|
|
|
|
- [ ] PostgreSQL Backup funktioniert
|
|
|
|
|
- [ ] Volume Mounts korrekt
|
|
|
|
|
- [ ] Environment Variables geladen
|
|
|
|
|
- [ ] prestart.sh läuft fehlerfrei
|
|
|
|
|
- [ ] worker.sh läuft fehlerfrei
|
|
|
|
|
|
|
|
|
|
## 41. Monitoring & Observability
|
|
|
|
|
- [ ] Prometheus Metrics Endpoint (`GET /api/v1/metrics`)
|
|
|
|
|
- [ ] Structured Logging (JSON Format)
|
|
|
|
|
- [ ] Trace IDs in jedem Request
|
|
|
|
|
- [ ] Error Rate Monitoring
|
|
|
|
|
- [ ] Health Check History
|
|
|
|
|
|
|
|
|
|
## 42. Deployment Tests
|
|
|
|
|
- [ ] Frontend-only Deploy funktioniert
|
|
|
|
|
- [ ] Full Deploy funktioniert
|
|
|
|
|
- [ ] Rollback funktioniert
|
|
|
|
|
- [ ] Zero-Downtime Deploy
|
|
|
|
|
- [ ] Migration Rollback (alembic downgrade)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
docs: Test-Plan erweitert auf 54 Kategorien (+Tenant Provisioning, Contract Testing, Regression, Exploratory, Cross-Browser, Data Truncation, API Versioning, Test Pyramid, Negative Testing, Sanity, Production Safety, Test Environment)
2026-08-21 21:36:23 +02:00
|
|
|
## 43. Tenant Provisioning Tests
|
|
|
|
|
- [ ] Neuen Tenant erstellen → Schema, RLS, Default-Daten korrekt
|
|
|
|
|
- [ ] Tenant mit eigenem Admin-User → Login funktioniert
|
|
|
|
|
- [ ] Tenant Default-Plugins aktiviert
|
|
|
|
|
- [ ] Tenant Default-Settings gesetzt
|
|
|
|
|
- [ ] Tenant löschen → alle Daten gelöscht (nur in Staging!)
|
|
|
|
|
- [ ] Tenant-Isolation: Daten zwischen Tenants komplett getrennt
|
|
|
|
|
|
|
|
|
|
## 44. Contract Testing (Frontend ↔ Backend)
|
|
|
|
|
- [ ] Frontend API Client Types stimmen mit Backend Schemas überein
|
|
|
|
|
- [ ] Response-Struktur: PaginatedResponse hat items, total, page, page_size
|
|
|
|
|
- [ ] Entity-IDs sind UUIDs (keine Integer)
|
|
|
|
|
- [ ] Datetime-Felder sind ISO 8601 mit Timezone
|
|
|
|
|
- [ ] Error-Response: {code, detail, field, trace_id, retryable, category}
|
|
|
|
|
- [ ] OpenAPI Schema mit Frontend Types generieren und vergleichen
|
|
|
|
|
|
|
|
|
|
## 45. Regression Testing
|
|
|
|
|
- [ ] Nach jedem Bug-Fix: betroffene Tests erneut ausführen
|
|
|
|
|
- [ ] Nach jedem Deploy: Smoke Tests erneut ausführen
|
|
|
|
|
- [ ] Nach jeder Migration: Schema-Validierung erneut ausführen
|
|
|
|
|
- [ ] Test-Suite bleibt grün nach Fixes (keine neuen Bugs durch Fixes)
|
|
|
|
|
|
|
|
|
|
## 46. Exploratory Testing (manuell)
|
|
|
|
|
- [ ] Login → Dashboard → alle Menüpunkte durchklicken
|
|
|
|
|
- [ ] Contact erstellen → bearbeiten → löschen → wiederherstellen
|
|
|
|
|
- [ ] Mail lesen → beantworten → weiterleiten
|
|
|
|
|
- [ ] Kalender: Termin erstellen → verschieben → löschen
|
|
|
|
|
- [ ] Wiki: Artikel erstellen → WYSIWYG Editor testen → speichern → Versionen
|
|
|
|
|
- [ ] Tasks: erstellen → zuweisen → Status ändern → Kanban-Board
|
|
|
|
|
- [ ] Tags: erstellen → zuweisen → filtern → löschen
|
|
|
|
|
- [ ] Kommunikation: Chat starten → AI Chat → Message senden
|
|
|
|
|
- [ ] Settings: alle Settings-Seiten durchklicken
|
|
|
|
|
- [ ] Search: verschiedene Suchbegriffe testen
|
|
|
|
|
|
|
|
|
|
## 47. Cross-Browser & Cross-Device Tests
|
|
|
|
|
- [ ] Chrome: alle Seiten laden
|
|
|
|
|
- [ ] Firefox: alle Seiten laden
|
|
|
|
|
- [ ] Safari: alle Seiten laden (falls verfügbar)
|
|
|
|
|
- [ ] Mobile Viewport (375px): alle Seiten laden
|
|
|
|
|
- [ ] Tablet Viewport (768px): alle Seiten laden
|
|
|
|
|
- [ ] Desktop Viewport (1920px): alle Seiten laden
|
|
|
|
|
|
|
|
|
|
## 48. Data Truncation & Formatting Tests
|
|
|
|
|
- [ ] Form-Daten mit max-length werden korrekt in DB gespeichert
|
|
|
|
|
- [ ] Unicode-Zeichen werden nicht trunciert
|
|
|
|
|
- [ ] Datumsformatierung: DD.MM.YYYY vs YYYY-MM-DD
|
|
|
|
|
- [ ] Zahlenformatierung: 1.234,56 vs 1,234.56
|
|
|
|
|
- [ ] Währungsformatierung korrekt
|
|
|
|
|
- [ ] Telefonnummern-Formatierung
|
|
|
|
|
|
|
|
|
|
## 49. API Version Compatibility
|
|
|
|
|
- [ ] `/api/v1/` Endpunkte funktionieren
|
|
|
|
|
- [ ] Alte API-Pfade geben 404 oder Deprecation Warning
|
|
|
|
|
- [ ] API Versionierung in OpenAPI dokumentiert
|
|
|
|
|
|
|
|
|
|
## 50. Test Pyramid Struktur
|
|
|
|
|
- [ ] **Unit Tests** (pytest, vitest): einzelne Funktionen, Models, Schemas
|
|
|
|
|
- [ ] **Integration Tests** (pytest): API Endpunkte mit Test-DB
|
|
|
|
|
- [ ] **E2E Tests** (Playwright): komplette User-Flows im Browser
|
|
|
|
|
- [ ] **Contract Tests**: Frontend ↔ Backend Types
|
|
|
|
|
- [ ] **Performance Tests**: Response Times
|
|
|
|
|
- [ ] **Security Tests**: CSRF, XSS, Rate Limiting
|
|
|
|
|
|
|
|
|
|
## 51. Negative Testing
|
|
|
|
|
- [ ] POST mit fehlenden Pflichtfeldern → 422
|
|
|
|
|
- [ ] POST mit falschem Datentyp (String statt Integer) → 422
|
|
|
|
|
- [ ] GET mit nicht existierender UUID → 404
|
|
|
|
|
- [ ] DELETE auf bereits gelöschtem Eintrag → 404
|
|
|
|
|
- [ ] POST mit zu langem String → 422 oder trunciert
|
|
|
|
|
- [ ] PATCH mit leerem Body → 422
|
|
|
|
|
- [ ] Login mit deaktiviertem Account → 403
|
|
|
|
|
- [ ] API ohne Auth → 401
|
|
|
|
|
- [ ] API mit falschem CSRF Token → 403
|
|
|
|
|
|
|
|
|
|
## 52. Sanity Testing (nach Deploy)
|
|
|
|
|
- [ ] Health Check: 200 healthy
|
|
|
|
|
- [ ] Login: Admin kann sich einloggen
|
|
|
|
|
- [ ] Contacts: Liste lädt
|
|
|
|
|
- [ ] Mail: Accounts sichtbar
|
|
|
|
|
- [ ] Frontend: Login-Seite rendert
|
|
|
|
|
- [ ] DB: Alembic Version korrekt
|
|
|
|
|
- [ ] Redis: Verbindung OK
|
|
|
|
|
- [ ] Worker: Queue leer
|
|
|
|
|
|
2026-08-21 21:40:17 +02:00
|
|
|
## 53. Production Testing Rules (System nicht produktiv — volle Tests erlaubt)
|
|
|
|
|
- [ ] **Volle destruktive Tests erlaubt (System nicht produktiv)** (Tenant-Löschung, Hard-Delete aller Daten)
|
|
|
|
|
- [ ] **Test-Daten werden nach Tests gelöscht (Sauberkeit)** (außer Test-User die für Rechte-Tests gebraucht werden)
|
|
|
|
|
- [ ] **Migrationen können in Produktion getestet werden** (nur in Staging)
|
|
|
|
|
- [ ] **Plugin-Deaktivierung kann getestet werden** (kann Datenverlust verursachen)
|
docs: Test-Plan erweitert auf 54 Kategorien (+Tenant Provisioning, Contract Testing, Regression, Exploratory, Cross-Browser, Data Truncation, API Versioning, Test Pyramid, Negative Testing, Sanity, Production Safety, Test Environment)
2026-08-21 21:36:23 +02:00
|
|
|
- [ ] **Test-User nach Tests löschen** (sales@test.com, reader@test.com)
|
|
|
|
|
- [ ] **Test-Daten nach Tests löschen** (Test-Contacts, Test-Tags, Test-Tasks, Test-Wiki)
|
2026-08-21 21:40:17 +02:00
|
|
|
- [ ] **Backup nicht nötig (System nicht produktiv)** (pg_dump)
|
docs: Test-Plan erweitert auf 54 Kategorien (+Tenant Provisioning, Contract Testing, Regression, Exploratory, Cross-Browser, Data Truncation, API Versioning, Test Pyramid, Negative Testing, Sanity, Production Safety, Test Environment)
2026-08-21 21:36:23 +02:00
|
|
|
|
|
|
|
|
## 54. Test Environment Setup
|
|
|
|
|
- [ ] **Lokale Test-DB**: PostgreSQL mit `leocrm_test` User, `test123` Passwort, `leocrm_test` DB
|
|
|
|
|
- [ ] **pgvector Extension**: in Test-DB installiert
|
|
|
|
|
- [ ] **Redis**: lokal verfügbar (PONG)
|
|
|
|
|
- [ ] **Node/npm**: v22+ installiert
|
|
|
|
|
- [ ] **Playwright**: installiert (v1.61.1)
|
|
|
|
|
- [ ] **pytest**: mit asyncio, coverage config
|
|
|
|
|
- [ ] **vitest**: mit jsdom, coverage config
|
|
|
|
|
- [ ] **CI Pipeline**: `scripts/ci_pipeline.sh` vorhanden
|
|
|
|
|
- [ ] **pre-commit hooks**: cross-plugin import check
|
|
|
|
|
- [ ] **Coverage**: pytest --cov mit branch coverage
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-08-21 21:44:26 +02:00
|
|
|
## 55. Architektur-Compliance Tests
|
|
|
|
|
|
|
|
|
|
### 55.1 Cross-Plugin Import Check
|
|
|
|
|
- [ ] Kein Plugin importiert direkt aus einem anderen Plugin (außer über Contracts)
|
|
|
|
|
- [ ] `scripts/check_cross_plugin_imports.py` läuft clean (0 violations)
|
|
|
|
|
- [ ] wiki/plugin.py: Cross-Plugin Imports aus unified_search entfernen → Contracts verwenden
|
|
|
|
|
- [ ] Alle 25 Plugins auf direkte Imports aus anderen Plugins prüfen
|
|
|
|
|
- [ ] Plugin-Deaktivierung: Wenn Plugin A deaktiviert wird, darf Plugin B nicht crashen
|
|
|
|
|
|
|
|
|
|
### 55.2 Contract-Verwendung
|
|
|
|
|
- [ ] Jedes Plugin das mit anderen Plugins kommuniziert, nutzt Contracts
|
|
|
|
|
- [ ] `get_contract("plugin_name")` wird verwendet statt direkter Imports
|
|
|
|
|
- [ ] Contracts sind in `app/plugins/builtins/contracts.py` definiert
|
|
|
|
|
- [ ] Contract-Functions haben type hints und docstrings
|
|
|
|
|
- [ ] Contract-Versionierung: Wenn sich ein Contract ändert, wird die Version erhöht
|
|
|
|
|
|
|
|
|
|
### 55.3 Plugin-Isolation
|
|
|
|
|
- [ ] Jedes Plugin kann unabhängig aktiviert/deaktiviert werden
|
|
|
|
|
- [ ] Plugin-Deaktivierung entfernt alle Routes, Models, Hooks
|
|
|
|
|
- [ ] Plugin-Reaktivierung stellt alles wieder her
|
|
|
|
|
- [ ] Kein Plugin hat Hard-Dependencies auf andere Plugins (außer über Contracts)
|
|
|
|
|
- [ ] Plugin-Migration-Runner läuft isoliert pro Plugin
|
|
|
|
|
|
|
|
|
|
### 55.4 Model-Abhängigkeiten
|
|
|
|
|
- [ ] Kein Model importiert aus einem anderen Plugin-Model
|
|
|
|
|
- [ ] Foreign Keys zwischen Plugin-Tabellen gehen über Core-Tabellen (nicht direkt)
|
|
|
|
|
- [ ] Model-Tabellen haben tenant_id (TenantMixin)
|
|
|
|
|
- [ ] Model-Tabellen haben owner_id (OwnedMixin) wo erforderlich
|
|
|
|
|
- [ ] Keine zirkulären Model-Abhängigkeiten
|
|
|
|
|
|
|
|
|
|
### 55.5 Service-Abhängigkeiten
|
|
|
|
|
- [ ] Services importieren nicht aus Plugin-Modulen (nur aus Core und eigenen Plugin)
|
|
|
|
|
- [ ] Services haben keine zirkulären Abhängigkeiten
|
|
|
|
|
- [ ] Services nutzen Dependency Injection (FastAPI Depends)
|
|
|
|
|
- [ ] Services sind async (keine sync I/O in async Routes)
|
|
|
|
|
|
|
|
|
|
### 55.6 Route-Abhängigkeiten
|
|
|
|
|
- [ ] Routes nutzen `require_permission` Dependency für Auth
|
|
|
|
|
- [ ] Routes nutzen `get_current_user` Dependency für User-Context
|
|
|
|
|
- [ ] Routes nutzen `get_db` Dependency für DB-Session
|
|
|
|
|
- [ ] Routes validieren Input mit Pydantic Schemas
|
|
|
|
|
- [ ] Routes erstellen Audit-Log-Einträge bei Mutationen
|
|
|
|
|
- [ ] Routes haben korrekte HTTP-Status-Codes (200/201/204/400/403/404/422/500)
|
|
|
|
|
|
|
|
|
|
### 55.7 Hook-Registrierung
|
|
|
|
|
- [ ] Alle Hooks sind in `plugin.py on_activate` registriert
|
|
|
|
|
- [ ] Hooks werden in `on_deactivate` deregistriert
|
|
|
|
|
- [ ] Hook-Namen sind eindeutig (keine Namens-Kollisionen zwischen Plugins)
|
|
|
|
|
- [ ] Hooks haben korrekte Signaturen (async, korrekte Parameter)
|
|
|
|
|
|
|
|
|
|
### 55.8 ARQ Worker-Registrierung
|
|
|
|
|
- [ ] Alle Background-Jobs sind in `worker.py` registriert
|
|
|
|
|
- [ ] Job-Namen sind eindeutig
|
|
|
|
|
- [ ] Jobs haben retry-logic konfiguriert
|
|
|
|
|
- [ ] Jobs sind async
|
|
|
|
|
- [ ] Job-Queue wird korrekt verarbeitet
|
|
|
|
|
|
|
|
|
|
### 55.9 Middleware-Kette
|
|
|
|
|
- [ ] CORS Middleware korrekt konfiguriert
|
|
|
|
|
- [ ] CSRF Middleware korrekt konfiguriert
|
|
|
|
|
- [ ] Security Headers Middleware korrekt konfiguriert
|
|
|
|
|
- [ ] Rate Limit Middleware korrekt konfiguriert
|
|
|
|
|
- [ ] Request Logging Middleware korrekt konfiguriert
|
|
|
|
|
- [ ] Circuit Breaker Middleware korrekt konfiguriert
|
|
|
|
|
- [ ] Middleware-Reihenfolge ist korrekt
|
|
|
|
|
|
|
|
|
|
### 55.10 Plugin-Manifest-Validierung
|
|
|
|
|
- [ ] Jedes Plugin hat ein gültiges `manifest.py`
|
|
|
|
|
- [ ] Manifest hat: name, version, description, author, dependencies
|
|
|
|
|
- [ ] Manifest-Dependencies sind erfüllt (abhängige Plugins sind aktiv)
|
|
|
|
|
- [ ] Manifest-Version folgt Semantic Versioning
|
|
|
|
|
- [ ] Plugin-Signature ist validiert (falls Signature-Checking aktiv)
|
|
|
|
|
|
|
|
|
|
### 55.11 Datenbank-Architektur
|
|
|
|
|
- [ ] Alle Tabellen haben `tenant_id` (außer System-Tabellen)
|
|
|
|
|
- [ ] Alle Tabellen haben `created_at` und `updated_at`
|
|
|
|
|
- [ ] Alle Tabellen haben `deleted_at` (Soft-Delete)
|
|
|
|
|
- [ ] UUID Primary Keys (keine Integer Auto-Increment)
|
|
|
|
|
- [ ] TIMESTAMPTZ (keine naive datetime)
|
|
|
|
|
- [ ] JSONB für flexible Felder (metadata, config, applicable_to)
|
|
|
|
|
- [ ] RLS Policies auf allen Tenant-Tabellen
|
|
|
|
|
- [ ] Indexes auf häufig gefilterten Spalten
|
|
|
|
|
- [ ] Foreign Keys mit ON DELETE CASCADE wo appropriate
|
|
|
|
|
|
|
|
|
|
### 55.12 Frontend-Architektur
|
|
|
|
|
- [ ] Keine Class Components (nur Functional Components)
|
|
|
|
|
- [ ] Keine inline Styles (nur Tailwind)
|
|
|
|
|
- [ ] Keine hardcoded Strings (nur `t()` i18n)
|
|
|
|
|
- [ ] Keine `any` Types (TypeScript strict)
|
|
|
|
|
- [ ] Keine manual fetch/axios (nur TanStack Query)
|
|
|
|
|
- [ ] Keine Server-Data in Zustand (nur Client-State)
|
|
|
|
|
- [ ] Keine `dangerouslySetInnerHTML` ohne Sanitization
|
|
|
|
|
- [ ] ARIA Attributes auf allen interaktiven Elementen
|
|
|
|
|
- [ ] Touch Targets ≥ 44px
|
|
|
|
|
- [ ] React Hook Form + Zod für alle Forms
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2026-08-21 21:21:33 +02:00
|
|
|
## Ausführungs-Reihenfolge
|
|
|
|
|
|
|
|
|
|
1. Smoke Tests (1.) — schnell, prüft ob System läuft
|
|
|
|
|
2. Code-Logik Tests (8.) — prüft Imports und Models
|
|
|
|
|
3. Datenbank Tests (4.) — prüft Schema und Daten
|
|
|
|
|
4. Backend API Tests (2.) — alle Endpunkte durchtesten
|
|
|
|
|
5. Rechte-System Tests (5.) — mit verschiedenen Usern
|
|
|
|
|
6. Cross-Tenant Security Tests (6.) — Tenant-Isolation
|
|
|
|
|
7. Plugin-Verbindungen Tests (7.) — alle Plugin-Interaktionen
|
|
|
|
|
8. Frontend Tests (3.) — vitest, Playwright, Browser
|
|
|
|
|
9. Performance Tests (9.) — Response Times
|
|
|
|
|
10. Security Tests (10.) — CSRF, XSS, Rate Limiting
|
|
|
|
|
11. Cleanup Tests (11.) — Test-Daten entfernen
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Test-User
|
|
|
|
|
|
|
|
|
|
| User | Email | Rolle | Berechtigungen |
|
|
|
|
|
|------|-------|-------|----------------|
|
|
|
|
|
| Admin | admin@media-on.de | admin | *:* (volle Rechte) |
|
|
|
|
|
| Sales | sales@test.com | Sales | contacts:read+write, mail:read, calendar:read, tags:read, tasks:read+write, wiki:read, communication:read+write, dms:read, reports:read |
|
|
|
|
|
| Reader | reader@test.com | viewer | keine |
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Prinzipien
|
|
|
|
|
|
|
|
|
|
- **Echte Tests gegen Produktion** — keine Mocks
|
|
|
|
|
- **Jeder Test wird mit curl/HTTP gegen https://crm.media-on.de ausgeführt**
|
|
|
|
|
- **Datenbank-Tests via SSH → psql auf Produktions-DB**
|
|
|
|
|
- **Frontend-Tests mit vitest + Playwright + Browser**
|
|
|
|
|
- **Test-Daten werden nach Tests gelöscht**
|
2026-08-21 21:28:11 +02:00
|
|
|
- **Alle Fehler werden in `docs/test-bugs.md` gesammelt** — KEINE Fixes während des Testens
|
2026-08-21 21:21:33 +02:00
|
|
|
- **Ergebnisse werden dokumentiert**
|
2026-08-21 21:28:11 +02:00
|
|
|
- **Fixes werden erst nach Abschluss aller Tests gesammelt durchgeführt**
|