# 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 (``) → 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 --- ## 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 --- ## 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) --- ## 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 ## 53. Production Safety Rules - [ ] **KEINE destruktiven Tests in Produktion** (Tenant-Löschung, Hard-Delete aller Daten) - [ ] **KEINE Test-Daten in Produktion lassen** (außer Test-User die für Rechte-Tests gebraucht werden) - [ ] **KEINE Migrationen in Produktion testen** (nur in Staging) - [ ] **KEINE Plugin-Deaktivierung in Produktion** (kann Datenverlust verursachen) - [ ] **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) - [ ] **Backup vor großen Test-Sessions** (pg_dump) ## 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 --- ## 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** - **Alle Fehler werden in `docs/test-bugs.md` gesammelt** — KEINE Fixes während des Testens - **Ergebnisse werden dokumentiert** - **Fixes werden erst nach Abschluss aller Tests gesammelt durchgeführt**