from __future__ import annotations import importlib.util from pathlib import Path import sys import pytest ROOT = Path(__file__).resolve().parents[2] def load_sample_preparer(): script_path = ROOT / "scripts" / "prepare_operator_real_data_samples.py" spec = importlib.util.spec_from_file_location("operator_sample_preparer", 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 test_operator_sample_registry_includes_kempen_reference_and_background_candidates() -> None: module = load_sample_preparer() expected_reference_slugs = {"geel", "mol", "turnhout", "herentals", "balen", "retie", "westerlo"} expected_background_slugs = {"postel_bos", "lommel_heide", "kasterlee_bos"} assert expected_reference_slugs.issubset(module.SAMPLES) assert expected_background_slugs.issubset(module.SAMPLES) assert all(not module.SAMPLES[slug].allow_empty_reference for slug in expected_reference_slugs) assert all(module.SAMPLES[slug].allow_empty_reference for slug in expected_background_slugs) assert all(module.SAMPLES[slug].sample_role == "background_candidate" for slug in expected_background_slugs) def test_background_candidate_can_write_empty_reference_geojson(tmp_path: Path, monkeypatch) -> None: module = load_sample_preparer() class EmptyFeatureResponse: headers = {"content-type": "application/geo+json"} def raise_for_status(self) -> None: return None def json(self) -> dict: return {"type": "FeatureCollection", "features": []} class FakeRequests: @staticmethod def get(*args, **kwargs): return EmptyFeatureResponse() monkeypatch.setattr(module, "requests", FakeRequests) monkeypatch.setattr(module, "prepared_url", lambda url, params: f"{url}?prepared=true") sample = module.OperatorSample( slug="background", display_name="Background", center_lon=5.0, center_lat=51.0, allow_empty_reference=True, sample_role="background_candidate", ) reference_path = tmp_path / "background.geojson" source_url, feature_count = module.fetch_reference(sample, reference_path, [4.9, 50.9, 5.1, 51.1]) assert source_url.endswith("?prepared=true") assert feature_count == 0 payload = reference_path.read_text(encoding="utf-8") assert '"features": []' in payload assert '"sample_role": "background_candidate"' in payload def test_reference_sample_still_rejects_empty_grb_response(tmp_path: Path, monkeypatch) -> None: module = load_sample_preparer() class EmptyFeatureResponse: def raise_for_status(self) -> None: return None def json(self) -> dict: return {"type": "FeatureCollection", "features": []} class FakeRequests: @staticmethod def get(*args, **kwargs): return EmptyFeatureResponse() monkeypatch.setattr(module, "requests", FakeRequests) monkeypatch.setattr(module, "prepared_url", lambda url, params: f"{url}?prepared=true") sample = module.OperatorSample( slug="urban", display_name="Urban", center_lon=5.0, center_lat=51.0, ) with pytest.raises(SystemExit, match="returned no building features"): module.fetch_reference(sample, tmp_path / "urban.geojson", [4.9, 50.9, 5.1, 51.1])