"""Functional tests for contract_flowthrough.""" from datetime import datetime from abacus_common_logic.constants.constants import SYSTEM_TIMEZONE from abacus_common_logic.constants.error import ERROR_ENTITY_DOES_NOT_EXIST from abacus_common_logic.utils.users import get_flask_user_id from freezegun import freeze_time from abacus_contract.constants.constants import CONTRACT_FLOWTHROUGH_STATUSES from abacus_contract.constants.error import ERROR_CONTRACT_FLOWTHROUGH_ALREADY_EXISTS from abacus_contract.tests.utils.factories import ( ContractFactory, ContractFlowthroughFactory, ReferenceFlowthroughCalculationFactory, ) def test_get_contract_flowthrough_by_id(fixture_client): """Test getting a contract_flowthrough by id.""" mock_contract_flowthrough = ContractFlowthroughFactory.create() contract_flowthrough_id = mock_contract_flowthrough.contract_flowthrough_id res = fixture_client.get(f'/contract-flowthrough/{contract_flowthrough_id}') assert res.status_code == 200 assert res.json == { 'contract_id': mock_contract_flowthrough.contract_id, 'contract_flowthrough_id': mock_contract_flowthrough.contract_flowthrough_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, 'calculation_comment': mock_contract_flowthrough.calculation_comment, '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() ), } def test_get_contract_flowthrough_by_id_error(fixture_client): """Test getting a contract_flowthrough by invalid id.""" contract_flowthrough_id = 12345 res = fixture_client.get(f'/contract-flowthrough/{contract_flowthrough_id}') assert res.status_code == 404 assert res.json['message'] == ERROR_ENTITY_DOES_NOT_EXIST.format( object_type='ContractFlowthrough', object_id=contract_flowthrough_id ) def test_get_contract_flowthrough_by_contract_id(fixture_client): """Test getting a contract_flowthrough by contract_id.""" mock_contract_flowthrough = ContractFlowthroughFactory.create() contract_id = mock_contract_flowthrough.contract_id res = fixture_client.get(f'/contract/{contract_id}/contract-flowthrough') assert res.status_code == 200 assert res.json == { 'contract_id': mock_contract_flowthrough.contract_id, 'contract_flowthrough_id': mock_contract_flowthrough.contract_flowthrough_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, 'calculation_comment': mock_contract_flowthrough.calculation_comment, '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() ), } def test_get_contract_flowthrough_by_contract_id_error(fixture_client): """Test getting a contract_flowthrough with invalid contract_id.""" contract_id = 12345 res = fixture_client.get(f'/contract/{contract_id}/contract-flowthrough') assert res.status_code == 404 assert res.json['message'] == ERROR_ENTITY_DOES_NOT_EXIST.format( object_type='Contract', object_id=contract_id ) def test_get_deleted_contract_flowthrough_by_contract_id(fixture_client): """Test getting a deleted contract_flowthrough by contract_id.""" mock_contract_flowthrough = ContractFlowthroughFactory.create( deleted_by='Test User', deleted_at='2025-03-03' ) contract_id = mock_contract_flowthrough.contract_id res = fixture_client.get(f'/contract/{contract_id}/contract-flowthrough') assert res.status_code == 200 assert not res.json def test_get_non_existing_contract_flowthrough_by_contract_id(fixture_client): """Test getting a contract_flowthrough by contract_id. contract_flowthrough is not created for specified contract. """ mock_contract = ContractFactory.create() contract_id = mock_contract.contract_id res = fixture_client.get(f'/contract/{contract_id}/contract-flowthrough') assert res.status_code == 200 assert not res.json def test_soft_delete_contract_flowthrough(fixture_client): """Test soft deleting contract flowthrough.""" mock_contract_flowthrough = ContractFlowthroughFactory.create() contract_flowthrough_id = mock_contract_flowthrough.contract_flowthrough_id res = fixture_client.delete(f'/contract-flowthrough/{contract_flowthrough_id}') assert res.status_code == 204 def test_soft_delete_contract_flowthrough_does_not_exist(fixture_client): """Test soft deleting contract flowthrough that does not exist.""" contract_flowthrough_id = 12345 res = fixture_client.delete(f'/contract-flowthrough/{contract_flowthrough_id}') assert res.status_code == 404 def test_update_contract_flowthrough(fixture_client): """Test updating contract_flowthrough.""" mock_reference_flowthrough_calculation = ( ReferenceFlowthroughCalculationFactory.create( flowthrough_calculation_name='net_only', flowthrough_calculation='Net Revenue * FT%', ) ) mock_contract_flowthrough = ContractFlowthroughFactory.create( flowthrough_rate='4.90', previous_flowthrough_status=None, status_last_modified_by=None, status_last_modified=None, ) contract_flowthrough_id = mock_contract_flowthrough.contract_flowthrough_id reference_flowthrough_calculation_id = ( mock_reference_flowthrough_calculation.reference_flowthrough_calculation_id ) mock_put_request_body = { 'reference_flowthrough_calculation_id': reference_flowthrough_calculation_id, 'flowthrough_rate': 5.12, } res = fixture_client.put( f'/contract-flowthrough/{contract_flowthrough_id}', json=mock_put_request_body ) assert res.status_code == 200 assert res.json == { 'contract_id': mock_contract_flowthrough.contract_id, 'contract_flowthrough_id': mock_contract_flowthrough.contract_flowthrough_id, 'reference_flowthrough_calculation_id': reference_flowthrough_calculation_id, 'flowthrough_rate': str(mock_put_request_body['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, 'calculation_comment': mock_contract_flowthrough.calculation_comment, 'previous_flowthrough_status': mock_contract_flowthrough.previous_flowthrough_status, 'status_last_modified_by': mock_contract_flowthrough.status_last_modified_by, 'status_last_modified': mock_contract_flowthrough.status_last_modified, } def test_update_contract_flowthrough_error(fixture_client): """Test throws an error when updating previous_flowthrough_status field.""" mock_contract_flowthrough = ContractFlowthroughFactory.create() contract_flowthrough_id = mock_contract_flowthrough.contract_flowthrough_id mock_put_request_body = { 'previous_flowthrough_status': CONTRACT_FLOWTHROUGH_STATUSES.SHUTOFF } res = fixture_client.put( f'/contract-flowthrough/{contract_flowthrough_id}', json=mock_put_request_body ) assert res.status_code == 400 assert res.json['message'] == {'previous_flowthrough_status': ['Unknown field.']} @freeze_time(datetime(2025, 3, 4, 0, 0, 0, tzinfo=SYSTEM_TIMEZONE)) def test_update_contract_flowthrough_status_to_paused(fixture_client): """Test updating contract_flowthrough status from active to paused.""" mock_contract_flowthrough = ContractFlowthroughFactory.create( flowthrough_status=CONTRACT_FLOWTHROUGH_STATUSES.ACTIVE, previous_flowthrough_status=None, status_last_modified_by=None, status_last_modified=None, ) contract_flowthrough_id = mock_contract_flowthrough.contract_flowthrough_id mock_put_request_body = {'flowthrough_status': CONTRACT_FLOWTHROUGH_STATUSES.PAUSED} res = fixture_client.put( f'/contract-flowthrough/{contract_flowthrough_id}', json=mock_put_request_body ) assert res.status_code == 200 assert res.json == { 'contract_id': mock_contract_flowthrough.contract_id, 'contract_flowthrough_id': mock_contract_flowthrough.contract_flowthrough_id, 'reference_flowthrough_calculation_id': mock_contract_flowthrough.reference_flowthrough_calculation_id, 'flowthrough_rate': str(mock_contract_flowthrough.flowthrough_rate), 'flowthrough_status': CONTRACT_FLOWTHROUGH_STATUSES.PAUSED, 'has_automatic_shutoff': mock_contract_flowthrough.has_automatic_shutoff, 'recoupment_cap': mock_contract_flowthrough.recoupment_cap, 'calculation_comment': mock_contract_flowthrough.calculation_comment, 'previous_flowthrough_status': CONTRACT_FLOWTHROUGH_STATUSES.ACTIVE, 'status_last_modified_by': get_flask_user_id(), 'status_last_modified': '2025-03-04', } def test_create_contract_flowthrough(fixture_client): """Test creating contract_flowthrough.""" mock_contract = ContractFactory.create() mock_reference_flowthrough_calculation = ( ReferenceFlowthroughCalculationFactory.create( flowthrough_calculation_name='net_only', flowthrough_calculation='Net Revenue * FT%', ) ) contract_id = mock_contract.contract_id reference_flowthrough_calculation_id = ( mock_reference_flowthrough_calculation.reference_flowthrough_calculation_id ) mock_post_request = { 'reference_flowthrough_calculation_id': reference_flowthrough_calculation_id, 'flowthrough_rate': '90.78', 'recoupment_cap': 908786, 'calculation_comment': 'foo', } res = fixture_client.post( f'/contract/{contract_id}/contract-flowthrough/', json=mock_post_request ) assert res.status_code == 201 assert res.json == { 'contract_id': contract_id, 'contract_flowthrough_id': 1, 'reference_flowthrough_calculation_id': reference_flowthrough_calculation_id, 'flowthrough_rate': '90.78', 'flowthrough_status': CONTRACT_FLOWTHROUGH_STATUSES.ACTIVE, 'has_automatic_shutoff': 1, 'recoupment_cap': 908786, 'calculation_comment': 'foo', 'previous_flowthrough_status': None, 'status_last_modified_by': None, 'status_last_modified': None, } def test_create_contract_flowthrough_error(fixture_client): """Test throws an error if flowthrough is already exist for a contract.""" mock_contract = ContractFactory.create() ContractFlowthroughFactory.create(contract=mock_contract) contract_id = mock_contract.contract_id mock_post_request = { 'reference_flowthrough_calculation_id': 1, 'flowthrough_rate': '90.78', 'recoupment_cap': 908786, } res = fixture_client.post( f'/contract/{contract_id}/contract-flowthrough/', json=mock_post_request ) assert res.status_code == 409 assert res.json['message'] == ERROR_CONTRACT_FLOWTHROUGH_ALREADY_EXISTS.format( contract_id=mock_contract.contract_id )