Skip to content
This repository was archived by the owner on Apr 2, 2025. It is now read-only.

Commit 723e645

Browse files
feat: update Failure logic in root_router get_orders to return 404 for bad token tests: reworking pagination tests tests: adding handle to max limit in test implemented backend
1 parent 53afb66 commit 723e645

File tree

3 files changed

+123
-55
lines changed

3 files changed

+123
-55
lines changed

src/stapi_fastapi/routers/root_router.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,14 @@ async def get_orders(
183183
)
184184
return collections
185185
case Failure(e):
186-
logging.exception("An error occurred while retrieving orders", e)
187-
raise HTTPException(
188-
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
189-
detail="Error finding Orders",
190-
)
186+
logging.exception(f"An error occurred while retrieving orders: {e}")
187+
if isinstance(e, IndexError):
188+
raise NotFoundException(detail="Error finding pagination token")
189+
else:
190+
raise HTTPException(
191+
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
192+
detail="Error finding Orders",
193+
)
191194
case _:
192195
raise AssertionError("Expected code to be unreachable")
193196

tests/application.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ async def get_orders(
5151
"""
5252
try:
5353
start = 0
54-
order_ids = sorted(self._orders_db._orders.keys())
55-
if not order_ids: # not data in db return empty
54+
if limit > 100:
55+
limit = 100
56+
57+
order_ids = [*self._orders_db._orders.keys()]
58+
if not order_ids: # no data in db
5659
return Success(
5760
(
5861
OrderCollection(
@@ -66,10 +69,11 @@ async def get_orders(
6669
start = [i for i, x in enumerate(order_ids) if x == next][0]
6770
end = start + limit
6871
ids = order_ids[start:end]
69-
7072
feats = [self._orders_db._orders[order_id] for order_id in ids]
71-
next = self._orders_db._orders[order_ids[end]].id
7273

74+
next = ""
75+
if end < len(order_ids):
76+
next = self._orders_db._orders[order_ids[end]].id
7377
return Success((OrderCollection(features=feats), next))
7478
except Exception as e:
7579
return Failure(e)

tests/test_order.py

Lines changed: 107 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -171,67 +171,128 @@ def test_order_status_after_update(
171171

172172

173173
@pytest.fixture
174-
def create_second_order_allowed_payloads() -> list[OrderPayload]:
175-
return [
176-
OrderPayload(
174+
def create_order_payloads() -> list[OrderPayload]:
175+
datetimes = [
176+
("2024-10-09T18:55:33Z", "2024-10-12T18:55:33Z"),
177+
("2024-10-15T18:55:33Z", "2024-10-18T18:55:33Z"),
178+
("2024-10-20T18:55:33Z", "2024-10-23T18:55:33Z"),
179+
]
180+
payloads = []
181+
for start, end in datetimes:
182+
payload = OrderPayload(
177183
geometry=Point(
178184
type="Point", coordinates=Position2D(longitude=14.4, latitude=56.5)
179185
),
180186
datetime=(
181-
datetime.fromisoformat("2024-10-09T18:55:33Z"),
182-
datetime.fromisoformat("2024-10-12T18:55:33Z"),
187+
datetime.fromisoformat(start),
188+
datetime.fromisoformat(end),
183189
),
184190
filter=None,
185191
order_parameters=MyOrderParameters(s3_path="s3://my-bucket"),
186-
),
187-
]
192+
)
193+
payloads.append(payload)
194+
return payloads
188195

189196

190-
@pytest.mark.parametrize("product_id", [pytest.param("test-spotlight", id="base test")])
191-
def test_order_pagination(
192-
product_id: str,
193-
product_backend: MockProductBackend,
197+
@pytest.fixture
198+
def prepare_order_pagination(
199+
stapi_client: TestClient, create_order_payloads: list[OrderPayload]
200+
) -> tuple[str, str, str]:
201+
# product_backend._allowed_payloads = create_order_payloads
202+
product_id = "test-spotlight"
203+
204+
# # check empty
205+
# res = stapi_client.get("/orders")
206+
# default_orders = {"type": "FeatureCollection", "features": [], "links": []}
207+
# assert res.status_code == status.HTTP_200_OK
208+
# assert res.headers["Content-Type"] == "application/geo+json"
209+
# assert res.json() == default_orders
210+
211+
# get uuids created to use as pagination tokens
212+
order_ids = []
213+
for payload in create_order_payloads:
214+
res = stapi_client.post(
215+
f"products/{product_id}/orders",
216+
json=payload.model_dump(),
217+
)
218+
assert res.status_code == status.HTTP_201_CREATED, res.text
219+
assert res.headers["Content-Type"] == "application/geo+json"
220+
order_ids.append(res.json()["id"])
221+
222+
# res = stapi_client.get("/orders")
223+
# checker = res.json()
224+
# assert len(checker['features']) == 3
225+
226+
return tuple(order_ids)
227+
228+
229+
@pytest.mark.parametrize(
230+
"product_id,expected_status,limit,id_retrieval,token_back",
231+
[
232+
pytest.param(
233+
"test-spotlight",
234+
status.HTTP_200_OK,
235+
1,
236+
0,
237+
True,
238+
id="input frst order_id token get new token back",
239+
),
240+
pytest.param(
241+
"test-spotlight",
242+
status.HTTP_200_OK,
243+
1,
244+
2,
245+
False,
246+
id="input last order_id token get NO token back",
247+
),
248+
pytest.param(
249+
"test-spotlight",
250+
status.HTTP_404_NOT_FOUND,
251+
1,
252+
"BAD_TOKEN",
253+
False,
254+
id="input bad token get 404 back",
255+
),
256+
pytest.param(
257+
"test-spotlight",
258+
status.HTTP_200_OK,
259+
1,
260+
1000000,
261+
False,
262+
id="high limit handled and returns valid records",
263+
),
264+
],
265+
)
266+
def test_order_pagination_hold(
267+
prepare_order_pagination,
194268
stapi_client: TestClient,
195-
create_order_allowed_payloads: list[OrderPayload],
196-
create_second_order_allowed_payloads: list[OrderPayload],
269+
product_id: str,
270+
expected_status: int,
271+
limit: int,
272+
id_retrieval: int | str,
273+
token_back: bool,
197274
) -> None:
198-
product_backend._allowed_payloads = create_order_allowed_payloads
199-
200-
# check empty
201-
res = stapi_client.get("/orders")
275+
order_ids = prepare_order_pagination
202276

203-
default_orders = {"type": "FeatureCollection", "features": [], "links": []}
204-
205-
assert res.status_code == status.HTTP_200_OK
206-
assert res.headers["Content-Type"] == "application/geo+json"
207-
assert res.json() == default_orders
208-
209-
# add order to product
210-
res = stapi_client.post(
211-
f"products/{product_id}/orders",
212-
json=create_order_allowed_payloads[0].model_dump(),
277+
res = stapi_client.get(
278+
"/orders", params={"next": order_ids[id_retrieval], "limit": limit}
213279
)
280+
assert res.status_code == expected_status
214281

215-
assert res.status_code == status.HTTP_201_CREATED, res.text
216-
assert res.headers["Content-Type"] == "application/geo+json"
217-
218-
res = stapi_client.post(
219-
f"products/{product_id}/orders",
220-
json=create_second_order_allowed_payloads[0].model_dump(),
221-
)
222-
# call all orders
223-
next = res.json()["id"]
224-
res = stapi_client.get("/orders", params={"next": next, "limit": 1})
225-
checker = res.json()
226-
227-
assert res.status_code == status.HTTP_200_OK
228-
229-
# temp check to make sure token link isn't added to inside collection
230-
for link in checker["features"][0]["links"]:
282+
body = res.json()
283+
for link in body["features"][0]["links"]:
231284
assert link["rel"] != "next"
232-
assert checker["links"] != []
285+
assert body["links"] != []
233286

234287
# check to make sure new token in link
235-
assert next not in checker["links"][0]["href"]
288+
if token_back:
289+
assert order_ids[id_retrieval] not in body["links"][0]["href"]
290+
291+
assert len(body["features"]) == limit
292+
236293

237-
assert len(checker["features"]) == 1
294+
# test cases to check
295+
# 1. Input token and get last record. Should not return a token if we are returning the last record - 'last' record being what is sorted
296+
# 2. Input a crzy high limit - how to handle? Default to max or all records if less than max
297+
# 3. Input token and get some intermediate records - return a token for next records
298+
# 4. handle requesting an orderid/token that does't exist and returns 400/404. Bad token --> bad request.

0 commit comments

Comments
 (0)