from datetime import datetime from typing import List, Optional import pytest from backend.app.domain.classes.plan import Plan from backend.app.domain.classes.scenario import Scenario from backend.app.domain.records.plan_record import PlanRecord from backend.app.domain.records.scenario_record import ScenarioRecord from backend.app.db.models.portfolio import PortfolioGoal from backend.categorisation.processor import choose_cheapest_relevant_plan from datatypes.epc.domain.epc import Epc @pytest.fixture def created_at_datetime() -> datetime: return datetime.now() def make_plan_record( created_at: datetime, default: bool, cost_of_works: Optional[float] = 500.0 ) -> PlanRecord: return PlanRecord( property_id=1, portfolio_id=1, created_at=created_at, is_default=default, post_epc_rating=Epc.C, cost_of_works=cost_of_works, ) def make_scenario(name: str, created_at: datetime, is_default: bool) -> Scenario: record = ScenarioRecord( name=name, created_at=created_at, housing_type="", goal=PortfolioGoal.INCREASING_EPC, goal_value="C", trigger_file_path="", multi_plan=False, is_default=is_default, ) return Scenario(record=record, id=3 if is_default else 4) def make_plan( created_at: datetime, default: bool, cost_of_works: Optional[float] = 500.0, name: str = "", ) -> Plan: scenario = make_scenario(name, created_at, default) plan_id = 1 if default else 2 return Plan( record=make_plan_record(created_at, default, cost_of_works), scenario=scenario, id=plan_id, ) def test_prioritised_scenario_selected(created_at_datetime: datetime) -> None: # arrange epc_c_plan = make_plan(created_at_datetime, True, name="EPC C") minor_works_plan = make_plan(created_at_datetime, False, name="EPC C - Minor Works") scenario_priority_order: List[int] = [4, 3] expected_default_plan_id = 2 # act actual_default_plan = choose_cheapest_relevant_plan( plans=[epc_c_plan, minor_works_plan], scenario_priority_order=scenario_priority_order, ) # assert assert actual_default_plan.id == expected_default_plan_id def test_cheapest_plan_returned_if_not_in_priority_list( created_at_datetime: datetime, ) -> None: # arrange epc_c_plan = make_plan( created_at_datetime, True, cost_of_works=1000.0, name="EPC C" ) minor_works_plan = make_plan( created_at_datetime, False, cost_of_works=100.0, name="EPC C - Minor Works" ) scenario_priority_order: List[int] = [3, 5] expected_default_plan_id = 2 # act actual_default_plan = choose_cheapest_relevant_plan( plans=[epc_c_plan, minor_works_plan], scenario_priority_order=scenario_priority_order, ) # assert assert actual_default_plan.id == expected_default_plan_id def test_all_plans_zero_cost__highest_priority_returned( created_at_datetime: datetime, ) -> None: # arrange epc_c_plan = make_plan(created_at_datetime, True, cost_of_works=0.0, name="EPC C") minor_works_plan = make_plan( created_at_datetime, False, cost_of_works=0.0, name="EPC C - Minor Works" ) scenario_priority_order: List[int] = [4, 3] expected_default_plan_id = 2 # act actual_default_plan = choose_cheapest_relevant_plan( plans=[epc_c_plan, minor_works_plan], scenario_priority_order=scenario_priority_order, ) # assert assert actual_default_plan.id == expected_default_plan_id def test_some_plans_zero_cost__cheapest_returned( created_at_datetime: datetime, ) -> None: # arrange epc_c_plan = make_plan(created_at_datetime, True, cost_of_works=0.0, name="EPC C") minor_works_plan = make_plan( created_at_datetime, False, cost_of_works=50.0, name="EPC C - Minor Works" ) scenario_priority_order: List[int] = [4, 3] expected_default_plan_id = 1 # act actual_default_plan = choose_cheapest_relevant_plan( plans=[epc_c_plan, minor_works_plan], scenario_priority_order=scenario_priority_order, ) # assert assert actual_default_plan.id == expected_default_plan_id def test_all_plans_null_cost__highest_priority_returned( created_at_datetime: datetime, ) -> None: # arrange epc_c_plan = make_plan(created_at_datetime, True, cost_of_works=None, name="EPC C") minor_works_plan = make_plan( created_at_datetime, False, cost_of_works=None, name="EPC C - Minor Works" ) scenario_priority_order: List[int] = [4, 3] expected_default_plan_id = 2 # act actual_default_plan = choose_cheapest_relevant_plan( plans=[epc_c_plan, minor_works_plan], scenario_priority_order=scenario_priority_order, ) # assert assert actual_default_plan.id == expected_default_plan_id