""" Tests fuer die GDPR UI-Funktionalitaet (Art. 15-21). Testet: - GDPR-Rechte im Legal Modal (Art. 15-21) - JavaScript-Funktionen fuer GDPR-Anfragen - Consent Manager Integration """ import pytest import re from pathlib import Path class TestGDPRUIStructure: """Tests fuer GDPR UI-Struktur im Legal Modal.""" @pytest.fixture def studio_html(self): """Laedt studio.html fuer Tests.""" html_path = Path(__file__).parent.parent / "frontend" / "templates" / "studio.html" if html_path.exists(): return html_path.read_text() return None def test_gdpr_section_exists(self, studio_html): """Test: GDPR-Bereich existiert im Legal Modal.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert 'id="legal-gdpr"' in studio_html, "GDPR-Bereich sollte im Legal Modal existieren" def test_gdpr_section_has_title(self, studio_html): """Test: GDPR-Bereich hat Titel mit Art. 15-21 Referenz.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 15-21" in studio_html, "GDPR-Bereich sollte Art. 15-21 im Titel erwaehnen" def test_art15_auskunftsrecht_exists(self, studio_html): """Test: Art. 15 (Auskunftsrecht) ist vorhanden.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 15" in studio_html, "Art. 15 (Auskunftsrecht) sollte vorhanden sein" assert "Auskunft" in studio_html, "Auskunftsrecht-Button sollte vorhanden sein" def test_art16_berichtigung_exists(self, studio_html): """Test: Art. 16 (Berichtigung) ist vorhanden.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 16" in studio_html, "Art. 16 (Berichtigung) sollte vorhanden sein" assert "Berichtigung" in studio_html, "Berichtigung-Button sollte vorhanden sein" def test_art17_loeschung_exists(self, studio_html): """Test: Art. 17 (Loeschung) ist vorhanden.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 17" in studio_html, "Art. 17 (Loeschung) sollte vorhanden sein" assert "Löschung" in studio_html, "Loeschung-Button sollte vorhanden sein" def test_art18_einschraenkung_exists(self, studio_html): """Test: Art. 18 (Einschraenkung der Verarbeitung) ist vorhanden.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 18" in studio_html, "Art. 18 (Einschraenkung) sollte vorhanden sein" assert "Einschränkung" in studio_html, "Einschraenkung-Button sollte vorhanden sein" def test_art19_mitteilungspflicht_exists(self, studio_html): """Test: Art. 19 (Mitteilungspflicht) ist vorhanden.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 19" in studio_html, "Art. 19 (Mitteilungspflicht) sollte vorhanden sein" assert "Mitteilung" in studio_html, "Mitteilungspflicht sollte erwaehnt werden" def test_art20_datenuebertragbarkeit_exists(self, studio_html): """Test: Art. 20 (Datenuebertragbarkeit) ist vorhanden.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 20" in studio_html, "Art. 20 (Datenuebertragbarkeit) sollte vorhanden sein" assert "Datenübertragbarkeit" in studio_html or "exportieren" in studio_html.lower(), \ "Datenexport-Button sollte vorhanden sein" def test_art21_widerspruch_exists(self, studio_html): """Test: Art. 21 (Widerspruchsrecht) ist vorhanden.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Art. 21" in studio_html, "Art. 21 (Widerspruchsrecht) sollte vorhanden sein" assert "Widerspruch" in studio_html, "Widerspruch-Button sollte vorhanden sein" def test_consent_manager_section_exists(self, studio_html): """Test: Consent Manager Bereich existiert.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert "Einwilligungen verwalten" in studio_html, \ "Consent Manager Bereich sollte vorhanden sein" class TestGDPRJavaScriptFunctions: """Tests fuer GDPR JavaScript-Funktionen.""" @pytest.fixture def studio_js(self): """Laedt studio.js fuer Tests.""" js_path = Path(__file__).parent.parent / "frontend" / "static" / "js" / "studio.js" if js_path.exists(): return js_path.read_text() return None def test_request_data_export_function_exists(self, studio_js): """Test: requestDataExport Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function requestDataExport" in studio_js or "async function requestDataExport" in studio_js, \ "requestDataExport Funktion sollte existieren" def test_request_data_correction_function_exists(self, studio_js): """Test: requestDataCorrection Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function requestDataCorrection" in studio_js or "async function requestDataCorrection" in studio_js, \ "requestDataCorrection Funktion (Art. 16) sollte existieren" def test_request_data_deletion_function_exists(self, studio_js): """Test: requestDataDeletion Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function requestDataDeletion" in studio_js or "async function requestDataDeletion" in studio_js, \ "requestDataDeletion Funktion (Art. 17) sollte existieren" def test_request_processing_restriction_function_exists(self, studio_js): """Test: requestProcessingRestriction Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function requestProcessingRestriction" in studio_js or \ "async function requestProcessingRestriction" in studio_js, \ "requestProcessingRestriction Funktion (Art. 18) sollte existieren" def test_request_data_download_function_exists(self, studio_js): """Test: requestDataDownload Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function requestDataDownload" in studio_js or "async function requestDataDownload" in studio_js, \ "requestDataDownload Funktion (Art. 20) sollte existieren" def test_request_processing_objection_function_exists(self, studio_js): """Test: requestProcessingObjection Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function requestProcessingObjection" in studio_js or \ "async function requestProcessingObjection" in studio_js, \ "requestProcessingObjection Funktion (Art. 21) sollte existieren" def test_show_consent_manager_function_exists(self, studio_js): """Test: showConsentManager Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function showConsentManager" in studio_js, \ "showConsentManager Funktion sollte existieren" def test_open_settings_modal_function_exists(self, studio_js): """Test: openSettingsModal Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function openSettingsModal" in studio_js, \ "openSettingsModal Funktion sollte existieren" def test_open_legal_modal_function_exists(self, studio_js): """Test: openLegalModal Funktion existiert.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") assert "function openLegalModal" in studio_js, \ "openLegalModal Funktion sollte existieren" def test_gdpr_functions_have_user_feedback(self, studio_js): """Test: GDPR-Funktionen geben Benutzer-Feedback (alert/confirm).""" if studio_js is None: pytest.skip("studio.js nicht gefunden") # Suche nach GDPR Functions Block gdpr_match = re.search(r'// GDPR FUNCTIONS.*?// Load saved cookie', studio_js, re.DOTALL) if gdpr_match: gdpr_content = gdpr_match.group(0) assert "alert(" in gdpr_content or "confirm(" in gdpr_content, \ "GDPR-Funktionen sollten Benutzer-Feedback geben" def test_deletion_requires_confirmation(self, studio_js): """Test: Loeschung erfordert Bestaetigung.""" if studio_js is None: pytest.skip("studio.js nicht gefunden") # Suche nach requestDataDeletion Funktion deletion_match = re.search(r'function requestDataDeletion.*?\}', studio_js, re.DOTALL) if deletion_match: deletion_content = deletion_match.group(0) assert "confirm(" in deletion_content, \ "Datenlöschung sollte Bestaetigung erfordern" class TestGDPRActions: """Tests fuer GDPR-Action Buttons im HTML.""" @pytest.fixture def studio_html(self): """Laedt studio.html fuer Tests.""" html_path = Path(__file__).parent.parent / "frontend" / "templates" / "studio.html" if html_path.exists(): return html_path.read_text() return None def test_gdpr_actions_container_exists(self, studio_html): """Test: GDPR-Actions Container existiert.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") assert 'class="gdpr-actions"' in studio_html, "GDPR-Actions Container sollte existieren" def test_gdpr_action_items_exist(self, studio_html): """Test: Mindestens 6 GDPR-Action Items existieren (Art. 15-21, ohne Art. 19 als Button).""" if studio_html is None: pytest.skip("studio.html nicht gefunden") gdpr_action_count = studio_html.count('class="gdpr-action"') assert gdpr_action_count >= 6, \ f"Mindestens 6 GDPR-Action Items sollten existieren, gefunden: {gdpr_action_count}" def test_deletion_button_has_danger_class(self, studio_html): """Test: Loeschung-Button hat btn-danger Klasse.""" if studio_html is None: pytest.skip("studio.html nicht gefunden") # Suche nach Loeschung-Button assert 'onclick="requestDataDeletion()"' in studio_html, "Loeschung-Button sollte existieren" # Der Button sollte btn-danger haben assert 'btn-danger' in studio_html and 'requestDataDeletion' in studio_html, \ "Loeschung-Button sollte btn-danger Klasse haben"