"""Tests for payment allocation handlers.""" from unittest.mock import call, patch from payment.config import Config from payment.constants.constants import ( DEFAULT_BULK_MAX_LIMIT, PAYMENT_ALLOCATION_LEDGER_STATUSES, PAYMENT_ALLOCATION_STATUSES, ) from payment.constants.error import ERROR_ALLOCATION_DUPLICATE, ERROR_BULK_MAX_LIMIT from payment.logic.exceptions import LogicError from payment.schemas.payment_allocation import ( PaymentAllocationFlowthroughBulkDeleteSchema, PaymentAllocationFlowthroughBulkUpdateSchema, ) @patch( 'payment.blueprints.payment_allocation.logic.bulk_update_payment_allocations_flowthrough' ) def test_bulk_update_payment_allocations_flowthrough_success( mock_logic, fixture_client, faker, mocker, mock_jwt_auth ) -> None: mock_jwt_auth.identity = Config.PAYMENT_ALLOCATION_IDENTITIES[0] payload = [ { 'payment_allocation_id': faker.pyint(min_value=1), 'payment_status': PAYMENT_ALLOCATION_STATUSES.PAID, 'ledger_status': PAYMENT_ALLOCATION_LEDGER_STATUSES.DEBITED, }, { 'payment_allocation_id': faker.pyint(min_value=1), 'payment_status': PAYMENT_ALLOCATION_STATUSES.PAID, }, ] spy_validation = mocker.spy(PaymentAllocationFlowthroughBulkUpdateSchema, 'load') resp = fixture_client.put( '/payment-allocations/flowthrough', json=payload, headers=mock_jwt_auth.headers, ) assert resp.status_code == 200 assert spy_validation.called assert mock_logic.call_args_list == [call(tuple(payload))] @patch( 'payment.blueprints.payment_allocation.logic.bulk_update_payment_allocations_flowthrough' ) def test_bulk_update_payment_allocations_flowthrough_duplicate_id( mock_logic, fixture_client, mock_jwt_auth ) -> None: mock_jwt_auth.identity = Config.PAYMENT_ALLOCATION_IDENTITIES[0] payload = [{'payment_allocation_id': 1}, {'payment_allocation_id': 1}] resp = fixture_client.put( '/payment-allocations/flowthrough', json=payload, headers=mock_jwt_auth.headers ) assert resp.status_code == 400 assert ERROR_ALLOCATION_DUPLICATE in resp.json['message']['json']['_schema'] assert not mock_logic.called @patch( 'payment.blueprints.payment_allocation.logic.bulk_update_payment_allocations_flowthrough' ) def test_bulk_update_payment_allocations_flowthrough_exceeds_limit( mock_logic, fixture_client, mock_jwt_auth ) -> None: mock_jwt_auth.identity = Config.PAYMENT_ALLOCATION_IDENTITIES[0] limit = DEFAULT_BULK_MAX_LIMIT payload = [{'payment_allocation_id': i} for i in range(limit + 1)] resp = fixture_client.put( '/payment-allocations/flowthrough', json=payload, headers=mock_jwt_auth.headers, ) assert resp.status_code == 400 assert ERROR_BULK_MAX_LIMIT.format(limit) in resp.json['message']['json']['_schema'] assert not mock_logic.called @patch( 'payment.blueprints.payment_allocation.logic.bulk_update_payment_allocations_flowthrough' ) def test_bulk_update_payment_allocations_flowthrough_logic_error( mock_logic, fixture_client, mock_jwt_auth ) -> None: mock_jwt_auth.identity = Config.PAYMENT_ALLOCATION_IDENTITIES[0] payload = ( { 'payment_allocation_id': 1, 'payment_status': PAYMENT_ALLOCATION_STATUSES.PAID, 'ledger_status': PAYMENT_ALLOCATION_LEDGER_STATUSES.DEBITED, }, ) mock_logic.side_effect = LogicError('Error text') resp = fixture_client.put( '/payment-allocations/flowthrough', json=payload, headers=mock_jwt_auth.headers, ) assert resp.status_code == 400 assert resp.json == {'code': 'error', 'message': 'Error text'} assert mock_logic.call_args_list == [call(payload)] @patch( 'payment.blueprints.payment_allocation.logic.bulk_update_payment_allocations_flowthrough' ) def test_bulk_update_payment_allocations_flowthrough_auth_error( mock_logic, fixture_client ) -> None: payload = ( { 'payment_allocation_id': 1, 'payment_status': PAYMENT_ALLOCATION_STATUSES.PAID, 'ledger_status': PAYMENT_ALLOCATION_LEDGER_STATUSES.DEBITED, }, ) mock_logic.side_effect = LogicError('Error text') resp = fixture_client.put( '/payment-allocations/flowthrough', json=payload, ) assert resp.status_code == 401 assert not mock_logic.called @patch( 'payment.blueprints.payment_allocation.logic.bulk_delete_payment_allocations_flowthrough' ) def test_bulk_delete_payment_allocations_flowthrough_success( mock_logic, fixture_client, faker, mocker, mock_jwt_auth ) -> None: mock_jwt_auth.identity = Config.PAYMENT_ALLOCATION_IDENTITIES[0] payload = { 'payment_allocation_ids': [ faker.pyint(min_value=1), faker.pyint(min_value=1), ] } spy_validation = mocker.spy(PaymentAllocationFlowthroughBulkDeleteSchema, 'load') resp = fixture_client.delete( '/payment-allocations/flowthrough', json=payload, headers=mock_jwt_auth.headers, ) assert resp.status_code == 204 assert spy_validation.called assert mock_logic.call_args_list == [call(payload['payment_allocation_ids'])] @patch( 'payment.blueprints.payment_allocation.logic.bulk_delete_payment_allocations_flowthrough' ) def test_bulk_delete_payment_allocations_flowthrough_validation_error_missing_ids( mock_logic, fixture_client, mocker, mock_jwt_auth ) -> None: mock_jwt_auth.identity = Config.PAYMENT_ALLOCATION_IDENTITIES[0] payload = {} spy_validation = mocker.spy(PaymentAllocationFlowthroughBulkDeleteSchema, 'load') resp = fixture_client.delete( '/payment-allocations/flowthrough', json=payload, headers=mock_jwt_auth.headers, ) assert resp.status_code == 400 assert spy_validation.called assert not mock_logic.called @patch( 'payment.blueprints.payment_allocation.logic.bulk_delete_payment_allocations_flowthrough' ) def test_bulk_delete_payment_allocations_flowthrough_logic_error( mock_logic, fixture_client, mocker, mock_jwt_auth ) -> None: mock_jwt_auth.identity = Config.PAYMENT_ALLOCATION_IDENTITIES[0] payload = {'payment_allocation_ids': [1, 2, 3]} spy_validation = mocker.spy(PaymentAllocationFlowthroughBulkDeleteSchema, 'load') mock_logic.side_effect = LogicError('Error text') resp = fixture_client.delete( '/payment-allocations/flowthrough', json=payload, headers=mock_jwt_auth.headers, ) assert resp.status_code == 400 assert spy_validation.called assert resp.json == {'code': 'error', 'message': 'Error text'} assert mock_logic.call_args_list == [call([1, 2, 3])]