from __future__ import annotations import importlib.util from pathlib import Path import sys from uuid import uuid4 import pytest from shapely.geometry import Polygon, shape from app.models import VectorFeature from app.services.vector_feature_service import VectorFeatureService ROOT = Path(__file__).resolve().parents[2] def load_provisioner(): script_path = ROOT / "scripts" / "provision_mol_municipality_workspace.py" spec = importlib.util.spec_from_file_location("mol_municipality_provisioner", script_path) assert spec is not None assert spec.loader is not None module = importlib.util.module_from_spec(spec) sys.modules[spec.name] = module spec.loader.exec_module(module) return module def feature(feature_id: str, coordinates: list[list[list[float]]]): return { "type": "Feature", "id": feature_id, "geometry": {"type": "Polygon", "coordinates": coordinates}, "properties": {"UIDN": feature_id}, } def test_mol_provisioner_uses_official_identity_and_exact_boundary_clipping() -> None: module = load_provisioner() boundary = Polygon([(5.0, 51.0), (5.2, 51.0), (5.2, 51.2), (5.0, 51.2), (5.0, 51.0)]) inside = feature("GBG.inside", [[[5.05, 51.05], [5.1, 51.05], [5.1, 51.1], [5.05, 51.1], [5.05, 51.05]]]) crossing = feature("GBG.crossing", [[[5.18, 51.08], [5.22, 51.08], [5.22, 51.12], [5.18, 51.12], [5.18, 51.08]]]) outside = feature("GBG.outside", [[[5.3, 51.3], [5.31, 51.3], [5.31, 51.31], [5.3, 51.31], [5.3, 51.3]]]) pages = [ ( {"type": "FeatureCollection", "features": [inside, crossing, outside, inside]}, "https://geo.api.vlaanderen.be/GRB/page-1", ) ] buildings, summary = module.build_municipality_buildings(pages, boundary, max_features=10) assert module.MUNICIPALITY_NIS_CODE == "13025" assert module.PROJECT_NAME == "Mol Municipality Workbench" assert module.GEOJSON_CRS == {"type": "name", "properties": {"name": "EPSG:4326"}} assert len(buildings) == 2 assert summary["bbox_feature_count"] == 3 assert summary["outside_boundary_count"] == 1 assert summary["clipped_at_boundary_count"] == 1 assert summary["reference_truncated"] is False assert all(shape(item["geometry"]).within(boundary) for item in buildings) assert buildings[0]["properties"]["coverage_scope"] == "municipality" assert buildings[0]["properties"]["source_name"] == "grb" assert buildings[0]["properties"]["reference_layer_name"] == "buildings" assert buildings[1]["properties"]["clipped_to_municipality"] is True def test_mol_provisioner_refuses_a_truncated_municipality_dataset() -> None: module = load_provisioner() boundary = Polygon([(5.0, 51.0), (5.2, 51.0), (5.2, 51.2), (5.0, 51.2), (5.0, 51.0)]) pages = [ ( { "type": "FeatureCollection", "features": [ feature("GBG.1", [[[5.01, 51.01], [5.02, 51.01], [5.02, 51.02], [5.01, 51.02], [5.01, 51.01]]]), feature("GBG.2", [[[5.03, 51.03], [5.04, 51.03], [5.04, 51.04], [5.03, 51.04], [5.03, 51.03]]]), ], }, "https://geo.api.vlaanderen.be/GRB/page-1", ) ] with pytest.raises(RuntimeError, match="refusing a truncated municipality dataset"): module.build_municipality_buildings(pages, boundary, max_features=1) def test_mol_source_session_retries_only_safe_get_requests() -> None: module = load_provisioner() with module.build_source_session() as session: retry = session.get_adapter("https://").max_retries assert retry.total == 5 assert retry.allowed_methods == frozenset({"GET"}) assert set(retry.status_forcelist) == {429, 500, 502, 503, 504} def test_large_vector_persistence_flushes_once_without_per_feature_refresh() -> None: class FakeSession: def __init__(self) -> None: self.added = [] self.flushes = 0 self.commits = 0 self.refreshes = 0 def add(self, item) -> None: self.added.append(item) def flush(self) -> None: self.flushes += 1 def commit(self) -> None: self.commits += 1 def refresh(self, _item) -> None: self.refreshes += 1 payload = { "type": "FeatureCollection", "features": [ { "type": "Feature", "id": f"GBG.{index}", "properties": {"layer_type": "building"}, "geometry": { "type": "Polygon", "coordinates": [[[5.0, 51.0], [5.001, 51.0], [5.001, 51.001], [5.0, 51.001], [5.0, 51.0]]], }, } for index in range(250) ], } db = FakeSession() persisted = VectorFeatureService.persist_geojson_features(db, uuid4(), payload, feature_class="buildings") assert len(persisted) == 250 assert all(isinstance(item, VectorFeature) for item in persisted) assert db.flushes == 1 assert db.commits == 1 assert db.refreshes == 0 def test_municipality_workspace_is_wired_into_runtime_and_frontend_priority() -> None: readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text(encoding="utf-8") dockerfile = (ROOT / "deploy" / "unraid" / "Dockerfile.all-in-one").read_text(encoding="utf-8") focus = (ROOT / "frontend" / "src" / "config" / "primaryFocus.ts").read_text(encoding="utf-8") project_hook = (ROOT / "frontend" / "src" / "hooks" / "useProjectWorkspace.ts").read_text(encoding="utf-8") dataset_hook = (ROOT / "frontend" / "src" / "hooks" / "useDatasetWorkflow.ts").read_text(encoding="utf-8") map_source = (ROOT / "frontend" / "src" / "components" / "GeoMap.tsx").read_text(encoding="utf-8") map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text(encoding="utf-8") assert "py_compile scripts/provision_mol_municipality_workspace.py" in readiness assert "COPY scripts/provision_mol_municipality_workspace.py" in dockerfile assert "PRIMARY_FOCUS_MUNICIPALITY_PROJECT_NAME = 'Mol Municipality Workbench'" in focus assert "items.find(isPrimaryFocusMunicipalityProject)" in project_hook assert "datasets.find(isPrimaryFocusMunicipalityBoundaryDataset)" in dataset_hook assert "featureCollectionBounds(featureCollection)" in map_source assert "useMemo(() => getFeatureCollectionBBox(mapFeatureCollection)" in map_workspace assert "Math.min(...xs)" not in map_source