Skip to content

Commit dda8bcb

Browse files
committed
Issue #678/#682 more tests for load_stac spatial_extent handling
1 parent 4a45519 commit dda8bcb

File tree

1 file changed

+217
-40
lines changed

1 file changed

+217
-40
lines changed

tests/rest/test_connection.py

Lines changed: 217 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,44 @@
5151

5252
BASIC_ENDPOINTS = [{"path": "/credentials/basic", "methods": ["GET"]}]
5353

54+
55+
GEOJSON_POINT_01 = {"type": "Point", "coordinates": [3, 52]}
56+
GEOJSON_LINESTRING_01 = {"type": "LineString", "coordinates": [[3, 50], [4, 51], [5, 53]]}
57+
GEOJSON_POLYGON_01 = {
58+
"type": "Polygon",
59+
"coordinates": [[[3, 51], [4, 51], [4, 52], [3, 52], [3, 51]]],
60+
}
61+
GEOJSON_MULTIPOLYGON_01 = {
62+
"type": "MultiPolygon",
63+
"coordinates": [[[[3, 51], [4, 51], [4, 52], [3, 52], [3, 51]]]],
64+
}
65+
GEOJSON_FEATURE_01 = {
66+
"type": "Feature",
67+
"properties": {},
68+
"geometry": GEOJSON_POLYGON_01,
69+
}
70+
GEOJSON_FEATURE_02 = {
71+
"type": "Feature",
72+
"properties": {},
73+
"geometry": GEOJSON_MULTIPOLYGON_01,
74+
}
75+
GEOJSON_FEATURECOLLECTION_01 = {
76+
"type": "FeatureCollection",
77+
"features": [
78+
GEOJSON_FEATURE_01,
79+
GEOJSON_FEATURE_02,
80+
],
81+
}
82+
GEOJSON_GEOMETRYCOLLECTION_01 = {
83+
"type": "GeometryCollection",
84+
"geometries": [
85+
GEOJSON_POINT_01,
86+
GEOJSON_POLYGON_01,
87+
],
88+
}
89+
5490
# Trick to avoid linting/auto-formatting tools to complain about or fix unused imports of these pytest fixtures
91+
# TODO: use proper way to reuse fixtures instead of this hack
5592
auth_config = auth_config
5693
refresh_token_store = refresh_token_store
5794

@@ -2427,42 +2464,6 @@ def test_load_collection_spatial_extent_bbox(self, dummy_backend):
24272464
"temporal_extent": None,
24282465
}
24292466

