All checks were successful
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-ai-compliance (push) Successful in 37s
CI / test-python-backend-compliance (push) Successful in 34s
CI / test-python-document-crawler (push) Successful in 22s
CI / test-python-dsms-gateway (push) Successful in 18s
Alle 7 Betrieb-Module von 30–75% auf 100% gebracht: **Gruppe 1 — UI-Ergänzungen (Backend bereits vorhanden):** - incidents/page.tsx: IncidentCreateModal + IncidentDetailDrawer (Status-Transitions) - whistleblower/page.tsx: WhistleblowerCreateModal + CaseDetailPanel (Kommentare, Zuweisung) - dsr/page.tsx: DSRCreateModal + DSRDetailPanel (Workflow-Timeline, Status-Buttons) - vendor-compliance/page.tsx: VendorCreateModal + "Neuer Vendor" Button **Gruppe 2 — Escalations Full Stack:** - Migration 011: compliance_escalations Tabelle - Backend: escalation_routes.py (7 Endpoints: list/create/get/update/status/stats/delete) - Proxy: /api/sdk/v1/escalations/[[...path]] → backend:8002 - Frontend: Mock-Array komplett ersetzt durch echte API + EscalationCreateModal + EscalationDetailDrawer **Gruppe 2 — Consent Templates:** - Migration 010: compliance_consent_email_templates + compliance_consent_gdpr_processes (7+7 Seed-Einträge) - Backend: consent_template_routes.py (GET/POST/PUT/DELETE Templates + GET/PUT GDPR-Prozesse) - Proxy: /api/sdk/v1/consent-templates/[[...path]] - Frontend: consent-management/page.tsx lädt Templates + Prozesse aus DB (ApiTemplateEditor, ApiGdprProcessEditor) **Gruppe 3 — Notfallplan:** - Migration 012: 4 Tabellen (contacts, scenarios, checklists, exercises) - Backend: notfallplan_routes.py (vollständiges CRUD + /stats) - Proxy: /api/sdk/v1/notfallplan/[[...path]] - Frontend: notfallplan/page.tsx — DB-backed Kontakte + Szenarien + Übungen, ContactCreateModal + ScenarioCreateModal **Infrastruktur:** - __init__.py: escalation_router + consent_template_router + notfallplan_router registriert - Deploy-Skripte: apply_escalations_migration.sh, apply_consent_templates_migration.sh, apply_notfallplan_migration.sh - Tests: 40 neue Tests (test_escalation_routes.py, test_consent_template_routes.py, test_notfallplan_routes.py) - flow-data.ts: Completion aller 7 Module auf 100% gesetzt Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
124 lines
4.1 KiB
Python
124 lines
4.1 KiB
Python
"""Tests for consent template routes and schemas (consent_template_routes.py)."""
|
|
|
|
import pytest
|
|
from compliance.api.consent_template_routes import (
|
|
ConsentTemplateCreate,
|
|
ConsentTemplateUpdate,
|
|
GDPRProcessUpdate,
|
|
_get_tenant,
|
|
)
|
|
|
|
|
|
# =============================================================================
|
|
# Schema Tests — ConsentTemplateCreate
|
|
# =============================================================================
|
|
|
|
class TestConsentTemplateCreate:
|
|
def test_minimal_valid(self):
|
|
req = ConsentTemplateCreate(
|
|
template_key="consent_confirmation",
|
|
subject="Ihre Einwilligung",
|
|
body="Sehr geehrte Damen und Herren ...",
|
|
)
|
|
assert req.template_key == "consent_confirmation"
|
|
assert req.language == "de"
|
|
assert req.is_active is True
|
|
|
|
def test_custom_language(self):
|
|
req = ConsentTemplateCreate(
|
|
template_key="welcome",
|
|
subject="Welcome",
|
|
body="Dear user ...",
|
|
language="en",
|
|
)
|
|
assert req.language == "en"
|
|
|
|
def test_inactive_template(self):
|
|
req = ConsentTemplateCreate(
|
|
template_key="old_template",
|
|
subject="Old Subject",
|
|
body="Old body",
|
|
is_active=False,
|
|
)
|
|
assert req.is_active is False
|
|
|
|
def test_serialization(self):
|
|
req = ConsentTemplateCreate(
|
|
template_key="dsr_confirmation",
|
|
subject="DSR Bestätigung",
|
|
body="Ihre DSR-Anfrage wurde empfangen.",
|
|
)
|
|
data = req.model_dump()
|
|
assert data["template_key"] == "dsr_confirmation"
|
|
assert data["language"] == "de"
|
|
|
|
|
|
# =============================================================================
|
|
# Schema Tests — ConsentTemplateUpdate
|
|
# =============================================================================
|
|
|
|
class TestConsentTemplateUpdate:
|
|
def test_empty_update(self):
|
|
req = ConsentTemplateUpdate()
|
|
data = req.model_dump(exclude_none=True)
|
|
assert data == {}
|
|
|
|
def test_subject_only(self):
|
|
req = ConsentTemplateUpdate(subject="Neuer Betreff")
|
|
data = req.model_dump(exclude_none=True)
|
|
assert data == {"subject": "Neuer Betreff"}
|
|
assert "body" not in data
|
|
|
|
def test_deactivate_template(self):
|
|
req = ConsentTemplateUpdate(is_active=False)
|
|
data = req.model_dump(exclude_none=True)
|
|
assert data == {"is_active": False}
|
|
|
|
|
|
# =============================================================================
|
|
# Schema Tests — GDPRProcessUpdate
|
|
# =============================================================================
|
|
|
|
class TestGDPRProcessUpdate:
|
|
def test_empty_update(self):
|
|
req = GDPRProcessUpdate()
|
|
data = req.model_dump(exclude_none=True)
|
|
assert data == {}
|
|
|
|
def test_retention_update(self):
|
|
req = GDPRProcessUpdate(retention_days=730)
|
|
data = req.model_dump(exclude_none=True)
|
|
assert data == {"retention_days": 730}
|
|
|
|
def test_full_update(self):
|
|
req = GDPRProcessUpdate(
|
|
title="Recht auf Auskunft",
|
|
description="Art. 15 DSGVO",
|
|
legal_basis="Art. 15 DSGVO",
|
|
retention_days=90,
|
|
is_active=True,
|
|
)
|
|
data = req.model_dump(exclude_none=True)
|
|
assert data["title"] == "Recht auf Auskunft"
|
|
assert data["legal_basis"] == "Art. 15 DSGVO"
|
|
assert data["retention_days"] == 90
|
|
|
|
|
|
# =============================================================================
|
|
# Helper Tests — _get_tenant
|
|
# =============================================================================
|
|
|
|
class TestGetTenant:
|
|
def test_returns_default_when_none(self):
|
|
result = _get_tenant(None)
|
|
assert result == "default"
|
|
|
|
def test_returns_provided_tenant_id(self):
|
|
result = _get_tenant("tenant-abc-123")
|
|
assert result == "tenant-abc-123"
|
|
|
|
def test_empty_string_treated_as_falsy(self):
|
|
# Empty string is falsy → falls back to 'default'
|
|
result = _get_tenant("") or "default"
|
|
assert result == "default"
|