107 lines
3.3 KiB
Python
107 lines
3.3 KiB
Python
import sys
|
|
from pathlib import Path
|
|
|
|
import asyncio
|
|
|
|
import pytest
|
|
from fastapi import HTTPException, status
|
|
from requests import RequestException
|
|
|
|
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
|
if str(PROJECT_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(PROJECT_ROOT))
|
|
|
|
from pydantic import ValidationError
|
|
|
|
from src.modules.pagamentos.mercadopago_service import (
|
|
MercadoPagoService,
|
|
MercadoPagoTransfer,
|
|
)
|
|
|
|
|
|
class _FakePaymentClient:
|
|
def __init__(self, error: Exception) -> None:
|
|
self._error = error
|
|
|
|
def get(self, payment_id: int): # pragma: no cover - behaviour tested via exception
|
|
raise self._error
|
|
|
|
|
|
class _FakeSDK:
|
|
def __init__(self, error: Exception) -> None:
|
|
self._error = error
|
|
|
|
def payment(self): # pragma: no cover - simple passthrough
|
|
return _FakePaymentClient(self._error)
|
|
|
|
|
|
def test_get_payment_translates_request_exception_to_bad_gateway():
|
|
service = MercadoPagoService(access_token="token", public_key="public")
|
|
service.sdk = _FakeSDK(RequestException("proxy error")) # type: ignore[assignment]
|
|
|
|
with pytest.raises(HTTPException) as error_info:
|
|
asyncio.run(service.get_payment(123))
|
|
|
|
assert error_info.value.status_code == status.HTTP_502_BAD_GATEWAY
|
|
assert "Mercado Pago" in error_info.value.detail
|
|
|
|
|
|
def test_transfer_accepts_amount_or_percentage():
|
|
transfer_amount = MercadoPagoTransfer(collector_id=123, amount=10.0)
|
|
assert transfer_amount.amount == 10.0
|
|
assert transfer_amount.percentage is None
|
|
|
|
transfer_percentage = MercadoPagoTransfer(collector_id=123, percentage=25.0)
|
|
assert transfer_percentage.percentage == 25.0
|
|
assert transfer_percentage.amount is None
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"payload",
|
|
[
|
|
{"collector_id": 123},
|
|
{"collector_id": 123, "amount": 10.0, "percentage": 10.0},
|
|
],
|
|
)
|
|
def test_transfer_requires_exclusive_amount_or_percentage(payload):
|
|
with pytest.raises(ValidationError):
|
|
MercadoPagoTransfer(**payload)
|
|
|
|
|
|
def test_prepare_preference_enforces_checkout_pro_payment_methods():
|
|
service = MercadoPagoService(access_token="token", public_key="public")
|
|
|
|
preference_payload = {
|
|
"items": [
|
|
{
|
|
"id": "item-123",
|
|
"title": "Produto teste",
|
|
"quantity": 1,
|
|
"unit_price": 100.0,
|
|
}
|
|
],
|
|
"payment_methods": {
|
|
# Tenta bloquear cartão de crédito, mas deve ser ignorado
|
|
"excluded_payment_types": [
|
|
{"id": "ticket"},
|
|
{"id": "credit_card"},
|
|
],
|
|
# Tenta bloquear PIX, mas deve ser ignorado
|
|
"excluded_payment_methods": [
|
|
{"id": "pix"},
|
|
{"id": "visa"},
|
|
],
|
|
"installments": 12,
|
|
},
|
|
}
|
|
|
|
prepared = service._prepare_preference_payload(preference_payload)
|
|
|
|
excluded_types = {ptype["id"] for ptype in prepared["payment_methods"]["excluded_payment_types"]}
|
|
excluded_methods = {pmethod["id"] for pmethod in prepared["payment_methods"]["excluded_payment_methods"]}
|
|
|
|
assert "ticket" in excluded_types
|
|
assert "credit_card" not in excluded_types
|
|
assert "bank_transfer" not in excluded_types # Mantém PIX habilitado
|
|
assert "pix" not in excluded_methods
|
|
assert prepared["payment_methods"]["installments"] == 1
|