Initial GeoIntel V1 foundation
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from uuid import uuid4
|
||||
|
||||
from app.core.errors import AppError
|
||||
from app.services import geojson_service
|
||||
from app.services.dataset_service import DatasetService
|
||||
|
||||
|
||||
def test_parse_geojson_payload_extracts_metadata() -> None:
|
||||
payload = {
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [4.5, 51.3],
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
metadata = geojson_service.parse_geojson_payload(payload)
|
||||
|
||||
assert metadata["feature_count"] == 1
|
||||
assert metadata["feature_geometry_count"] == 1
|
||||
assert metadata["bounds_json"] == {
|
||||
"min_x": 4.5,
|
||||
"min_y": 51.3,
|
||||
"max_x": 4.5,
|
||||
"max_y": 51.3,
|
||||
}
|
||||
assert metadata["geometry_types"] == ["Point"]
|
||||
|
||||
|
||||
def test_parse_geojson_payload_rejects_non_feature_collection() -> None:
|
||||
payload = {"type": "Feature", "features": []}
|
||||
|
||||
try:
|
||||
geojson_service.parse_geojson_payload(payload)
|
||||
except ValueError as exc:
|
||||
assert "FeatureCollection" in str(exc)
|
||||
else:
|
||||
raise AssertionError("Invalid GeoJSON should raise ValueError")
|
||||
|
||||
|
||||
def test_get_dataset_geojson_reads_stored_payload(tmp_path, monkeypatch) -> None:
|
||||
file_path = tmp_path / "dataset.geojson"
|
||||
file_path.write_text(
|
||||
json.dumps({"type": "FeatureCollection", "features": []}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
dataset = SimpleNamespace(dataset_type="vector", storage_path=str(file_path))
|
||||
monkeypatch.setattr(DatasetService, "get_dataset", lambda _db, _id: dataset)
|
||||
|
||||
payload = DatasetService.get_dataset_geojson(Path("."), uuid4())
|
||||
|
||||
assert payload["type"] == "FeatureCollection"
|
||||
|
||||
|
||||
def test_get_dataset_geojson_rejects_invalid_stored_json(tmp_path, monkeypatch) -> None:
|
||||
file_path = tmp_path / "invalid.geojson"
|
||||
file_path.write_text("not-json", encoding="utf-8")
|
||||
|
||||
dataset = SimpleNamespace(dataset_type="vector", storage_path=str(file_path))
|
||||
monkeypatch.setattr(DatasetService, "get_dataset", lambda _db, _id: dataset)
|
||||
|
||||
try:
|
||||
DatasetService.get_dataset_geojson(Path("."), uuid4())
|
||||
except AppError as exc:
|
||||
assert exc.code == "INVALID_GEOJSON"
|
||||
else:
|
||||
raise AssertionError("Invalid stored payload should raise AppError")
|
||||
|
||||
|
||||
def test_parse_geojson_payload_returns_vector_metadata() -> None:
|
||||
payload = {
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": [
|
||||
[
|
||||
[4.3, 51.2],
|
||||
[4.4, 51.2],
|
||||
[4.4, 51.3],
|
||||
[4.3, 51.3],
|
||||
[4.3, 51.2],
|
||||
]
|
||||
],
|
||||
},
|
||||
}
|
||||
],
|
||||
"crs": {"type": "name", "properties": {"name": "EPSG:31370"}},
|
||||
}
|
||||
|
||||
metadata = geojson_service.parse_geojson_payload(payload)
|
||||
|
||||
assert metadata["feature_count"] == 1
|
||||
assert metadata["feature_geometry_count"] == 1
|
||||
assert metadata["geometry_types"] == ["Polygon"]
|
||||
assert metadata["bounds_json"] == {
|
||||
"min_x": 4.3,
|
||||
"min_y": 51.2,
|
||||
"max_x": 4.4,
|
||||
"max_y": 51.3,
|
||||
}
|
||||
assert metadata["crs"] == "EPSG:31370"
|
||||
assert metadata["approximate_area_m2"] is not None
|
||||
assert metadata["approximate_area_m2"] >= 0.0
|
||||
|
||||
|
||||
def test_parse_geojson_payload_rejects_invalid_geometry() -> None:
|
||||
payload = {
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Polygon",
|
||||
"coordinates": "invalid",
|
||||
},
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
try:
|
||||
geojson_service.parse_geojson_payload(payload)
|
||||
except ValueError as exc:
|
||||
assert "Invalid feature geometry" in str(exc)
|
||||
else:
|
||||
raise AssertionError("Invalid geometry should raise ValueError")
|
||||
|
||||
|
||||
def test_get_dataset_geojson_accepts_legacy_geojson_type(tmp_path, monkeypatch) -> None:
|
||||
file_path = tmp_path / "legacy.geojson"
|
||||
file_path.write_text(
|
||||
json.dumps({"type": "FeatureCollection", "features": []}),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
dataset = SimpleNamespace(dataset_type="geojson", storage_path=str(file_path))
|
||||
monkeypatch.setattr(DatasetService, "get_dataset", lambda _db, _id: dataset)
|
||||
|
||||
payload = DatasetService.get_dataset_geojson(Path("."), uuid4())
|
||||
assert payload["type"] == "FeatureCollection"
|
||||
|
||||
|
||||
def test_vector_summary_supports_legacy_geojson_type(monkeypatch) -> None:
|
||||
dataset = SimpleNamespace(
|
||||
dataset_type="geojson",
|
||||
metadata_json={
|
||||
"feature_count": 7,
|
||||
"geometry_types": ["Point"],
|
||||
"bounds_json": {"min_x": 0.0, "min_y": 0.0, "max_x": 1.0, "max_y": 1.0},
|
||||
},
|
||||
storage_path="",
|
||||
)
|
||||
monkeypatch.setattr(DatasetService, "get_dataset", lambda _db, _id: dataset)
|
||||
|
||||
summary = DatasetService.vector_summary(Path("."), uuid4())
|
||||
assert summary["feature_count"] == 7
|
||||
assert summary["geometry_types"] == ["Point"]
|
||||
Reference in New Issue
Block a user