2430-
# TODO: make this more reusable
2431-
GEOJSON_POINT_01 = {"type": "Point", "coordinates": [3, 52]}
2432-
GEOJSON_LINESTRING_01 = {"type": "LineString", "coordinates": [[3, 50], [4, 51], [5, 53]]}
2433-
GEOJSON_POLYGON_01 = {
2434-
"type": "Polygon",
2435-
"coordinates": [[[3, 51], [4, 51], [4, 52], [3, 52], [3, 51]]],
2436-
}
2437-
GEOJSON_MULTIPOLYGON_01 = {
2438-
"type": "MultiPolygon",
2439-
"coordinates": [[[[3, 51], [4, 51], [4, 52], [3, 52], [3, 51]]]],
2440-
}
2441-
GEOJSON_FEATURE_01 = {
2442-
"type": "Feature",
2443-
"properties": {},
2444-
"geometry": GEOJSON_POLYGON_01,
2445-
}
2446-
GEOJSON_FEATURE_02 = {
2447-
"type": "Feature",
2448-
"properties": {},
2449-
"geometry": GEOJSON_MULTIPOLYGON_01,
2450-
}
2451-
GEOJSON_FEATURECOLLECTION_01 = {
2452-
"type": "FeatureCollection",
2453-
"features": [
2454-
GEOJSON_FEATURE_01,
2455-
GEOJSON_FEATURE_02,
2456-
],
2457-
}
2458-
GEOJSON_GEOMETRYCOLLECTION_01 = {
2459-
"type": "GeometryCollection",
2460-
"geometries": [
2461-
GEOJSON_POINT_01,
2462-
GEOJSON_POLYGON_01,
2463-
],
2464-
}
2465-
24662467
@pytest.mark.parametrize(
24672468
"spatial_extent",
24682469
[
@@ -2485,9 +2486,9 @@ def test_load_collection_spatial_extent_geojson(self, dummy_backend, spatial_ext
24852486
"spatial_extent",
24862487
[GEOJSON_POINT_01, GEOJSON_LINESTRING_01, GEOJSON_GEOMETRYCOLLECTION_01],
24872488
)
2488-
def test_load_collection_spatial_extent_geojson_wrong_type(self, con120, spatial_extent):
2489+
def test_load_collection_spatial_extent_geojson_wrong_type(self, dummy_backend, spatial_extent):
24892490
with pytest.raises(OpenEoClientException, match="Invalid geometry type"):
2490-
_ = con120.load_collection("S2", spatial_extent=spatial_extent)
2491+
_ = dummy_backend.connection.load_collection("S2", spatial_extent=spatial_extent)
24912492

24922493
@pytest.mark.parametrize(
24932494
"geojson",
@@ -2544,11 +2545,18 @@ def test_load_collection_spatial_extent_url(self, dummy_backend):
25442545
assert dummy_backend.get_sync_pg() == {
25452546
"loadurl1": {
25462547
"process_id": "load_url",
2547-
"arguments": {"url": "https://geo.test/geometry.json", "format": "GeoJSON"},
2548+
"arguments": {
2549+
"url": "https://geo.test/geometry.json",
2550+
"format": "GeoJSON",
2551+
},
25482552
},
25492553
"loadcollection1": {
25502554
"process_id": "load_collection",
2551-
"arguments": {"id": "S2", "spatial_extent": {"from_node": "loadurl1"}, "temporal_extent": None},
2555+
"arguments": {
2556+
"id": "S2",
2557+
"spatial_extent": {"from_node": "loadurl1"},
2558+
"temporal_extent": None,
2559+
},
25522560
"result": True,
25532561
},
25542562
}
@@ -2921,6 +2929,175 @@ def test_bands_parameterized(self, con120):
29212929
}
29222930
}
29232931

2932+
def test_load_stac_spatial_extent_bbox(self, dummy_backend):
2933+
spatial_extent = {"west": 1, "south": 2, "east": 3, "north": 4}
2934+
# TODO #694 how to avoid request to dummy STAC URL (without mocking, which is overkill for this test)
2935+
cube = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=spatial_extent)
2936+
cube.execute()
2937+
assert dummy_backend.get_sync_pg()["loadstac1"]["arguments"] == {
2938+
"spatial_extent": {"east": 3, "north": 4, "south": 2, "west": 1},
2939+
"url": "https://stac.test/data",
2940+
}
2941+
2942+
@pytest.mark.parametrize(
2943+
"spatial_extent",
2944+
[
2945+
GEOJSON_POLYGON_01,
2946+
GEOJSON_MULTIPOLYGON_01,
2947+
GEOJSON_FEATURE_01,
2948+
GEOJSON_FEATURECOLLECTION_01,
2949+
],
2950+
)
2951+
def test_load_stac_spatial_extent_geojson(self, dummy_backend, spatial_extent):
2952+
# TODO #694 how to avoid request to dummy STAC URL (without mocking, which is overkill for this test)
2953+
cube = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=spatial_extent)
2954+
cube.execute()
2955+
assert dummy_backend.get_sync_pg()["loadstac1"]["arguments"] == {
2956+
"spatial_extent": spatial_extent,
2957+
"url": "https://stac.test/data",
2958+
}
2959+
2960+
@pytest.mark.parametrize(
2961+
"spatial_extent",
2962+
[
2963+
GEOJSON_POINT_01,
2964+
GEOJSON_LINESTRING_01,
2965+
GEOJSON_GEOMETRYCOLLECTION_01,
2966+
],
2967+
)
2968+
def test_load_stac_spatial_extent_geojson_wrong_type(self, dummy_backend, spatial_extent):
2969+
# TODO #694 how to avoid request to dummy STAC URL (without mocking, which is overkill for this test)
2970+
with pytest.raises(OpenEoClientException, match="Invalid geometry type"):
2971+
_ = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=spatial_extent)
2972+
2973+
@pytest.mark.parametrize(
2974+
"geojson",
2975+
[
2976+
GEOJSON_POLYGON_01,
2977+
GEOJSON_MULTIPOLYGON_01,
2978+
],
2979+
)
2980+
def test_load_stac_spatial_extent_shapely(self, dummy_backend, geojson):
2981+
spatial_extent = shapely.geometry.shape(geojson)
2982+
# TODO #694 how to avoid request to dummy STAC URL (without mocking, which is overkill for this test)
2983+
cube = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=spatial_extent)
2984+
cube.execute()
2985+
assert dummy_backend.get_sync_pg()["loadstac1"]["arguments"] == {
2986+
"url": "https://stac.test/data",
2987+
"spatial_extent": geojson,
2988+
}
2989+
2990+
@pytest.mark.parametrize(
2991+
"geojson",
2992+
[
2993+
GEOJSON_POINT_01,
2994+
GEOJSON_GEOMETRYCOLLECTION_01,
2995+
],
2996+
)
2997+
def test_load_stac_spatial_extent_shapely_wront_type(self, dummy_backend, geojson):
2998+
spatial_extent = shapely.geometry.shape(geojson)
2999+
# TODO #694 how to avoid request to dummy STAC URL (without mocking, which is overkill for this test)
3000+
with pytest.raises(OpenEoClientException, match="Invalid geometry type"):
3001+
_ = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=spatial_extent)
3002+
3003+
@pytest.mark.parametrize(
3004+
"geojson",
3005+
[
3006+
GEOJSON_MULTIPOLYGON_01,
3007+
GEOJSON_FEATURECOLLECTION_01,
3008+
],
3009+
)
3010+
@pytest.mark.parametrize("path_factory", [str, Path])
3011+
def test_load_stac_spatial_extent_path(self, geojson, dummy_backend, tmp_path, path_factory):
3012+
path = tmp_path / "geometry.json"
3013+
with path.open("w") as f:
3014+
json.dump(geojson, f)
3015+
3016+
# TODO #694 how to avoid request to dummy STAC URL (without mocking, which is overkill for this test)
3017+
cube = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=path_factory(path))
3018+
cube.execute()
3019+
assert dummy_backend.get_sync_pg()["loadstac1"]["arguments"] == {
3020+
"url": "https://stac.test/data",
3021+
"spatial_extent": geojson,
3022+
}
3023+
3024+
def test_load_stac_spatial_extent_url(self, dummy_backend):
3025+
# TODO #694 how to avoid request to dummy STAC URL (without mocking, which is overkill for this test)
3026+
cube = dummy_backend.connection.load_stac(
3027+
"https://stac.test/data", spatial_extent="https://geo.test/geometry.json"
3028+
)
3029+
cube.execute()
3030+
assert dummy_backend.get_sync_pg() == {
3031+
"loadurl1": {
3032+
"process_id": "load_url",
3033+
"arguments": {
3034+
"url": "https://geo.test/geometry.json",
3035+
"format": "GeoJSON",
3036+
},
3037+
},
3038+
"loadstac1": {
3039+
"process_id": "load_stac",
3040+
"arguments": {
3041+
"url": "https://stac.test/data",
3042+
"spatial_extent": {"from_node": "loadurl1"},
3043+
},
3044+
"result": True,
3045+
},
3046+
}
3047+
3048+
@pytest.mark.parametrize(
3049+
"parameter",
3050+
[
3051+
Parameter("zpatial_extent"),
3052+
Parameter.spatial_extent("zpatial_extent"),
3053+
Parameter.geojson("zpatial_extent"),
3054+
],
3055+
)
3056+
def test_load_stac_spatial_extent_parameter(self, dummy_backend, parameter, recwarn):
3057+
cube = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=parameter)
3058+
assert len(recwarn) == 0
3059+
3060+
cube.execute()
3061+
assert dummy_backend.get_sync_pg()["loadstac1"]["arguments"] == {
3062+
"url": "https://stac.test/data",
3063+
"spatial_extent": {"from_parameter": "zpatial_extent"},
3064+
}
3065+
3066+
def test_load_stac_spatial_extent_parameter_schema_mismatch(self, dummy_backend, recwarn):
3067+
cube = dummy_backend.connection.load_stac(
3068+
"https://stac.test/data", spatial_extent=Parameter.number("zpatial_extent", description="foo")
3069+
)
3070+
assert [str(w.message) for w in recwarn] == [
3071+
"Schema mismatch with parameter given to `spatial_extent` in `load_stac`: expected a schema compatible with type 'object' but got {'type': 'number'}."
3072+
]
3073+
3074+
cube.execute()
3075+
assert dummy_backend.get_sync_pg()["loadstac1"]["arguments"] == {
3076+
"url": "https://stac.test/data",
3077+
"spatial_extent": {"from_parameter": "zpatial_extent"},
3078+
}
3079+
3080+
def test_load_stac_spatial_extent_vector_cube(self, dummy_backend):
3081+
vector_cube = VectorCube.load_url(
3082+
connection=dummy_backend.connection, url="https://geo.test/geometry.json", format="GeoJSON"
3083+
)
3084+
cube = dummy_backend.connection.load_stac("https://stac.test/data", spatial_extent=vector_cube)
3085+
cube.execute()
3086+
assert dummy_backend.get_sync_pg() == {
3087+
"loadurl1": {
3088+
"process_id": "load_url",
3089+
"arguments": {"format": "GeoJSON", "url": "https://geo.test/geometry.json"},
3090+
},
3091+
"loadstac1": {
3092+
"process_id": "load_stac",
3093+
"arguments": {
3094+
"url": "https://stac.test/data",
3095+
"spatial_extent": {"from_node": "loadurl1"},
3096+
},
3097+
"result": True,
3098+
},
3099+
}
3100+
29243101

29253102
@pytest.mark.parametrize(
29263103
"data",

0 commit comments

Comments
 (0)