import pytest from typing import Any, Dict from io import BytesIO from openpyxl import Workbook from datetime import datetime from backend.condition.parsing.peabody_parser import PeabodyParser from backend.condition.parsing.records.peabody.peabody_asset_condition import ( PeabodyAssetCondition, ) from backend.condition.parsing.records.peabody.peabody_property import PeabodyProperty @pytest.fixture def peabody_assets_xlsx_bytes() -> BytesIO: wb = Workbook() survey_records_d_and_lower = wb.active survey_records_d_and_lower.title = "Survey Records - D & Lower" survey_records_d_and_lower.append( [ "Lo_Reference", "full_address", "location_type_code", "Parent_Lo_Reference", "Element_Code", "Element", "Sub_Element_Code", "Sub_Element", "Material_Code", "material_or_answer", "Renewal_Quantity", "Renewal_Year", "Renewal_Cost", "cloned", "lo_type_code", "condition_survey_date", ] ) survey_records_d_and_lower.append( [ "B000RAND", "1 RANDOM HOUSE LONDON", 3, "RAND2EST", 110, "ROOFS", 1, "Primary Roof", 9, "Other", 3, 2054, 330, "N", 3, datetime(2025, 12, 4, 9, 17, 0), ] ) survey_records_d_and_lower.append( [ "B000BLOCK", "1100 BLOCK", 3, "RAND2EST", 110, "ROOFS", 1, "Primary Roof", 9, "Other", 3, 2054, 330, "N", 3, datetime(2025, 12, 4, 9, 17, 0), ] ) survey_records_d_and_lower.append( [ "B000FAKE", "3 FAKE CLOSE LONDON", 3, "FAKEEST", 100, "GENERAL", 15, "External Decoration", 2, "Normal", 1, 2035, 1500.7, "N", 3, datetime(2025, 7, 5, 0, 0, 0), ] ) survey_records_d_and_lower.append( [ "B000MIS", "99 MISC ROAD LONDON", 3, "300828", 54, "HHSRS", 29, "HHSRS Structural Collapse & Falling Elements", 4, "HHSRS Moderate", 2, 2027, None, "N", 3, None, ] ) survey_records_d_and_lower.append( [ "B000MIS", "99 MISC ROAD LONDON", 3, "300828", 53, "External", 2, "Chimney", 2, "Present", 33, 2053, 3531, "N", 3, None, ] ) stream = BytesIO() wb.save(stream) stream.seek(0) return stream @pytest.fixture def location_ref_to_uprn_map() -> Dict[str, int]: return { "B000RAND": 1, "B000BLOCK": 2, "B000FAKE": 3, "B000MIS": 4, } def test_peabody_parser_parses_conditions( peabody_assets_xlsx_bytes, location_ref_to_uprn_map ): # arrange parser = PeabodyParser() # act result: Any = parser.parse(peabody_assets_xlsx_bytes, location_ref_to_uprn_map) # assert assert len(result) == 3 assert all(isinstance(item, PeabodyProperty) for item in result) @pytest.fixture def asset_condition_factory(): def _factory(full_address: str) -> PeabodyAssetCondition: return PeabodyAssetCondition( lo_reference="", full_address=full_address, location_type_code=0, parent_lo_reference="", element_code=0, element="", sub_element_code=0, sub_element="", material_code=0, material_or_answer="", renewal_quantity=0, renewal_year=2026, cloned="", lo_type_code=0, renewal_cost=None, condition_survey_date=None, ) return _factory @pytest.mark.parametrize( "full_address, expected_block_level", [ ("1-80 PRINCESS ALICE HOUSE LONDON", True), ("FLATS A-D 7 ST CHARLES SQUARE LONDON", True), ("9A-9H HEDGEGATE COURT LONDON", True), ("BLOCK MILNE HOUSE LONDON", True), ("81A-B GORE ROAD LONDON", True), ("73 & 74 HARVEST COURT ST. ALBANS", True), ("25 HAVERSHAM COURT GREENFORD", False), ("FLAT 10 SPARROW COURT SOUTHMERE DRIVE LONDON SE2 9ES", False), ], ) def test_peabody_asset_is_block_level( asset_condition_factory, full_address, expected_block_level, ): # arrange asset_condition = asset_condition_factory(full_address) # act + assert assert asset_condition.is_block_level == expected_block_level