Skip to content

Commit e650a4c

Browse files
authored
Merge pull request #37 from buserbrasil/fix-partial-refund
Fix partial_refund
2 parents c1c29e8 + 4eb4893 commit e650a4c

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

barte/client.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,20 @@ def get_instance(cls) -> "BarteClient":
6969
)
7070
return cls._instance
7171

72+
def _extract_error_data(
73+
self, json_response: Union[Dict[str, Any], List[Any]]
74+
) -> Optional[Dict[str, Any]]:
75+
"""Extract error data from API response if present."""
76+
if isinstance(json_response, dict) and "errors" in json_response:
77+
return json_response
78+
79+
if isinstance(json_response, list) and json_response:
80+
first_item = json_response[0]
81+
if isinstance(first_item, dict) and "errors" in first_item:
82+
return first_item
83+
84+
return None
85+
7286
def _request(
7387
self,
7488
method: str,
@@ -105,9 +119,9 @@ def _request(
105119
response.raise_for_status()
106120
return None
107121

108-
if isinstance(json_response, dict) and "errors" in json_response:
122+
if error_data := self._extract_error_data(json_response):
109123
error_response = from_dict(
110-
data_class=ErrorResponse, data=json_response, config=DACITE_CONFIG
124+
data_class=ErrorResponse, data=error_data, config=DACITE_CONFIG
111125
)
112126
error_response.raise_exception(response=response)
113127

barte/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ class ErrorMetadata:
353353
@dataclass
354354
class ErrorResponse:
355355
errors: List[ErrorItem]
356-
metadata: ErrorMetadata
356+
metadata: Optional[ErrorMetadata] = None
357357

358358
def raise_exception(self, response=None):
359359
error = self.errors[0]

tests/test_client.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,22 @@ def mock_refund_error_response_with_charge_uuid():
142142
}
143143

144144

145+
@pytest.fixture
146+
def mock_partial_refund_list_error_response():
147+
"""Error response in list format (used by partial_refund endpoint)"""
148+
return [
149+
{
150+
"errors": [
151+
{
152+
"code": "BAR-3002",
153+
"title": "Não é possível estornar esse valor.",
154+
"description": "Valor solicitado é maior que o valor disponível na cobrança.",
155+
}
156+
]
157+
}
158+
]
159+
160+
145161
@pytest.fixture
146162
def mock_charge_response():
147163
return {
@@ -874,3 +890,24 @@ def test_request_handles_list_response(self, mock_request, barte_client):
874890
assert result == list_response
875891
assert isinstance(result, list)
876892
assert len(result) == 2
893+
894+
@patch("barte.client.requests.Session.request")
895+
def test_partial_refund_charge_with_list_error_response(
896+
self, mock_request, barte_client, mock_partial_refund_list_error_response
897+
):
898+
"""Test partial refund charge returns BarteError when API returns error in list format"""
899+
mock_request.return_value.json.return_value = (
900+
mock_partial_refund_list_error_response
901+
)
902+
mock_request.return_value.raise_for_status = Mock()
903+
904+
with pytest.raises(BarteError) as exc_info:
905+
barte_client.partial_refund_charge(
906+
"d54f6553-8bcf-4376-a995-aaffb6d29492", value=Decimal("101.00")
907+
)
908+
909+
assert exc_info.value.code == "BAR-3002"
910+
assert (
911+
exc_info.value.message
912+
== "Valor solicitado é maior que o valor disponível na cobrança."
913+
)

0 commit comments

Comments
 (0)