A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
214 lines
8.5 KiB
Python
214 lines
8.5 KiB
Python
"""
|
|
Tests fuer das BreakPilot Customer Portal (customer.py)
|
|
|
|
Testet die neuen schlanken Kundenportal-Routen und -Dateien.
|
|
|
|
Erstellt: 2024-12-16
|
|
"""
|
|
import pytest
|
|
import sys
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# Add parent directory to path for imports
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
# Pfade zu den Customer Portal Dateien
|
|
FRONTEND_DIR = Path(__file__).parent.parent / "frontend"
|
|
CUSTOMER_CSS = FRONTEND_DIR / "static" / "css" / "customer.css"
|
|
CUSTOMER_JS = FRONTEND_DIR / "static" / "js" / "customer.js"
|
|
CUSTOMER_HTML = FRONTEND_DIR / "templates" / "customer.html"
|
|
|
|
|
|
class TestCustomerPortalFiles:
|
|
"""Tests fuer die Customer Portal Dateistruktur."""
|
|
|
|
def test_customer_html_exists(self):
|
|
"""Testet, dass das Customer HTML-Template existiert."""
|
|
assert CUSTOMER_HTML.exists(), f"Customer HTML nicht gefunden: {CUSTOMER_HTML}"
|
|
|
|
def test_customer_css_exists(self):
|
|
"""Testet, dass die Customer CSS-Datei existiert."""
|
|
assert CUSTOMER_CSS.exists(), f"Customer CSS nicht gefunden: {CUSTOMER_CSS}"
|
|
|
|
def test_customer_js_exists(self):
|
|
"""Testet, dass die Customer JS-Datei existiert."""
|
|
assert CUSTOMER_JS.exists(), f"Customer JS nicht gefunden: {CUSTOMER_JS}"
|
|
|
|
def test_customer_py_exists(self):
|
|
"""Testet, dass das Customer Python-Modul existiert."""
|
|
customer_py = FRONTEND_DIR / "customer.py"
|
|
assert customer_py.exists(), f"Customer Python nicht gefunden: {customer_py}"
|
|
|
|
|
|
class TestCustomerHTMLStructure:
|
|
"""Tests fuer die Customer Portal HTML-Struktur."""
|
|
|
|
@pytest.fixture
|
|
def customer_html(self):
|
|
"""Laedt den HTML-Inhalt aus dem Template."""
|
|
return CUSTOMER_HTML.read_text(encoding="utf-8")
|
|
|
|
def test_html_has_doctype(self, customer_html):
|
|
"""Testet, dass das HTML-Dokument einen DOCTYPE hat."""
|
|
assert customer_html.strip().startswith("<!DOCTYPE html>"), \
|
|
"Customer HTML muss mit DOCTYPE beginnen"
|
|
|
|
def test_html_has_german_language(self, customer_html):
|
|
"""Testet, dass das HTML-Dokument auf Deutsch eingestellt ist."""
|
|
assert 'lang="de"' in customer_html, \
|
|
"Customer HTML sollte lang='de' haben"
|
|
|
|
def test_html_references_css(self, customer_html):
|
|
"""Testet, dass das HTML die Customer CSS-Datei referenziert."""
|
|
assert '/static/css/customer.css' in customer_html, \
|
|
"Customer HTML muss CSS-Datei referenzieren"
|
|
|
|
def test_html_references_js(self, customer_html):
|
|
"""Testet, dass das HTML die Customer JS-Datei referenziert."""
|
|
assert '/static/js/customer.js' in customer_html, \
|
|
"Customer HTML muss JS-Datei referenzieren"
|
|
|
|
def test_html_has_login_modal(self, customer_html):
|
|
"""Testet, dass das Login-Modal existiert."""
|
|
assert 'login-modal' in customer_html, \
|
|
"Customer HTML muss Login-Modal enthalten"
|
|
|
|
def test_html_has_consents_modal(self, customer_html):
|
|
"""Testet, dass das Consents-Modal existiert."""
|
|
assert 'consents-modal' in customer_html, \
|
|
"Customer HTML muss Consents-Modal enthalten"
|
|
|
|
def test_html_has_export_modal(self, customer_html):
|
|
"""Testet, dass das Export-Modal (GDPR) existiert."""
|
|
assert 'export-modal' in customer_html, \
|
|
"Customer HTML muss Export-Modal fuer GDPR enthalten"
|
|
|
|
def test_html_has_legal_modal(self, customer_html):
|
|
"""Testet, dass das Legal Documents Modal existiert."""
|
|
assert 'legal-modal' in customer_html, \
|
|
"Customer HTML muss Legal-Modal enthalten"
|
|
|
|
def test_html_has_theme_toggle(self, customer_html):
|
|
"""Testet, dass ein Theme-Toggle existiert."""
|
|
assert 'theme' in customer_html.lower(), \
|
|
"Customer HTML sollte Theme-Funktionalitaet haben"
|
|
|
|
|
|
class TestCustomerCSSTheme:
|
|
"""Tests fuer die Customer Portal CSS-Themes."""
|
|
|
|
@pytest.fixture
|
|
def customer_css(self):
|
|
"""Laedt den CSS-Inhalt."""
|
|
return CUSTOMER_CSS.read_text(encoding="utf-8")
|
|
|
|
def test_css_has_root_variables(self, customer_css):
|
|
"""Testet, dass CSS Custom Properties (Variablen) definiert sind."""
|
|
assert ':root' in customer_css, \
|
|
"Customer CSS sollte :root CSS-Variablen haben"
|
|
|
|
def test_css_has_dark_theme(self, customer_css):
|
|
"""Testet, dass ein Dark-Theme definiert ist."""
|
|
assert 'data-theme="dark"' in customer_css or '[data-theme="dark"]' in customer_css, \
|
|
"Customer CSS sollte Dark-Theme unterstuetzen"
|
|
|
|
def test_css_has_primary_color(self, customer_css):
|
|
"""Testet, dass eine Primary-Color Variable existiert."""
|
|
assert '--bp-primary' in customer_css or 'primary' in customer_css.lower(), \
|
|
"Customer CSS sollte Primary-Color definieren"
|
|
|
|
|
|
class TestCustomerJSFunctions:
|
|
"""Tests fuer die Customer Portal JavaScript-Funktionen."""
|
|
|
|
@pytest.fixture
|
|
def customer_js(self):
|
|
"""Laedt den JS-Inhalt."""
|
|
return CUSTOMER_JS.read_text(encoding="utf-8")
|
|
|
|
def test_js_has_consent_service_url(self, customer_js):
|
|
"""Testet, dass die Consent Service URL definiert ist."""
|
|
assert 'CONSENT_SERVICE_URL' in customer_js, \
|
|
"Customer JS muss CONSENT_SERVICE_URL definieren"
|
|
|
|
def test_js_has_login_function(self, customer_js):
|
|
"""Testet, dass eine Login-Funktion existiert."""
|
|
assert 'handleLogin' in customer_js or 'login' in customer_js.lower(), \
|
|
"Customer JS muss Login-Funktion haben"
|
|
|
|
def test_js_has_auth_check(self, customer_js):
|
|
"""Testet, dass ein Auth-Check existiert."""
|
|
assert 'checkAuth' in customer_js or 'auth' in customer_js.lower(), \
|
|
"Customer JS muss Auth-Check haben"
|
|
|
|
def test_js_has_theme_toggle(self, customer_js):
|
|
"""Testet, dass Theme-Toggle Funktion existiert."""
|
|
assert 'theme' in customer_js.lower(), \
|
|
"Customer JS sollte Theme-Funktionalitaet haben"
|
|
|
|
def test_js_has_consent_functions(self, customer_js):
|
|
"""Testet, dass Consent-Funktionen existieren."""
|
|
assert 'consent' in customer_js.lower(), \
|
|
"Customer JS muss Consent-Funktionen haben"
|
|
|
|
def test_js_has_export_function(self, customer_js):
|
|
"""Testet, dass eine Export-Funktion (GDPR) existiert."""
|
|
assert 'export' in customer_js.lower(), \
|
|
"Customer JS sollte Export-Funktion haben"
|
|
|
|
|
|
class TestCustomerRouter:
|
|
"""Tests fuer die Customer Portal Router-Registrierung."""
|
|
|
|
def test_customer_router_in_main_py(self):
|
|
"""Testet, dass customer_router in main.py importiert wird."""
|
|
main_py = Path(__file__).parent.parent / "main.py"
|
|
main_content = main_py.read_text(encoding="utf-8")
|
|
|
|
assert 'from frontend.customer import router as customer_router' in main_content, \
|
|
"main.py muss customer_router importieren"
|
|
|
|
def test_customer_router_included(self):
|
|
"""Testet, dass customer_router in main.py eingebunden wird."""
|
|
main_py = Path(__file__).parent.parent / "main.py"
|
|
main_content = main_py.read_text(encoding="utf-8")
|
|
|
|
assert 'app.include_router(customer_router)' in main_content, \
|
|
"main.py muss customer_router einbinden"
|
|
|
|
def test_customer_routes_defined(self):
|
|
"""Testet, dass die Customer-Routen korrekt definiert sind."""
|
|
from frontend.customer import router as customer_router
|
|
|
|
routes = [r.path for r in customer_router.routes]
|
|
assert '/customer' in routes, "Route /customer muss definiert sein"
|
|
assert '/account' in routes, "Route /account muss definiert sein"
|
|
assert '/mein-konto' in routes, "Route /mein-konto muss definiert sein"
|
|
|
|
|
|
class TestCustomerPortalResponsiveness:
|
|
"""Tests fuer die Customer Portal Responsiveness."""
|
|
|
|
@pytest.fixture
|
|
def customer_css(self):
|
|
"""Laedt den CSS-Inhalt."""
|
|
return CUSTOMER_CSS.read_text(encoding="utf-8")
|
|
|
|
def test_css_has_media_queries(self, customer_css):
|
|
"""Testet, dass Media Queries fuer Responsiveness vorhanden sind."""
|
|
assert '@media' in customer_css, \
|
|
"Customer CSS sollte Media Queries haben"
|
|
|
|
def test_css_has_mobile_breakpoint(self, customer_css):
|
|
"""Testet, dass ein Mobile-Breakpoint definiert ist."""
|
|
# Typische Mobile-Breakpoints: 768px, 640px, 480px
|
|
mobile_breakpoints = ['768px', '640px', '480px', '767px']
|
|
has_mobile = any(bp in customer_css for bp in mobile_breakpoints)
|
|
assert has_mobile, \
|
|
"Customer CSS sollte Mobile-Breakpoint haben"
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pytest.main([__file__, '-v'])
|