179 lines
6.0 KiB
Python
179 lines
6.0 KiB
Python
"""Unit tests for domain model validation."""
|
|
|
|
from typing import cast
|
|
|
|
import pytest
|
|
|
|
|
|
class TestPersonaModelValidation:
|
|
"""Test DemoPersona model validation and enum coercion."""
|
|
|
|
def test_persona_with_valid_role_enum(self) -> None:
|
|
"""Test creating persona with PersonaRole enum."""
|
|
from guide.app.models.personas.models import (
|
|
DemoPersona,
|
|
PersonaRole,
|
|
LoginMethod,
|
|
)
|
|
|
|
persona = DemoPersona(
|
|
id="user1",
|
|
role=PersonaRole.BUYER,
|
|
email="buyer@example.com",
|
|
login_method=LoginMethod.MFA_EMAIL,
|
|
browser_host_id="demo-headless",
|
|
)
|
|
assert persona.role == PersonaRole.BUYER
|
|
assert persona.id == "user1"
|
|
|
|
def test_persona_with_string_role_coercion(self) -> None:
|
|
"""Test that string role is coerced to PersonaRole enum."""
|
|
from guide.app.models.personas.models import (
|
|
DemoPersona,
|
|
PersonaRole,
|
|
LoginMethod,
|
|
)
|
|
|
|
persona = DemoPersona(
|
|
id="user1",
|
|
role=cast(PersonaRole, cast(object, "buyer")),
|
|
email="buyer@example.com",
|
|
login_method=cast(LoginMethod, cast(object, "mfa_email")),
|
|
browser_host_id="demo-headless",
|
|
)
|
|
assert persona.role == PersonaRole.BUYER
|
|
assert persona.login_method == LoginMethod.MFA_EMAIL
|
|
|
|
def test_persona_invalid_role_raises_validation_error(self) -> None:
|
|
"""Test that invalid role raises ValidationError."""
|
|
from pydantic import ValidationError
|
|
from guide.app.models.personas.models import (
|
|
DemoPersona,
|
|
PersonaRole,
|
|
LoginMethod,
|
|
)
|
|
|
|
with pytest.raises(ValidationError):
|
|
_ = DemoPersona(
|
|
id="user1",
|
|
role=cast(PersonaRole, cast(object, "invalid_role")),
|
|
email="buyer@example.com",
|
|
login_method=LoginMethod.MFA_EMAIL,
|
|
browser_host_id="demo-headless",
|
|
)
|
|
|
|
def test_persona_invalid_login_method_raises_validation_error(self) -> None:
|
|
"""Test that invalid login_method raises ValidationError."""
|
|
from pydantic import ValidationError
|
|
from guide.app.models.personas.models import (
|
|
DemoPersona,
|
|
PersonaRole,
|
|
LoginMethod,
|
|
)
|
|
|
|
with pytest.raises(ValidationError):
|
|
_ = DemoPersona(
|
|
id="user1",
|
|
role=PersonaRole.BUYER,
|
|
email="buyer@example.com",
|
|
login_method=cast(LoginMethod, cast(object, "invalid_method")),
|
|
browser_host_id="demo-headless",
|
|
)
|
|
|
|
@pytest.mark.parametrize(
|
|
"role_input,expected_role",
|
|
[
|
|
("buyer", "buyer"),
|
|
("supplier", "supplier"),
|
|
("approver", "approver"),
|
|
],
|
|
)
|
|
def test_persona_role_coercion_all_variants(
|
|
self, role_input: str, expected_role: str
|
|
) -> None:
|
|
"""Test role coercion for all valid variants."""
|
|
from guide.app.models.personas.models import (
|
|
DemoPersona,
|
|
PersonaRole,
|
|
LoginMethod,
|
|
)
|
|
|
|
persona = DemoPersona(
|
|
id="user1",
|
|
role=cast(PersonaRole, cast(object, role_input)),
|
|
email="test@example.com",
|
|
login_method=LoginMethod.MFA_EMAIL,
|
|
browser_host_id="demo-headless",
|
|
)
|
|
assert persona.role.value == expected_role
|
|
|
|
|
|
class TestBrowserHostConfigValidation:
|
|
"""Test BrowserHostConfig model validation."""
|
|
|
|
def test_headless_host_config(self) -> None:
|
|
"""Test creating headless browser host configuration."""
|
|
from guide.app.core.config import BrowserHostConfig, HostKind
|
|
|
|
config = BrowserHostConfig(
|
|
id="headless-1",
|
|
kind=HostKind.HEADLESS,
|
|
browser="chromium",
|
|
)
|
|
assert config.id == "headless-1"
|
|
assert config.kind == HostKind.HEADLESS
|
|
assert config.browser == "chromium"
|
|
assert config.host is None
|
|
assert config.port is None
|
|
|
|
def test_cdp_host_config(self) -> None:
|
|
"""Test creating CDP browser host configuration."""
|
|
from guide.app.core.config import BrowserHostConfig, HostKind
|
|
|
|
config = BrowserHostConfig(
|
|
id="cdp-1",
|
|
kind=HostKind.CDP,
|
|
host="localhost",
|
|
port=9222,
|
|
)
|
|
assert config.id == "cdp-1"
|
|
assert config.kind == HostKind.CDP
|
|
assert config.host == "localhost"
|
|
assert config.port == 9222
|
|
|
|
def test_host_kind_string_coercion(self) -> None:
|
|
"""Test that HostKind accepts string values."""
|
|
from guide.app.core.config import BrowserHostConfig, HostKind
|
|
|
|
config = BrowserHostConfig(
|
|
id="test",
|
|
kind=cast(HostKind, cast(object, "headless")),
|
|
)
|
|
assert config.kind == HostKind.HEADLESS
|
|
|
|
def test_invalid_host_kind_raises_validation_error(self) -> None:
|
|
"""Test that invalid host kind raises ValidationError."""
|
|
from pydantic import ValidationError
|
|
from guide.app.core.config import BrowserHostConfig, HostKind
|
|
|
|
with pytest.raises(ValidationError):
|
|
_ = BrowserHostConfig(
|
|
id="test",
|
|
kind=cast(HostKind, cast(object, "invalid_kind")),
|
|
)
|
|
|
|
|
|
class TestAppSettingsDefaults:
|
|
"""Test AppSettings model defaults (avoiding circular imports)."""
|
|
|
|
def test_app_settings_has_defaults(self) -> None:
|
|
"""Test AppSettings applies defaults correctly."""
|
|
from guide.app.core.config import AppSettings
|
|
|
|
settings = AppSettings()
|
|
assert settings.raindrop_base_url == "https://app.raindrop.com"
|
|
assert settings.raindrop_graphql_url == "https://app.raindrop.com/graphql"
|
|
assert settings.default_browser_host_id == "demo-cdp"
|
|
assert isinstance(settings.browser_hosts, dict)
|
|
assert isinstance(settings.personas, dict)
|