fixed roof recs

This commit is contained in:
Khalim Conn-Kowlessar 2026-03-27 01:12:56 +00:00
parent 5ab48f3bb4
commit 845ab857b2
3 changed files with 82 additions and 87 deletions

View file

@ -15,6 +15,7 @@ def property_instance():
id="P1",
has_ventilation=False,
data={"current-energy-efficiency": "52"},
epc_record=SimpleNamespace(current_energy_efficiency=52),
)
@ -93,8 +94,11 @@ class TestCalculateFixedGain:
class TestCalculateGain:
def test_returns_none_for_energy_savings_goal(self):
body = SimpleNamespace(goal="Energy Savings")
prop = SimpleNamespace(data={"current-energy-efficiency": "50"})
gain = optimiser_functions.calculate_gain(body, prop, fixed_gain=0)
prop = SimpleNamespace(
data={"current-energy-efficiency": "50"},
epc_record=SimpleNamespace(current_energy_efficiency=50)
)
gain = optimiser_functions.calculate_gain(body, prop, fixed_gain=2)
assert gain is None
def test_returns_zero_for_already_installed_getting_to_target(self):
@ -118,7 +122,10 @@ class TestCalculateGain:
monkeypatch.setattr(optimiser_functions, "epc_to_sap_lower_bound", lambda goal_value: 69)
body = SimpleNamespace(goal="Increasing EPC", goal_value="C", simulate_sap_10=False)
prop = SimpleNamespace(data={"current-energy-efficiency": "50"})
prop = SimpleNamespace(
data={"current-energy-efficiency": "50"},
epc_record=SimpleNamespace(current_energy_efficiency=50)
)
gain = optimiser_functions.calculate_gain(body, prop, fixed_gain=2)
assert gain == 17.5
@ -192,6 +199,7 @@ class TestIncreasingEpcE2e:
id="P1",
has_ventilation=False,
data={"current-energy-efficiency": "52"},
epc_record=SimpleNamespace(current_energy_efficiency=52),
)
# Dummy request body

View file

