Добавлена валидация цены

This commit is contained in:
Раис Юсупалиев
2026-05-13 16:35:22 +03:00
parent 6b66af5eb3
commit 39cd5ddc7a
24 changed files with 1021 additions and 56 deletions
+5 -3
View File
@@ -183,6 +183,7 @@ def test_post_delivery_price_uses_registered_provider_in_default_dependency(
"currency": "RUB",
"delivery_days_min": 2,
"delivery_days_max": 3,
"tariff_code": None,
},
{
"provider": "stub-provider",
@@ -191,6 +192,7 @@ def test_post_delivery_price_uses_registered_provider_in_default_dependency(
"currency": "RUB",
"delivery_days_min": 4,
"delivery_days_max": 5,
"tariff_code": None,
}
]
assert second_response.json() == first_response.json()
@@ -308,9 +310,9 @@ def test_post_delivery_price_filters_response_by_optional_parcel_type(
) -> None:
provider = StubPriceProvider(
response=[
_make_price(service_name="Parcel locker", price="90.00"),
_make_price(service_name="Срочный документ", price="150.00"),
_make_price(service_name="DOCUMENT EXPRESS", price="200.00"),
_make_price(service_name="Parcel locker", price="90.00", provider="other"),
_make_price(service_name="Срочный документ", price="150.00", provider="other"),
_make_price(service_name="DOCUMENT EXPRESS", price="200.00", provider="other"),
]
)
service = AggregatorService(providers=[provider])
+75 -13
View File
@@ -85,7 +85,7 @@ def test_post_init_payment_returns_response_and_delegates_to_service() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=_valid_payload(),
)
@@ -101,7 +101,7 @@ def test_post_init_payment_rejects_invalid_payload() -> None:
app = create_app()
_install_service_override(app, service)
invalid_payload = _valid_payload()
invalid_payload["tariff_code"] = 136
invalid_payload["tariff_code"] = "not-a-number"
async def run_request() -> httpx.Response:
transport = httpx.ASGITransport(app=app)
@@ -110,7 +110,7 @@ def test_post_init_payment_rejects_invalid_payload() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -134,7 +134,7 @@ def test_post_init_payment_rejects_missing_price() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -158,7 +158,7 @@ def test_post_init_payment_rejects_non_positive_price() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -182,7 +182,7 @@ def test_post_init_payment_rejects_non_integer_price() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -209,7 +209,7 @@ def test_post_init_payment_rejects_sender_company_field() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -236,7 +236,7 @@ def test_post_init_payment_rejects_sender_phones_field() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -263,7 +263,7 @@ def test_post_init_payment_rejects_recipient_company_field() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -290,7 +290,7 @@ def test_post_init_payment_rejects_recipient_phones_field() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=invalid_payload,
)
@@ -314,7 +314,7 @@ def test_post_init_payment_accepts_request_without_services() -> None:
transport=transport,
base_url="http://testserver",
) as client:
return await client.post("/api/v1/delivery/init-payment", json=payload)
return await client.post("/api/v1/delivery/order", json=payload)
response = asyncio.run(run_request())
@@ -338,7 +338,7 @@ def test_post_init_payment_maps_invalid_request_to_400() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=_valid_payload(),
)
@@ -353,6 +353,37 @@ def test_post_init_payment_maps_invalid_request_to_400() -> None:
}
def test_post_init_payment_maps_price_mismatch_to_400() -> None:
service = StubAggregatorService(
response=None,
error=InvalidInitPaymentRequestError("price mismatch"),
)
app = create_app()
_install_service_override(app, service)
async def run_request() -> httpx.Response:
transport = httpx.ASGITransport(app=app, raise_app_exceptions=False)
async with httpx.AsyncClient(
transport=transport,
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/order",
json=_valid_payload(),
)
response = asyncio.run(run_request())
assert response.status_code == 400
assert response.json() == {
"detail": {
"code": "invalid_init_payment_request",
"message": "Payment request contains invalid or unsupported TBank data.",
}
}
assert service.calls == [InitPaymentRequest(**_valid_payload())]
def test_post_init_payment_maps_service_exception_to_503() -> None:
service = StubAggregatorService(
response=None,
@@ -368,7 +399,7 @@ def test_post_init_payment_maps_service_exception_to_503() -> None:
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/init-payment",
"/api/v1/delivery/order",
json=_valid_payload(),
)
@@ -383,6 +414,37 @@ def test_post_init_payment_maps_service_exception_to_503() -> None:
}
def test_post_init_payment_maps_temporary_cdek_validation_error_to_503() -> None:
service = StubAggregatorService(
response=None,
error=InitPaymentUnavailableError("CDEK validation unavailable"),
)
app = create_app()
_install_service_override(app, service)
async def run_request() -> httpx.Response:
transport = httpx.ASGITransport(app=app, raise_app_exceptions=False)
async with httpx.AsyncClient(
transport=transport,
base_url="http://testserver",
) as client:
return await client.post(
"/api/v1/delivery/order",
json=_valid_payload(),
)
response = asyncio.run(run_request())
assert response.status_code == 503
assert response.json() == {
"detail": {
"code": "init_payment_unavailable",
"message": "Payment initialization is temporarily unavailable.",
}
}
assert service.calls == [InitPaymentRequest(**_valid_payload())]
def test_delivery_order_endpoint_is_removed() -> None:
service = StubAggregatorService(response=None)
app = create_app()