Добавлен заказ накладной
This commit is contained in:
@@ -10,7 +10,10 @@ from app.adapters.delivery_providers.cdek.client import (
|
||||
CDEKProvider,
|
||||
CDEKRequestError,
|
||||
)
|
||||
from app.schemas.payment import InitPaymentRequest
|
||||
from app.adapters.delivery_providers.cdek.order_mapper import (
|
||||
CDEKOrderRegistrationResult,
|
||||
)
|
||||
from tests.payment_fixtures import make_init_payment_request
|
||||
|
||||
|
||||
class StubAuthClient:
|
||||
@@ -51,179 +54,53 @@ class SequenceHTTPClient:
|
||||
return result
|
||||
|
||||
|
||||
def _make_order_request(**overrides: object) -> InitPaymentRequest:
|
||||
payload: dict[str, object] = {
|
||||
"order_uuid": "order-uuid-1",
|
||||
"price": 125000,
|
||||
"type": 2,
|
||||
"tariff_code": 535,
|
||||
"comment": "Test order",
|
||||
"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_provider_register_order_posts_cdek_contract_payload_and_maps_response() -> None:
|
||||
response = httpx.Response(
|
||||
200,
|
||||
json={"entity": {"uuid": "cdek-order-uuid"}},
|
||||
request=httpx.Request("POST", "https://api.cdek.test/v2/orders"),
|
||||
)
|
||||
http_client = SequenceHTTPClient([response])
|
||||
provider = CDEKProvider(
|
||||
def _make_provider(http_client: SequenceHTTPClient, **kwargs: Any) -> CDEKProvider:
|
||||
return CDEKProvider(
|
||||
CDEKClient(
|
||||
http_client=http_client, # type: ignore[arg-type]
|
||||
auth_client=StubAuthClient(), # type: ignore[arg-type]
|
||||
base_url="https://api.cdek.test/v2",
|
||||
timeout_seconds=7.5,
|
||||
retry_attempts=0,
|
||||
**kwargs,
|
||||
)
|
||||
)
|
||||
|
||||
result = asyncio.run(provider.register_order(_make_order_request()))
|
||||
|
||||
assert result == "cdek-order-uuid"
|
||||
assert http_client.calls == [
|
||||
{
|
||||
"method": "POST",
|
||||
"url": "https://api.cdek.test/v2/orders",
|
||||
"json": {
|
||||
"number": "order-uuid-1",
|
||||
"type": 2,
|
||||
"tariff_code": 535,
|
||||
"comment": "Test order",
|
||||
"sender": {
|
||||
"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",
|
||||
}
|
||||
],
|
||||
},
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test-token"},
|
||||
"timeout": 7.5,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
def test_provider_register_order_omits_services_when_none_and_converts_package_weights() -> None:
|
||||
def test_provider_register_order_posts_payload_and_maps_response() -> None:
|
||||
response = httpx.Response(
|
||||
200,
|
||||
json={"entity": {"uuid": "cdek-order-uuid"}},
|
||||
json={
|
||||
"entity": {"uuid": "cdek-order-uuid"},
|
||||
"related_entities": [
|
||||
{
|
||||
"type": "waybill",
|
||||
"uuid": "waybill-uuid-1",
|
||||
"url": "https://cdek.test/waybill/1.pdf",
|
||||
}
|
||||
],
|
||||
},
|
||||
request=httpx.Request("POST", "https://api.cdek.test/v2/orders"),
|
||||
)
|
||||
http_client = SequenceHTTPClient([response])
|
||||
provider = CDEKProvider(
|
||||
CDEKClient(
|
||||
http_client=http_client, # type: ignore[arg-type]
|
||||
auth_client=StubAuthClient(), # type: ignore[arg-type]
|
||||
base_url="https://api.cdek.test/v2",
|
||||
timeout_seconds=7.5,
|
||||
retry_attempts=0,
|
||||
)
|
||||
)
|
||||
request = _make_order_request(
|
||||
services=None,
|
||||
packages=[
|
||||
{
|
||||
"number": "1",
|
||||
"weight": 1,
|
||||
"length": 20,
|
||||
"width": 15,
|
||||
"height": 10,
|
||||
"comment": "Package 1",
|
||||
},
|
||||
{
|
||||
"number": "2",
|
||||
"weight": 2,
|
||||
"length": 25,
|
||||
"width": 18,
|
||||
"height": 12,
|
||||
"comment": "Package 2",
|
||||
},
|
||||
],
|
||||
)
|
||||
provider = _make_provider(http_client)
|
||||
|
||||
asyncio.run(provider.register_order(request))
|
||||
result = asyncio.run(provider.register_order(make_init_payment_request()))
|
||||
|
||||
assert result == CDEKOrderRegistrationResult(
|
||||
order_uuid="cdek-order-uuid",
|
||||
waybill_uuid="waybill-uuid-1",
|
||||
waybill_url="https://cdek.test/waybill/1.pdf",
|
||||
)
|
||||
assert http_client.calls[0]["url"] == "https://api.cdek.test/v2/orders"
|
||||
payload = http_client.calls[0]["json"]
|
||||
assert "services" not in payload
|
||||
assert payload["sender"]["phones"] == [{"number": "+79009876543"}]
|
||||
assert payload["recipient"]["phones"] == [{"number": "+79001234567"}]
|
||||
assert payload["packages"] == [
|
||||
{
|
||||
"number": "1",
|
||||
"weight": 1000,
|
||||
"length": 20,
|
||||
"width": 15,
|
||||
"height": 10,
|
||||
"comment": "Package 1",
|
||||
},
|
||||
{
|
||||
"number": "2",
|
||||
"weight": 2000,
|
||||
"length": 25,
|
||||
"width": 18,
|
||||
"height": 12,
|
||||
"comment": "Package 2",
|
||||
},
|
||||
]
|
||||
assert payload["number"] == "order-uuid-1"
|
||||
assert payload["type"] == 2
|
||||
assert payload["tariff_code"] == 535
|
||||
assert payload["print"] == "WAYBILL"
|
||||
assert payload["from_location"]["code"] == 7017
|
||||
assert payload["to_location"]["code"] == 16454
|
||||
assert payload["packages"][0]["weight"] == 1000
|
||||
|
||||
|
||||
def test_cdek_client_register_order_maps_4xx_to_request_error() -> None:
|
||||
@@ -241,7 +118,7 @@ def test_cdek_client_register_order_maps_4xx_to_request_error() -> None:
|
||||
)
|
||||
|
||||
with pytest.raises(CDEKRequestError, match="status 422"):
|
||||
asyncio.run(client.register_order(_make_order_request()))
|
||||
asyncio.run(client.register_order(make_init_payment_request()))
|
||||
|
||||
assert len(http_client.calls) == 1
|
||||
|
||||
@@ -272,41 +149,13 @@ def test_cdek_client_register_order_maps_duplicate_external_id_to_success() -> N
|
||||
retry_attempts=2,
|
||||
)
|
||||
|
||||
result = asyncio.run(client.register_order(_make_order_request()))
|
||||
result = asyncio.run(client.register_order(make_init_payment_request()))
|
||||
|
||||
assert result == "existing-cdek-order-uuid"
|
||||
assert len(http_client.calls) == 1
|
||||
|
||||
|
||||
def test_cdek_client_register_order_4xx_with_unrelated_entity_uuid_raises_request_error() -> None:
|
||||
unrelated_response = httpx.Response(
|
||||
409,
|
||||
json={
|
||||
"entity": {"uuid": "unrelated-uuid"},
|
||||
"requests": [
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "v2_recipient_phone_invalid",
|
||||
"message": "Recipient phone is invalid",
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
request=httpx.Request("POST", "https://api.cdek.test/v2/orders"),
|
||||
assert result == CDEKOrderRegistrationResult(
|
||||
order_uuid="existing-cdek-order-uuid",
|
||||
waybill_uuid=None,
|
||||
waybill_url=None,
|
||||
)
|
||||
http_client = SequenceHTTPClient([unrelated_response])
|
||||
client = CDEKClient(
|
||||
http_client=http_client, # type: ignore[arg-type]
|
||||
auth_client=StubAuthClient(), # type: ignore[arg-type]
|
||||
base_url="https://api.cdek.test/v2",
|
||||
retry_attempts=2,
|
||||
)
|
||||
|
||||
with pytest.raises(CDEKRequestError):
|
||||
asyncio.run(client.register_order(_make_order_request()))
|
||||
|
||||
assert len(http_client.calls) == 1
|
||||
|
||||
|
||||
@@ -337,7 +186,7 @@ def test_cdek_client_register_order_retries_5xx_and_raises_client_error() -> Non
|
||||
)
|
||||
|
||||
with pytest.raises(CDEKClientError, match="retriable status 503"):
|
||||
asyncio.run(client.register_order(_make_order_request()))
|
||||
asyncio.run(client.register_order(make_init_payment_request()))
|
||||
|
||||
assert len(http_client.calls) == 2
|
||||
assert sleep_calls == [0.25]
|
||||
@@ -358,4 +207,4 @@ def test_cdek_client_register_order_raises_client_error_for_invalid_success_payl
|
||||
)
|
||||
|
||||
with pytest.raises(CDEKClientError, match="response payload is invalid"):
|
||||
asyncio.run(client.register_order(_make_order_request()))
|
||||
asyncio.run(client.register_order(make_init_payment_request()))
|
||||
|
||||
@@ -1,53 +1,209 @@
|
||||
from app.adapters.delivery_providers.cdek.order_mapper import (
|
||||
CDEKOrderRegistrationResult,
|
||||
compose_address_line,
|
||||
map_cdek_existing_order_response,
|
||||
map_cdek_order_request,
|
||||
map_cdek_order_response,
|
||||
)
|
||||
from app.schemas.payment import InitPaymentRequest
|
||||
from app.schemas.payment import Address
|
||||
from tests.payment_fixtures import make_init_payment_request
|
||||
|
||||
|
||||
def _make_order_request(**overrides: object) -> InitPaymentRequest:
|
||||
payload: dict[str, object] = {
|
||||
"order_uuid": "order-uuid-1",
|
||||
"price": 125000,
|
||||
"type": 2,
|
||||
"tariff_code": 535,
|
||||
"comment": "Test order",
|
||||
"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_cdek_order_payload_uses_order_uuid_as_external_number() -> None:
|
||||
payload = map_cdek_order_request(_make_order_request())
|
||||
def test_order_payload_uses_order_uuid_and_tariff_code_from_system_data() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
assert payload["number"] == "order-uuid-1"
|
||||
assert payload["type"] == 2
|
||||
assert payload["tariff_code"] == 535
|
||||
|
||||
|
||||
def test_order_payload_requests_waybill_print() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
assert payload["print"] == "WAYBILL"
|
||||
|
||||
|
||||
def test_map_cdek_order_response_extracts_order_uuid_without_waybill() -> None:
|
||||
result = map_cdek_order_response({"entity": {"uuid": "cdek-order-uuid"}})
|
||||
|
||||
assert result == CDEKOrderRegistrationResult(
|
||||
order_uuid="cdek-order-uuid",
|
||||
waybill_uuid=None,
|
||||
waybill_url=None,
|
||||
)
|
||||
|
||||
|
||||
def test_map_cdek_order_response_extracts_waybill_from_related_entities() -> None:
|
||||
result = map_cdek_order_response(
|
||||
{
|
||||
"entity": {"uuid": "cdek-order-uuid"},
|
||||
"related_entities": [
|
||||
{"type": "delivery", "uuid": "ignored"},
|
||||
{
|
||||
"type": "waybill",
|
||||
"uuid": "waybill-uuid-1",
|
||||
"url": "https://cdek.test/waybill/1.pdf",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
assert result == CDEKOrderRegistrationResult(
|
||||
order_uuid="cdek-order-uuid",
|
||||
waybill_uuid="waybill-uuid-1",
|
||||
waybill_url="https://cdek.test/waybill/1.pdf",
|
||||
)
|
||||
|
||||
|
||||
def test_map_cdek_existing_order_response_returns_waybill_for_duplicate() -> None:
|
||||
result = map_cdek_existing_order_response(
|
||||
{
|
||||
"entity": {"uuid": "existing-uuid"},
|
||||
"requests": [
|
||||
{"errors": [{"code": "v2_entity_already_exists", "message": "dup"}]}
|
||||
],
|
||||
"related_entities": [
|
||||
{
|
||||
"type": "waybill",
|
||||
"uuid": "waybill-existing",
|
||||
"url": "https://cdek.test/waybill/existing.pdf",
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
assert result == CDEKOrderRegistrationResult(
|
||||
order_uuid="existing-uuid",
|
||||
waybill_uuid="waybill-existing",
|
||||
waybill_url="https://cdek.test/waybill/existing.pdf",
|
||||
)
|
||||
|
||||
|
||||
def test_order_payload_maps_phones_and_phone_ext_to_additional() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
assert payload["sender"]["phones"] == [{"number": "+79009876543"}]
|
||||
assert payload["recipient"]["phones"] == [
|
||||
{"number": "+79001234567", "additional": "101"}
|
||||
]
|
||||
|
||||
|
||||
def test_order_payload_maps_locations_with_address_and_postal_code() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
assert payload["from_location"] == {
|
||||
"code": 7017,
|
||||
"address": "Дубай, Sheikh Zayed Road, 10, кв. 201",
|
||||
"postal_code": "12345",
|
||||
}
|
||||
assert payload["to_location"] == {
|
||||
"code": 16454,
|
||||
"address": "Шарджа, Al Wahda, 5",
|
||||
"postal_code": "54321",
|
||||
}
|
||||
|
||||
|
||||
def test_order_payload_for_parcel_includes_dimensions() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
package = payload["packages"][0]
|
||||
assert package["weight"] == 1000
|
||||
assert package["length"] == 20
|
||||
assert package["width"] == 15
|
||||
assert package["height"] == 10
|
||||
|
||||
|
||||
def test_order_payload_for_doc_omits_dimensions() -> None:
|
||||
request = make_init_payment_request(
|
||||
content={"description": "Docs"},
|
||||
systemData={
|
||||
"tariff": {
|
||||
"provider": "СДЭК",
|
||||
"serviceName": "Документы",
|
||||
"price": 50000,
|
||||
"deliveryDaysMin": 1,
|
||||
"deliveryDaysMax": 2,
|
||||
"tariffCode": 535,
|
||||
},
|
||||
"parcelType": "doc",
|
||||
"docPackaging": "envelope",
|
||||
"weight": "0.5",
|
||||
"dimensions": None,
|
||||
},
|
||||
)
|
||||
|
||||
payload = map_cdek_order_request(request)
|
||||
package = payload["packages"][0]
|
||||
|
||||
assert package["weight"] == 500
|
||||
assert "length" not in package
|
||||
assert "width" not in package
|
||||
assert "height" not in package
|
||||
|
||||
|
||||
def test_order_payload_omits_shipment_and_delivery_point() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
assert "shipment_point" not in payload
|
||||
assert "delivery_point" not in payload
|
||||
|
||||
|
||||
def test_order_payload_includes_company_requisites_for_legal_entity() -> None:
|
||||
request = make_init_payment_request(
|
||||
senderContact={
|
||||
"fullName": "Romashka LLC",
|
||||
"email": "buh@romashka.test",
|
||||
"phone": "+74950000000",
|
||||
"phoneExt": None,
|
||||
"isCompany": True,
|
||||
"companyName": "Romashka LLC",
|
||||
"inn": "7707083893",
|
||||
"kpp": "770701001",
|
||||
}
|
||||
)
|
||||
|
||||
sender = map_cdek_order_request(request)["sender"]
|
||||
|
||||
assert sender["contragent_type"] == "LEGAL_ENTITY"
|
||||
assert sender["company"] == "Romashka LLC"
|
||||
assert sender["inn"] == "7707083893"
|
||||
assert sender["kpp"] == "770701001"
|
||||
|
||||
|
||||
def test_order_payload_propagates_description_to_comments_without_items() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
assert payload["comment"] == "Headphones"
|
||||
assert payload["packages"][0]["comment"] == "Headphones"
|
||||
assert "items" not in payload["packages"][0]
|
||||
|
||||
|
||||
def test_order_payload_falls_back_package_comment_to_order_uuid() -> None:
|
||||
payload = map_cdek_order_request(
|
||||
make_init_payment_request(content={"description": None})
|
||||
)
|
||||
|
||||
assert payload["packages"][0]["comment"] == "order-uuid-1"
|
||||
|
||||
|
||||
def test_order_payload_includes_company_for_individual_sender_as_full_name() -> None:
|
||||
payload = map_cdek_order_request(make_init_payment_request())
|
||||
|
||||
assert payload["sender"]["company"] == "Petr Petrov"
|
||||
assert payload["recipient"]["company"] == "Ivan Ivanov"
|
||||
assert "contragent_type" not in payload["sender"]
|
||||
assert "contragent_type" not in payload["recipient"]
|
||||
|
||||
|
||||
def test_compose_address_line_handles_empty_apartment() -> None:
|
||||
address = Address(
|
||||
cityId=1,
|
||||
city="Москва",
|
||||
street="Lenina",
|
||||
house="1",
|
||||
apartment=None,
|
||||
zip="12345",
|
||||
comment=None,
|
||||
)
|
||||
|
||||
assert compose_address_line(address) == "Москва, Lenina, 1"
|
||||
|
||||
@@ -11,7 +11,7 @@ from app.adapters.delivery_providers.cdek.client import (
|
||||
CDEKProvider,
|
||||
CDEKRequestError,
|
||||
)
|
||||
from app.schemas.payment import InitPaymentRequest
|
||||
from tests.payment_fixtures import make_init_payment_request
|
||||
|
||||
|
||||
class StubAuthClient:
|
||||
@@ -52,62 +52,11 @@ class SequenceHTTPClient:
|
||||
return result
|
||||
|
||||
|
||||
def _make_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_provider_get_payment_price_posts_tarifflist_payload_and_maps_requested_tariff() -> None:
|
||||
def test_provider_get_payment_price_posts_payload_from_camelcase_request() -> None:
|
||||
response = httpx.Response(
|
||||
200,
|
||||
json={
|
||||
"tariff_codes": [
|
||||
{
|
||||
"tariff_code": 234,
|
||||
"tariff_name": "Other tariff",
|
||||
"delivery_sum": "999.00",
|
||||
"currency": "RUB",
|
||||
"period_min": 3,
|
||||
"period_max": 5,
|
||||
},
|
||||
{
|
||||
"tariff_code": 535,
|
||||
"tariff_name": "CDEK tariff",
|
||||
@@ -131,11 +80,9 @@ def test_provider_get_payment_price_posts_tarifflist_payload_and_maps_requested_
|
||||
)
|
||||
)
|
||||
|
||||
result = asyncio.run(provider.get_payment_price(_make_request()))
|
||||
result = asyncio.run(provider.get_payment_price(make_init_payment_request()))
|
||||
|
||||
assert result is not None
|
||||
assert result.provider == "cdek"
|
||||
assert result.service_name == "CDEK tariff"
|
||||
assert result.price == Decimal("1250.00")
|
||||
assert http_client.calls == [
|
||||
{
|
||||
@@ -143,16 +90,8 @@ def test_provider_get_payment_price_posts_tarifflist_payload_and_maps_requested_
|
||||
"url": "https://api.cdek.test/v2/calculator/tarifflist",
|
||||
"json": {
|
||||
"type": 2,
|
||||
"from_location": {
|
||||
"address": "Lenina 1",
|
||||
"city": "Moscow",
|
||||
"country_code": "RU",
|
||||
},
|
||||
"to_location": {
|
||||
"address": "Pushkina 10",
|
||||
"city": "Novosibirsk",
|
||||
"country_code": "RU",
|
||||
},
|
||||
"from_location": {"code": 7017},
|
||||
"to_location": {"code": 16454},
|
||||
"packages": [
|
||||
{
|
||||
"weight": 1000,
|
||||
@@ -161,7 +100,6 @@ def test_provider_get_payment_price_posts_tarifflist_payload_and_maps_requested_
|
||||
"height": 10,
|
||||
}
|
||||
],
|
||||
"services": [{"code": "INSURANCE", "parameter": "1000"}],
|
||||
},
|
||||
"data": None,
|
||||
"headers": {"Authorization": "Bearer test-token"},
|
||||
@@ -170,7 +108,7 @@ def test_provider_get_payment_price_posts_tarifflist_payload_and_maps_requested_
|
||||
]
|
||||
|
||||
|
||||
def test_provider_get_payment_price_omits_services_when_none() -> None:
|
||||
def test_provider_get_payment_price_omits_dimensions_for_doc() -> None:
|
||||
response = httpx.Response(
|
||||
200,
|
||||
json={"tariff_codes": []},
|
||||
@@ -185,11 +123,28 @@ def test_provider_get_payment_price_omits_services_when_none() -> None:
|
||||
retry_attempts=0,
|
||||
)
|
||||
)
|
||||
request = make_init_payment_request(
|
||||
content={"description": "Docs"},
|
||||
systemData={
|
||||
"tariff": {
|
||||
"provider": "СДЭК",
|
||||
"serviceName": "Документы",
|
||||
"price": 50000,
|
||||
"deliveryDaysMin": 1,
|
||||
"deliveryDaysMax": 2,
|
||||
"tariffCode": 535,
|
||||
},
|
||||
"parcelType": "doc",
|
||||
"docPackaging": "envelope",
|
||||
"weight": "0.5",
|
||||
"dimensions": None,
|
||||
},
|
||||
)
|
||||
|
||||
result = asyncio.run(provider.get_payment_price(_make_request(services=None)))
|
||||
asyncio.run(provider.get_payment_price(request))
|
||||
|
||||
assert result is None
|
||||
assert "services" not in http_client.calls[0]["json"]
|
||||
package = http_client.calls[0]["json"]["packages"][0]
|
||||
assert package == {"weight": 500}
|
||||
|
||||
|
||||
def test_client_get_raw_payment_price_maps_4xx_to_request_error() -> None:
|
||||
@@ -207,7 +162,7 @@ def test_client_get_raw_payment_price_maps_4xx_to_request_error() -> None:
|
||||
)
|
||||
|
||||
with pytest.raises(CDEKRequestError, match="status 422"):
|
||||
asyncio.run(client.get_raw_payment_price(_make_request()))
|
||||
asyncio.run(client.get_raw_payment_price(make_init_payment_request()))
|
||||
|
||||
assert len(http_client.calls) == 1
|
||||
|
||||
@@ -239,7 +194,7 @@ def test_client_get_raw_payment_price_retries_5xx_and_raises_client_error() -> N
|
||||
)
|
||||
|
||||
with pytest.raises(CDEKClientError, match="status 503"):
|
||||
asyncio.run(client.get_raw_payment_price(_make_request()))
|
||||
asyncio.run(client.get_raw_payment_price(make_init_payment_request()))
|
||||
|
||||
assert len(http_client.calls) == 2
|
||||
assert sleep_calls == [0.25]
|
||||
@@ -262,4 +217,4 @@ def test_provider_get_payment_price_maps_invalid_success_payload_to_client_error
|
||||
)
|
||||
|
||||
with pytest.raises(CDEKClientError, match="response payload is invalid"):
|
||||
asyncio.run(provider.get_payment_price(_make_request()))
|
||||
asyncio.run(provider.get_payment_price(make_init_payment_request()))
|
||||
|
||||
Reference in New Issue
Block a user