Constrain selections to active work areas
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-17 12:58:38 +02:00
parent a29c787238
commit d652db6a1e
20 changed files with 329 additions and 71 deletions
@@ -6,7 +6,10 @@ from types import SimpleNamespace
from uuid import uuid4
from fastapi.testclient import TestClient
from geoalchemy2.shape import from_shape, to_shape
from shapely.geometry import box
from app.core.errors import AppError
from app.main import app
from app.models import Area, Dataset, Export
from app.schemas.export import ExportCreateResponse
@@ -140,7 +143,8 @@ def test_vector_selection_export_uses_exact_area_scope_when_requested(tmp_path,
source="fixture",
status="ready",
)
area_geometry = object()
area_shape = box(5.0, 51.1, 5.2, 51.3)
area_geometry = from_shape(area_shape, srid=4326)
area = SimpleNamespace(id=area_id, project_id=project_id, name="Gemeente Mol", geometry=area_geometry)
db = FakeSession({(Dataset, dataset_id): dataset, (Area, area_id): area})
selection_bbox = {"min_x": 5.0, "min_y": 51.1, "max_x": 5.2, "max_y": 51.3, "crs": "EPSG:4326"}
@@ -170,12 +174,78 @@ def test_vector_selection_export_uses_exact_area_scope_when_requested(tmp_path,
area_id=area_id,
)
assert captured["selection_geometry"] is area_geometry
assert to_shape(captured["selection_geometry"]).equals(area_shape)
assert captured["selection_area_id"] == area_id
assert captured["full_dataset_area"] is True
assert response.metadata_json["selection_area_id"] == str(area_id)
def test_area_constrained_bbox_uses_intersection_and_disables_full_area_fast_path(tmp_path, monkeypatch) -> None:
project_id = uuid4()
dataset_id = uuid4()
area_id = uuid4()
dataset = Dataset(
id=dataset_id,
project_id=project_id,
area_id=area_id,
name="mol-buildings.geojson",
dataset_type="vector",
source="fixture",
source_metadata={"geometry_clipped_to_area": True},
status="ready",
)
area_shape = box(5.0, 51.0, 5.2, 51.2)
area = SimpleNamespace(
id=area_id,
project_id=project_id,
name="Gemeente Mol - officiële grens",
geometry=from_shape(area_shape, srid=4326),
)
db = FakeSession({(Dataset, dataset_id): dataset, (Area, area_id): area})
crossing_bbox = {"min_x": 4.9, "min_y": 51.1, "max_x": 5.1, "max_y": 51.3, "crs": "EPSG:4326"}
captured: dict = {}
selection_payload = {
"selection_bbox": crossing_bbox,
"selection_area_id": str(area_id),
"feature_count": 0,
"limit": 250,
"truncated": False,
"geojson": {"type": "FeatureCollection", "features": []},
}
monkeypatch.setattr(StorageService, "dataset_export_path", lambda *_args: str(tmp_path / "selection.geojson"))
def fake_select(*_args, **kwargs):
captured.update(kwargs)
return selection_payload
monkeypatch.setattr(VectorFeatureService, "select_features_by_bbox", fake_select)
ExportService.export_vector_selection_geojson(
db,
dataset_id,
crossing_bbox,
area_id=area_id,
)
assert to_shape(captured["selection_geometry"]).equals(box(5.0, 51.1, 5.1, 51.2))
assert captured["selection_area_id"] == area_id
assert captured["full_dataset_area"] is False
def test_area_constrained_bbox_rejects_selection_outside_work_area() -> None:
area_geometry = from_shape(box(5.0, 51.0, 5.2, 51.2), srid=4326)
outside_bbox = {"min_x": 4.0, "min_y": 50.0, "max_x": 4.1, "max_y": 50.1, "crs": "EPSG:4326"}
try:
VectorFeatureService.constrain_bbox_to_area(outside_bbox, area_geometry)
except AppError as error:
assert error.code == "VECTOR_SELECTION_OUTSIDE_AREA"
assert error.status_code == 422
else:
raise AssertionError("Expected an outside-area selection to be rejected")
def test_frontend_exposes_map_selection_export_action() -> None:
types = (ROOT / "frontend" / "src" / "types.ts").read_text(encoding="utf-8")
exports_api = (ROOT / "frontend" / "src" / "services" / "api" / "exports.ts").read_text(encoding="utf-8")