"""Unit tests for WorksheetPaymentContractAdvance API.""" from decimal import Decimal from typing import Any from unittest.mock import call, patch import pytest from payment.models.generic import Items from tests.utils.factories import WorksheetPaymentContractAdvanceFactory @patch('payment.blueprints.worksheet_payment_contract_advance.logic') def test_create_worksheet_payment_contract_advance_success(mock_logic, fixture_client): """Test create_worksheet_payment_contract_advance endpoint.""" worksheet = WorksheetPaymentContractAdvanceFactory.build(contract_advance_id=1) mock_logic.create_worksheet_payment_contract_advance.return_value = worksheet test_data = { 'exchange_rate_id': 1, 'statement_period_id': 1, 'payment_name': 'test_name', 'amount': '100.00', 'currency_code': 'USD', 'payee_currency_code': 'GBP', 'withholding_tax_amount': '-10.00', 'vat_amount': '20.00', 'amount_after_withholding_and_vat': '110.00', 'us_source_income_rate': '90.00', 'is_internal': True, } res = fixture_client.post('/payment/advance/1', json=test_data) assert res.status_code == 201 assert mock_logic.create_worksheet_payment_contract_advance.call_args_list == [ call( contract_advance_id=1, exchange_rate_id=1, statement_period_id=1, payment_name='test_name', amount=Decimal('100.00'), currency_code='USD', payee_currency_code='GBP', withholding_tax_amount=Decimal('-10.00'), vat_amount=Decimal('20.00'), amount_after_withholding_and_vat=Decimal('110.00'), us_source_income_rate=Decimal('90.00'), is_internal=True, ) ] @patch('payment.blueprints.worksheet_payment_contract_advance.logic') def test_get_worksheet_payment_contract_advance_success(mock_logic, fixture_client): """Test get_worksheet_payment_contract_advance endpoint.""" worksheet = WorksheetPaymentContractAdvanceFactory.build() mock_logic.get_worksheet_payment_contract_advance.return_value = worksheet res = fixture_client.get('/payment/advance/worksheet/1') assert res.status_code == 200 mock_logic.get_worksheet_payment_contract_advance.assert_called_once_with(1) @patch('payment.blueprints.worksheet_payment_contract_advance.logic') def test_update_worksheet_payment_contract_advance_success(mock_logic, fixture_client): """Test update_worksheet_payment_contract_advance endpoint.""" worksheet = WorksheetPaymentContractAdvanceFactory.build() mock_logic.update_worksheet_payment_contract_advance.return_value = worksheet test_data = {'salesforce_id': 'new_salesforce_id'} res = fixture_client.put('/payment/advance/worksheet/1', json=test_data) assert res.status_code == 201 assert mock_logic.update_worksheet_payment_contract_advance.call_args_list == [ call(1, salesforce_id='new_salesforce_id') ] @patch('payment.blueprints.worksheet_payment_contract_advance.logic') def test_delete_worksheet_payment_contract_advance_success(mock_logic, fixture_client): """Test delete_worksheet_payment_contract_advance endpoint.""" res = fixture_client.delete('/payment/advance/worksheet/1') assert res.status_code == 204 mock_logic.delete_worksheet_payment_contract_advance.assert_called_once_with(1) @patch('payment.blueprints.worksheet_payment_contract_advance.logic') def test_dataloader_worksheets_by_ids(mock_logic, fixture_client): """Test for the worksheets dataloader handler.""" worksheet = WorksheetPaymentContractAdvanceFactory.build() mock_logic.dataload_worksheets_by_ids.return_value = { 'items': [{'data': worksheet}, {'data': None}] } post_data = [1, 2] res = fixture_client.post('/payment/advance/worksheet/dataloader', json=post_data) assert res.status_code == 200 mock_logic.dataload_worksheets_by_ids.assert_called_once_with([1, 2]) @pytest.mark.parametrize( 'verify_rules_access_standalone_result,' 'authorize_resource_result,' 'expected_status_code,' 'expect_authorize_resource_called', [ pytest.param( True, False, 200, False, id='profile checks authorized request', ), pytest.param( False, False, 403, True, id='profile and pp checks failed to authorize request', ), pytest.param( False, True, 200, True, id='pp checks authorized request', ), ], ) @patch('payment.utils.authorization.authorize_resource') @patch('payment.utils.authorization.flask_request') @patch('payment.blueprints.worksheet_payment_contract_advance.logic') def test_list_worksheet_payment_contract_advances_authorization_checks( mock_logic: Any, mock_flask_request: Any, mock_authorize_resource: Any, verify_rules_access_standalone_result: bool, authorize_resource_result: bool, expected_status_code: int, expect_authorize_resource_called: bool, fixture_client: Any, ) -> None: """Test endpoint uses authorization checks.""" mock_flask_request.verify_rules_access_standalone.return_value = ( verify_rules_access_standalone_result ) mock_authorize_resource.return_value = authorize_resource_result mock_logic.list_worksheet_payment_contract_advances.return_value = Items([], 0) res = fixture_client.get('/payments/advances/') assert res.status_code == expected_status_code, res.text if res.status_code != 200: assert res.json == {'code': 'authorization_error', 'message': 'Unauthorized'} mock_logic.list_worksheet_payment_contract_advances.assert_not_called() else: assert res.json == {'items': [], 'total_count': 0} mock_logic.list_worksheet_payment_contract_advances.assert_called_once() mock_flask_request.verify_rules_access_standalone.assert_called_once() if expect_authorize_resource_called: mock_authorize_resource.assert_called_once_with( resource_id='0', resource_type='contract_advance_payment', action='view', ) else: mock_authorize_resource.assert_not_called()