Skip to content

Commit 94a97c8

Browse files
committed
Make TestSTACAPIJobDatabase.test_get_by_status_result less fake
further elimination of unnecessary fixtures Based on working on #794 and #798
1 parent 481ab0c commit 94a97c8

File tree

1 file changed

+71
-36
lines changed

1 file changed

+71
-36
lines changed

tests/extra/job_management/test_stac_job_db.py

Lines changed: 71 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import collections
12
import datetime
23
import re
3-
from typing import Any, Dict, Optional, Union
4+
from typing import Any, Dict, List, Optional, Union
45
from unittest import mock
56
from unittest.mock import MagicMock, patch
67

@@ -19,18 +20,14 @@
1920

2021

2122
@pytest.fixture
22-
def mock_pystac_client(dummy_stac_item):
23+
def mock_pystac_client():
2324
mock_client = MagicMock(spec=pystac_client.Client)
2425

2526
mock_client.get_collections.return_value = [
2627
MagicMock(id="collection-1"),
2728
MagicMock(id="collection-2"),
2829
]
2930

30-
mock_item_search = MagicMock(spec=pystac_client.ItemSearch)
31-
mock_item_search.items.return_value = [dummy_stac_item]
32-
mock_client.search.return_value = mock_item_search
33-
3431
with patch("pystac_client.Client.open", return_value=mock_client):
3532
yield mock_client
3633

@@ -97,22 +94,6 @@ def _pystac_item(
9794
)
9895

9996

