diff --git a/tests/domain/modelling/test_products.py b/tests/domain/modelling/test_products.py index e4953a3e..e99daedc 100644 --- a/tests/domain/modelling/test_products.py +++ b/tests/domain/modelling/test_products.py @@ -111,3 +111,33 @@ def test_decommission_falls_back_for_systems_not_on_the_rate_sheet() -> None: assert abs(products.ashp_bundle_cost(_small_no_reuse(AshpExistingSystem.NONE)).total - (base + 0.0)) <= 1e-9 assert abs(products.ashp_bundle_cost(_small_no_reuse(AshpExistingSystem.ELECTRIC_OTHER)).total - (base + 570.0)) <= 1e-9 assert abs(products.ashp_bundle_cost(_small_no_reuse(AshpExistingSystem.OTHER)).total - (base + 720.0)) <= 1e-9 + + +def _pump_price(products: Products, design_heat_loss_kw: float) -> float: + """Isolate the heat-pump line: no-system (decommission 0) + cylinder + 2382.60 + distribution (7 rads) 3618 = 6000.60 base, so total - base is the + pump band price for ``design_heat_loss_kw``.""" + inputs = AshpCostInputs( + existing_system=AshpExistingSystem.NONE, + is_small_property=True, + design_heat_loss_kw=design_heat_loss_kw, + radiator_count=7, + has_reusable_wet_system=False, + ) + return products.ashp_bundle_cost(inputs).total - 6000.60 + + +def test_heat_pump_rounds_design_heat_loss_up_to_the_next_band() -> None: + # Arrange + products = Products() + + # Act / Assert — bands {5,8,11,15,16+} kW -> {9720,9840,10200,10680,11400}; + # a load is rounded UP to the smallest band that covers it. + assert abs(_pump_price(products, 5.0) - 9720.0) <= 1e-9 # at the 5 kW edge + assert abs(_pump_price(products, 5.01) - 9840.0) <= 1e-9 # just over -> 8 kW + assert abs(_pump_price(products, 8.0) - 9840.0) <= 1e-9 + assert abs(_pump_price(products, 8.01) - 10200.0) <= 1e-9 + assert abs(_pump_price(products, 11.0) - 10200.0) <= 1e-9 + assert abs(_pump_price(products, 15.0) - 10680.0) <= 1e-9 + assert abs(_pump_price(products, 15.01) - 11400.0) <= 1e-9 # above largest + assert abs(_pump_price(products, 25.0) - 11400.0) <= 1e-9