"""Test ledger account handlers.""" from datetime import datetime from unittest.mock import MagicMock, patch import pytest from flask.testing import FlaskClient from owsresponse import response from ledger.constants import error from ledger.constants.constants import DEFAULT_PAGE_LIMIT, DEFAULT_PAGE_OFFSET @patch('ledger.blueprints.ledger_account.logic') def test_get_ledger_info(mock_logic, fixture_client): """Test get ledger items by account_id.""" account_id = 123 mock_ledger_items = [ { 'ledger_account_id': 1, 'account_id': account_id, 'accounting_period_id': 1, 'amount': '320260.99', 'contract_id': 44, 'currency_code': 'USD', 'date': '2020-05-07', 'ending_balance': '320260.99', 'opening_balance': '0.00', 'transaction_type': 'accounting_run', } ] mock_logic.get_ledger_account_info.return_value = response.Response( message=mock_ledger_items, status=200 ) res = fixture_client.get(f'/ledger-account/account/{account_id}') assert res.status_code == 200 assert res.json == mock_ledger_items mock_logic.get_ledger_account_info.assert_called_once_with(account_id) @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.pdp_authorize_resource') @patch('ledger.blueprints.ledger_account.LedgerAccount') def test_get_ledger_info_paginated( mock_model: MagicMock, mock_pdp_authorize_resource: MagicMock, authorize_account_return: bool, profile_type: str, profile_role: str, expected_status_code: int, fixture_client: FlaskClient, ) -> None: """Test get ledger items by account_id.""" mock_pdp_authorize_resource.return_value = authorize_account_return account_id = 123 mock_ledger_items = [ { 'ledger_account_id': 1, 'account_id': 123, 'accounting_period_id': 1, 'amount': '320260.99', 'contract_id': 44, 'currency_code': 'USD', 'date': datetime(2020, 5, 17), 'ending_balance': '320260.99', 'opening_balance': '0.00', 'statement_period_id': 265, 'transaction_type': 'accounting_run', } ] mock_model.get_ledger_account_info.return_value = mock_ledger_items, 1 res = fixture_client.get( f'/ledger-accounts/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 = 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['items'] assert res.json['total_count'] mock_model.get_ledger_account_info.assert_called_once_with( account_id, limit=DEFAULT_PAGE_LIMIT, offset=DEFAULT_PAGE_OFFSET ) @patch('ledger.blueprints.ledger_account.logic') def test_get_current_balance(mock_logic, fixture_client): """Test getting an account's current balance.""" account_id = 123 mock_current_balance = { 'current_balance': '320260.99', 'currency_code': 'USD', 'currency_name': 'US Dollars', } mock_logic.get_current_balance.return_value = response.Response( message=mock_current_balance, status=200 ) res = fixture_client.get(f'/ledger-account/account/{account_id}/current-balance') assert res.status_code == 200 assert res.json == mock_current_balance mock_logic.get_current_balance.assert_called_once_with(account_id) @pytest.mark.parametrize( ('access_check_result', 'expected_status'), [ pytest.param(True, 200, id='Access OK'), pytest.param(False, 403, id='Access not OK'), ], ) @patch('ledger.blueprints.ledger_account.logic') @patch('ledger.blueprints.ledger_account.flask_request') @patch('ledger.blueprints.ledger_account.permissions_authorize_many_accounts') @patch('ledger.blueprints.ledger_account.ows_client') def test_access_check_get_current_balance( mock_ows_client, mock_authorize_many_accounts, mock_flask_request, mock_logic, fixture_client, access_check_result, expected_status, ): """Test the access check for the `current-balance` endpoint.""" mock_authorize_many_accounts.return_value = access_check_result mock_flask_request.verify_rules_access_standalone.return_value = True mock_current_balance = { 'current_balance': '320260.99', 'currency_code': 'USD', 'currency_name': 'US Dollars', } mock_logic.get_current_balance.return_value = response.Response( message=mock_current_balance, status=200 ) account_id = 1 res = fixture_client.get( f'/ledger-account/account/{account_id}/current-balance', headers={ 'Orchard-Profile-Type': 'MoneyhubProfile', 'Orchard-Profile-Id': '123', }, ) assert res.status_code == expected_status mock_authorize_many_accounts.assert_called_once_with( mock_ows_client, 'MoneyhubProfile', '123', [account_id] ) @patch('ledger.blueprints.ledger_account.logic') def test_get_ledger_accounts(mock_logic, fixture_client): """Test getting ledger_account list by accounting_period_id.""" accounting_period_id = 100 ledger_items = ['ledger_account_1', 'ledger_account_2'] mock_logic.get_ledger_accounts_by_acc_period_id.return_value = response.Response( message=ledger_items, status=200 ) res = fixture_client.get( f'/ledger-account/accounting-period/{accounting_period_id}/accounts' ) assert res.status_code == 200 mock_logic.get_ledger_accounts_by_acc_period_id.assert_called_once()