diff --git a/api/src/domain/schemas.py b/api/src/domain/schemas.py index c7ef75c..5f08df6 100644 --- a/api/src/domain/schemas.py +++ b/api/src/domain/schemas.py @@ -143,7 +143,23 @@ class UserUpdate(BaseModel): load_orgs: bool = Field(default=False) -class UserInDB(UserBase): +class UserReadBase(BaseModel): + """Выходная база пользователя без входных ограничений. + + Запись в БД может не проходить входную валидацию (email на .local, + короткий username, '<' в full_name), но чтение не должно из-за этого + отвечать 500. Входные схемы (UserBase/UserCreate/UserUpdate) не меняются. + """ + + email: str + username: str + full_name: Optional[str] = None + role_id: int = 3 + + model_config = ConfigDict(from_attributes=True) + + +class UserInDB(UserReadBase): model_config = ConfigDict(from_attributes=True) id: int diff --git a/api/tests/unit/test_user_schemas.py b/api/tests/unit/test_user_schemas.py new file mode 100644 index 0000000..d989a49 --- /dev/null +++ b/api/tests/unit/test_user_schemas.py @@ -0,0 +1,63 @@ +from datetime import datetime +from types import SimpleNamespace + +import pytest +from fastapi import FastAPI +from fastapi.testclient import TestClient +from pydantic import ValidationError + +from src.api.v1.deps import get_current_active_user +from src.api.v1.users import router as users_router +from src.db.session import get_db +from src.domain.schemas import UserAdminListResponse, UserCreate, UserInDB + +_VALID = dict( + id=1, + email="admin@corp.example", + username="admin_1", + full_name="Иван Иванов", + role_id=1, + is_active=True, + created_at=datetime(2026, 1, 1), + updated_at=None, + org_units=[], +) + +# Записи, которые API на входе не пропустил бы, но которые могут лежать в БД +# (прямой INSERT, например perf-стенд): вывод не должен из-за них падать. +_LEGACY = [ + {"email": "admin@corp.local"}, + {"username": "rf"}, + {"full_name": "a