from __future__ import annotations import importlib.util import sys from pathlib import Path from shapely.geometry import box from tests.frontend_contract import read_feature ROOT = Path(__file__).resolve().parents[2] def load_operator(): script_path = ROOT / "scripts" / "provision_waterinfo_station_history.py" spec = importlib.util.spec_from_file_location("waterinfo_history_operator", 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 class JsonResponse: ok = True status_code = 200 text = "" def __init__(self, payload): self.payload = payload def raise_for_status(self): return None def json(self): return self.payload class JsonSession: def __init__(self, payloads): self.payloads = iter(payloads) self.calls = [] def get(self, url, *, params, timeout): self.calls.append((url, params, timeout)) return JsonResponse(next(self.payloads)) def test_waterinfo_station_discovery_filters_exact_area_and_uses_annual_group() -> None: module = load_operator() payload = { "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": {"type": "Point", "coordinates": [5.1, 51.2]}, "properties": {"ts_id": 5319042, "station_no": "L10_089", "station_name": "Mol/ScheppelijkeNete"}, }, { "type": "Feature", "geometry": {"type": "Point", "coordinates": [6.0, 52.0]}, "properties": {"ts_id": 999, "station_no": "outside", "station_name": "Outside"}, }, ], } session = JsonSession([payload]) raw, stations = module.discover_station_series( session, module.PARAMETERS["water_level"], box(5.0, 51.0, 5.3, 51.4), timeout=30, ) assert raw == payload assert [item["ts_id"] for item in stations] == ["5319042"] assert session.calls[0][1]["timeseriesgroup_id"] == "192784" assert session.calls[0][1]["request"] == "getTimeseriesValueLayer" def test_waterinfo_annual_values_reject_invalid_sentinel_and_keep_real_zero() -> None: module = load_operator() payload = [ { "ts_id": 5319042, "data": [ ["2013-01-01T00:00:00.000+01:00", 30.46], ["2014-01-01T00:00:00.000+01:00", -9999], ["2015-01-01T00:00:00.000+01:00", 0.0], ["2026-01-01T00:00:00.000+01:00", 99.0], ], } ] session = JsonSession([payload]) raw, values = module.fetch_annual_values(session, "5319042", from_year=2013, to_year=2025, timeout=30) assert raw == payload assert values == {2013: 30.46, 2015: 0.0} assert session.calls[0][1]["request"] == "getTimeseriesValues" def test_waterinfo_snapshot_and_series_keep_station_identity_and_honest_metric() -> None: module = load_operator() parameter = module.PARAMETERS["water_level"] station = { "ts_id": "5319042", "geometry": {"type": "Point", "coordinates": [5.1, 51.2]}, "properties": { "station_id": "123", "station_no": "L10_089", "station_name": "Mol/ScheppelijkeNete", "ts_unitsymbol": "m", }, } snapshot = module.build_snapshot(parameter, station, 2025, 30.455) feature = snapshot["features"][0] assert module.series_key(parameter, station) == "waterinfo:water_level:annual:l10-089" assert feature["geometry"]["type"] == "Point" assert feature["properties"]["annual_mean_water_level_m"] == 30.455 assert feature["properties"]["timeseries_id"] == "5319042" assert "volume" in parameter.limitation def test_waterinfo_operator_is_packaged_and_readiness_checked() -> 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") vector_service = (ROOT / "backend" / "app" / "services" / "vector_feature_service.py").read_text(encoding="utf-8") assert "py_compile scripts/provision_waterinfo_station_history.py" in readiness assert "COPY scripts/provision_waterinfo_station_history.py" in dockerfile assert '"provision_waterinfo_station_history.py"' in vector_service assert '"sum", "mean", "area_weighted_sum"' in vector_service assert '"status": "no_stations_in_area"' in (ROOT / "scripts" / "provision_waterinfo_station_history.py").read_text(encoding="utf-8") def test_frontend_loads_all_dataset_pages_after_temporal_import_expansion() -> None: client = read_feature("datasets") assert "DATASET_PAGE_SIZE = 200" in client assert "offset < (total ?? 0)" in client assert "items.length !== total" in client def test_source_inventory_remains_full_width_after_premium_desktop_rules() -> None: styles = (ROOT / "frontend" / "src" / "styles" / "premium.css").read_text(encoding="utf-8") final_rule = styles.rsplit(".workspace-grid-data > section.source-catalog-panel", maxsplit=1)[1] assert "grid-column: 1 / -1" in final_rule assert "max-height: none" in final_rule assert "overflow: visible" in final_rule