Constrain selections to active work areas
This commit is contained in:
@@ -6,8 +6,8 @@ from types import SimpleNamespace
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from geoalchemy2.shape import from_shape
|
||||
from shapely.geometry import Polygon
|
||||
from geoalchemy2.shape import from_shape, to_shape
|
||||
from shapely.geometry import Polygon, box
|
||||
|
||||
from app.core.errors import AppError
|
||||
from app.models import Dataset, DatasetVersion
|
||||
@@ -347,6 +347,73 @@ def test_temporal_compare_returns_delta_and_canonical_change_payload(monkeypatch
|
||||
assert result.geojson["type"] == "FeatureCollection"
|
||||
|
||||
|
||||
def test_temporal_comparison_clips_cross_boundary_bbox_to_selected_area(monkeypatch) -> None:
|
||||
project_id = uuid4()
|
||||
area_id = uuid4()
|
||||
earlier = temporal_dataset(project_id=project_id, observed_year=2021)
|
||||
later = temporal_dataset(project_id=project_id, observed_year=2024)
|
||||
area_shape = box(5.0, 51.0, 5.2, 51.2)
|
||||
area = SimpleNamespace(
|
||||
id=area_id,
|
||||
project_id=project_id,
|
||||
geometry=from_shape(area_shape, srid=4326),
|
||||
)
|
||||
captured_geometries = []
|
||||
identity_capture = {}
|
||||
|
||||
monkeypatch.setattr(
|
||||
TemporalAnalysisService,
|
||||
"_get_temporal_dataset",
|
||||
staticmethod(lambda _db, _project_id, dataset_id, _label: earlier if dataset_id == earlier.id else later),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
TemporalAnalysisService,
|
||||
"_get_selection_area",
|
||||
staticmethod(lambda _db, _project_id, requested_area_id: area if requested_area_id == area_id else None),
|
||||
)
|
||||
|
||||
def summarize(_db, *, dataset, bbox, selection_geometry, full_dataset_area): # noqa: ARG001
|
||||
captured_geometries.append(selection_geometry)
|
||||
return {
|
||||
"metric_label": "Oppervlakte",
|
||||
"metric_value": 10.0 if dataset.id == earlier.id else 12.0,
|
||||
"metric_unit": "ha",
|
||||
"aggregation_method": "intersection_area",
|
||||
"feature_count": 1,
|
||||
"is_estimate": False,
|
||||
"warning": None,
|
||||
}
|
||||
|
||||
def compare_identity(*_args, **kwargs):
|
||||
identity_capture.update(kwargs)
|
||||
return (
|
||||
TemporalObjectChanges(available=False),
|
||||
{"type": "FeatureCollection", "features": []},
|
||||
[],
|
||||
)
|
||||
|
||||
monkeypatch.setattr(VectorFeatureService, "summarize_features_by_bbox", staticmethod(summarize))
|
||||
monkeypatch.setattr(TemporalAnalysisService, "_compare_identity_features", staticmethod(compare_identity))
|
||||
|
||||
result = TemporalAnalysisService.compare(
|
||||
SimpleNamespace(),
|
||||
project_id=project_id,
|
||||
payload=TemporalComparisonRequest(
|
||||
earlier_dataset_id=earlier.id,
|
||||
later_dataset_id=later.id,
|
||||
area_id=area_id,
|
||||
bbox={"min_x": 4.9, "min_y": 51.1, "max_x": 5.1, "max_y": 51.3},
|
||||
),
|
||||
)
|
||||
|
||||
expected = box(5.0, 51.1, 5.1, 51.2)
|
||||
assert result.metric.absolute_change == 2.0
|
||||
assert all(to_shape(geometry).equals(expected) for geometry in captured_geometries)
|
||||
assert to_shape(identity_capture["selection_geometry"]).equals(expected)
|
||||
assert identity_capture["earlier_full_dataset_area"] is False
|
||||
assert identity_capture["later_full_dataset_area"] is False
|
||||
|
||||
|
||||
def test_unstable_temporal_identity_returns_clear_end_user_warning() -> None:
|
||||
project_id = uuid4()
|
||||
earlier = temporal_dataset(project_id=project_id, observed_year=2021)
|
||||
|
||||
Reference in New Issue
Block a user