"""User/member DTO validation (no DB).""" from __future__ import annotations from uuid import uuid4 import pytest from pydantic import ValidationError from mimic.db.types import UserType from mimic.schemas import EngagementMemberCreate, UserCreate, UserUpdate from mimic.schemas.pagination import MAX_PAGE_SIZE, PageQuery class TestUserCreate: def test_minimal_valid_payload(self) -> None: u = UserCreate.model_validate( { "email": "alice@example.org", "password": "longenough", "type": "rt_operator", } ) assert u.email == "alice@example.org" assert u.type is UserType.RT_OPERATOR assert u.display_name is None def test_password_min_length(self) -> None: with pytest.raises(ValidationError): UserCreate.model_validate( {"email": "a@b.c", "password": "short", "type": "rt_operator"} ) def test_invalid_email_rejected(self) -> None: with pytest.raises(ValidationError): UserCreate.model_validate( {"email": "not-an-email", "password": "longenough", "type": "rt_operator"} ) def test_invalid_type_rejected(self) -> None: with pytest.raises(ValidationError): UserCreate.model_validate( {"email": "a@b.c", "password": "longenough", "type": "not-a-role"} ) class TestUserUpdate: def test_all_optional(self) -> None: u = UserUpdate.model_validate({}) assert u.display_name is None assert u.password is None assert u.type is None def test_password_validates_when_provided(self) -> None: with pytest.raises(ValidationError): UserUpdate.model_validate({"password": "tiny"}) class TestEngagementMemberCreate: def test_default_role(self) -> None: member = EngagementMemberCreate.model_validate({"user_id": str(uuid4())}) assert member.role == "member" def test_explicit_role(self) -> None: member = EngagementMemberCreate.model_validate( {"user_id": str(uuid4()), "role": "lead-on-mission"} ) assert member.role == "lead-on-mission" def test_role_max_length(self) -> None: with pytest.raises(ValidationError): EngagementMemberCreate.model_validate({"user_id": str(uuid4()), "role": "x" * 41}) class TestPageQuery: def test_defaults(self) -> None: page = PageQuery.model_validate({}) assert page.page == 1 assert page.page_size == 50 assert page.offset == 0 assert page.limit == 50 def test_offset_arithmetic(self) -> None: page = PageQuery.model_validate({"page": 4, "page_size": 25}) assert page.offset == 75 assert page.limit == 25 def test_page_size_clamped(self) -> None: with pytest.raises(ValidationError): PageQuery.model_validate({"page_size": MAX_PAGE_SIZE + 1}) def test_page_lower_bound(self) -> None: with pytest.raises(ValidationError): PageQuery.model_validate({"page": 0})