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

Commit d3c5aa8

Browse files
feat: adding pagination to GET /products endpoint in root_router.py tests: adding tests for GET /products pagination
1 parent 2fca5c7 commit d3c5aa8

File tree

4 files changed

+107
-10
lines changed

4 files changed

+107
-10
lines changed

src/stapi_fastapi/routers/root_router.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,47 @@ def get_root(self, request: Request) -> RootResponse:
140140
def get_conformance(self, request: Request) -> Conformance:
141141
return Conformance(conforms_to=self.conformances)
142142

143-
def get_products(self, request: Request) -> ProductsCollection:
144-
return ProductsCollection(
145-
products=[pr.get_product(request) for pr in self.product_routers.values()],
146-
links=[
143+
def get_products(
144+
self, request: Request, next: str | None = None, limit: int = 10
145+
) -> ProductsCollection:
146+
try:
147+
start = 0
148+
product_ids = [*self.product_routers.keys()]
149+
if next:
150+
start = product_ids.index(next)
151+
if not product_ids and not next:
152+
ProductsCollection(
153+
products=[],
154+
links=[
155+
Link(
156+
href=str(request.url_for(f"{self.name}:list-products")),
157+
rel="self",
158+
type=TYPE_JSON,
159+
)
160+
],
161+
)
162+
end = start + limit
163+
ids = product_ids[start:end]
164+
products = [
165+
self.product_routers[product_id].get_product(request)
166+
for product_id in ids
167+
]
168+
links = [
147169
Link(
148170
href=str(request.url_for(f"{self.name}:list-products")),
149171
rel="self",
150172
type=TYPE_JSON,
151-
)
152-
],
153-
)
173+
),
174+
]
175+
next = ""
176+
if end < len(product_ids):
177+
next = self.product_routers[product_ids[end]].product.id
178+
updated_url = request.url.include_query_params(next=next)
179+
links.append(Link(href=str(updated_url), rel="next", type=TYPE_JSON))
180+
return ProductsCollection(products=products, links=links)
181+
except ValueError as e:
182+
logging.exception(f"An error occurred while retrieving orders: {e}")
183+
raise NotFoundException(detail="Error finding pagination token")
154184

155185
async def get_orders(
156186
self, request: Request, next: str | None = None, limit: int = 10

tests/conftest.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,46 @@ def mock_product_test_spotlight(
7171
)
7272

7373

74+
@pytest.fixture
75+
def mock_product_test_wolf_cola(
76+
product_backend: MockProductBackend, mock_provider: Provider
77+
) -> Product:
78+
"""Fixture for a mock Wolf Cola product."""
79+
return Product(
80+
id="test-wolf-cola",
81+
title="Test Wolf Cola Product",
82+
description="Test product for Wolf Cola for testing GET /product pagination",
83+
license="CC-BY-4.0",
84+
keywords=["test", "satellite", "wolf-cola"],
85+
providers=[mock_provider],
86+
links=[],
87+
constraints=MyProductConstraints,
88+
opportunity_properties=MyOpportunityProperties,
89+
order_parameters=MyOrderParameters,
90+
backend=product_backend,
91+
)
92+
93+
7494
@pytest.fixture
7595
def stapi_client(
76-
root_backend, mock_product_test_spotlight, base_url: str
96+
root_backend,
97+
mock_product_test_spotlight,
98+
mock_product_test_wolf_cola,
99+
base_url: str,
77100
) -> Iterator[TestClient]:
78101
root_router = RootRouter(root_backend)
79102
root_router.add_product(mock_product_test_spotlight)
103+
root_router.add_product(mock_product_test_wolf_cola)
104+
app = FastAPI()
105+
app.include_router(root_router, prefix="")
106+
107+
with TestClient(app, base_url=f"{base_url}") as client:
108+
yield client
109+
110+
111+
@pytest.fixture
112+
def empty_stapi_client(root_backend, base_url: str) -> Iterator[TestClient]:
113+
root_router = RootRouter(root_backend)
80114
app = FastAPI()
81115
app.include_router(root_router, prefix="")
82116

tests/test_order.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ def test_order_pagination(stapi_client: TestClient, setup_pagination, limit) ->
166166
res = stapi_client.get("/orders", params={"next": None, "limit": limit})
167167
assert res.status_code == status.HTTP_200_OK
168168
body = res.json()
169+
assert len(body["features"]) == limit
169170
next = body["links"][0]["href"]
170171

171172
while next:
@@ -179,7 +180,6 @@ def test_order_pagination(stapi_client: TestClient, setup_pagination, limit) ->
179180
break
180181

181182

182-
def test_token_not_found(stapi_client: TestClient):
183+
def test_token_not_found(stapi_client: TestClient) -> None:
183184
res = stapi_client.get("/orders", params={"next": "a_token"})
184-
# should return 404 as a result of bad token
185185
assert res.status_code == status.HTTP_404_NOT_FOUND

tests/test_product.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,36 @@ def test_product_order_parameters_response(
6363
json_schema = res.json()
6464
assert "properties" in json_schema
6565
assert "s3_path" in json_schema["properties"]
66+
67+
68+
@pytest.mark.parametrize("limit", [1])
69+
def test_product_pagination(stapi_client: TestClient, limit: int):
70+
res = stapi_client.get("/products", params={"next": None, "limit": limit})
71+
assert res.status_code == status.HTTP_200_OK
72+
body = res.json()
73+
assert len(body["products"]) == limit
74+
for d in body["links"]:
75+
if ("rel", "next") in d.items():
76+
next = d["href"]
77+
78+
while len(body["links"]) > 1:
79+
res = stapi_client.get(next)
80+
assert res.status_code == status.HTTP_200_OK
81+
body = res.json()
82+
assert len(body["products"]) == limit
83+
for d in body["links"]:
84+
if ("rel", "next") in d.items():
85+
next = body["links"][0]["href"]
86+
87+
88+
def test_token_not_found(stapi_client: TestClient) -> None:
89+
res = stapi_client.get("/products", params={"next": "a_token"})
90+
assert res.status_code == status.HTTP_404_NOT_FOUND
91+
92+
93+
def test_no_products(empty_stapi_client: TestClient):
94+
res = empty_stapi_client.get("/products")
95+
body = res.json()
96+
print("hold")
97+
assert res.status_code == status.HTTP_200_OK
98+
assert len(body["products"]) == 0

0 commit comments

Comments
 (0)