"""Tests fuer src/models.py - Pydantic-Validierung.""" import pytest from pydantic import ValidationError from models import ( MagicLinkRequest, MagicLinkResponse, VerifyTokenRequest, TokenResponse, OrgCreate, LicenseCreate, LicenseParams, LicenseResponse, UserCreate, ) def test_magic_link_request_accepts_email(): r = MagicLinkRequest(email="info@aegis-sight.de") assert r.email == "info@aegis-sight.de" def test_magic_link_request_rejects_too_short(): with pytest.raises(ValidationError): MagicLinkRequest(email="a") def test_verify_token_min_length(): with pytest.raises(ValidationError): VerifyTokenRequest(token="abc") def test_token_response_default_email_empty(): r = TokenResponse(access_token="x" * 40, username="info") assert r.email == "" assert r.token_type == "bearer" def test_org_create_slug_pattern(): """Slug muss lowercase mit Bindestrichen sein.""" OrgCreate(name="Test", slug="abc-123") with pytest.raises(ValidationError): OrgCreate(name="Test", slug="Wrong Case") with pytest.raises(ValidationError): OrgCreate(name="Test", slug="under_score") def test_license_create_type_pattern(): LicenseCreate(organization_id=1, license_type="trial") LicenseCreate(organization_id=1, license_type="annual") LicenseCreate(organization_id=1, license_type="permanent") with pytest.raises(ValidationError): LicenseCreate(organization_id=1, license_type="lifetime") def test_license_params_credits_defaults(): """Monatskontingent OHNE Übertrag ist die Voreinstellung.""" p = LicenseParams(license_type="trial") assert p.credits_period == "monthly" assert p.credits_rollover is False assert p.budget_warning_percent == 80 def test_license_params_period_pattern(): LicenseParams(license_type="trial", credits_period="monthly") LicenseParams(license_type="trial", credits_period="total") with pytest.raises(ValidationError): LicenseParams(license_type="trial", credits_period="weekly") def test_license_create_inherits_credits_fields(): lic = LicenseCreate( organization_id=1, license_type="annual", credits_total=10000, credits_period="monthly", credits_rollover=False, ) assert lic.credits_total == 10000 assert lic.credits_rollover is False def test_org_create_without_license_still_valid(): """Rückwärtskompatibilität, das Lizenz-Objekt ist optional.""" org = OrgCreate(name="Test", slug="test") assert org.license is None def test_org_create_with_nested_license(): org = OrgCreate( name="Test", slug="test", license={"license_type": "trial", "credits_total": 10000}, ) assert org.license.credits_total == 10000 assert org.license.credits_period == "monthly" with pytest.raises(ValidationError): OrgCreate(name="Test", slug="test", license={"license_type": "trial", "credits_period": "weekly"}) def test_license_response_without_new_columns(): """Responses müssen auch von einer noch nicht migrierten DB validieren.""" r = LicenseResponse( id=1, organization_id=1, license_type="trial", max_users=5, valid_from="2026-07-25", valid_until=None, status="active", notes=None, created_at="2026-07-25", ) assert r.credits_period == "monthly" assert r.credits_carried == 0 def test_user_create_role_pattern(): UserCreate(email="a@b.de", role="member") UserCreate(email="a@b.de", role="org_admin") with pytest.raises(ValidationError): UserCreate(email="a@b.de", role="superuser")