"""Functional tests for LedgerAccountContract.""" from typing import Any from unittest.mock import MagicMock, patch import pytest from flask.testing import FlaskClient from ledger.constants import error from tests.conftest import mock_account from tests.utils.factories import LedgerAccountContractFactory @pytest.mark.parametrize( ( 'authorize_account_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standalone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ), ], ) @patch('ledger.blueprints.ledger_account_contract.pdp_authorize_resource') def test_get_payable_balance_by_account( mock_pdp_authorize_resource: MagicMock, authorize_account_return: bool, profile_type: str, profile_role: str, expected_status_code: int, fixture_client: FlaskClient, mock_event_fixtures: Any, ): """Test GET /ledger-account-contract/account//payable-balance.""" mock_pdp_authorize_resource.return_value = authorize_account_return account_id = 2 currency_code = 'USD' mock_account(account_id) LedgerAccountContractFactory.create( account_id=account_id, contract_id=1, abacus_event_id=2, currency_code=currency_code, current_balance=1000.00, ) LedgerAccountContractFactory.create( account_id=account_id, contract_id=2, abacus_event_id=2, currency_code=currency_code, current_balance=-100.00, ) LedgerAccountContractFactory.create( account_id=account_id, contract_id=3, abacus_event_id=2, currency_code=currency_code, current_balance=2000.00, ) res = fixture_client.get( f'/ledger-account-contract/account/{account_id}/payable-balance', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus', }, ) res_json = res.json assert res.status_code == expected_status_code if expected_status_code == 403: assert res_json['code'] == error.ERROR_CODE_AUTHORIZATION assert res_json['message'] == 'Unauthorized' else: assert res.json == { 'account_id': account_id, 'currency_code': currency_code, 'payable_balance': '3000.00', } @pytest.mark.parametrize( ( 'authorize_account_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standalone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ), ], ) @patch('ledger.blueprints.ledger_account_contract.pdp_authorize_resource') def test_get_ledger_list_by_account_id( mock_pdp_authorize_resource: MagicMock, authorize_account_return: bool, profile_type: str, profile_role: str, expected_status_code: int, fixture_client: FlaskClient, mock_event_fixtures: Any, ) -> None: """Test getting list of ledgers by account_id.""" mock_pdp_authorize_resource.return_value = authorize_account_return account_id = 50 LedgerAccountContractFactory.create( account_id=1, abacus_event_id=24, currency_code='USD', currency_amount=-1000.0, previous_balance=5000.00, current_balance=4000.00, note='mechanical deduction (debit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=1, currency_code='USD', currency_amount=-100.0, previous_balance=0, current_balance=-100.0, note='take reserves (debit)', ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=2, currency_code='USD', currency_amount=5000.0, previous_balance=-100.00, current_balance=4900.00, note='close accounting period (credit)', contract_id=2, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=9, currency_code='USD', currency_amount=500.0, previous_balance=-100.00, current_balance=400.00, note='commit accounting run (credit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=3, currency_code='USD', currency_amount=25.00, previous_balance=4900.00, current_balance=4925.00, note='release reserves (credit)', ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=5, currency_code='USD', currency_amount=-502.37, previous_balance=4925.00, current_balance=4422.63, note='adjustments applied (debit)', contract_id=4, ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=6, currency_code='USD', currency_amount=-4422.63, previous_balance=4422.63, current_balance=0.00, note='payment accepted (debit)', contract_id=4, ) result = fixture_client.get( f'/ledger-account-contracts/account/{account_id}', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus', }, ) res_json = result.json assert result.status_code == expected_status_code if expected_status_code == 403: assert res_json['code'] == error.ERROR_CODE_AUTHORIZATION assert res_json['message'] == 'Unauthorized' else: assert result.json['total_count'] == 2 assert result.json['items'] == [ { 'ledger_account_contract_id': 7, 'account_id': 50, 'accounting_period_id': None, 'amount': '-4422.63', 'contract_id': 4, 'currency_code': 'USD', 'date': '2020-01-04', 'ending_balance': '0.00', 'opening_balance': '4422.63', 'statement_period_id': 1, 'transaction_type': 'send_payments', }, { 'ledger_account_contract_id': 6, 'account_id': 50, 'accounting_period_id': None, 'amount': '-502.37', 'contract_id': 4, 'currency_code': 'USD', 'date': '2020-01-04', 'ending_balance': '4422.63', 'opening_balance': '4925.00', 'statement_period_id': 1, 'transaction_type': 'apply_pending_adjustments', }, ] @pytest.mark.parametrize( ( 'authorize_account_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standalone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ), ], ) @patch('ledger.blueprints.ledger_account_contract.pdp_authorize_resource') def test_get_ledger_list_by_account_id_and_event_names( mock_pdp_authorize_resource: MagicMock, authorize_account_return: bool, profile_type: str, profile_role: str, expected_status_code: int, fixture_client: FlaskClient, mock_event_fixtures: Any, ) -> None: """Test getting list of ledgers by account_id and event_names.""" mock_pdp_authorize_resource.return_value = authorize_account_return account_id = 50 LedgerAccountContractFactory.create( account_id=1, abacus_event_id=24, currency_code='USD', currency_amount=-1000.0, previous_balance=5000.00, current_balance=4000.00, note='mechanical deduction (debit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=1, currency_code='USD', currency_amount=-100.0, previous_balance=0, current_balance=-100.0, note='take reserves (debit)', ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=2, currency_code='USD', currency_amount=5000.0, previous_balance=-100.00, current_balance=4900.00, note='close accounting period (credit)', contract_id=2, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=9, currency_code='USD', currency_amount=500.0, previous_balance=-100.00, current_balance=400.00, note='commit accounting run (credit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=3, currency_code='USD', currency_amount=25.00, previous_balance=4900.00, current_balance=4925.00, note='release reserves (credit)', ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=5, currency_code='USD', currency_amount=-502.37, previous_balance=4925.00, current_balance=4422.63, note='adjustments applied (debit)', contract_id=4, ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=6, currency_code='USD', currency_amount=-4422.63, previous_balance=4422.63, current_balance=0.00, note='payment accepted (debit)', contract_id=4, ) query_params = '?event_names=send_payments,payment_returned' result = fixture_client.get( f'/ledger-account-contracts/account/{account_id}{query_params}', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus', }, ) res_json = result.json assert result.status_code == expected_status_code if expected_status_code == 403: assert res_json['code'] == error.ERROR_CODE_AUTHORIZATION assert res_json['message'] == 'Unauthorized' else: assert result.json['total_count'] == 1 assert result.json['items'] == [ { 'ledger_account_contract_id': 7, 'account_id': 50, 'accounting_period_id': None, 'amount': '-4422.63', 'contract_id': 4, 'currency_code': 'USD', 'date': '2020-01-04', 'ending_balance': '0.00', 'opening_balance': '4422.63', 'statement_period_id': 1, 'transaction_type': 'send_payments', } ] @pytest.mark.parametrize( ( 'authorize_account_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standalone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ), ], ) @patch('ledger.blueprints.ledger_account_contract.pdp_authorize_resource') def test_get_ledger_list_by_account_id_and_statement_period_ids( mock_pdp_authorize_resource: MagicMock, authorize_account_return: bool, profile_type: str, profile_role: str, expected_status_code: int, fixture_client: FlaskClient, mock_event_fixtures: Any, ) -> None: """Test getting list of ledgers by account_id and statement_period_ids.""" mock_pdp_authorize_resource.return_value = authorize_account_return account_id = 50 LedgerAccountContractFactory.create( account_id=1, abacus_event_id=24, currency_code='USD', currency_amount=-1000.0, previous_balance=5000.00, current_balance=4000.00, note='mechanical deduction (debit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=1, currency_code='USD', currency_amount=-100.0, previous_balance=0, current_balance=-100.0, note='take reserves (debit)', ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=2, currency_code='USD', currency_amount=5000.0, previous_balance=-100.00, current_balance=4900.00, note='close accounting period (credit)', contract_id=2, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=9, currency_code='USD', currency_amount=500.0, previous_balance=-100.00, current_balance=400.00, note='commit accounting run (credit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=3, currency_code='USD', currency_amount=25.00, previous_balance=4900.00, current_balance=4925.00, note='release reserves (credit)', ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=5, currency_code='USD', currency_amount=-502.37, previous_balance=4925.00, current_balance=4422.63, note='adjustments applied (debit)', contract_id=4, ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=6, currency_code='USD', currency_amount=-4422.63, previous_balance=4422.63, current_balance=0.00, note='payment accepted (debit)', contract_id=4, ) query_params = '?statement_period_ids=1,2,3,4' result = fixture_client.get( f'/ledger-account-contracts/account/{account_id}{query_params}', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus', }, ) res_json = result.json assert result.status_code == expected_status_code if expected_status_code == 403: assert res_json['code'] == error.ERROR_CODE_AUTHORIZATION assert res_json['message'] == 'Unauthorized' else: assert result.json['total_count'] == 2 assert result.json['items'] == [ { 'ledger_account_contract_id': 7, 'account_id': 50, 'accounting_period_id': None, 'amount': '-4422.63', 'contract_id': 4, 'currency_code': 'USD', 'date': '2020-01-04', 'ending_balance': '0.00', 'opening_balance': '4422.63', 'statement_period_id': 1, 'transaction_type': 'send_payments', }, { 'ledger_account_contract_id': 6, 'account_id': 50, 'accounting_period_id': None, 'amount': '-502.37', 'contract_id': 4, 'currency_code': 'USD', 'date': '2020-01-04', 'ending_balance': '4422.63', 'opening_balance': '4925.00', 'statement_period_id': 1, 'transaction_type': 'apply_pending_adjustments', }, ] @pytest.mark.parametrize( ( 'authorize_account_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standalone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ), ], ) @patch('ledger.blueprints.ledger_account_contract.pdp_authorize_resource') def test_get_ledger_list_by_account_id_and_filters( mock_pdp_authorize_resource: MagicMock, authorize_account_return: bool, profile_type: str, profile_role: str, expected_status_code: int, fixture_client: FlaskClient, mock_event_fixtures: Any, ) -> None: """Test getting list of ledgers by account_id and event_names/statement_period_ids filters.""" mock_pdp_authorize_resource.return_value = authorize_account_return account_id = 50 LedgerAccountContractFactory.create( account_id=1, abacus_event_id=24, currency_code='USD', currency_amount=-1000.0, previous_balance=5000.00, current_balance=4000.00, note='mechanical deduction (debit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=1, currency_code='USD', currency_amount=-100.0, previous_balance=0, current_balance=-100.0, note='take reserves (debit)', ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=2, currency_code='USD', currency_amount=5000.0, previous_balance=-100.00, current_balance=4900.00, note='close accounting period (credit)', contract_id=2, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=9, currency_code='USD', currency_amount=500.0, previous_balance=-100.00, current_balance=400.00, note='commit accounting run (credit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=3, currency_code='USD', currency_amount=25.00, previous_balance=4900.00, current_balance=4925.00, note='release reserves (credit)', ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=5, currency_code='USD', currency_amount=-502.37, previous_balance=4925.00, current_balance=4422.63, note='adjustments applied (debit)', contract_id=4, ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=6, currency_code='USD', currency_amount=-4422.63, previous_balance=4422.63, current_balance=0.00, note='payment accepted (debit)', contract_id=4, ) statement_period_ids = 'statement_period_ids=1,2,3,4' event_names = 'event_names=apply_pending_adjustments,tax_withholding' query_params = f'?{event_names}&{statement_period_ids}' result = fixture_client.get( f'/ledger-account-contracts/account/{account_id}{query_params}', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus', }, ) res_json = result.json assert result.status_code == expected_status_code if expected_status_code == 403: assert res_json['code'] == error.ERROR_CODE_AUTHORIZATION assert res_json['message'] == 'Unauthorized' else: assert result.json['total_count'] == 1 assert result.json['items'] == [ { 'ledger_account_contract_id': 6, 'account_id': 50, 'accounting_period_id': None, 'amount': '-502.37', 'contract_id': 4, 'currency_code': 'USD', 'date': '2020-01-04', 'ending_balance': '4422.63', 'opening_balance': '4925.00', 'statement_period_id': 1, 'transaction_type': 'apply_pending_adjustments', } ] @pytest.mark.parametrize( ( 'authorize_account_return', 'profile_type', 'profile_role', 'expected_status_code', ), [ pytest.param( None, 'AbacusProfile', 'administrator', 200, id='standalone check passes' ), pytest.param( True, 'Account360Profile', 'account360', 200, id='pdp check authorized' ), pytest.param( False, 'Account360Profile', 'account360', 403, id='pdp check not authorized' ), ], ) @patch('ledger.blueprints.ledger_account_contract.pdp_authorize_resource') def test_get_ledger_list_by_account_id_and_contract_ids( mock_pdp_authorize_resource: MagicMock, authorize_account_return: bool, profile_type: str, profile_role: str, expected_status_code: int, fixture_client: FlaskClient, mock_event_fixtures: Any, ): """Test getting list of ledgers by account_id and contract_ids.""" mock_pdp_authorize_resource.return_value = authorize_account_return account_id = 50 LedgerAccountContractFactory.create( account_id=1, abacus_event_id=24, currency_code='USD', currency_amount=-1000.0, previous_balance=5000.00, current_balance=4000.00, note='mechanical deduction (debit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=1, currency_code='USD', currency_amount=-100.0, previous_balance=0, current_balance=-100.0, note='take reserves (debit)', ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=2, currency_code='USD', currency_amount=5000.0, previous_balance=-100.00, current_balance=4900.00, note='close accounting period (credit)', contract_id=2, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=9, currency_code='USD', currency_amount=500.0, previous_balance=-100.00, current_balance=400.00, note='commit accounting run (credit)', contract_id=1, ) LedgerAccountContractFactory.create( account_id=1, abacus_event_id=3, currency_code='USD', currency_amount=25.00, previous_balance=4900.00, current_balance=4925.00, note='release reserves (credit)', ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=5, currency_code='USD', currency_amount=-502.37, previous_balance=4925.00, current_balance=4422.63, note='adjustments applied (debit)', contract_id=5, ) LedgerAccountContractFactory.create( account_id=50, abacus_event_id=6, currency_code='USD', currency_amount=-4422.63, previous_balance=4422.63, current_balance=0.00, note='payment accepted (debit)', contract_id=4, ) query_params = '?contract_ids=1,2,3,4' result = fixture_client.get( f'/ledger-account-contracts/account/{account_id}{query_params}', headers={ 'Content-Type': 'application/json', 'Orchard-Identity-Id': 'd5ca8ac3-7e51-4793-8775-50d11282504c', 'Orchard-Profile-Id': '35109', 'Orchard-Profile-Type': profile_type, 'Orchard-Roles': profile_role, 'Orchard-Requestor-Service': 'graphql-abacus', }, ) res_json = result.json assert result.status_code == expected_status_code if expected_status_code == 403: assert res_json['code'] == error.ERROR_CODE_AUTHORIZATION assert res_json['message'] == 'Unauthorized' else: assert result.json['total_count'] == 1 assert result.json['items'] == [ { 'ledger_account_contract_id': 7, 'account_id': 50, 'accounting_period_id': None, 'amount': '-4422.63', 'contract_id': 4, 'currency_code': 'USD', 'date': '2020-01-04', 'ending_balance': '0.00', 'opening_balance': '4422.63', 'statement_period_id': 1, 'transaction_type': 'send_payments', } ]