Добавлен адаптер к tbank и формирование ссылки на оплату
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import asyncio
|
||||
|
||||
import pytest
|
||||
|
||||
from app.adapters.tbank.base import (
|
||||
TBankPaymentAdapterError,
|
||||
TBankPaymentRequestError,
|
||||
)
|
||||
from app.schemas.payment import InitPaymentRequest, InitPaymentResponse
|
||||
from app.services.aggregator import (
|
||||
AggregatorService,
|
||||
InitPaymentUnavailableError,
|
||||
InvalidInitPaymentRequestError,
|
||||
)
|
||||
|
||||
|
||||
class StubPaymentAdapter:
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
response: str | None = None,
|
||||
error: Exception | None = None,
|
||||
) -> None:
|
||||
self._response = response
|
||||
self._error = error
|
||||
self.calls: list[tuple[str, int]] = []
|
||||
|
||||
async def create_payment_link(self, order_uuid: str, amount_kopecks: int) -> str:
|
||||
self.calls.append((order_uuid, amount_kopecks))
|
||||
if self._error is not None:
|
||||
raise self._error
|
||||
if self._response is None:
|
||||
raise RuntimeError("Stub payment adapter has no response configured.")
|
||||
return self._response
|
||||
|
||||
|
||||
def _make_init_payment_request(**overrides: object) -> InitPaymentRequest:
|
||||
payload: dict[str, object] = {
|
||||
"order_uuid": "order-uuid-1",
|
||||
"price": 125000,
|
||||
"type": 2,
|
||||
"tariff_code": 535,
|
||||
"comment": "Test payment",
|
||||
"sender": {
|
||||
"name": "Petr Petrov",
|
||||
"email": "sender@example.com",
|
||||
"phone": {"number": "+79009876543"},
|
||||
},
|
||||
"recipient": {
|
||||
"name": "Ivan Ivanov",
|
||||
"email": "ivan@example.com",
|
||||
"phone": {"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": 1,
|
||||
"length": 20,
|
||||
"width": 15,
|
||||
"height": 10,
|
||||
"comment": "Package 1",
|
||||
}
|
||||
],
|
||||
}
|
||||
payload.update(overrides)
|
||||
return InitPaymentRequest(**payload)
|
||||
|
||||
|
||||
def test_init_payment_delegates_to_adapter_and_returns_payment_url() -> None:
|
||||
request = _make_init_payment_request()
|
||||
adapter = StubPaymentAdapter(response="https://pay.test/payment/1")
|
||||
service = AggregatorService(providers=[], payment_adapter=adapter)
|
||||
|
||||
result = asyncio.run(service.init_payment(request))
|
||||
|
||||
assert result == InitPaymentResponse(payment_url="https://pay.test/payment/1")
|
||||
assert adapter.calls == [("order-uuid-1", 125000)]
|
||||
|
||||
|
||||
def test_init_payment_maps_provider_request_errors_to_invalid_payment_error() -> None:
|
||||
request = _make_init_payment_request()
|
||||
adapter = StubPaymentAdapter(error=TBankPaymentRequestError("bad payload"))
|
||||
service = AggregatorService(providers=[], payment_adapter=adapter)
|
||||
|
||||
with pytest.raises(InvalidInitPaymentRequestError):
|
||||
asyncio.run(service.init_payment(request))
|
||||
|
||||
assert adapter.calls == [("order-uuid-1", 125000)]
|
||||
|
||||
|
||||
def test_init_payment_delegates_request_with_services_none_without_new_logic() -> None:
|
||||
request = _make_init_payment_request(services=None)
|
||||
adapter = StubPaymentAdapter(response="https://pay.test/payment/2")
|
||||
service = AggregatorService(providers=[], payment_adapter=adapter)
|
||||
|
||||
result = asyncio.run(service.init_payment(request))
|
||||
|
||||
assert result == InitPaymentResponse(payment_url="https://pay.test/payment/2")
|
||||
assert adapter.calls == [("order-uuid-1", 125000)]
|
||||
assert request.services is None
|
||||
|
||||
|
||||
def test_init_payment_maps_client_failures_to_unavailable_error() -> None:
|
||||
request = _make_init_payment_request()
|
||||
adapter = StubPaymentAdapter(error=TBankPaymentAdapterError("transport down"))
|
||||
service = AggregatorService(providers=[], payment_adapter=adapter)
|
||||
|
||||
with pytest.raises(InitPaymentUnavailableError):
|
||||
asyncio.run(service.init_payment(request))
|
||||
|
||||
assert adapter.calls == [("order-uuid-1", 125000)]
|
||||
|
||||
|
||||
def test_init_payment_without_configured_adapter_raises_unavailable_error() -> None:
|
||||
service = AggregatorService(providers=[])
|
||||
|
||||
with pytest.raises(InitPaymentUnavailableError):
|
||||
asyncio.run(service.init_payment(_make_init_payment_request()))
|
||||
Reference in New Issue
Block a user