import json from unittest import mock from payoneer_status_sync import payoneer def _mocked_response(payload: dict[str, object]) -> mock.MagicMock: response = mock.MagicMock() response.read.return_value = json.dumps(payload).encode("utf-8") response.__enter__.return_value = response return response @mock.patch("payoneer_status_sync.payoneer.request.urlopen") def test_fetch_payout_status_reads_bank_rejection_reason( mock_urlopen: mock.MagicMock, ) -> None: mock_urlopen.return_value = _mocked_response( { "result": { "status": "Transferred", "reason_code": "13", "reason_description": "Bank cannot process", } } ) result = payoneer.fetch_payout_status( api_url="https://api.example.com", auth_token="token", program_id="1", client_reference_id="split:1:2", timeout_seconds=10, ) assert result["status"] == "Transferred" assert result["reason_code"] == "13" assert result["reason_description"] == "Bank cannot process" @mock.patch("payoneer_status_sync.payoneer.request.urlopen") def test_fetch_payout_status_reads_cancellation_reason( mock_urlopen: mock.MagicMock, ) -> None: mock_urlopen.return_value = _mocked_response( { "result": { "status": "Cancelled", "cancel_reason_code": 30013, "cancel_reason_description": "Bank details - Invalid Branch Code", } } ) result = payoneer.fetch_payout_status( api_url="https://api.example.com", auth_token="token", program_id="1", client_reference_id="split:1:2", timeout_seconds=10, ) assert result["status"] == "Cancelled" assert result["reason_code"] == "30013" assert result["reason_description"] == "Bank details - Invalid Branch Code" @mock.patch("payoneer_status_sync.payoneer.request.urlopen") def test_fetch_payout_status_returns_no_reason_when_absent( mock_urlopen: mock.MagicMock, ) -> None: mock_urlopen.return_value = _mocked_response({"result": {"status": "Transferred"}}) result = payoneer.fetch_payout_status( api_url="https://api.example.com", auth_token="token", program_id="1", client_reference_id="split:1:2", timeout_seconds=10, ) assert result["reason_code"] is None assert result["reason_description"] is None