017 add creating order router

This commit is contained in:
Раис Юсупалиев
2026-03-14 04:12:59 +03:00
parent 15a17be4ed
commit 2b68d050a9
7 changed files with 364 additions and 12 deletions
+115
View File
@@ -0,0 +1,115 @@
import asyncio
import pytest
from app.adapters.delivery_providers.base import ProviderRequestError
from app.schemas.order import OrderCreateRequest, OrderCreateResponse
from app.services.aggregator import (
AggregatorService,
InvalidOrderCreateRequestError,
OrderCreationUnavailableError,
)
class StubOrderAdapter:
def __init__(
self,
*,
response: OrderCreateResponse | None = None,
error: Exception | None = None,
) -> None:
self._response = response
self._error = error
self.calls: list[OrderCreateRequest] = []
async def register_order(self, request: OrderCreateRequest) -> OrderCreateResponse:
self.calls.append(request)
if self._error is not None:
raise self._error
if self._response is None:
raise RuntimeError("Stub order adapter has no response configured.")
return self._response
def _make_order_request(**overrides: object) -> OrderCreateRequest:
payload: dict[str, object] = {
"type": 2,
"tariff_code": 535,
"comment": "Test order",
"sender": {
"company": "Romashka LLC",
"name": "Petr Petrov",
"email": "sender@example.com",
"phones": [{"number": "+79009876543"}],
},
"recipient": {
"name": "Ivan Ivanov",
"email": "ivan@example.com",
"phones": [{"number": "+79001234567"}],
},
"from_location": {
"address": "Lenina 1",
"city": "Moscow",
"country_code": "RU",
},
"to_location": {
"address": "Pushkina 10",
"city": "Novosibirsk",
"country_code": "RU",
},
"services": [{"code": "INSURANCE", "parameter": "1000"}],
"packages": [
{
"number": "1",
"weight": 1000,
"length": 20,
"width": 15,
"height": 10,
"comment": "Package 1",
}
],
}
payload.update(overrides)
return OrderCreateRequest(**payload)
def test_create_order_delegates_to_adapter_and_returns_created_order() -> None:
request = _make_order_request()
adapter = StubOrderAdapter(
response=OrderCreateResponse(provider="cdek", order_uuid="order-uuid-1")
)
service = AggregatorService(providers=[], order_adapter=adapter)
result = asyncio.run(service.create_order(request))
assert result == OrderCreateResponse(provider="cdek", order_uuid="order-uuid-1")
assert adapter.calls == [request]
def test_create_order_maps_provider_request_errors_to_invalid_order_error() -> None:
request = _make_order_request()
adapter = StubOrderAdapter(error=ProviderRequestError("bad payload"))
service = AggregatorService(providers=[], order_adapter=adapter)
with pytest.raises(InvalidOrderCreateRequestError):
asyncio.run(service.create_order(request))
assert adapter.calls == [request]
def test_create_order_maps_transport_failures_to_unavailable_error() -> None:
request = _make_order_request()
adapter = StubOrderAdapter(error=RuntimeError("transport down"))
service = AggregatorService(providers=[], order_adapter=adapter)
with pytest.raises(OrderCreationUnavailableError):
asyncio.run(service.create_order(request))
assert adapter.calls == [request]
def test_create_order_without_configured_adapter_raises_unavailable_error() -> None:
service = AggregatorService(providers=[])
with pytest.raises(OrderCreationUnavailableError):
asyncio.run(service.create_order(_make_order_request()))