"""Unit tests for contract_flowthrough handlers.""" from decimal import Decimal from unittest.mock import MagicMock, patch from flask import testing as flask_testing from owsresponse import response import pytest from abacus_contract.constants.constants import CONTRACT_FLOWTHROUGH_STATUSES from abacus_contract.schemas.contract_flowthrough import \ ContractFlowthroughDetailSchema from tests.utils.factories import ContractFactory from tests.utils.factories import ContractFlowthroughFactory @patch('abacus_contract.blueprints.contract_flowthrough.logic') def test_get_contract_flowthrough_by_contract_id(mock_logic, fixture_client): """Test GET contract_flowthrough by contract_id.""" mock_contract_flowthrough = ContractFlowthroughFactory.create() mock_contract_id = mock_contract_flowthrough.contract_id mock_logic.get_contract_flowthrough_by_contract_id.return_value =\ response.Response( message=ContractFlowthroughDetailSchema().dump(mock_contract_flowthrough), status=200 ) res = fixture_client.get( f'/contract/{mock_contract_id}/contract-flowthrough/' ) assert res.status_code == 200 assert res.json == { 'contract_flowthrough_id': mock_contract_flowthrough.contract_flowthrough_id, 'contract_id': mock_contract_flowthrough.contract_id, 'reference_flowthrough_calculation_id': mock_contract_flowthrough.reference_flowthrough_calculation_id, 'flowthrough_rate': str(mock_contract_flowthrough.flowthrough_rate), 'flowthrough_status': mock_contract_flowthrough.flowthrough_status, 'has_automatic_shutoff': mock_contract_flowthrough.has_automatic_shutoff, 'recoupment_cap': mock_contract_flowthrough.recoupment_cap, 'previous_flowthrough_status': mock_contract_flowthrough.previous_flowthrough_status, 'status_last_modified_by': mock_contract_flowthrough.status_last_modified_by, 'status_last_modified': str(mock_contract_flowthrough.status_last_modified.date()) } mock_logic.get_contract_flowthrough_by_contract_id.assert_called_once_with( mock_contract_id ) @pytest.mark.parametrize( [ 'standalone_check_result', 'get_account_id_result', 'pdp_check_result', 'expected_status_code', ], [ pytest.param(True, None, None, 200, id='Standalone check passed'), pytest.param(False, None, None, 403, id='Account id not found'), pytest.param(False, 999, False, 403, id='PDP check failed'), pytest.param(False, 999, True, 200, id='PDP check passed'), ] ) @patch('abacus_contract.blueprints.contract_flowthrough.logic') @patch('abacus_contract.blueprints.contract_flowthrough.authorization') @patch('abacus_contract.blueprints.contract_flowthrough.contract_logic') @patch('abacus_contract.blueprints.contract_flowthrough.flask_request') def test_get_contract_flowthrough_by_id_authorization( mock_flask_request: MagicMock, mock_contract_logic: MagicMock, mock_authorization: MagicMock, mock_logic: MagicMock, standalone_check_result: bool, get_account_id_result: int | None, pdp_check_result: bool | None, expected_status_code: int, fixture_client: flask_testing.FlaskClient, ) -> None: """Test GET contract_flowthrough by id with authorization check.""" mock_flask_request.verify_rules_access_standalone.return_value = \ standalone_check_result mock_contract_logic.get_account_id_by_contract_id.return_value = \ get_account_id_result mock_authorization.pdp_authorize_many_accounts.return_value = pdp_check_result mock_logic.get_contract_flowthrough_by_contract_id.return_value = \ response.Response() contract_id = 777 res = fixture_client.get(f'/contract/{contract_id}/contract-flowthrough/') assert res.status_code == expected_status_code mock_flask_request.verify_rules_access_standalone.assert_called_once() if not standalone_check_result: mock_contract_logic.get_account_id_by_contract_id.assert_called_once_with( contract_id ) if get_account_id_result: mock_authorization.pdp_authorize_many_accounts.assert_called_once_with( [get_account_id_result] ) @patch('abacus_contract.blueprints.contract_flowthrough.logic') def test_soft_delete_contract_flowthrough( mock_logic, fixture_client ): """Test soft deleting contract_flowthrough by id.""" mock_contract_flowthrough = ContractFlowthroughFactory.create() contract_flowthrough_id = mock_contract_flowthrough.contract_flowthrough_id mock_logic.soft_delete_contract_flowthrough.return_value = \ response.Response( status=204 ) res = fixture_client.delete( f'/contract-flowthrough/{contract_flowthrough_id}' ) assert res.status_code == 204 mock_logic.soft_delete_contract_flowthrough \ .assert_called_once_with(mock_contract_flowthrough) @patch('abacus_contract.blueprints.contract_flowthrough.logic') def test_update_contract_flowthrough(mock_logic, fixture_client): """Test updating contract_flowthough.""" mock_contract_flowthrough = ContractFlowthroughFactory.create() contract_flowthrough_id = mock_contract_flowthrough.contract_flowthrough_id mock_put_request_body = { 'flowthrough_rate': 1.78, 'flowthrough_status': CONTRACT_FLOWTHROUGH_STATUSES.PAUSED, 'has_automatic_shutoff': 0 } mock_logic.update_contract_flowthrough.return_value = \ response.Response(message='ok', status=200) res = fixture_client.put( f'/contract-flowthrough/{contract_flowthrough_id}', json=mock_put_request_body ) assert res.status_code == 200 mock_logic.update_contract_flowthrough.assert_called_once_with( mock_contract_flowthrough, flowthrough_rate=Decimal('1.78'), flowthrough_status=CONTRACT_FLOWTHROUGH_STATUSES.PAUSED, has_automatic_shutoff=False ) @patch('abacus_contract.blueprints.contract_flowthrough.logic') def test_create_contract_flowthrough( mock_logic, fixture_client ): """Test creating contract_flowthrough.""" mock_contract = ContractFactory.create() contract_id = mock_contract.contract_id mock_logic.create_contract_flowthrough.return_value =\ response.Response( message='OK', status=201 ) mock_post_request = { 'reference_flowthrough_calculation_id': 2, 'flowthrough_rate': '90.78', 'has_automatic_shutoff': 1, 'recoupment_cap': 908786 } res = fixture_client.post( f'/contract/{contract_id}/contract-flowthrough/', json=mock_post_request ) assert res.status_code == 201 mock_logic.create_contract_flowthrough.assert_called_once_with( contract_id=mock_contract.contract_id, reference_flowthrough_calculation_id=2, flowthrough_rate=Decimal('90.78'), has_automatic_shutoff=1, recoupment_cap=908786 )