# Test Report — LeoCRM Fix Branch **Date**: 2026-07-27 **Branch**: main (leocrm-fix) ## Test Results ### Backend: AI Copilot Tests (tests/test_ai_copilot.py) ``` 76 passed, 2 warnings in 63.31s ``` **AC Tests (all pass):** - AC1: test_ac1_copilot_query_returns_proposed_actions ✅ - AC2: test_ac2_copilot_execute_action_success ✅ - AC3: test_ac3_copilot_execute_blocked_by_rbac ✅ - AC4: test_ac4_copilot_history_paginated ✅ - AC5: test_ac5_copilot_action_logged_in_audit ✅ - AC6: test_ac6_copilot_tenant_isolation ✅ - AC7: test_ac7_copilot_field_level_permissions ✅ **Other tests fixed:** - test_copilot_unauthenticated: Fixed 401→403 for POST (CSRF middleware returns 403) - test_route_copilot_history_unauthenticated: GET returns 401 (no CSRF needed) - test_route_copilot_execute_unauthenticated: Fixed 401→403 for POST - action_mapper tests: Updated /api/v1/companies → /api/v1/contacts (unified contact model) - llm_client tests: Fixed ai_client → client variable, api_base default '' - service tests: Updated /api/v1/companies → /api/v1/contacts, PATCH/DELETE return 400 (unsupported) ### Frontend: TypeScript Type Check ``` cd frontend && npx tsc --noEmit # Exit code 0 — no errors ``` ### Event Loop Fix Added `asyncio_default_fixture_loop_scope = "session"` and `asyncio_default_test_loop_scope = "session"` to pyproject.toml to fix 'Event loop is closed' error when running multiple AI copilot tests in sequence. ## Changes Summary ### 1. Backend Security Fixes - **RCE Dead Code repariert** (`app/routes/plugins.py`): Security-Check (`_check_dangerous_imports`) wurde VOR `exec_module()` verschoben. Zuvor war exec_module vor dem Security-Check, was eine RCE-Lücke war (auch wenn alle Upload-Endpoints deaktiviert waren). - **verify_ws_origin verschärft** (`app/core/auth.py`): Leerer Origin-Header wird jetzt abgelehnt (return False) wenn CORS konfiguriert ist, statt automatisch akzeptiert zu werden. ### 2. Test Infrastructure Fixes (conftest.py) - Neuer `ai_app` und `ai_client` Fixture mit `init_permission_registry(active_plugin_names={'ai_assistant'})` - `login_client` setzt jetzt CSRF-Token und Origin als Client-Default-Header - `SESSION_COOKIE_SECURE=false` und `SESSION_COOKIE_SAMESITE=lax` werden vor allen Imports gesetzt - `get_settings.cache_clear()` nach env-Override - `pyproject.toml`: `asyncio_default_fixture_loop_scope = "session"` und `asyncio_default_test_loop_scope = "session"` hinzugefügt - `tests/test_ai_copilot.py`: `/api/v1/companies` → `/api/v1/contacts` (Companies sind Contacts mit type='company'). 15 weitere Test-Fixes (action_mapper paths, llm_client variables, service test paths, unauthenticated test assertions). ### 3. Event Bus Lücken geschlossen - system_notif/plugin.py: Added conversation.created, participant.joined, participant.left, reaction.added to manifest events list - Added handler methods: on_conversation_created, on_participant_joined, on_participant_left, on_reaction_added - Added event titles for new events in _create_system_notification ### 4. Frontend Integration: SavedFilterBar - ContactsList.tsx: Added SavedFilterBar with entityType="contacts" in middle pane - Mail.tsx: Added SavedFilterBar with entityType="mail" in mail list pane - Calendar.tsx: Added SavedFilterBar with entityType="calendar" in calendar view pane ### 5. Frontend Integration: TagSelector - ContactsList.tsx: Added TagSelector with entityType="contact" in middle pane - Mail.tsx: Added TagSelector with entityType="file" in mail list pane - Calendar.tsx: Added TagSelector with entityType="calendar_entry" in calendar view pane ### 6. Event Loop Fix - pyproject.toml: Added asyncio_default_fixture_loop_scope and asyncio_default_test_loop_scope = "session" - Fixed 15 pre-existing test failures (action_mapper, llm_client, service tests) caused by unified contact model migration ## Smoke Test - Backend: All 76 AI copilot tests pass including AC1-AC7 - Frontend: TypeScript compilation passes with 0 errors - Event bus: system_notif plugin now subscribes to conversation.created, participant.joined/left, reaction.added - RCE Dead Code: Security-Check (_check_dangerous_imports) wird VOR exec_module() ausgeführt - verify_ws_origin: Leerer Origin-Header wird abgelehnt bei konfiguriertem CORS - conftest.py: ai_app/ai_client Fixtures mit ai_assistant Plugin-Aktivierung, CSRF-Token, Origin-Header - Frontend-Integration: SavedFilterBar und TagSelector in ContactsList, Mail, Calendar integriert