"""Test ows-payment requests.""" from unittest.mock import patch import httpx from owsclient.test import OwsClientMock import pytest from payoneer_payments_payout.error_handling import OwsServiceException from payoneer_payments_payout.ows_payment import ( get_payment_group, get_payment_group_payment_account, get_payment_group_payment_data, post_payment_group_payment_batch, post_payment_group_payment_batch_accounts, update_flowthrough_allocations ) @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_get_payment_group_payment_success( mock_raise_service_error, mock_payment_group_payment_accounts, ows_client_mock: OwsClientMock ): """Test successfully getting payment_group_payment detail.""" payment_group_payment_id = 2 sort_by = 'payoneer_program_id' request_url = f'/payment-group-payment/{payment_group_payment_id}/accounts' ows_client_mock.get('ows-payment', request_url).mock( return_value=httpx.Response( 200, json={'items': mock_payment_group_payment_accounts, 'total_count': 2} ) ) res = get_payment_group_payment_account(payment_group_payment_id, 0, 1, sort_by) assert res['items'] == mock_payment_group_payment_accounts mock_raise_service_error.assert_not_called() @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_get_payment_group_payment_failure( mock_raise_service_error, ows_client_mock: OwsClientMock ): """Test failure getting payment_group_payment detail.""" payment_group_payment_id = 12 sort_by = 'payoneer_program_id' request_url = f'/payment-group-payment/{payment_group_payment_id}/accounts' ows_client_mock.get('ows-payment', request_url).mock( return_value=httpx.Response( 400, json='error' ) ) res = get_payment_group_payment_account(payment_group_payment_id, 0, 1, sort_by) assert res is None mock_raise_service_error.assert_called_once_with( f'ERROR in GET /payment-group-payment/{payment_group_payment_id}/accounts?limit=1&offset=0&sort_by=payoneer_program_id', # noqa: E501 'ows-payment' ) @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_post_payment_group_payment_batch_success( mock_raise_service_error, mock_payment_group_payment_batch, ows_client_mock: OwsClientMock ): """Test successfully creating payment_group_payment_batch.""" request_url = '/payment-group-payment-batch' ows_client_mock.post('ows-payment', request_url).mock( return_value=httpx.Response( 201, json=mock_payment_group_payment_batch ) ) request_body = { 'payment_group_payment_id': 1, 'batch_num': 5 } res = post_payment_group_payment_batch(request_body) assert res == mock_payment_group_payment_batch mock_raise_service_error.assert_not_called() @patch('payoneer_payments_payout.ows_payment.app_logger') @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_post_payment_group_payment_batch_failure( mock_raise_service_error, app_logger_mock, mock_payment_group_payment_batch, ows_client_mock: OwsClientMock ): """Test failure creating payment_group_payment_batch.""" request_url = '/payment-group-payment-batch' ows_client_mock.post('ows-payment', request_url).mock( return_value=httpx.Response( 400, json='error' ) ) request_body = { 'payment_group_payment_id': 1, 'batch_num': 5 } post_payment_group_payment_batch(request_body) mock_raise_service_error.assert_called_once_with( 'ERROR in POST /payment-group-payment-batch', 'ows-payment' ) @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_post_payment_group_payment_batch_account_success( mock_raise_service_error, mock_payment_group_payment_batch_account, ows_client_mock: OwsClientMock ): """Test successfully creating payment_group_payment_batch_accounts.""" request_url = '/payment-group-payment-batch-account/bulk' ows_client_mock.post('ows-payment', request_url).mock( return_value=httpx.Response( 201, json=mock_payment_group_payment_batch_account ) ) request_body = [ { 'payment_group_payment_acount_id': 1, 'payment_group_payment_batch_id': 2 }, { 'payment_group_payment_acount_id': 2, 'payment_group_payment_batch_id': 2 } ] res = post_payment_group_payment_batch_accounts(request_body) assert res == mock_payment_group_payment_batch_account mock_raise_service_error.assert_not_called() @patch('payoneer_payments_payout.ows_payment.app_logger') @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_post_payment_group_payment_batch_account_failure( mock_raise_service_error, app_logger_mock, mock_payment_group_payment_batch, ows_client_mock: OwsClientMock ): """Test failure creating payment_group_payment_batch_account.""" request_url = '/payment-group-payment-batch-account/bulk' ows_client_mock.post('ows-payment', request_url).mock( return_value=httpx.Response( 400, json='error' ) ) request_body = [ { 'payment_group_payment_acount_id': 1, 'payment_group_payment_batch_id': 2 }, { 'payment_group_payment_acount_id': 2, 'payment_group_payment_batch_id': 2 } ] post_payment_group_payment_batch_accounts(request_body) mock_raise_service_error.assert_called_once_with( 'ERROR in POST /payment-group-payment-batch-account/bulk', 'ows-payment' ) @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_get_payment_group_payment_data( mock_raise_service_error, mock_payment_group_payment, ows_client_mock: OwsClientMock ): """Test get_payment_group_payment_data success.""" mock_payment_group_payment_id = 1 request_url = f'/payment-group-payment/{mock_payment_group_payment_id}' ows_client_mock.get('ows-payment', request_url).mock( return_value=httpx.Response( 200, json=mock_payment_group_payment ) ) response = get_payment_group_payment_data(mock_payment_group_payment_id) assert response == mock_payment_group_payment mock_raise_service_error.assert_not_called() @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_get_payment_group_payment_data_failure( mock_raise_service_error, ows_client_mock: OwsClientMock ): """Test get_payment_group_payment_data success.""" mock_payment_group_payment_id = 1 request_url = f'/payment-group-payment/{mock_payment_group_payment_id}' ows_client_mock.get('ows-payment', request_url).mock( return_value=httpx.Response( 400, json='error' ) ) get_payment_group_payment_data(mock_payment_group_payment_id) mock_raise_service_error.assert_called_once_with( 'ERROR in GET /payment-group-payment/1', 'ows-payment' ) @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_get_payment_group( mock_raise_service_error, mock_knr_payment_group, ows_client_mock: OwsClientMock ): """Test get_payment_group success.""" mock_payment_group_id = 2 request_url = f'/payment-group/{mock_payment_group_id}' ows_client_mock.get('ows-payment', request_url).mock( return_value=httpx.Response( 200, json=mock_knr_payment_group ) ) response = get_payment_group(mock_payment_group_id) assert response == mock_knr_payment_group mock_raise_service_error.assert_not_called() @patch('payoneer_payments_payout.ows_payment.raise_service_error') def test_get_payment_group_failure( mock_raise_service_error, ows_client_mock: OwsClientMock ): """Test get_payment_group success.""" mock_payment_group_id = 2 request_url = f'/payment-group/{mock_payment_group_id}' ows_client_mock.get('ows-payment', request_url).mock( return_value=httpx.Response( 400, json='error' ) ) get_payment_group(mock_payment_group_id) mock_raise_service_error.assert_called_once_with( 'ERROR in GET /payment-group/2', 'ows-payment' ) def test_update_flowthrough_allocations_full_chain( ows_client_mock: OwsClientMock, ): """Test update_flowthrough_allocations 2-step chain.""" # Step 1: payable details (target_id = payment_allocation_id) ows_client_mock.post( 'ows-payment', '/payment-group-payment-account/payable-details/bulk' ).mock( return_value=httpx.Response(200, json={ 'items': [ {'target_id': 100, 'payable_detail_type_id': 6}, {'target_id': 200, 'payable_detail_type_id': 6}, ], 'total_count': 2, }) ) # Step 2: bulk update ows_client_mock.put( 'ows-payment', '/payment-allocations/flowthrough' ).mock( return_value=httpx.Response(200, json={}) ) update_flowthrough_allocations( [1, 2], ledger_status_transition=('attached_to_payment', 'debited'), ) def test_update_flowthrough_allocations_with_both_transitions( ows_client_mock: OwsClientMock, ): """Test update_flowthrough_allocations with payment and ledger transitions.""" ows_client_mock.post( 'ows-payment', '/payment-group-payment-account/payable-details/bulk' ).mock( return_value=httpx.Response(200, json={ 'items': [{'target_id': 100, 'payable_detail_type_id': 6}], 'total_count': 1, }) ) ows_client_mock.put( 'ows-payment', '/payment-allocations/flowthrough' ).mock( return_value=httpx.Response(200, json={}) ) update_flowthrough_allocations( [1], payment_status_transition=('attached_to_payment', 'returned'), ledger_status_transition=('attached_to_payment', 'returned'), ) @patch('payoneer_payments_payout.ows_payment.app_logger') def test_update_flowthrough_allocations_empty_ids(mock_logger): """Test update_flowthrough_allocations with empty payment_account_ids.""" update_flowthrough_allocations([], ledger_status_transition=('a', 'b')) mock_logger.info.assert_not_called() @patch('payoneer_payments_payout.ows_payment.app_logger') def test_update_flowthrough_allocations_no_payable_details( mock_logger, ows_client_mock: OwsClientMock, ): """Test update_flowthrough_allocations when no payable details found.""" ows_client_mock.post( 'ows-payment', '/payment-group-payment-account/payable-details/bulk' ).mock( return_value=httpx.Response(200, json={ 'items': [], 'total_count': 0, }) ) update_flowthrough_allocations( [1], ledger_status_transition=('attached_to_payment', 'debited'), ) mock_logger.info.assert_called_once_with('No flowthrough payable details found') def test_update_flowthrough_allocations_payable_details_api_error( ows_client_mock: OwsClientMock, ): """Test update_flowthrough_allocations raises on payable details API error.""" ows_client_mock.post( 'ows-payment', '/payment-group-payment-account/payable-details/bulk' ).mock( return_value=httpx.Response(500, json='error') ) with pytest.raises(OwsServiceException): update_flowthrough_allocations( [1], ledger_status_transition=('attached_to_payment', 'debited'), ) def test_update_flowthrough_allocations_bulk_update_api_error( ows_client_mock: OwsClientMock, ): """Test update_flowthrough_allocations raises on bulk update API error.""" ows_client_mock.post( 'ows-payment', '/payment-group-payment-account/payable-details/bulk' ).mock( return_value=httpx.Response(200, json={ 'items': [{'target_id': 100, 'payable_detail_type_id': 6}], 'total_count': 1, }) ) ows_client_mock.put( 'ows-payment', '/payment-allocations/flowthrough' ).mock( return_value=httpx.Response(500, json='error') ) with pytest.raises(OwsServiceException): update_flowthrough_allocations( [1], payment_status_transition=('attached_to_payment', 'returned'), ) @patch('payoneer_payments_payout.ows_payment.get_all_flowthrough_payable_details') def test_update_flowthrough_allocations_with_prefetched_details( mock_get_details, ows_client_mock: OwsClientMock, ): """Test update_flowthrough_allocations skips fetch when payable_details provided.""" ows_client_mock.put( 'ows-payment', '/payment-allocations/flowthrough' ).mock( return_value=httpx.Response(200, json={}) ) prefetched = [ {'target_id': 100, 'payable_detail_type_id': 6}, {'target_id': 200, 'payable_detail_type_id': 6}, ] update_flowthrough_allocations( [1, 2], ledger_status_transition=('attached_to_payment', 'debited'), payable_details=prefetched, ) mock_get_details.assert_not_called()