Skip to content

Commit 7f1b5e5

Browse files
committed
fix GET sortby, tests
1 parent b324592 commit 7f1b5e5

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed

stac_fastapi/elasticsearch/stac_fastapi/elasticsearch/core.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,10 @@ async def get_search(
329329
sort_param.append(
330330
{
331331
"field": sort[1:],
332-
"direction": "asc" if sort[0] == "+" else "desc",
332+
"direction": "desc" if sort[0] == "-" else "asc",
333333
}
334334
)
335+
print(sort_param)
335336
base_args["sortby"] = sort_param
336337

337338
# todo: requires fastapi > 2.3 unreleased

stac_fastapi/elasticsearch/tests/api/test_api.py

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import uuid
33
from datetime import datetime, timedelta
44

5+
import pytest
6+
57
from ..conftest import create_collection, create_item
68

79
ROUTES = {
@@ -31,17 +33,20 @@
3133
}
3234

3335

36+
@pytest.mark.asyncio
3437
async def test_post_search_content_type(app_client, ctx):
3538
params = {"limit": 1}
3639
resp = await app_client.post("/search", json=params)
3740
assert resp.headers["content-type"] == "application/geo+json"
3841

3942

43+
@pytest.mark.asyncio
4044
async def test_get_search_content_type(app_client, ctx):
4145
resp = await app_client.get("/search")
4246
assert resp.headers["content-type"] == "application/geo+json"
4347

4448

49+
@pytest.mark.asyncio
4550
async def test_api_headers(app_client):
4651
resp = await app_client.get("/api")
4752
assert (
@@ -50,11 +55,13 @@ async def test_api_headers(app_client):
5055
assert resp.status_code == 200
5156

5257

58+
@pytest.mark.asyncio
5359
async def test_router(app):
5460
api_routes = set([f"{list(route.methods)[0]} {route.path}" for route in app.routes])
5561
assert len(api_routes - ROUTES) == 0
5662

5763

64+
@pytest.mark.asyncio
5865
async def test_app_transaction_extension(app_client, ctx):
5966
item = copy.deepcopy(ctx.item)
6067
item["id"] = str(uuid.uuid4())
@@ -64,6 +71,7 @@ async def test_app_transaction_extension(app_client, ctx):
6471
await app_client.delete(f"/collections/{item['collection']}/items/{item['id']}")
6572

6673

74+
@pytest.mark.asyncio
6775
async def test_app_search_response(app_client, ctx):
6876
resp = await app_client.get("/search", params={"ids": ["test-item"]})
6977
assert resp.status_code == 200
@@ -75,6 +83,7 @@ async def test_app_search_response(app_client, ctx):
7583
assert resp_json.get("stac_extensions") is None
7684

7785

86+
@pytest.mark.asyncio
7887
async def test_app_context_extension(app_client, ctx, txn_client):
7988
test_item = ctx.item
8089
test_item["id"] = "test-item-2"
@@ -108,13 +117,15 @@ async def test_app_context_extension(app_client, ctx, txn_client):
108117
assert matched == 1
109118

110119

120+
@pytest.mark.asyncio
111121
async def test_app_fields_extension(app_client, ctx, txn_client):
112122
resp = await app_client.get("/search", params={"collections": ["test-collection"]})
113123
assert resp.status_code == 200
114124
resp_json = resp.json()
115125
assert list(resp_json["features"][0]["properties"]) == ["datetime"]
116126

117127

128+
@pytest.mark.asyncio
118129
async def test_app_fields_extension_query(app_client, ctx, txn_client):
119130
resp = await app_client.post(
120131
"/search",
@@ -128,6 +139,7 @@ async def test_app_fields_extension_query(app_client, ctx, txn_client):
128139
assert list(resp_json["features"][0]["properties"]) == ["datetime", "proj:epsg"]
129140

130141

142+
@pytest.mark.asyncio
131143
async def test_app_fields_extension_no_properties_get(app_client, ctx, txn_client):
132144
resp = await app_client.get(
133145
"/search", params={"collections": ["test-collection"], "fields": "-properties"}
@@ -137,6 +149,7 @@ async def test_app_fields_extension_no_properties_get(app_client, ctx, txn_clien
137149
assert "properties" not in resp_json["features"][0]
138150

139151

152+
@pytest.mark.asyncio
140153
async def test_app_fields_extension_no_properties_post(app_client, ctx, txn_client):
141154
resp = await app_client.post(
142155
"/search",
@@ -150,6 +163,7 @@ async def test_app_fields_extension_no_properties_post(app_client, ctx, txn_clie
150163
assert "properties" not in resp_json["features"][0]
151164

152165

166+
@pytest.mark.asyncio
153167
async def test_app_fields_extension_return_all_properties(app_client, ctx, txn_client):
154168
item = ctx.item
155169
resp = await app_client.get(
@@ -166,6 +180,7 @@ async def test_app_fields_extension_return_all_properties(app_client, ctx, txn_c
166180
assert feature["properties"][expected_prop] == expected_value
167181

168182

183+
@pytest.mark.asyncio
169184
async def test_app_query_extension_gt(app_client, ctx):
170185
params = {"query": {"proj:epsg": {"gt": ctx.item["properties"]["proj:epsg"]}}}
171186
resp = await app_client.post("/search", json=params)
@@ -174,6 +189,7 @@ async def test_app_query_extension_gt(app_client, ctx):
174189
assert len(resp_json["features"]) == 0
175190

176191

192+
@pytest.mark.asyncio
177193
async def test_app_query_extension_gte(app_client, ctx):
178194
params = {"query": {"proj:epsg": {"gte": ctx.item["properties"]["proj:epsg"]}}}
179195
resp = await app_client.post("/search", json=params)
@@ -182,21 +198,95 @@ async def test_app_query_extension_gte(app_client, ctx):
182198
assert len(resp.json()["features"]) == 1
183199

184200

201+
@pytest.mark.asyncio
185202
async def test_app_query_extension_limit_lt0(app_client):
186203
assert (await app_client.post("/search", json={"limit": -1})).status_code == 400
187204

188205

206+
@pytest.mark.asyncio
189207
async def test_app_query_extension_limit_gt10000(app_client):
190208
assert (await app_client.post("/search", json={"limit": 10001})).status_code == 400
191209

192210

211+
@pytest.mark.asyncio
193212
async def test_app_query_extension_limit_10000(app_client):
194213
params = {"limit": 10000}
195214
resp = await app_client.post("/search", json=params)
196215
assert resp.status_code == 200
197216

198217

199-
async def test_app_sort_extension(app_client, txn_client, ctx):
218+
@pytest.mark.asyncio
219+
async def test_app_sort_extension_get_asc(app_client, txn_client, ctx):
220+
first_item = ctx.item
221+
item_date = datetime.strptime(
222+
first_item["properties"]["datetime"], "%Y-%m-%dT%H:%M:%SZ"
223+
)
224+
225+
second_item = dict(first_item)
226+
second_item["id"] = "another-item"
227+
another_item_date = item_date - timedelta(days=1)
228+
second_item["properties"]["datetime"] = another_item_date.strftime(
229+
"%Y-%m-%dT%H:%M:%SZ"
230+
)
231+
await create_item(txn_client, second_item)
232+
233+
resp = await app_client.get("/search?sortby=+properties.datetime")
234+
assert resp.status_code == 200
235+
resp_json = resp.json()
236+
assert resp_json["features"][1]["id"] == first_item["id"]
237+
assert resp_json["features"][0]["id"] == second_item["id"]
238+
239+
240+
@pytest.mark.asyncio
241+
async def test_app_sort_extension_get_desc(app_client, txn_client, ctx):
242+
first_item = ctx.item
243+
item_date = datetime.strptime(
244+
first_item["properties"]["datetime"], "%Y-%m-%dT%H:%M:%SZ"
245+
)
246+
247+
second_item = dict(first_item)
248+
second_item["id"] = "another-item"
249+
another_item_date = item_date - timedelta(days=1)
250+
second_item["properties"]["datetime"] = another_item_date.strftime(
251+
"%Y-%m-%dT%H:%M:%SZ"
252+
)
253+
await create_item(txn_client, second_item)
254+
255+
resp = await app_client.get("/search?sortby=-properties.datetime")
256+
assert resp.status_code == 200
257+
resp_json = resp.json()
258+
assert resp_json["features"][0]["id"] == first_item["id"]
259+
assert resp_json["features"][1]["id"] == second_item["id"]
260+
261+
262+
@pytest.mark.asyncio
263+
async def test_app_sort_extension_post_asc(app_client, txn_client, ctx):
264+
first_item = ctx.item
265+
item_date = datetime.strptime(
266+
first_item["properties"]["datetime"], "%Y-%m-%dT%H:%M:%SZ"
267+
)
268+
269+
second_item = dict(first_item)
270+
second_item["id"] = "another-item"
271+
another_item_date = item_date - timedelta(days=1)
272+
second_item["properties"]["datetime"] = another_item_date.strftime(
273+
"%Y-%m-%dT%H:%M:%SZ"
274+
)
275+
await create_item(txn_client, second_item)
276+
277+
params = {
278+
"collections": [first_item["collection"]],
279+
"sortby": [{"field": "properties.datetime", "direction": "asc"}],
280+
}
281+
resp = await app_client.post("/search", json=params)
282+
assert resp.status_code == 200
283+
resp_json = resp.json()
284+
assert resp_json["features"][1]["id"] == first_item["id"]
285+
assert resp_json["features"][0]["id"] == second_item["id"]
286+
287+
288+
@pytest.mark.asyncio
289+
async def test_app_sort_extension_post_desc(app_client, txn_client, ctx):
200290
first_item = ctx.item
201291
item_date = datetime.strptime(
202292
first_item["properties"]["datetime"], "%Y-%m-%dT%H:%M:%SZ"
@@ -221,6 +311,7 @@ async def test_app_sort_extension(app_client, txn_client, ctx):
221311
assert resp_json["features"][1]["id"] == second_item["id"]
222312

223313

314+
@pytest.mark.asyncio
224315
async def test_search_invalid_date(app_client, ctx):
225316
params = {
226317
"datetime": "2020-XX-01/2020-10-30",
@@ -231,6 +322,7 @@ async def test_search_invalid_date(app_client, ctx):
231322
assert resp.status_code == 400
232323

233324

325+
@pytest.mark.asyncio
234326
async def test_search_point_intersects(app_client, ctx):
235327
point = [150.04, -33.14]
236328
intersects = {"type": "Point", "coordinates": point}
@@ -246,6 +338,7 @@ async def test_search_point_intersects(app_client, ctx):
246338
assert len(resp_json["features"]) == 1
247339

248340

341+
@pytest.mark.asyncio
249342
async def test_search_point_does_not_intersect(app_client, ctx):
250343
point = [15.04, -3.14]
251344
intersects = {"type": "Point", "coordinates": point}
@@ -261,6 +354,7 @@ async def test_search_point_does_not_intersect(app_client, ctx):
261354
assert len(resp_json["features"]) == 0
262355

263356

357+
@pytest.mark.asyncio
264358
async def test_datetime_non_interval(app_client, ctx):
265359
dt_formats = [
266360
"2020-02-12T12:30:22+00:00",
@@ -282,6 +376,7 @@ async def test_datetime_non_interval(app_client, ctx):
282376
assert resp_json["features"][0]["properties"]["datetime"][0:19] == dt[0:19]
283377

284378

379+
@pytest.mark.asyncio
285380
async def test_bbox_3d(app_client, ctx):
286381
australia_bbox = [106.343365, -47.199523, 0.1, 168.218365, -19.437288, 0.1]
287382
params = {
@@ -294,6 +389,7 @@ async def test_bbox_3d(app_client, ctx):
294389
assert len(resp_json["features"]) == 1
295390

296391

392+
@pytest.mark.asyncio
297393
async def test_search_line_string_intersects(app_client, ctx):
298394
line = [[150.04, -33.14], [150.22, -33.89]]
299395
intersects = {"type": "LineString", "coordinates": line}

stac_fastapi/elasticsearch/tests/conftest.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ class Config:
6161

6262
@pytest.fixture(scope="session")
6363
def event_loop():
64-
return asyncio.get_event_loop()
64+
loop = asyncio.new_event_loop()
65+
yield loop
66+
loop.close()
6567

6668

6769
def _load_file(filename: str) -> Dict:

0 commit comments

Comments
 (0)