/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
tests/unit/kernel/test_argument_resolver.py
406 строк
13 KB
User
0.4.18 - fix: устранение дублирования парсинга тела запроса (T-001)
07 июл 2026, 22:07
07 июл 2026, 22:07
3182883
Код
Авторство
О чём код?
"""Unit-тесты для ArgumentResolver.""" import pytest from liquidcode.container import Container from liquidcode.kernel.argument_resolver import ArgumentResolver from liquidcode.contracts import Request class MockRequest: """Мок для Request.""" def __init__(self, path="/test", method="GET", headers=None, body=b"", query_params=None, route_params=None): self._path = path self._method = method self._headers = headers or {} self._body = body self._query_params = query_params or {} self._route_params = route_params or {} self._attributes = {} def get_path(self): return self._path def get_method(self): return self._method def get_headers(self): return self._headers def get_body(self): return self._body def get_query_params(self): return self._query_params def get_route_params(self): return self._route_params def set_route_params(self, params): self._route_params = params def get_attr(self, key): return self._attributes.get(key) def set_attr(self, key, value): self._attributes[key] = value class TestArgumentResolver: """Тесты ArgumentResolver.""" def test_resolver_creation(self): """Создание ArgumentResolver.""" container = Container() resolver = ArgumentResolver(container) assert resolver.container == container def test_resolve_route_params(self): """Разрешение параметров маршрута.""" container = Container() resolver = ArgumentResolver(container) def controller(id: int, name: str): return {"id": id, "name": name} route_params = {"id": "123", "name": "test"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["id"] == 123 assert result["name"] == "test" def test_resolve_query_params(self): """Разрешение query параметров.""" container = Container() resolver = ArgumentResolver(container) def controller(page: int, limit: int = 10): return {"page": page, "limit": limit} query_params = {"page": "2", "limit": "20"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, {}, query_params, "GET") assert result["page"] == 2 assert result["limit"] == 20 def test_resolve_with_request_object(self): """Разрешение с Request объектом.""" container = Container() resolver = ArgumentResolver(container) request = MockRequest() def controller(request: Request): return request result = resolver.resolve(controller, request, {}, {}, "GET") assert result["request"] == request def test_resolve_with_service(self): """Разреше��ие сервиса из контейнера.""" container = Container() class Service: def __init__(self): self.name = "test_service" container.set(Service, Service()) resolver = ArgumentResolver(container) def controller(service: Service): return service request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, {}, {}, "GET") assert result["service"].name == "test_service" def test_resolve_with_default_values(self): """Разрешение с значениями по умолчанию.""" container = Container() resolver = ArgumentResolver(container) def controller(id: int = 0, name: str = "default"): return {"id": id, "name": name} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, {}, {}, "GET") assert result["id"] == 0 assert result["name"] == "default" def test_resolve_with_body_data(self): """Разрешение с данными из тела запроса.""" container = Container() resolver = ArgumentResolver(container) def controller(data: dict): return data body = b'{"key": "value"}' request = MockRequest() # Имитируем работу BodyParserMiddleware import json parsed = json.loads(body.decode('utf-8')) request.set_attr('parsed_body', parsed) result = resolver.resolve(controller, request, {}, {}, "POST") assert result["data"]["key"] == "value" def test_resolve_with_body_data_not_post(self): """Разрешение data не для POST запроса.""" container = Container() resolver = ArgumentResolver(container) def controller(data: dict = None): return data body = b'{"key": "value"}' request = MockRequest() # Для не-POST методов parsed_body должен быть None request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, {}, {}, "GET") assert result["data"] is None def test_resolve_with_json_decode_error(self): """Разрешение с ошибкой JSON.""" container = Container() resolver = ArgumentResolver(container) def controller(data: dict = None): return data body = b'invalid json' request = MockRequest() # При ошибке парсинга parsed_body будет None (как в BodyParserMiddleware) request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, {}, {}, "POST") assert result["data"] is None def test_resolve_with_int_conversion(self): """Преобразование типа int.""" container = Container() resolver = ArgumentResolver(container) def controller(count: int): return count route_params = {"count": "42"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["count"] == 42 assert isinstance(result["count"], int) def test_resolve_with_float_conversion(self): """Преобразование типа float.""" container = Container() resolver = ArgumentResolver(container) def controller(ratio: float): return ratio route_params = {"ratio": "3.14"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["ratio"] == 3.14 assert isinstance(result["ratio"], float) def test_resolve_with_bool_conversion(self): """Преобразование типа bool.""" container = Container() resolver = ArgumentResolver(container) def controller(active: bool): return active route_params = {"active": "true"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["active"] is True def test_resolve_with_bool_false(self): """Преобразование bool с false.""" container = Container() resolver = ArgumentResolver(container) def controller(active: bool): return active route_params = {"active": "false"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["active"] is False def test_resolve_with_bool_1(self): """Преобразование bool с 1.""" container = Container() resolver = ArgumentResolver(container) def controller(active: bool): return active route_params = {"active": "1"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["active"] is True def test_resolve_with_bool_yes(self): """Преобразование bool с yes.""" container = Container() resolver = ArgumentResolver(container) def controller(active: bool): return active route_params = {"active": "yes"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["active"] is True def test_resolve_without_annotation(self): """Разрешение без аннотации типа.""" container = Container() resolver = ArgumentResolver(container) def controller(id): return id route_params = {"id": "123"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["id"] == "123" def test_resolve_with_empty_annotation(self): """Разрешение с пустой аннотацией.""" container = Container() resolver = ArgumentResolver(container) def controller(param: None): return param route_params = {"param": "value"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["param"] == "value" def test_resolve_with_none_annotation(self): """Разрешение с None аннотацией.""" container = Container() resolver = ArgumentResolver(container) def controller(param=None): return param route_params = {} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["param"] is None def test_resolve_with_str_annotation(self): """Разрешение с str аннотацией.""" container = Container() resolver = ArgumentResolver(container) def controller(name: str): return name route_params = {"name": "test"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["name"] == "test" def test_resolve_priority_route_over_query(self): """Приоритет параметров маршрута над query.""" container = Container() resolver = ArgumentResolver(container) def controller(id: int): return id route_params = {"id": "1"} query_params = {"id": "2"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, query_params, "GET") assert result["id"] == 1 def test_resolve_with_route_and_query_params(self): """Разрешение с маршрутными и query параметрами.""" container = Container() resolver = ArgumentResolver(container) def controller(id: int, page: int = 1): return {"id": id, "page": page} route_params = {"id": "123"} query_params = {"page": "3"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, query_params, "GET") assert result["id"] == 123 assert result["page"] == 3 def test_resolve_with_service_not_found(self): """Разрешение несуществующего сервиса. Сервис не зарегистрирован, но может быть построен через autowiring. Контейнер создаст экземпляр автоматически. """ container = Container() resolver = ArgumentResolver(container) class NonexistentService: pass def controller(service: NonexistentService = None): return service request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, {}, {}, "GET") # Контейнер создает экземпляр через autowiring (без зависимостей) assert isinstance(result["service"], NonexistentService) def test_resolve_preserves_string_value(self): """Сохранение строкового значения без преобразования.""" container = Container() resolver = ArgumentResolver(container) def controller(name: str): return name route_params = {"name": "test123"} request = MockRequest() request.set_attr('parsed_body', None) result = resolver.resolve(controller, request, route_params, {}, "GET") assert result["name"] == "test123"