/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
tests/test_pydantic.py
296 строк
9 KB
User
0.4.18 - fix: устранение дублирования парсинга тела запроса (T-001)
07 июл 2026, 22:07
07 июл 2026, 22:07
3182883
Код
Авторство
О чём код?
""" Тесты Pydantic-интеграции для LiquidCode. """ import pytest # Пропустим тесты если Pydantic не установлен try: from pydantic import BaseModel HAS_PYDANTIC = True except ImportError: HAS_PYDANTIC = False @pytest.mark.skipif(not HAS_PYDANTIC, reason="Pydantic not installed") class TestPydanticSerialization: """Тесты сериализации Pydantic моделей.""" def test_serialize_single_model(self): """Сериализация одиночной модели.""" from liquidcode.pydantic import serialize_response class User(BaseModel): id: int name: str user = User(id=1, name="John") result = serialize_response(user) assert result == {"id": 1, "name": "John"} def test_serialize_list_of_models(self): """Сериализация списка моделей.""" from liquidcode.pydantic import serialize_response class User(BaseModel): id: int name: str users = [ User(id=1, name="John"), User(id=2, name="Jane"), ] result = serialize_response(users) assert result == [{"id": 1, "name": "John"}, {"id": 2, "name": "Jane"}] def test_serialize_dict_with_models(self): """Сериализация dict с Pydantic моделями.""" from liquidcode.pydantic import serialize_response class User(BaseModel): id: int name: str response_data = { "user": User(id=1, name="John"), "count": 1, } result = serialize_response(response_data) assert result == {"user": {"id": 1, "name": "John"}, "count": 1} def test_serialize_non_pydantic_return_unchanged(self): """Непydantic модели возвращаются без изменений.""" from liquidcode.pydantic import serialize_response assert serialize_response({"key": "value"}) == {"key": "value"} assert serialize_response([1, 2, 3]) == [1, 2, 3] assert serialize_response("string") == "string" assert serialize_response(None) is None @pytest.mark.skipif(not HAS_PYDANTIC, reason="Pydantic not installed") class TestPydanticDeserialization: """Тесты десериализации Pydantic моделей.""" def test_deserialize_single_model(self): """Десериализация одиночной модели.""" from liquidcode.pydantic import deserialize_body class User(BaseModel): id: int name: str body = b'{"id": 1, "name": "John"}' result = deserialize_body(body, User) assert isinstance(result, User) assert result.id == 1 assert result.name == "John" def test_deserialize_list_of_models(self): """Десериализация списка моделей.""" from liquidcode.pydantic import deserialize_body from typing import List class User(BaseModel): id: int name: str body = b'[{"id": 1, "name": "John"}, {"id": 2, "name": "Jane"}]' result = deserialize_body(body, List[User]) assert isinstance(result, list) assert len(result) == 2 assert isinstance(result[0], User) assert result[0].id == 1 assert result[1].id == 2 def test_deserialize_non_pydantic_returns_json(self): """Если тип не Pydantic модель, возвращается JSON.""" from liquidcode.pydantic import deserialize_body body = b'{"key": "value"}' result = deserialize_body(body, dict) assert result == {"key": "value"} def test_deserialize_empty_body_returns_none(self): """Пустое тело возвращает None.""" from liquidcode.pydantic import deserialize_body class User(BaseModel): id: int name: str assert deserialize_body(b'', User) is None assert deserialize_body(None, User) is None @pytest.mark.skipif(not HAS_PYDANTIC, reason="Pydantic not installed") class TestIsPydanticModel: """Тесты проверки является ли тип Pydantic моделью.""" def test_is_pydantic_model_single(self): """Проверка одиночной модели.""" from liquidcode.pydantic import is_pydantic_model class User(BaseModel): id: int name: str assert is_pydantic_model(User) is True assert is_pydantic_model(dict) is False assert is_pydantic_model(int) is False def test_is_pydantic_model_optional(self): """Проверка Optional[Model].""" from liquidcode.pydantic import is_pydantic_model from typing import Optional class User(BaseModel): id: int name: str assert is_pydantic_model(Optional[User]) is True def test_is_pydantic_model_list(self): """Проверка List[Model].""" from liquidcode.pydantic import is_pydantic_model from typing import List class User(BaseModel): id: int name: str assert is_pydantic_model(List[User]) is True def test_is_pydantic_model_non_model(self): """Проверка неней модели.""" from liquidcode.pydantic import is_pydantic_model from typing import List assert is_pydantic_model(List[int]) is False assert is_pydantic_model(dict) is False assert is_pydantic_model(None) is False @pytest.mark.skipif(not HAS_PYDANTIC, reason="Pydantic not installed") class TestNormalizeResponseWithPydantic: """Тесты normalize_response с Pydantic.""" def test_normalize_pydantic_model(self): """Нормализация Pydantic модели.""" from liquidcode.kernel.response_normalizer import normalize_response from liquidcode.http import HttpResponse class User(BaseModel): id: int name: str user = User(id=1, name="John") response = normalize_response(user, HttpResponse) assert response.get_status() == 200 assert response.get_content() == {"id": 1, "name": "John"} def test_normalize_tuple_with_pydantic(self): """Нормализация tuple с Pydantic моделью.""" from liquidcode.kernel.response_normalizer import normalize_response from liquidcode.http import HttpResponse class User(BaseModel): id: int name: str user = User(id=1, name="John") response = normalize_response((user, 201), HttpResponse) assert response.get_status() == 201 assert response.get_content() == {"id": 1, "name": "John"} @pytest.mark.skipif(not HAS_PYDANTIC, reason="Pydantic not installed") class TestArgumentResolverWithPydantic: """Тесты ArgumentResolver с Pydantic.""" def test_resolve_pydantic_model_from_body(self): """Разрешение Pydantic модели из тела запроса.""" from liquidcode.kernel.argument_resolver import ArgumentResolver from liquidcode.container import Container from liquidcode.http import HttpRequest class User(BaseModel): id: int name: str container = Container() resolver = ArgumentResolver(container) # Создаём запрос с JSON-телом body = b'{"id": 1, "name": "John"}' request = HttpRequest( path='/users', method='POST', body=body, ) # Имитируем работу BodyParserMiddleware import json parsed = json.loads(body.decode('utf-8')) request.set_attr('parsed_body', parsed) # Симулируем вызов resolve с аннотацией User def dummy_controller(data: User): pass kwargs = resolver.resolve( controller_method=dummy_controller, request=request, route_params={}, query_params={}, method='POST', ) assert 'data' in kwargs assert isinstance(kwargs['data'], User) assert kwargs['data'].id == 1 assert kwargs['data'].name == "John" def test_resolve_non_pydantic_dict_from_body(self): """Разрешение dict из тела запроса (без Pydantic).""" from liquidcode.kernel.argument_resolver import ArgumentResolver from liquidcode.container import Container from liquidcode.http import HttpRequest container = Container() resolver = ArgumentResolver(container) # Создаём запрос с JSON-телом body = b'{"key": "value"}' request = HttpRequest( path='/data', method='POST', body=body, ) # Имитируем работу BodyParserMiddleware import json parsed = json.loads(body.decode('utf-8')) request.set_attr('parsed_body', parsed) # Симулируем вызов resolve без аннотации def dummy_controller(data: dict): pass kwargs = resolver.resolve( controller_method=dummy_controller, request=request, route_params={}, query_params={}, method='POST', ) assert 'data' in kwargs assert kwargs['data'] == {"key": "value"}