from datetime import date from io import BytesIO from typing import Dict, List, Optional from openpyxl import Workbook from infrastructure.condition.parsing.calico_parser import CalicoParser from repositories.condition.uprn_lookup import UprnLookup HEADERS = [ "Asset Reference", "Asset Type", "Address", "Path", "Type", "Fitted / Renewed Date", "Quantity", "Remaining Life", ] class FakeUprnLookup(UprnLookup): def __init__(self, mapping: Dict[str, int]) -> None: self._mapping = mapping def get_property_ref_to_uprn_lookup(self) -> Dict[str, int]: return self._mapping def _workbook(rows: List[List[object]]) -> BytesIO: wb = Workbook() ws = wb.active assert ws is not None ws.append(HEADERS) for row in rows: ws.append(row) buffer = BytesIO() wb.save(buffer) buffer.seek(0) return buffer def test_calico_parser_counts_blank_and_unmatched_drops(): # Arrange -- one loaded, one blank placeholder, one unmatched (not in lookup) workbook = _workbook( [ [443, "HOUSE", "31 Venice Avenue", "Roof Covering", "Concrete Tiles", date(1998, 4, 1), 55, 36], [438, "FLAT", "137 Brownhill Avenue", "Roof Covering", "N/A", date(2000, 4, 1), 0, 973], [777, "HOUSE", "8 Marine Avenue", "Roof Covering", "Natural Slate", date(2010, 4, 1), 60, 50], ] ) parser = CalicoParser(FakeUprnLookup({"443": 100093305101})) # Act parser.parse(workbook) # Assert assert parser.blank_placeholder_count == 1 assert parser.unmatched_reference_count == 1 def test_calico_parser_drops_na_sentinel_covering_rows(): # Arrange -- Calico writes the literal string "N/A" for a placeholder row # (no roof-covering record captured), not an empty cell. workbook = _workbook( [ [443, "HOUSE", "31 Venice Avenue", "Roof Covering", "Concrete Tiles", date(1998, 4, 1), 55, 36], [438, "FLAT", "137 Brownhill Avenue", "Roof Covering", "N/A", date(2000, 4, 1), 0, 973], ] ) parser = CalicoParser(FakeUprnLookup({"443": 100093305101, "438": 100093388053})) # Act properties = parser.parse(workbook) # Assert references = [asset.asset_reference for prop in properties for asset in prop.assets] assert references == [443] def test_calico_parser_drops_rows_with_no_covering_type(): # Arrange workbook = _workbook( [ [443, "HOUSE", "31 Venice Avenue", "Roof Covering", "Concrete Tiles", date(1998, 4, 1), 55, 36], [438, "FLAT", "137 Brownhill Avenue", "Roof Covering", None, date(2000, 4, 1), 0, 973], ] ) parser = CalicoParser(FakeUprnLookup({"443": 100093305101, "438": 100093388053})) # Act properties = parser.parse(workbook) # Assert all_assets = [asset for prop in properties for asset in prop.assets] references: List[int] = [asset.asset_reference for asset in all_assets] coverings: List[Optional[str]] = [asset.covering_type for asset in all_assets] assert references == [443] assert coverings == ["Concrete Tiles"]