mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
246 lines
8.5 KiB
Python
246 lines
8.5 KiB
Python
from recommendations.Costs import Costs
|
|
from unittest.mock import Mock
|
|
import pytest
|
|
|
|
|
|
class TestCosts:
|
|
|
|
def test_cavity_wall_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire"
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
|
|
cwi_material = {
|
|
"description": "cwi",
|
|
"depth": 75,
|
|
"thermal_conductivity": 0.037,
|
|
"total_cost": 14,
|
|
"labour_hours_per_unit": 0.065,
|
|
"is_installer_quote": True
|
|
}
|
|
|
|
cwi_results = costs.cavity_wall_insulation(
|
|
wall_area=95.9104281347967,
|
|
material=cwi_material,
|
|
)
|
|
|
|
assert cwi_results["total"] == 1342.7459938871539
|
|
assert cwi_results["contingency"] == 134.2745993887154
|
|
|
|
def test_loft_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire"
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
loft_material = {
|
|
"type": "loft_insulation",
|
|
"description": "Crown Loft Roll 44 glass fibre roll",
|
|
"depth": 270,
|
|
"thermal_conductivity": 0.044,
|
|
"total_cost": 11,
|
|
"labour_hours_per_unit": 0.11,
|
|
"is_installer_quote": True,
|
|
}
|
|
|
|
loft_results = costs.loft_and_flat_insulation(
|
|
floor_area=33.5,
|
|
material=loft_material,
|
|
)
|
|
|
|
assert loft_results["total"] == 368.5
|
|
assert loft_results["contingency"] == 36.85
|
|
|
|
def test_internal_wall_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire"
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
|
|
iwi_material = {
|
|
"type": "internal_wall_insulation",
|
|
"description": "Ecotherm Eco-Versal PIR Insulation Board",
|
|
"depth": 150,
|
|
"depth_unit": "mm",
|
|
"cost_unit": "gbp_per_m2",
|
|
"thermal_conductivity": 0.022,
|
|
"thermal_conductivity_unit": "watt_per_meter_kelvin",
|
|
"labour_hours_per_unit": 0.18,
|
|
"total_cost": 200,
|
|
"link": "link",
|
|
"is_installer_quote": True
|
|
}
|
|
|
|
iwi_results = costs.solid_wall_insulation(
|
|
wall_area=95.9104281347967,
|
|
material=iwi_material,
|
|
)
|
|
|
|
assert iwi_results["total"] == 19182.085626959342
|
|
assert iwi_results["contingency"] == 4987.342263009429
|
|
|
|
def test_suspended_floor_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire"
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
|
|
sus_floor_material = {
|
|
'type': 'suspended_floor_insulation', 'description': 'Thermafleece CosyWool Roll',
|
|
'depth': 140.0,
|
|
'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.039,
|
|
'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 0,
|
|
'material_cost': 11.68, 'labour_cost': 1.78, 'labour_hours_per_unit': 0.1,
|
|
'plant_cost': 0,
|
|
'total_cost': 75,
|
|
"is_installer_quote": False
|
|
}
|
|
|
|
sus_floor_results = costs.suspended_floor_insulation(
|
|
insulation_floor_area=33.5,
|
|
material=sus_floor_material,
|
|
)
|
|
|
|
assert sus_floor_results["total"] == 2512.5
|
|
assert sus_floor_results["contingency"] == 502.5
|
|
|
|
@pytest.mark.parametrize("insulation_floor_area, expected_result", [
|
|
(5, 3),
|
|
(33.5, 5.446976345666071),
|
|
(45, 7),
|
|
(70, 10.190623048464415),
|
|
(90, 12.617506476551622),
|
|
(150, 19.47802744828744),
|
|
(200, 24.873843619763473),
|
|
])
|
|
def test_estimate_estimate_number_of_days_for_solid_floor(
|
|
self, insulation_floor_area, expected_result
|
|
):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire"
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
assert costs._estimate_number_of_days_for_solid_floor(insulation_floor_area) == expected_result
|
|
|
|
def test_solid_floor_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire"
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
sol_floor_material = {
|
|
'type': 'solid_floor_insulation', 'description': 'Kay-Cel Expanded Polystyrene Board',
|
|
'depth': 100.0, 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.033,
|
|
'thermal_conductivity_unit': 'watt_per_meter_kelvin', 'prime_material_cost': 0,
|
|
'material_cost': 12.02, 'labour_cost': 4.4, 'labour_hours_per_unit': 0.19, 'plant_cost': 0,
|
|
'total_cost': 16.42, 'link': 'SPONs', 'Notes': 0, "is_installer_quote": False
|
|
}
|
|
|
|
sol_floor_results = costs.solid_floor_insulation(
|
|
insulation_floor_area=33.5,
|
|
material=sol_floor_material,
|
|
)
|
|
|
|
assert sol_floor_results["total"] == 2184
|
|
assert sol_floor_results["contingency"] == 567.84
|
|
|
|
def test_external_wall_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire",
|
|
"property-type": "House",
|
|
"built-form": 'End-Terrace'
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
|
|
ewi_material = {
|
|
'type': 'external_wall_insulation', 'description': 'Ecotherm Eco-Versal PIR Insulation Board',
|
|
'depth': 150.0, 'depth_unit': 'mm', 'cost_unit': 'gbp_per_m2', 'thermal_conductivity': 0.022,
|
|
'thermal_conductivity_unit': 'watt_per_meter_kelvin',
|
|
'labour_hours_per_unit': 1.4,
|
|
'total_cost': 300, 'link': 'SPONs', 'Notes': 0, "is_installer_quote": True
|
|
}
|
|
|
|
ewi_results = costs.solid_wall_insulation(
|
|
wall_area=95.9104281347967,
|
|
material=ewi_material,
|
|
)
|
|
|
|
assert ewi_results["total"] == 28773.12844043901
|
|
assert ewi_results["contingency"] == 7481.013394514142
|
|
|
|
def test_flat_roof_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {
|
|
"county": "Northamptonshire"
|
|
}
|
|
|
|
costs = Costs(mock_property)
|
|
flat_roof_material = {
|
|
'id': 1225, 'type': 'flat_roof_insulation',
|
|
'description': 'Kingspan Thermaroof TR21 zero OPD '
|
|
'urethene insulation board',
|
|
'depth': 100.0, 'depth_unit': 'mm', 'cost': None,
|
|
'cost_unit': 'gbp_per_m2', 'r_value_per_mm': 0.04,
|
|
'r_value_unit': 'square_meter_kelvin_per_watt',
|
|
'thermal_conductivity': 0.025,
|
|
'thermal_conductivity_unit': 'watt_per_meter_kelvin',
|
|
'link': 'SPONs',
|
|
'created_at': "now", 'is_active': True,
|
|
'prime_material_cost': None, 'material_cost': 50.95,
|
|
'labour_cost': 10.66, 'labour_hours_per_unit': 0.48,
|
|
'plant_cost': 0.0, 'total_cost': 61.61,
|
|
'notes': "SPONs didn't have a labour hours so we use "
|
|
"0.48 which is similar to other materials",
|
|
"is_installer_quote": False
|
|
}
|
|
|
|
flat_roof_floor_results = costs.loft_and_flat_insulation(
|
|
floor_area=33.5,
|
|
material=flat_roof_material,
|
|
)
|
|
|
|
assert flat_roof_floor_results["total"] == 2063.935
|
|
assert flat_roof_floor_results["contingency"] == 536.6231
|
|
|
|
assert costs.labour_adjustment_factor == 0.88
|
|
|
|
# Test for different wattages
|
|
@pytest.mark.parametrize("solar_product, expected_cost", [
|
|
({"total_cost": 5000, "includes_scaffolding": False}, 6000),
|
|
({"total_cost": 5000, "includes_scaffolding": True}, 5000),
|
|
])
|
|
def test_solar_pv_different_wattages(self, solar_product, expected_cost):
|
|
mock_property = Mock()
|
|
mock_property.data = {"county": "Mansfield"}
|
|
scaffolding_options = [
|
|
{"size": 2, "total_cost": 1000}
|
|
]
|
|
costs = Costs(mock_property)
|
|
result = costs.solar_pv(
|
|
solar_product=solar_product,
|
|
scaffolding_options=scaffolding_options,
|
|
n_floors=2
|
|
)
|
|
|
|
assert result['total'] == pytest.approx(expected_cost, rel=0.01)
|
|
|
|
def test_sloping_ceiling_insulation(self):
|
|
mock_property = Mock()
|
|
mock_property.data = {"county": "Mansfield"}
|
|
costs = Costs(mock_property)
|
|
res = costs.sloping_ceiling_insulation(insulation_roof_area=64.085)
|
|
assert res["total"] == 5238.713924924947
|
|
assert res["contingency"] == 1362.0656204804861
|