"""Tests for payee handlers.""" from http import HTTPStatus from unittest.mock import call, MagicMock, Mock, patch from flask import Response from flask.testing import FlaskClient from owsresponse import response import pytest from payee.config import Config from payee.constants.constants import ( PAYONEER_ACCOUNT_STATUS_NAMES_CODES, PAYONEER_ACCOUNT_STATUSES, PAYONEER_SERVICE_STATUSES, PAYONEER_STATUS_CODE, PAYONEER_STATUS_DESC, PREEXISTING_PAYONEER_ACCOUNT_PROGRAM_IDS, ) from payee.constants.error import ( ERROR_DONT_HAVE_PERMISSIONS, ERROR_PAYEE_DETAILS_NOT_FOUND, ) from payee.logic.exceptions import LogicError from payee.utils.exception import ( HttpMassPayoutsException, PayoneerMassPayoutsException, PayoneerPayeeDetailsException, ) from tests.conftest import mock_abacus_headers, mock_documents_headers from tests.utils.auth import MockJWTAuth from tests.utils.factories import ( AccountPayeeFactory, PayeeCollaboratorFactory, PayeeFactory, PayeeRegistrationFormatDumpedFactory, PayeeRegistrationFormatFactory, PayeeRegistrationFormatGetFactory, ) @patch( 'payee.logic.payoneer.create_registration_link', return_value={'account_payee_id': 123, 'registration_link': 'https://example.com'}, ) @patch('payee.utils.permissions.validate_record_owner', return_value=True) def test_post_payoneer_route_success( mock_validate_record_owner, mock_create_registration_link, fixture_client, mock_bypass_headers, ): """Verify that POST route exists and returns 201 status code.""" post_body = {'account_payee_id': 123, 'payoneer_program_id': 456} res = fixture_client.post( '/payoneer/registration-link', json=post_body, headers=mock_bypass_headers ) assert res.status_code == 201 assert mock_create_registration_link.called @patch( 'payee.logic.payoneer.create_registration_link', return_value={'account_payee_id': 123, 'registration_link': 'https://example.com'}, ) @patch('payee.utils.permissions.validate_record_owner', return_value=False) def test_post_payoneer_route_no_access( mock_validate_record_owner, mock_create_registration_link, fixture_client, mock_bypass_headers, ): """Verify that POST route exists and returns 401 status code without access.""" post_body = {'account_payee_id': 123, 'payoneer_program_id': 456} res = fixture_client.post( '/payoneer/registration-link', json=post_body, headers=mock_bypass_headers ) assert res.status_code == 401 mock_create_registration_link.assert_not_called() @patch('payee.logic.payoneer.build_payoneer_redirect_uri', return_value='AWAL') @patch('payee.logic.payoneer._build_payoneer_headers', return_value={'mock': 'header'}) @patch('payee.logic.payoneer.post') @patch('payee.utils.permissions.validate_record_owner', return_value=True) def test_post_payoneer_route_success_preexisting_program( mock_validate_record_owner, mock_post_request, mock_build_payoneer_headers, mock_build_redirect_uri, fixture_client, mock_bypass_headers, mock_config, monkeypatch, payoneer_registration_link_post_success, ): """Verify a preexisting Payoneer program returns a 201 with a registration link.""" mock_post_request.return_value.json.return_value = ( payoneer_registration_link_post_success ) monkeypatch.setattr( 'payee.config.Config.PAYONEER_CLIENT_ID', mock_config.PAYONEER_CLIENT_ID ) monkeypatch.setattr( 'payee.config.Config.PAYONEER_REDIRECT_URL', mock_config.PAYONEER_REDIRECT_URL ) post_body = { 'account_payee_id': 123, 'payoneer_program_id': PREEXISTING_PAYONEER_ACCOUNT_PROGRAM_IDS[0], } res = fixture_client.post( '/payoneer/registration-link', json=post_body, headers=mock_bypass_headers ) assert res.status_code == 201 assert res.json['account_payee_id'] == 123 assert 'registration_link' in res.json @patch('payee.logic.payoneer.build_payoneer_redirect_uri', return_value='AWAL') @patch('payee.logic.payoneer._build_payoneer_headers', return_value={'mock': 'header'}) @patch('payee.logic.payoneer.post') @patch('payee.utils.permissions.validate_record_owner', return_value=True) def test_post_payoneer_route_forbidden_program( mock_validate_record_owner, mock_post_request, mock_build_payoneer_headers, mock_build_redirect_uri, fixture_client, mock_bypass_headers, ): """Verify a non-preexisting Payoneer program is rejected with a 400.""" post_body = {'account_payee_id': 123, 'payoneer_program_id': 456} res = fixture_client.post( '/payoneer/registration-link', json=post_body, headers=mock_bypass_headers ) assert res.status_code == 400 mock_post_request.assert_not_called() @patch('payee.logic.payoneer.create_mass_payouts') def test_create_mass_payouts_success( mock_create_mass_payouts, fixture_client, mock_payoneer_mass_payouts ): """Verify that mass payouts route exists and logic is invoked.""" mock_create_mass_payouts.return_value = response.Response( message={'result': 'Payments Created'}, status=201 ) post_body = mock_payoneer_mass_payouts res = fixture_client.post('/payoneer/programs/1/mass-payouts', json=post_body) assert res.status_code == 201 mock_create_mass_payouts.assert_called_once() assert mock_create_mass_payouts.call_args[0][0] == 1 @patch( 'payee.logic.payoneer.create_mass_payouts', side_effect=PayoneerMassPayoutsException('Bad Request'), ) def test_create_mass_payouts_payonner_error( mock_create_mass_payouts, fixture_client, mock_payoneer_mass_payouts ): """Verify that mass payouts route exists and logic is invoked.""" post_body = mock_payoneer_mass_payouts res = fixture_client.post('/payoneer/programs/1/mass-payouts', json=post_body) assert res.status_code == 400 assert res.json['message'] == {'error': 'Bad Request', 'provider': 'payoneer'} mock_create_mass_payouts.assert_called_once() assert mock_create_mass_payouts.call_args[0][0] == 1 @patch( 'payee.logic.payoneer.create_mass_payouts', side_effect=HttpMassPayoutsException('Server error'), ) def test_create_mass_payouts_http_error( mock_create_mass_payouts, fixture_client, mock_payoneer_mass_payouts ): """Verify that mass payouts route exists and logic is invoked.""" post_body = mock_payoneer_mass_payouts res = fixture_client.post('/payoneer/programs/1/mass-payouts', json=post_body) assert res.status_code == 500 assert res.json['message'] == {'error': 'Server error', 'provider': 'http'} mock_create_mass_payouts.assert_called_once() assert mock_create_mass_payouts.call_args[0][0] == 1 @patch('payee.logic.payoneer.create_mass_payouts') def test_create_mass_payouts_description_optional( mock_create_mass_payouts, fixture_client ): """Test that description field is optional.""" mock_create_mass_payouts.return_value = response.Response( message={'result': 'Payments Created'}, status=201 ) post_body = [ { 'client_reference_id': 'test1', 'account_payee_id': '56732', 'currency': 'USD', 'amount': 222, } ] res = fixture_client.post('/payoneer/programs/1/mass-payouts', json=post_body) assert res.status_code == 201 @patch('payee.logic.payoneer.create_mass_payouts') def test_create_mass_payouts_description_can_be_null( mock_create_mass_payouts, fixture_client ): """Test that description field can be null.""" mock_create_mass_payouts.return_value = response.Response( message={'result': 'Payments Created'}, status=201 ) post_body = [ { 'client_reference_id': 'test1', 'account_payee_id': '56732', 'description': None, 'currency': 'USD', 'amount': 222, } ] res = fixture_client.post('/payoneer/programs/1/mass-payouts', json=post_body) assert res.status_code == 201 @patch( 'payee.blueprints.payoneer.logic.get_payoneer_account', ) @patch( 'payee.blueprints.payoneer.validate_multiple_record_owner', return_value={123: True} ) def test_get_payoneer_account_not_found( mock_validate_record_owner, mock_get_payoneer_account, fixture_client ): """Test get payoneer account not found.""" account_payee_id = 123 mock_get_payoneer_account.return_value = response.create_not_found_response( message=ERROR_PAYEE_DETAILS_NOT_FOUND.format(id=account_payee_id) ) res = fixture_client.get(f'/account-payee/{account_payee_id}/payoneer-status') assert res.status_code == 404 assert res.json['message'] == ERROR_PAYEE_DETAILS_NOT_FOUND.format( id=account_payee_id ) mock_get_payoneer_account.assert_called_once_with(account_payee_id) @patch('payee.blueprints.payoneer.logic.get_payoneer_account') @patch( 'payee.blueprints.payoneer.validate_multiple_record_owner', return_value={123: True} ) def test_get_payoneer_account_status_success_active( mock_validate_record_owner, mock_get_payoneer_account, fixture_client ): """Test get payoneer account status `ACTIVE`.""" account_payee_id = 123 mock_get_payoneer_account.return_value = response.Response( message={ 'result': { 'account_id': 987, 'status': { 'type': PAYONEER_ACCOUNT_STATUS_NAMES_CODES[ PAYONEER_ACCOUNT_STATUSES.ACTIVE ] }, } } ) res = fixture_client.get(f'/account-payee/{account_payee_id}/payoneer-status') assert res.json == { 'payoneer_account_id': 987, 'status': PAYONEER_ACCOUNT_STATUSES.ACTIVE, } mock_get_payoneer_account.assert_called_once_with(account_payee_id) @patch( 'payee.blueprints.payoneer.logic.get_payoneer_account', side_effect=PayoneerPayeeDetailsException(), ) @patch( 'payee.blueprints.payoneer.validate_multiple_record_owner', return_value={123: True} ) def test_get_payoneer_account_status_error( mock_validate_record_owner, mock_get_payoneer_account, fixture_client ): """Test get payoneer account status error.""" account_payee_id = 123 res = fixture_client.get(f'/account-payee/{account_payee_id}/payoneer-status') assert res.status_code == 500 @patch('payee.blueprints.payoneer.logic.get_payoneer_payee_name') @patch('payee.blueprints.payoneer.logic.get_payoneer_payee_details') @patch( 'payee.blueprints.payoneer.validate_multiple_record_owner', return_value={123: True} ) def test_get_payoneer_account_details_success( mock_validate_record_owner, mock_get_payoneer_account, mock_get_name, fixture_client ): """Test get payoneer account details success.""" account_payee_id = 123 account_details = { 'contact': { 'first_name': 'first_name', 'last_name': 'last_name', }, 'account_id': 'account_id', } mock_get_name.return_value = 'first_name last_name' mock_get_payoneer_account.return_value = MagicMock( status=200, message=account_details ) res = fixture_client.get( f'/account-payee/{account_payee_id}/payee-payoneer-details' ) assert res.status_code == 200 assert res.json == {'payee_name': 'first_name last_name'} mock_get_payoneer_account.assert_called_once_with(account_payee_id) mock_get_name.assert_called_once_with(account_details) @patch('payee.blueprints.payoneer.logic.get_payoneer_payee_name') @patch( 'payee.blueprints.payoneer.logic.get_payoneer_payee_details', side_effect=PayoneerPayeeDetailsException(), ) @patch( 'payee.blueprints.payoneer.validate_multiple_record_owner', return_value={123: True} ) def test_get_payoneer_account_details_error_payee_details_( mock_validate_record_owner, mock_get_payoneer_account, mock_get_name, fixture_client ): """Test get payoneer account details error.""" account_payee_id = 123 res = fixture_client.get( f'/account-payee/{account_payee_id}/payee-payoneer-details' ) assert res.status_code == 500 mock_get_payoneer_account.assert_called_once_with(account_payee_id) mock_get_name.assert_not_called() @pytest.mark.parametrize('payoneer_program_id', (None, 100500)) @patch('payee.blueprints.payoneer.logic.payoneer_release_payee') @patch('payee.blueprints.payoneer.logic.get_payoneer_account') @patch( 'payee.utils.permissions.validate_multiple_record_owner', return_value={123: True} ) @patch('payee.models.account_payee.AccountPayee.get_by_id') def test_release_payee_from_payoneer_success( mock_get_payee_by_id: Mock, mock_validate_record_owner: Mock, mock_get_payoneer_account: Mock, mock_release_payee: Mock, fixture_client: FlaskClient, payoneer_program_id: int | None, ): """Test release account payee from payoneer.""" account_payee_id = 123 account_payee = AccountPayeeFactory.build( account_payee_id=account_payee_id, payoneer_program_id=None, ) mock_get_payee_by_id.return_value = account_payee account_details = { 'contact': { 'first_name': 'first_name', 'last_name': 'last_name', }, 'account_id': 'account_id', } release_payee_response_json = { 'result': {'payee_id': 'testyyy', 'release_date': '2023-03-31T15:54:02-04:00'} } mock_get_payoneer_account.return_value = MagicMock( status=200, message=account_details ) mock_release_payee.return_value = MagicMock( status=200, message=release_payee_response_json ) res = fixture_client.delete( f'/account-payee/{account_payee_id}/payoneer-account', json=( {'payoneer_program_id': payoneer_program_id} if payoneer_program_id else None ), ) assert isinstance(res, Response) assert res.status_code == 200 mock_validate_record_owner.assert_called_once_with([account_payee_id]) mock_get_payoneer_account.assert_called_once_with( account_payee_id, payoneer_program_id ) mock_release_payee.assert_called_once_with(account_payee_id, payoneer_program_id) @pytest.mark.parametrize('payoneer_program_id', (None, 100500)) @patch('payee.blueprints.payoneer.logic.payoneer_release_payee') @patch('payee.blueprints.payoneer.logic.get_payoneer_account') @patch( 'payee.utils.permissions.validate_multiple_record_owner', return_value={123: True} ) @patch('payee.models.payee.Payee.get_by_id') def test_release_payee_from_payoneer_success( mock_get_payee_by_id: Mock, mock_validate_record_owner: Mock, mock_get_payoneer_account: Mock, mock_release_payee: Mock, fixture_client: FlaskClient, payoneer_program_id: int | None, ): """Test release payee from payoneer.""" payoneer_client_reference_id = '123' payee = PayeeFactory.build( payoneer_client_reference_id=payoneer_client_reference_id ) mock_get_payee_by_id.return_value = payee account_details = { 'contact': { 'first_name': 'first_name', 'last_name': 'last_name', }, 'account_id': 'account_id', } release_payee_response_json = { 'result': {'payee_id': 'testyyy', 'release_date': '2023-03-31T15:54:02-04:00'} } mock_get_payoneer_account.return_value = MagicMock( status=200, message=account_details ) mock_release_payee.return_value = MagicMock( status=200, message=release_payee_response_json ) res = fixture_client.delete( f'/payee/{payoneer_client_reference_id}/payoneer-account', json=( {'payoneer_program_id': payoneer_program_id} if payoneer_program_id else None ), ) assert isinstance(res, Response) assert res.status_code == 200 mock_get_payoneer_account.assert_called_once_with( payoneer_client_reference_id, payoneer_program_id or payee.payoneer_program_id ) mock_release_payee.assert_called_once_with( payoneer_client_reference_id, payoneer_program_id or payee.payoneer_program_id ) @patch('payee.blueprints.payoneer.logic.payoneer_release_payee') @patch( 'payee.blueprints.payoneer.logic.get_payoneer_account', side_effect=PayoneerPayeeDetailsException(), ) @patch( 'payee.utils.permissions.validate_multiple_record_owner', return_value={123: True} ) @patch('payee.models.account_payee.AccountPayee.get_by_id') def test_release_payee_from_payoneer_error_payoneer_empty_response( mock_get_payee_by_id, mock_validate_record_owner, mock_get_payoneer_account, mock_release_payee, fixture_client, ): """Test release payee from payoneer.""" account_payee_id = 123 account_payee = AccountPayeeFactory.build( account_payee_id=account_payee_id, payoneer_program_id=None, ) mock_get_payee_by_id.return_value = account_payee res = fixture_client.delete(f'/account-payee/{account_payee_id}/payoneer-account') assert isinstance(res, Response) assert res.status_code == 500 mock_validate_record_owner.assert_called_once_with([account_payee_id]) mock_get_payoneer_account.assert_called_once_with(account_payee_id, None) mock_release_payee.assert_not_called() @patch('payee.blueprints.payoneer.logic.payoneer_release_payee') @patch('payee.blueprints.payoneer.logic.get_payoneer_account') @patch('payee.utils.permissions.validate_multiple_record_owner') @patch('payee.models.account_payee.AccountPayee.get_by_id') def test_release_payee_from_payoneer_error_no_payoneer_account( mock_get_payee_by_id: Mock, mock_validate_record_owner: Mock, mock_get_payoneer_account: Mock, mock_release_payee: Mock, fixture_client: FlaskClient, mock_jwt_auth: MockJWTAuth, ): """Test release payee from payoneer.""" mock_jwt_auth.identity = Config.PAYONEER_SERVICE_IDENTITIES[0] account_payee_id = 123 account_payee = AccountPayeeFactory.build( account_payee_id=account_payee_id, payoneer_program_id=None, ) mock_get_payee_by_id.return_value = account_payee mock_get_payoneer_account.return_value = response.Response( status=404, message='Not found error!', ) res = fixture_client.delete( f'/account-payee/{account_payee_id}/payoneer-account', headers=mock_jwt_auth.headers, ) assert isinstance(res, Response) assert res.status_code == 404 mock_validate_record_owner.assert_not_called() mock_get_payoneer_account.assert_called_once_with(account_payee_id, None) mock_release_payee.assert_not_called() @patch('payee.blueprints.payoneer.logic.payoneer_release_payee') @patch('payee.blueprints.payoneer.logic.get_payoneer_account') @patch( 'payee.utils.permissions.validate_multiple_record_owner', return_value={123: True} ) @patch('payee.models.account_payee.AccountPayee.get_by_id') def test_release_payee_from_payoneer_error_payoneer_response( mock_get_payee_by_id, mock_validate_record_owner, mock_get_payoneer_account, mock_release_payee, fixture_client, ): """Test release payee from payoneer.""" account_payee_id = 123 account_payee = AccountPayeeFactory.build( account_payee_id=account_payee_id, payoneer_program_id=None, ) mock_get_payee_by_id.return_value = account_payee account_details = { 'contact': { 'first_name': 'first_name', 'last_name': 'last_name', }, 'account_id': 'account_id', } mock_get_payoneer_account.return_value = MagicMock( status=200, message=account_details ) mock_release_payee.return_value = MagicMock( status=400, message='Some payoneer error!' ) res = fixture_client.delete(f'/account-payee/{account_payee_id}/payoneer-account') assert isinstance(res, Response) assert res.status_code == 400 mock_validate_record_owner.assert_called_once_with([account_payee_id]) mock_get_payoneer_account.assert_called_once_with(account_payee_id, None) mock_release_payee.assert_called_once_with(account_payee_id, None) @patch('payee.blueprints.payoneer.MovePayoneerProgramSchema') @patch('payee.blueprints.payoneer.validated_request_body') @patch('payee.blueprints.payoneer.logic.move_payoneer_program') def test_move_payoneer_program( mock_logic, mock_validation, mock_schema, fixture_client ): """Test for move Payoneer program endpoint.""" test_payload = {'existing_payoneer_program_id': 123, 'new_payoneer_program_id': 234} test_account_payee_id = 1 mock_result = { 'result': { 'payee_id': '1', 'adopted_to_partner_id': 123, 'adopted_payee_id': '1', 'date_adopted': '2021-03-24T14:45:43-04:00', } } mock_validation.return_value = test_payload mock_logic.return_value = response.Response(status=200, message=mock_result) res = fixture_client.post( f'/account-payee/{test_account_payee_id}/move-payoneer-program' ) assert res.status_code == 200 assert res.json == mock_result assert mock_validation.call_args_list == [call(mock_schema.return_value)] assert mock_logic.call_args_list == [call(test_account_payee_id, **test_payload)] @patch('payee.blueprints.payoneer.logic.get_payee_status') def test_get_payee_status(mock_logic, fixture_client): """Test for get Payoneer status endpoint.""" test_account_payee_id = 1 test_program_id = 2 mock_result = { 'result': { 'account_id': '3676945', 'status': {'type': 1, 'description': 'Active'}, 'registration_date': '2021-05-05', 'payout_method': {'type': 'BANK', 'currency': 'USD'}, } } mock_logic.return_value = response.Response(status=200, message=mock_result) res = fixture_client.get( f'/account-payee/{test_account_payee_id}' f'/program/{test_program_id}/payoneer-status' ) assert res.status_code == 200 assert res.json == mock_result assert mock_logic.call_args_list == [call(test_account_payee_id, test_program_id)] @patch('payee.logic.payee.Payee') @patch('payee.logic.payee.AccountPayee') @patch('payee.utils.permissions.validate_record_owner', return_value=True) @patch('payee.blueprints.payoneer.logic.get_payee_register_format') def test_get_account_payee_whitelabel_registration_format( mock_logic, mock_perm, account_payee_mock, payee_mock, fixture_client, mock_bypass_headers, ): """Test for get Payoneer whitelabel registration format endpoint.""" account_payee_id = 12 request_data = PayeeRegistrationFormatGetFactory.build() mock_logic.return_value = PayeeRegistrationFormatFactory.build() payee = AccountPayeeFactory.build(account_payee_id=account_payee_id) payee_mock.get_by_id.return_value = None account_payee_mock.get_by_id.return_value = payee query_args = '&'.join(f'{k}={v}' for k, v in request_data.items()) result = fixture_client.get( f'/account-payee/{account_payee_id}/whitelabel/payee-registration/format?{query_args}', headers=mock_bypass_headers, ) assert result.status_code == HTTPStatus.OK assert result.json == PayeeRegistrationFormatDumpedFactory.build() mock_logic.assert_called_once_with(payee, **request_data) @patch('payee.logic.payee.Payee') @patch('payee.logic.payee.AccountPayee') @patch('payee.utils.permissions.validate_record_owner', return_value=True) @patch('payee.blueprints.payoneer.logic.get_payee_register_format') def test_get_payee_whitelabel_registration_format( mock_logic, mock_perm, account_payee_mock, payee_mock, fixture_client, mock_bypass_headers, ): """Test for get Payoneer whitelabel registration format endpoint.""" payee_id = 12 request_data = PayeeRegistrationFormatGetFactory.build() mock_logic.return_value = PayeeRegistrationFormatFactory.build() payee = PayeeFactory.build(payee_id=payee_id) payee_collaborator = PayeeCollaboratorFactory.build(payee_id=payee_id) payee.get_typed_payee = MagicMock(return_value=payee_collaborator) payee_mock.get_by_id.return_value = payee account_payee_mock.get_by_id.return_value = None query_args = '&'.join(f'{k}={v}' for k, v in request_data.items()) result = fixture_client.get( f'/payee/{payee_id}/whitelabel/payee-registration/format?{query_args}', headers=mock_bypass_headers, ) assert result.status_code == HTTPStatus.OK assert result.json == PayeeRegistrationFormatDumpedFactory.build() mock_logic.assert_called_once_with(payee, **request_data) @patch('payee.logic.payee.Payee') @patch('payee.logic.payee.AccountPayee') @patch('payee.utils.permissions.authorization_backend.is_authorized', return_value=True) @patch('payee.blueprints.payoneer.logic.get_payee_register_format') def test_get_account_payee_whitelabel_registration_format_abacus_profile( mock_logic, mock_perm, account_payee_mock, payee_mock, fixture_client, mock_headers ): """Test for get Payoneer whitelabel registration format endpoint.""" account_payee_id = 12 request_data = PayeeRegistrationFormatGetFactory.build() mock_logic.return_value = PayeeRegistrationFormatFactory.build() payee = AccountPayeeFactory.build(account_payee_id=account_payee_id) payee_mock.get_by_id.return_value = None account_payee_mock.get_by_id.return_value = payee query_args = '&'.join(f'{k}={v}' for k, v in request_data.items()) result = fixture_client.get( f'/account-payee/{account_payee_id}/whitelabel/payee-registration/format?{query_args}', headers=mock_headers, ) assert result.status_code == HTTPStatus.OK assert result.json == PayeeRegistrationFormatDumpedFactory.build() mock_logic.assert_called_once_with(payee, **request_data) @patch('payee.logic.payee.Payee') @patch('payee.logic.payee.AccountPayee') @patch('payee.utils.permissions.validate_record_owner', return_value=True) @patch('payee.blueprints.payoneer.logic.get_payee_register_format') def test_get_account_payee_whitelabel_registration_format_payoneer_failure( mock_logic, mock_perm, account_payee_mock, payee_mock, fixture_client, mock_bypass_headers, ): """Test for get Payoneer whitelabel registration format endpoint error.""" account_payee_id = 12 request_data = PayeeRegistrationFormatGetFactory.build() message = 'test message' mock_logic.side_effect = LogicError(message) payee = AccountPayeeFactory.build(account_payee_id=account_payee_id) payee_mock.get_by_id.return_value = None account_payee_mock.get_by_id.return_value = payee query_args = '&'.join(f'{k}={v}' for k, v in request_data.items()) result = fixture_client.get( f'/account-payee/{account_payee_id}/whitelabel/payee-registration/format?{query_args}', headers=mock_bypass_headers, ) assert result.status_code == HTTPStatus.INTERNAL_SERVER_ERROR assert result.json == message mock_logic.assert_called_once_with(payee, **request_data) @patch('payee.logic.payee.Payee') @patch('payee.logic.payee.AccountPayee') @pytest.mark.parametrize( 'headers,mock_perm_func', [ ( mock_abacus_headers, 'payee.utils.permissions.authorization_backend.is_authorized', ), (mock_documents_headers, 'payee.utils.permissions.validate_record_owner'), ], ) def test_get_account_payee_whitelabel_registration_format_no_permissions( account_payee_mock, payee_mock, headers, mock_perm_func, fixture_client, monkeypatch ): """Test for get Payoneer whitelabel registration format endpoint error.""" monkeypatch.setattr(mock_perm_func, lambda *args, **kwargs: False) account_payee_id = 12 request_data = PayeeRegistrationFormatGetFactory.build() payee = AccountPayeeFactory.build(account_payee_id=account_payee_id) payee_mock.get_by_id.return_value = None account_payee_mock.get_by_id.return_value = payee query_args = '&'.join(f'{k}={v}' for k, v in request_data.items()) result = fixture_client.get( f'/account-payee/{account_payee_id}/whitelabel/payee-registration/format?{query_args}', headers=headers(), ) assert result.status_code == HTTPStatus.UNAUTHORIZED assert result.json == {'error': ERROR_DONT_HAVE_PERMISSIONS} @patch('payee.logic.payee.Payee') @patch('payee.logic.payee.AccountPayee') @patch( 'payee.utils.permissions.authorization_backend.is_authorized', return_value=False ) def test_get_account_payee_whitelabel_registration_format_no_permissions_abacus_profile( account_payee_mock, payee_mock, mock_perm, fixture_client, mock_headers ): """Test for get Payoneer whitelabel registration format endpoint error.""" account_payee_id = 12 request_data = PayeeRegistrationFormatGetFactory.build() payee = AccountPayeeFactory.build(account_payee_id=account_payee_id) payee_mock.get_by_id.return_value = None account_payee_mock.get_by_id.return_value = payee query_args = '&'.join(f'{k}={v}' for k, v in request_data.items()) result = fixture_client.get( f'/account-payee/{account_payee_id}/whitelabel/payee-registration/format?{query_args}', headers=mock_headers, ) assert result.status_code == HTTPStatus.UNAUTHORIZED assert result.json == {'error': ERROR_DONT_HAVE_PERMISSIONS} # Tests for get_payoneer_status endpoint @patch('payee.logic.payoneer.get_payoneer_service_status') def test_get_payoneer_status_success_operational(mock_get_status, fixture_client): """Test GET /payoneer_status returns operational status code.""" operational_status = PAYONEER_STATUS_CODE[PAYONEER_SERVICE_STATUSES.OPERATIONAL] mock_get_status.return_value = operational_status result = fixture_client.get('/payoneer_status') assert result.status_code == HTTPStatus.OK assert result.json == { 'status_code': operational_status, 'status_desc': PAYONEER_STATUS_DESC.get(operational_status), } assert 'status_code' in result.json assert isinstance(result.json['status_code'], int) assert result.json['status_code'] in list( PAYONEER_STATUS_CODE.values() ) # Valid status codes mock_get_status.assert_called_once() def test_get_payoneer_status_endpoint_exists(fixture_client): """Test that the /payoneer_status endpoint exists and is accessible.""" operational_status = PAYONEER_STATUS_CODE[PAYONEER_SERVICE_STATUSES.OPERATIONAL] with patch( 'payee.logic.payoneer.get_payoneer_service_status', return_value=operational_status, ): result = fixture_client.get('/payoneer_status') assert result.status_code == HTTPStatus.OK @pytest.mark.parametrize('method', ['post', 'put', 'delete']) def test_get_payoneer_status_method_not_allowed(fixture_client, method): """Test that only GET method is allowed on /payoneer_status endpoint.""" response = getattr(fixture_client, method)('/payoneer_status') assert response.status_code == HTTPStatus.METHOD_NOT_ALLOWED