"""Unit tests for worksheet_account_contract_closing_balance handler.""" from decimal import Decimal from unittest.mock import call, patch from payment.constants import constants from payment.schemas.worksheet_account_contract_closing_balance import ( PaginatedWorksheetAccountContractClosingBalanceOutputSchema, WorksheetAccountContractClosingBalanceSchema, ) from tests.utils.factories import WorksheetAccountContractClosingBalanceFactory @patch( 'payment.blueprints.worksheet_account_contract_closing_balance.logic.bulk_create' ) def test_create(mock_logic, fixture_client): """Test bulk create method.""" worksheet_account_contract_closing_balance_1 = ( WorksheetAccountContractClosingBalanceFactory.build() ) worksheet_account_contract_closing_balance_2 = ( WorksheetAccountContractClosingBalanceFactory.build() ) post_body = [ { 'account_id': worksheet_account_contract_closing_balance_1.account_id, 'contract_id': 1, 'amount': str(worksheet_account_contract_closing_balance_1.amount), 'ledger_account_contract_id': worksheet_account_contract_closing_balance_1.ledger_account_contract_id, # noqa: E501 'currency_code': worksheet_account_contract_closing_balance_1.currency_code, 'includes_tax_adjustments': worksheet_account_contract_closing_balance_1.includes_tax_adjustments, # noqa: E501 }, { 'account_id': worksheet_account_contract_closing_balance_2.account_id, 'contract_id': 2, 'amount': str(worksheet_account_contract_closing_balance_2.amount), 'ledger_account_contract_id': worksheet_account_contract_closing_balance_2.ledger_account_contract_id, # noqa: E501 'currency_code': worksheet_account_contract_closing_balance_2.currency_code, 'includes_tax_adjustments': worksheet_account_contract_closing_balance_2.includes_tax_adjustments, # noqa: E501 }, ] mock_instances = [ worksheet_account_contract_closing_balance_1, worksheet_account_contract_closing_balance_2, ] mock_logic.return_value = mock_instances res = fixture_client.post( '/worksheet-account-contract-closing-balance/event/1/statement-period/1/payment-entity/1/bulk/', # noqa: E501 json=post_body, ) assert res.status_code == 201 assert res.json == WorksheetAccountContractClosingBalanceSchema(many=True).dump( mock_instances ) expected_create_params = [ { 'account_id': worksheet_account_contract_closing_balance_1.account_id, 'contract_id': 1, 'amount': Decimal(str(worksheet_account_contract_closing_balance_1.amount)), 'ledger_account_contract_id': worksheet_account_contract_closing_balance_1.ledger_account_contract_id, # noqa: E501 'currency_code': worksheet_account_contract_closing_balance_1.currency_code, 'includes_tax_adjustments': worksheet_account_contract_closing_balance_1.includes_tax_adjustments, # noqa: E501 }, { 'account_id': worksheet_account_contract_closing_balance_2.account_id, 'contract_id': 2, 'amount': Decimal(str(worksheet_account_contract_closing_balance_2.amount)), 'ledger_account_contract_id': worksheet_account_contract_closing_balance_2.ledger_account_contract_id, # noqa: E501 'currency_code': worksheet_account_contract_closing_balance_2.currency_code, 'includes_tax_adjustments': worksheet_account_contract_closing_balance_2.includes_tax_adjustments, # noqa: E501 }, ] assert mock_logic.call_args_list == [call(1, 1, 1, tuple(expected_create_params))] @patch( 'payment.blueprints.worksheet_account_contract_closing_balance.logic.bulk_delete' ) def test_delete(mock_logic, fixture_client): """Test bulk soft delete method.""" mock_logic.return_value = None res = fixture_client.delete( '/worksheet-account-contract-closing-balance/event/1/bulk/' ) assert res.status_code == 204 assert mock_logic.call_args_list == [call(1)] @patch( 'payment.blueprints.worksheet_account_contract_closing_balance.logic.get_by_statement_period_id' # noqa: E501 ) def test_get_by_statement_period_id(mock_logic, fixture_client): """Test get contracts by statement period id.""" worksheet_account_contract_closing_balance = ( WorksheetAccountContractClosingBalanceFactory.build() ) mock_response = { 'items': [worksheet_account_contract_closing_balance], 'total_count': 1, } mock_logic.return_value = mock_response res = fixture_client.get( f'/worksheet-account-contract-closing-balance/statement-period/' f'{worksheet_account_contract_closing_balance.statement_period_id}/' ) assert res.status_code == 200 assert ( res.json['items'] == PaginatedWorksheetAccountContractClosingBalanceOutputSchema().dump( mock_response )['items'] ) assert res.json['total_count'] == mock_response['total_count'] assert mock_logic.call_args_list == [ call( statement_period_id=worksheet_account_contract_closing_balance.statement_period_id, # noqa: E501 account_ids=[], contract_ids=[], limit=100, offset=0, ) ] res = fixture_client.get( f'/worksheet-account-contract-closing-balance/statement-period/' f'{worksheet_account_contract_closing_balance.statement_period_id}/' f'?limit=10&offset=5&account_ids=1,2&contract_ids=1,2' ) assert res.status_code == 200 assert ( res.json['items'] == PaginatedWorksheetAccountContractClosingBalanceOutputSchema().dump( mock_response )['items'] ) assert res.json['total_count'] == mock_response['total_count'] assert mock_logic.call_args_list == [ call( statement_period_id=worksheet_account_contract_closing_balance.statement_period_id, # noqa: E501 account_ids=[], contract_ids=[], limit=100, offset=0, ), call( statement_period_id=worksheet_account_contract_closing_balance.statement_period_id, # noqa: E501 account_ids=[1, 2], contract_ids=[1, 2], limit=10, offset=5, ), ] @patch('payment.blueprints.worksheet_account_contract_closing_balance.logic.get_by_ids') def test_get_bulk_by_worksheet_closing_balance_ids(mock_logic, fixture_client): """Test POST /bulk returns closing balances by IDs.""" instance = WorksheetAccountContractClosingBalanceFactory.build() mock_response = {'items': [instance], 'total_count': 1} mock_logic.return_value = mock_response res = fixture_client.post( '/worksheet-account-contract-closing-balance/bulk', json={'filters': {'worksheet_closing_balance_ids': [1, 2]}}, ) assert res.status_code == 200 expected = PaginatedWorksheetAccountContractClosingBalanceOutputSchema().dump( mock_response ) assert res.json == expected assert mock_logic.call_args_list == [ call( worksheet_closing_balance_ids=[1, 2], limit=100, offset=0, ) ] @patch('payment.blueprints.worksheet_account_contract_closing_balance.logic.get_by_ids') def test_get_bulk_by_worksheet_closing_balance_ids_no_filters( mock_logic, fixture_client ): """Test that omitting filters calls logic with no IDs (fields are optional).""" mock_response = {'items': [], 'total_count': 0} mock_logic.return_value = mock_response res = fixture_client.post( '/worksheet-account-contract-closing-balance/bulk', json={}, ) assert res.status_code == 200 assert mock_logic.call_args_list == [ call( worksheet_closing_balance_ids=None, limit=100, offset=0, ) ] @patch('payment.blueprints.worksheet_account_contract_closing_balance.logic') def test_worksheet_by_payment_account_ids_dataloader_success( mock_logic, fixture_client, faker ): """ Test POST request success. Endpoint: /worksheet-account-contract-closing-balance/by-payment-account-ids/dataloader. """ mock_data = { 'items': [ { 'data': { 'worksheet_account_contract_closing_balance_id': 1, 'account_id': 12, 'contract_id': 123, 'reference_payment_entity_id': 1234, 'abacus_event_id': 1234, 'ledger_account_contract_id': 1234, 'statement_period_id': 1234, 'currency_code': 'USD', 'amount': '100.00', 'includes_tax_adjustments': False, } } ] } mock_logic.dataload_by_payment_account_ids.return_value = mock_data test_ids = faker.pylist(value_types=[int]) res = fixture_client.post( '/worksheet-account-contract-closing-balance' '/by-payment-account-ids/dataloader', json=test_ids, ) assert res.status_code == 200, res.text assert res.json == mock_data assert mock_logic.dataload_by_payment_account_ids.call_args_list == [call(test_ids)] @patch('payment.blueprints.worksheet_account_contract_closing_balance.logic') def test_worksheet_by_payment_account_ids_dataloader_failure( mock_logic, fixture_client, faker ): """ Test POST request failure. Endpoint: /worksheet-account-contract-closing-balance/by-payment-account-ids/dataloader. """ mock_logic.dataload_by_payment_account_ids.return_value = [] test_ids = faker.pylist(value_types=[str]) res = fixture_client.post( '/worksheet-account-contract-closing-balance' '/by-payment-account-ids/dataloader', json=test_ids, ) assert res.status_code == 400 assert not mock_logic.dataload_by_payment_account_ids.called @patch( 'payment.blueprints.worksheet_account_contract_closing_balance.logic.bulk_copy_into_taxable_revenue_by_event_id' # noqa: E501 ) def test_bulk_copy_close_balances_to_taxable_revenues(mock_logic, fixture_client): """Test copy close_balance into taxable_revenue by event id.""" mock_logic.return_value = None event_id = 1 res = fixture_client.post( '/worksheet-account-contract-closing-balance/event/' f'{event_id}/taxable-revenue/copy/' ) assert res.status_code == 201 assert res.json == constants.BULK_ENDPOINT_SUCCESS_RESPONSE assert mock_logic.call_args_list == [call(event_id)]