Model/recommendations/tests/test_recommendation_utils.py
2023-09-21 15:14:10 +01:00

250 lines
9.6 KiB
Python

import pytest
from unittest.mock import MagicMock
from recommendations import recommendation_utils
from datatypes.enums import QuantityUnits
class TestRecommendationUtils:
@pytest.fixture
def property_mock(self):
PropertyMock = MagicMock()
PropertyMock.data = {
'total_floor_area_group_decile': 'Decile 1',
'number-habitable-rooms': 3,
'number-heated-rooms': 2
}
return PropertyMock
def test_r_value_per_mm_to_u_value(self):
assert recommendation_utils.r_value_per_mm_to_u_value(1, 2) == 0.5
with pytest.raises(ZeroDivisionError):
recommendation_utils.r_value_per_mm_to_u_value(0, 2)
def test_calculate_u_value_uplift(self):
assert recommendation_utils.calculate_u_value_uplift(1, 2) == (0.33333333333333337, 0.6666666666666666)
with pytest.raises(ZeroDivisionError):
recommendation_utils.calculate_u_value_uplift(0, 2)
with pytest.raises(ZeroDivisionError):
recommendation_utils.calculate_u_value_uplift(1, 0)
def test_is_diminishing_returns(self):
assert not recommendation_utils.is_diminishing_returns([1, 2, 3], 1, 1, 1)
assert recommendation_utils.is_diminishing_returns([1, 2, 3], 0.5, 1, 1)
assert not recommendation_utils.is_diminishing_returns([], 1, None, 1)
def test_update_lowest_selected_u_value(self):
assert recommendation_utils.update_lowest_selected_u_value(1, 2) == 1
assert recommendation_utils.update_lowest_selected_u_value(None, 2) == 2
assert recommendation_utils.update_lowest_selected_u_value(1, 0.5) == 0.5
def test_get_recommended_part(self):
part = {'depths': [1, 2, 3]}
assert recommendation_utils.get_recommended_part(
part=part, selected_depth=1, selected_total_cost=50, quantity=99, quantity_unit="m2"
) == {'depths': [1], 'estimated_cost': 50, 'quantity': 99, 'quantity_unit': QuantityUnits.m2.value}
def test_get_uvalue_estimate(self, property_mock):
uvalue_estimates = [
{
'total-floor-area_group': 'Decile 1',
'number-habitable-rooms': 3,
'number-heated-rooms': 2,
'median_thermal_transmittance': 1
},
{
'total-floor-area_group': 'Decile 1',
'number-habitable-rooms': 3,
'number-heated-rooms': 2,
'median_thermal_transmittance': 2
}
]
assert recommendation_utils.get_uvalue_estimate(uvalue_estimates, property_mock, "Decile 1") == 1.5
with pytest.raises(ValueError):
recommendation_utils.get_uvalue_estimate([], property_mock, "Decile 1")
# Test with missing 'median_thermal_transmittance' key
uvalue_estimates_missing_key = [
{
'total-floor-area_group': 'Decile 1',
'number-habitable-rooms': 3,
'number-heated-rooms': 2
}
]
with pytest.raises(KeyError):
recommendation_utils.get_uvalue_estimate(uvalue_estimates_missing_key, property_mock, "Decile 1")
def test_get_roof_u_value(self):
# Test case 1: Insulation thickness is known and is_loft is True
description_dict = {
'insulation_thickness': '50',
'is_loft': True,
'is_roof_room': False,
'is_thatched': False,
'has_dwelling_above': False,
'is_flat': False,
'is_pitched': True,
'is_at_rafters': False,
}
for age_band in ["A", "B", "C", "D"]:
assert recommendation_utils.get_roof_u_value(description_dict, age_band) == 0.68
def test_get_roof_u_value_case_2(self):
description_dict = {
'original_description': 'Pitched, 400+ mm insulation at joists',
'clean_description': 'Pitched, 400+ mm insulation at joists',
'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': '400+'
}
age_band = "J"
u_value = recommendation_utils.get_roof_u_value(description_dict, age_band)
assert u_value == 0.16, f"Expected 0.16, but got {u_value}"
def test_get_roof_u_value_case_3(self):
description_dict = {
'original_description': 'Room-in-roof, 200 mm insulation at rafters',
'clean_description': 'Room-in-roof, 200 mm insulation at rafters',
'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': True,
'is_assumed': False,
'has_dwelling_above': False,
'is_valid': True,
'insulation_thickness': '200'
}
age_band = "J"
u_value = recommendation_utils.get_roof_u_value(description_dict, age_band)
assert u_value == 0.21, f"Expected 0.21, but got {u_value}"
def test_get_roof_u_value_case_4(self):
description_dict = {
'original_description': 'Pitched, below average insulation',
'clean_description': 'Pitched, below average 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': 'below average'
}
age_band = "E"
u_value = recommendation_utils.get_roof_u_value(description_dict, age_band)
assert u_value == 1.5, f"Expected 1.5, but got {u_value}"
def test_get_roof_u_value_case_5():
# Test case where insulation thickness is exactly specified
description_dict = {
'original_description': 'Pitched, 100mm insulation',
'clean_description': 'Pitched, 100mm 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': '100'
}
age_band = "G"
u_value = get_roof_u_value(description_dict, age_band, table_s9, table_s10)
assert u_value == 0.40, f"Expected 0.40, but got {u_value}"
def test_get_roof_u_value_case_6():
# Test case for a thatched roof
description_dict = {
'original_description': 'Thatched, 75mm insulation',
'clean_description': 'Thatched, 75mm insulation',
'thermal_transmittance': None,
'thermal_transmittance_unit': None,
'is_pitched': False,
'is_roof_room': False,
'is_loft': False,
'is_flat': False,
'is_thatched': True,
'is_at_rafters': False,
'is_assumed': False,
'has_dwelling_above': False,
'is_valid': True,
'insulation_thickness': '75'
}
age_band = "H"
u_value = get_roof_u_value(description_dict, age_band, table_s9, table_s10)
assert u_value == 0.22, f"Expected 0.22, but got {u_value}"
def test_get_roof_u_value_case_7():
# Test case where the roof has a room in it
description_dict = {
'original_description': 'Pitched, room-in-roof, 100mm insulation',
'clean_description': 'Pitched, room-in-roof, 100mm insulation',
'thermal_transmittance': None,
'thermal_transmittance_unit': None,
'is_pitched': True,
'is_roof_room': True,
'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': '100'
}
age_band = "J"
u_value = get_roof_u_value(description_dict, age_band, table_s9, table_s10)
assert u_value == 0.30, f"Expected 0.30, but got {u_value}"
def test_get_roof_u_value_case_8():
# Test case where there is a dwelling above the roof, U-value should be 0
description_dict = {
'original_description': 'Pitched, 100mm insulation',
'clean_description': 'Pitched, 100mm 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': True,
'is_valid': True,
'insulation_thickness': '100'
}
age_band = "J"
u_value = get_roof_u_value(description_dict, age_band, table_s9, table_s10)
assert u_value == 0.0, f"Expected 0.0, but got {u_value}"