100-
@pytest.fixture
101-
def dummy_stac_item() -> pystac.Item:
102-
properties = {
103-
"datetime": "2020-05-22T00:00:00Z",
104-
"some_property": "value",
105-
}
106-
return pystac.Item(
107-
id="test", geometry=None, bbox=None, properties=properties, datetime=datetime.datetime(2020, 5, 22)
108-
)
109-
110-
111-
@pytest.fixture
112-
def dummy_series_no_item_id() -> pd.Series:
113-
return pd.Series({"datetime": "2020-05-22T00:00:00Z", "some_property": "value"}, name="test")
114-
115-
11697
@pytest.fixture
11798
def bulk_dataframe():
11899
return pd.DataFrame(
@@ -227,8 +208,19 @@ def test_initialize_from_df_with_geometry(self, mock_persists, job_db_not_exists
227208
assert job_db_not_exists.has_geometry == True
228209
assert job_db_not_exists.geometry_column == "geometry"
229210

230-
def test_series_from(self, job_db_exists, dummy_series_no_item_id, dummy_stac_item):
231-
pdt.assert_series_equal(job_db_exists.series_from(dummy_stac_item), dummy_series_no_item_id)
211+
def test_series_from(self, job_db_exists):
212+
item = pystac.Item(
213+
id="test",
214+
geometry=None,
215+
bbox=None,
216+
properties={
217+
"datetime": "2020-05-22T00:00:00Z",
218+
"some_property": "value",
219+
},
220+
datetime=datetime.datetime(2020, 5, 22),
221+
)
222+
expected = pd.Series({"datetime": "2020-05-22T00:00:00Z", "some_property": "value"}, name="test")
223+
pdt.assert_series_equal(job_db_exists.series_from(item), expected)
232224

233225
@pytest.mark.parametrize(
234226
["series", "expected"],
@@ -328,18 +320,43 @@ def test_get_by_status_with_filter(self, job_db_exists):
328320
method="GET", collections=["collection-1"], filter="\"properties.status\"='not_started'", max_items=None
329321
)
330322

331-
def test_get_by_status_result(self, job_db_exists):
332-
df = job_db_exists.get_by_status(["not_started"])
323+
def test_get_by_status_result(self, requests_mock):
324+
stac_api_url = "http://stacapi.test"
325+
dummy_stac_api = DummyStacApi(root_url=stac_api_url, requests_mock=requests_mock)
326+
dummy_stac_api.predefine_collection("collection-123")
327+
dummy_stac_api.predefine_item(
328+
collection_id="collection-123",
329+
item=_pystac_item(id="item-123", properties={"status": "not_started"}),
330+
)
331+
dummy_stac_api.predefine_item(
332+
collection_id="collection-123",
333+
item=_pystac_item(id="item-456", properties={"status": "running"}),
334+
)
335+
dummy_stac_api.predefine_item(
336+
collection_id="collection-123",
337+
item=_pystac_item(id="item-789", properties={"status": "not_started"}),
338+
)
339+
340+
job_db = STACAPIJobDatabase(collection_id="collection-123", stac_root_url=stac_api_url)
333341

334342
pdt.assert_frame_equal(
335-
df,
343+
job_db.get_by_status(["not_started"]),
336344
pd.DataFrame(
337345
{
338-
"item_id": ["test"],
339-
"datetime": ["2020-05-22T00:00:00Z"],
340-
"some_property": ["value"],
346+
"item_id": ["item-123", "item-789"],
347+
"status": ["not_started", "not_started"],
348+
"datetime": ["2025-06-07T00:00:00Z", "2025-06-07T00:00:00Z"],
349+
},
350+
),
351+
)
352+
pdt.assert_frame_equal(
353+
job_db.get_by_status(["running"]),
354+
pd.DataFrame(
355+
{
356+
"item_id": ["item-456"],
357+
"status": ["running"],
358+
"datetime": ["2025-06-07T00:00:00Z"],
341359
},
342-
index=[0],
343360
),
344361
)
345362

@@ -443,16 +460,16 @@ def sleep_mock():
443460
class DummyStacApi:
444461
"""Minimal dummy implementation of a STAC API for testing purposes."""
445462

446-
def __init__(self, root_url: str, requests_mock):
463+
def __init__(self, *, root_url: str = "http://stacapi.test", requests_mock):
447464
self.root_url = root_url.rstrip("/")
448465
self._requests_mock = requests_mock
449466

450467
requests_mock.get(f"{self.root_url}/", json=self._get_root())
451-
self.collections = []
468+
self.collections: List[dict] = []
452469
requests_mock.get(f"{self.root_url}/collections", json=self._get_collections)
453470
requests_mock.post(f"{self.root_url}/collections", json=self._post_collections)
454471

455-
self.items: Dict[str, Dict[str, Any]] = {}
472+
self.items: Dict[str, Dict[str, Any]] = collections.defaultdict(dict)
456473
requests_mock.post(
457474
re.compile(rf"{self.root_url}/collections/[^/]+/bulk_items"), json=self._post_collections_bulk_items
458475
)
@@ -485,15 +502,33 @@ def _post_collections(self, request, context):
485502
self.collections.append(post_data)
486503
return {}
487504

505+
def predefine_collection(self, collection_id: str):
506+
"""Pre-define a collection with the given ID."""
507+
assert collection_id not in [c["id"] for c in self.collections]
508+
self.collections.append(
509+
pystac.Collection(
510+
id=collection_id,
511+
description=collection_id,
512+
extent=pystac.Extent(
513+
spatial=pystac.SpatialExtent([-180, -90, 180, 90]),
514+
temporal=pystac.TemporalExtent([None, None]),
515+
),
516+
title=collection_id,
517+
).to_dict()
518+
)
519+
520+
def predefine_item(self, *, collection_id: str, item: pystac.Item):
521+
if collection_id not in [c["id"] for c in self.collections]:
522+
self.predefine_collection(collection_id)
523+
self.items[collection_id][item.id] = item.to_dict()
524+
488525
def _post_collections_bulk_items(self, request, context):
489526
"""Handler of `POST /collections/{collection_id}/bulk_items` requests."""
490527
# extract the collection_id from the URL
491528
collection_id = re.search("/collections/([^/]+)/bulk_items", request.url).group(1)
492529
post_data = request.json()
493530
# TODO handle insert/upsert method?
494531
for item_id, item in post_data["items"].items():
495-
if collection_id not in self.items:
496-
self.items[collection_id] = {}
497532
self.items[collection_id][item_id] = item
498533
return {}
499534

0 commit comments

Comments
 (0)