"""Unit tests for CommitCustomPayment.""" from decimal import Decimal from unittest.mock import patch import pytest from commit_ledger_account_contract.constants.constants import ( CUSTOM_PAYMENT_AMOUNT_TYPES, LEDGER_EVENT_TYPES, LEDGER_TYPES, ) from commit_ledger_account_contract.constants.errors import SOMETHING_WENT_WRONG from commit_ledger_account_contract.ledger_events.commit_custom_payment import ( CommitCustomPayment, ) import_path = 'commit_ledger_account_contract.ledger_events.commit_custom_payment' def test__format_ledger_account_contract_entries_payment_debit( mock_custom_payment_data, ): """Test formatting ledger_account_contract entry for payment debit.""" commit = CommitCustomPayment( abacus_event_id=999, ledger_event_type=LEDGER_EVENT_TYPES.DEBIT, amount_type=CUSTOM_PAYMENT_AMOUNT_TYPES.PAYMENT, worksheet_payment_custom_id=111, ) res = commit._format_ledger_account_contract_entries(mock_custom_payment_data) assert len(res) == 1 assert res[0] == { 'abacus_event_id': 999, 'account_id': mock_custom_payment_data['account_id'], 'contract_id': mock_custom_payment_data['contract_id'], 'currency_amount': -Decimal( mock_custom_payment_data['amount_after_withholding_and_vat'] ), 'currency_code': mock_custom_payment_data['currency_code'], 'model_type': LEDGER_TYPES.ACCOUNT, } def test__format_ledger_account_contract_entries_payment_credit( mock_custom_payment_data, ): """Test formatting ledger_account_contract entry for payment credit.""" commit = CommitCustomPayment( abacus_event_id=999, ledger_event_type=LEDGER_EVENT_TYPES.CREDIT, amount_type=CUSTOM_PAYMENT_AMOUNT_TYPES.PAYMENT, worksheet_payment_custom_id=111, ) res = commit._format_ledger_account_contract_entries(mock_custom_payment_data) assert len(res) == 1 assert res[0]['currency_amount'] == Decimal( mock_custom_payment_data['amount_after_withholding_and_vat'] ) def test__format_ledger_account_contract_entries_vat_debit(mock_custom_payment_data): """Test formatting ledger_account_contract entry for VAT debit.""" commit = CommitCustomPayment( abacus_event_id=999, ledger_event_type=LEDGER_EVENT_TYPES.DEBIT, amount_type=CUSTOM_PAYMENT_AMOUNT_TYPES.VAT, worksheet_payment_custom_id=111, ) res = commit._format_ledger_account_contract_entries(mock_custom_payment_data) assert len(res) == 1 assert res[0]['currency_amount'] == Decimal(mock_custom_payment_data['vat_amount']) def test__format_ledger_account_contract_entries_wht_credit(mock_custom_payment_data): """Test formatting ledger_account_contract entry for WHT credit (sign inverted).""" commit = CommitCustomPayment( abacus_event_id=999, ledger_event_type=LEDGER_EVENT_TYPES.CREDIT, amount_type=CUSTOM_PAYMENT_AMOUNT_TYPES.WHT, worksheet_payment_custom_id=111, ) res = commit._format_ledger_account_contract_entries(mock_custom_payment_data) assert len(res) == 1 assert res[0]['currency_amount'] == -Decimal( mock_custom_payment_data['withholding_tax_amount'] ) def test__format_ledger_account_contract_entries_unknown_amount_type_raises( mock_custom_payment_data, ): """Test unknown amount type raises Exception.""" commit = CommitCustomPayment( abacus_event_id=999, ledger_event_type=LEDGER_EVENT_TYPES.DEBIT, amount_type='unknown', worksheet_payment_custom_id=111, ) with pytest.raises(Exception, match='Unknown amount_type'): commit._format_ledger_account_contract_entries(mock_custom_payment_data) @patch(f'{import_path}.LedgerEntryQueue') @patch(f'{import_path}.get_worksheet_payment_custom_data') @patch('commit_ledger_account_contract.ledger_events.commit_custom_payment.config') def test_commit_batches_and_flushes( mock_config, mock_get_data, mock_queue, mock_custom_payment_data ): """Test commit batches entries and flushes.""" mock_config.BATCH_SIZE_POST = '2' mock_get_data.return_value = mock_custom_payment_data mock_queue.return_value.length = 2 entry_base = { 'abacus_event_id': 999, 'account_id': mock_custom_payment_data['account_id'], 'contract_id': mock_custom_payment_data['contract_id'], 'currency_code': mock_custom_payment_data['currency_code'], 'model_type': LEDGER_TYPES.ACCOUNT, } entry1 = {**entry_base, 'currency_amount': 1} entry2 = {**entry_base, 'currency_amount': 2} with patch.object( CommitCustomPayment, '_format_ledger_account_contract_entries', return_value=[entry1, entry2], ): commit = CommitCustomPayment( abacus_event_id=999, ledger_event_type=LEDGER_EVENT_TYPES.DEBIT, amount_type=CUSTOM_PAYMENT_AMOUNT_TYPES.VAT, worksheet_payment_custom_id=111, ) commit.commit() mock_get_data.assert_called_once_with(111) assert mock_queue.return_value.append.call_count == 2 assert mock_queue.return_value.flush_entries.call_count >= 1 @patch(f'{import_path}.app_logger') @patch(f'{import_path}.get_worksheet_payment_custom_data') def test_commit_handles_error_and_raises(mock_get_data, mock_logger): """Test commit handles errors: logs and re-raises.""" mock_get_data.side_effect = Exception('test') commit = CommitCustomPayment( abacus_event_id=999, ledger_event_type=LEDGER_EVENT_TYPES.DEBIT, amount_type=CUSTOM_PAYMENT_AMOUNT_TYPES.PAYMENT, worksheet_payment_custom_id=111, ) with pytest.raises(Exception, match='test'): commit.commit() mock_logger.error.assert_any_call( SOMETHING_WENT_WRONG.format('custom payment: 111/debit/payment') ) mock_logger.error.assert_called_with('test')