@ -323,15 +323,17 @@ def carbon_predictions():
@pytest.fixture
def property_instance():
return Mock(
from types import SimpleNamespace
return SimpleNamespace(
id=614626,
data={
"current-energy-efficiency": 65,
"co2-emissions-current": 2.4,
"energy-consumption-current": 284,
"roof-energy-eff": "Good",
"lighting-energy-eff": "Good",
},
epc_record=SimpleNamespace(
current_energy_efficiency=65,
co2_emissions_current=2.4,
energy_consumption_current=284,
roof_energy_eff="Good",
lighting_energy_eff="Good"
),
roof={
"is_loft": True,
"insulation_thickness": "250",

View file

@ -9,10 +9,7 @@ from recommendations.tests.test_data.materials import materials
class TestRoofRecommendations:
def test_null_roof_description(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {
"county": "Cambridgeshire",
}
epc_record = EPCRecord(county="Cambridgeshire")
property_instance = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance.age_band = "F"
property_instance.insulation_floor_area = 100
@ -33,10 +30,7 @@ class TestRoofRecommendations:
assert not roof_recommender.recommendations
def test_loft_insulation_recommendation_no_insulation(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {
"county": "Cambridgeshire",
}
epc_record = EPCRecord(county="Cambridgeshire")
property_instance = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance.age_band = "F"
property_instance.insulation_floor_area = 100
@ -61,8 +55,7 @@ class TestRoofRecommendations:
assert roof_recommender.recommendations[0]["parts"][0]["depth"] == 300
def test_loft_insulation_recommendation_50mm_insulation(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Kent", "roof-energy-eff": "Very Poor"}
epc_record = EPCRecord(county="Kent", **{"roof_energy_eff": "Very Poor"})
property_instance2 = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance2.age_band = "F"
property_instance2.insulation_floor_area = 100
@ -90,8 +83,7 @@ class TestRoofRecommendations:
assert float(roof_recommender2.recommendations[0]["starting_u_value"]) == 0.68
assert roof_recommender2.recommendations[0]["parts"][0]["depth"] == 300
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Greater London Authority", "roof-energy-eff": "Very Poor"}
epc_record = EPCRecord(county="Greater London Authority", **{"roof_energy_eff": "Very Poor"})
property_instance3 = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance3.age_band = "F"
property_instance3.insulation_floor_area = 100
@ -117,8 +109,7 @@ class TestRoofRecommendations:
assert roof_recommender3.recommendations[0]["parts"][0]["depth"] == 300.0
def test_loft_insulation_recommendation_150mm_insulation(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "North East Lincolnshire", "roof-energy-eff": "Good"}
epc_record = EPCRecord(county="North East Lincolnshire", **{"roof_energy_eff": "Good"})
property_instance4 = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance4.age_band = "F"
property_instance4.insulation_floor_area = 100
@ -146,8 +137,7 @@ class TestRoofRecommendations:
assert float(roof_recommender4.recommendations[0]["starting_u_value"]) == 0.3
assert roof_recommender4.recommendations[0]["parts"][0]["depth"] == 300
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Somerset", "roof-energy-eff": "Good"}
epc_record = EPCRecord(county="Somerset", **{"roof_energy_eff": "Good"})
property_instance5 = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance5.age_band = "F"
property_instance5.insulation_floor_area = 100
@ -173,9 +163,7 @@ class TestRoofRecommendations:
assert roof_recommender5.recommendations[0]["parts"][0]["depth"] == 300
def test_loft_insulation_recommendation_270mm_insulation(self):
# We shouldn't recommend anything in this case
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Portsmouth"}
epc_record = EPCRecord(county="Portsmouth")
property_instance6 = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance6.age_band = "F"
property_instance6.insulation_floor_area = 100
@ -199,17 +187,18 @@ class TestRoofRecommendations:
assert len(roof_recommender6.recommendations) == 0
def test_uninsulated_room_in_roof(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Southampton", "roof-energy-eff": "Very Poor"}
epc_record = EPCRecord(county="Southampton", roof_energy_eff="Very Poor")
property_instance7 = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance7.age_band = "F"
property_instance7.insulation_floor_area = 100
property_instance7.roof = {
'original_description': 'Roof room(s), no insulation (assumed)',
'clean_description': 'Roof room(s), no insulation',
'thermal_transmittance': None, 'thermal_transmittance_unit': None, 'is_pitched': False,
'is_roof_room': True, 'is_loft': False, 'is_flat': False, 'is_thatched': False, 'is_at_rafters': False,
'is_assumed': True, 'has_dwelling_above': False, 'is_valid': True, 'insulation_thickness': 'none'
'original_description': 'Room-in-roof, no insulation (assumed)',
'clean_description': 'Room-in-roof, no insulation',
'thermal_transmittance': None,
'thermal_transmittance_unit': None,
'is_pitched': False, 'is_roof_room': True, 'is_loft': False, 'is_flat': False, 'is_thatched': False,
'is_at_rafters': False, 'is_assumed': True, 'has_dwelling_above': False, 'is_valid': True,
'insulation_thickness': 'none', 'roof_thermal_transmittance': None, 'roof_insulation_thickness': 'none'
}
property_instance7.already_installed = []
@ -225,10 +214,11 @@ class TestRoofRecommendations:
assert roof_recommender7.recommendations[0]["new_u_value"] == 0.18
assert roof_recommender7.recommendations[0]["starting_u_value"] == 0.8
assert roof_recommender7.recommendations[0]["description"] == "Insulate room in roof at rafters and re-decorate"
# Ensure all tests are room in roof
assert all(rec["measure_type"] == "room_roof_insulation" for rec in roof_recommender7.recommendations)
def test_ceiling_insulated_room_in_roof(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Southampton", "roof-energy-eff": "Very Poor"}
epc_record = EPCRecord(county="Southampton", roof_energy_eff="Very Poor")
property_instance8 = Property(id=8, address="fake", postcode="fake", epc_record=epc_record)
property_instance8.age_band = "F"
property_instance8.insulation_floor_area = 100
@ -255,8 +245,7 @@ class TestRoofRecommendations:
assert not roof_recommender8.recommendations
def test_insulated_room_in_roof(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Southampton", "roof-energy-eff": "Very Poor"}
epc_record = EPCRecord(county="Southampton", roof_energy_eff="Very Poor")
property_instance9 = Property(id=9, address="fake", postcode="fake", epc_record=epc_record)
property_instance9.age_band = "F"
property_instance9.insulation_floor_area = 100
@ -282,8 +271,7 @@ class TestRoofRecommendations:
assert not roof_recommender9.recommendations
def test_limited_insulated_room_in_roof(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Westmorland", "roof-energy-eff": "Poor"}
epc_record = EPCRecord(county="Westmorland", roof_energy_eff="Poor")
property_instance10 = Property(id=10, address="fake", postcode="fake", epc_record=epc_record)
property_instance10.age_band = "F"
property_instance10.insulation_floor_area = 100
@ -315,8 +303,7 @@ class TestRoofRecommendations:
'Insulate room in roof at rafters and re-decorate')
def test_flat_no_insulation(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Swindon"}
epc_record = EPCRecord(county="Swindon")
property_instance11 = Property(id=11, address="fake", postcode="fake", epc_record=epc_record)
property_instance11.age_band = "D"
property_instance11.insulation_floor_area = 33.5
@ -346,8 +333,7 @@ class TestRoofRecommendations:
"Insulate the home's flat roof with 150mm of Ecotherm Eco-Versal General Purpose Insulation Board"
def test_flat_insulated(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Thurrock"}
epc_record = EPCRecord(county="Thurrock")
property_instance12 = Property(id=12, address="fake", postcode="fake", epc_record=epc_record)
property_instance12.age_band = "D"
property_instance12.insulation_floor_area = 40
@ -372,8 +358,7 @@ class TestRoofRecommendations:
assert not roof_recommender12.recommendations
def test_flat_limited_insulation(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Tyne and Wear"}
epc_record = EPCRecord(county="Tyne and Wear")
property_instance13 = Property(id=12, address="fake", postcode="fake", epc_record=epc_record)
property_instance13.age_band = "D"
property_instance13.insulation_floor_area = 40
@ -406,8 +391,7 @@ class TestRoofRecommendations:
"Insulate the home's flat roof with 150mm of Ecotherm Eco-Versal General Purpose Insulation Board"
def test_property_above(self):
epc_record = EPCRecord()
epc_record.prepared_epc = {"county": "Suffolk"}
epc_record = EPCRecord(county="Suffolk")
property_instance14 = Property(id=0, address="fake", postcode="fake", epc_record=epc_record)
property_instance14.age_band = "F"
property_instance14.insulation_floor_area = 100
@ -435,40 +419,41 @@ class TestRoofRecommendations:
"has_loft_insulation_recommendation, expected_result",
[
(
{
'original_description': 'Pitched, no insulation',
'thermal_transmittance': None,
'thermal_transmittance_unit': None,
'is_pitched': True,
'is_roof_room': False,
'is_loft': False,
'is_flat': False,
'is_thatched': False,
'is_at_rafters': False,
'is_assumed': False,
'has_dwelling_above': False,
'is_valid': True,
'insulation_thickness': 'none'
},
True,
True,
"none",
False,
True,
{
'original_description': 'Pitched, no insulation',
'thermal_transmittance': None,
'thermal_transmittance_unit': None,
'is_pitched': True,
'is_roof_room': False,
'is_loft': False,
'is_flat': False,
'is_thatched': False,
'is_at_rafters': False,
'is_assumed': False,
'has_dwelling_above': False,
'is_valid': True,
'insulation_thickness': 'none'
},
True,
True,
"none",
False,
True,
),
(
{
'original_description': 'Pitched, insulated (assumed)', 'clean_description': 'Pitched, insulated',
'thermal_transmittance': None, 'thermal_transmittance_unit': None, 'is_pitched': True,
'is_roof_room': False, 'is_loft': False, 'is_flat': False, 'is_thatched': False,
'is_at_rafters': False, 'is_assumed': True, 'has_dwelling_above': False, 'is_valid': True,
'insulation_thickness': 'average'
},
False,
False,
"average",
False,
False
{
'original_description': 'Pitched, insulated (assumed)',
'clean_description': 'Pitched, insulated',
'thermal_transmittance': None, 'thermal_transmittance_unit': None, 'is_pitched': True,
'is_roof_room': False, 'is_loft': False, 'is_flat': False, 'is_thatched': False,
'is_at_rafters': False, 'is_assumed': True, 'has_dwelling_above': False, 'is_valid': True,
'insulation_thickness': 'average'
},
False,
False,
"average",
False,
False
)
]
)
@ -477,10 +462,10 @@ class TestRoofRecommendations:
insulation_thickness, has_loft_insulation_recommendation, expected_result
):
assert RoofRecommendations.is_sloping_ceiling_appropriate(
is_flat=roof["is_flat"],
is_pitched=roof["is_pitched"],
is_loft=roof["is_loft"],
is_assumed=roof["is_assumed"],
is_flat=bool(roof["is_flat"]),
is_pitched=bool(roof["is_pitched"]),
is_loft=bool(roof["is_loft"]),
is_assumed=bool(roof["is_assumed"]),
has_sloping_ceiling_recommendation=has_sloping_ceiling_recommendation,
primary_roof_looks_sloped=primary_roof_looks_sloped,
insulation_thickness=insulation_thickness,