Model/tests/condition/parsing/test_calico_parser.py
Khalim Conn-Kowlessar 5c9757ad89 Count Calico rows dropped as blank placeholders or unmatched references 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 15:08:18 +00:00

106 lines
3.2 KiB
Python

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"]