"""Unit tests for Payment Group Payment Batch logic.""" from unittest.mock import call, patch import pytest from payment.constants.constants import PAYMENT_TYPES, VALID_PAYMENT_BATCH_STATUSES from payment.constants.error import ERROR_INVALID_PAYMENT_BATCH_STATUS from payment.logic import payment_group_payment_batch as logic from payment.logic.exceptions import LogicError from tests.utils.factories import ( PaymentDebitCreditDataEntryFactory, PaymentGroupPaymentAccountDetailFactory, PaymentGroupPaymentBatchAccountFactory, PaymentGroupPaymentBatchFactory, PaymentGroupPaymentFactory, WorksheetAccountContractClosingBalanceFactory, WorksheetPayableBalanceAfterTaxFactory, ) @patch('payment.logic.payment_group_payment_batch.PaymentGroupPaymentBatch') @patch('payment.logic.payment_group_payment_batch.PaymentGroupPayment') def test_create_payment_batch_success( mock_payment_group_payment, mock_payment_group_payment_batch ): """Test successfully creating payment_group_payment_batch.""" payment_group_payment = PaymentGroupPaymentFactory.create() payment_group_payment_id = payment_group_payment.payment_group_payment_id params = { 'payment_group_payment_id': payment_group_payment_id, 'payoneer_program_id': 1001, 'batch_num': 1, } res = logic.create_payment_group_payment_batch(**params) assert res == mock_payment_group_payment_batch.create.return_value mock_payment_group_payment_batch.create.assert_called_once_with(**params) def test_create_payment_batch_failure(): """Test creating payment batch throws an exception when payment_group_payment_id doesn't exist.""" # noqa: E501 params = { 'payment_group_payment_id': 1234, 'payoneer_program_id': 1001, 'batch_num': 1, } with pytest.raises(Exception): logic.create_payment_group_payment_batch(**params) @patch('payment.logic.payment_group_payment_batch.PaymentGroupPaymentBatch') def test_get_payment_group_payment_batches(mock_payment_group_payment_batch): """Test get_payment_group_payment_batches function.""" payment_group_payment_id = 1 payment_batch_status = 'failed' payment_group_payment_batches = PaymentGroupPaymentBatchFactory.build_batch(2) mock_payment_group_payment_batch.get_by_payment_group_payment_and_batch_status.return_value = payment_group_payment_batches res = logic.get_payment_group_payment_batches( payment_group_payment_id, payment_batch_status ) assert res == payment_group_payment_batches mock_payment_group_payment_batch.get_by_payment_group_payment_and_batch_status.assert_called_once_with( payment_group_payment_id, payment_batch_status ) def test_get_payment_group_payment_batches_invalid_batch_status(): """Test get_payment_group_payment_batches function for invalid batch status.""" payment_batch_status = 'test' with pytest.raises(LogicError) as exc_info: logic.get_payment_group_payment_batches(1, payment_batch_status) assert str(exc_info.value) == ERROR_INVALID_PAYMENT_BATCH_STATUS.format( batch_status=', '.join(VALID_PAYMENT_BATCH_STATUSES) ) def test_validate_payment_batch_status_success(): """Test _validate_payment_batch_status function for valid status.""" res = logic._validate_payment_batch_status('failed') assert res def test_validate_payment_batch_status_failed(): """Test _validate_payment_batch_status function for invalid status.""" with pytest.raises(LogicError): logic._validate_payment_batch_status('test') @pytest.mark.parametrize('payment_type', PAYMENT_TYPES) @patch('payment.logic.payment_group_payment_batch.PaymentDebitCreditDataEntry') @patch('payment.logic.payment_group_payment_batch.repository') def test_get_batch_debit_data( mock_repository, mock_payment_debit_credit_data_entry, payment_type, mock_accounts, mock_contracts, mock_abacus_event, mock_ledger_account_contracts, ): """Test get_batch_debit_data method.""" worksheet_closing_balance = WorksheetAccountContractClosingBalanceFactory.create() worksheet_after_tax1 = WorksheetPayableBalanceAfterTaxFactory.create( # noqa worksheet_account_contract_closing_balance_id=worksheet_closing_balance.worksheet_account_contract_closing_balance_id ) detail = PaymentGroupPaymentAccountDetailFactory.create( # noqa worksheet_account_contract_payable_after_tax_id=worksheet_after_tax1.worksheet_account_contract_payable_after_tax_id ) batch = PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_account=detail.payment_group_payment_account ) mock_repository.get_by_payment_group_payment_batch.return_value = [detail] mock_data_entry = PaymentDebitCreditDataEntryFactory.build() mock_payment_debit_credit_data_entry.return_value = mock_data_entry res = logic.get_batch_debit_data(batch.payment_group_payment_batch_id, payment_type) match payment_type: case PAYMENT_TYPES.WHT: # negative according to formula, return as is amount = detail.tax_withholding_amount case PAYMENT_TYPES.VAT: # positive according to formula, return as is amount = detail.vat_amount case _: # positive according to formula, make negative amount = ( detail.payable_amount_post_tax * -1 if detail.payable_amount_post_tax else detail.payable_amount_post_tax ) assert res == [mock_data_entry] assert mock_repository.get_by_payment_group_payment_batch.call_args_list == [ call(batch.payment_group_payment_batch_id) ] assert mock_payment_debit_credit_data_entry.call_args_list == [ call( detail.account_id, detail.contract_id, detail.currency_code, amount, detail.worksheet_account_contract_payable_after_tax_id, ) ] @pytest.mark.parametrize('payment_type', PAYMENT_TYPES) @patch('payment.logic.payment_group_payment_batch.PaymentDebitCreditDataEntry') @patch('payment.logic.payment_group_payment_batch.repository') def test_get_batch_debit_data_no_zero_amounts( mock_repository, mock_payment_debit_credit_data_entry, payment_type, mock_accounts, mock_contracts, mock_abacus_event, mock_ledger_account_contracts, ): """Test get_batch_debit_data method.""" worksheet_closing_balance = WorksheetAccountContractClosingBalanceFactory.create() worksheet_after_tax1 = WorksheetPayableBalanceAfterTaxFactory.create( # noqa worksheet_account_contract_closing_balance_id=worksheet_closing_balance.worksheet_account_contract_closing_balance_id ) detail = PaymentGroupPaymentAccountDetailFactory.create( # noqa worksheet_account_contract_payable_after_tax_id=worksheet_after_tax1.worksheet_account_contract_payable_after_tax_id, payable_amount_pre_tax=0, tax_withholding_amount=0, payable_amount_post_tax=0, vat_amount=0, ) batch = PaymentGroupPaymentBatchAccountFactory.create( payment_group_payment_account=detail.payment_group_payment_account ) mock_repository.get_by_payment_group_payment_batch.return_value = [detail] mock_data_entry = PaymentDebitCreditDataEntryFactory.build() mock_payment_debit_credit_data_entry.return_value = mock_data_entry res = logic.get_batch_debit_data(batch.payment_group_payment_batch_id, payment_type) assert res == [] @patch('payment.logic.payment_group_payment_batch.PaymentGroupPaymentBatch') def test_get_payment_group_payment_batch_success(mock_payment_group_payment_batch): """Test successfully getting payment_group_payment_batch by id.""" payment_group_payment_batch = PaymentGroupPaymentBatchFactory.build() mock_payment_group_payment_batch.get_by_id_or_error.return_value = ( payment_group_payment_batch ) res = logic.get_payment_batch_by_id( payment_group_payment_batch.payment_group_payment_batch_id ) assert res == payment_group_payment_batch mock_payment_group_payment_batch.get_by_id_or_error.assert_called_once_with( payment_group_payment_batch.payment_group_payment_batch_id ) def test_get_payment_group_payment_batch_failure(): """Test getting payment batch throws an exception when payment_group_payment_batch_id doesn't exist.""" # noqa: E501 with pytest.raises(Exception): logic.get_payment_batch_by_id(123)