diff --git a/docker-compose.yml b/docker-compose.yml index ec1080aa..95e7d430 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,6 +35,8 @@ services: build: context: . dockerfile: Dockerfile.tests + volumes: + - .:/app environment: - ENVIRONMENT=local - DB_MIN_CONN_SIZE=1 diff --git a/stac_fastapi/pgstac/core.py b/stac_fastapi/pgstac/core.py index e7dcab21..1a962165 100644 --- a/stac_fastapi/pgstac/core.py +++ b/stac_fastapi/pgstac/core.py @@ -25,6 +25,7 @@ from stac_fastapi.pgstac.config import Settings from stac_fastapi.pgstac.models.links import ( CollectionLinks, + CollectionSearchPagingLinks, ItemCollectionLinks, ItemLinks, PagingLinks, @@ -90,12 +91,16 @@ async def all_collections( # noqa: C901 ) collections_result: Collections = await conn.fetchval(q, *p) - next: Optional[str] = None - prev: Optional[str] = None - + next: Optional[Dict[str, Any]] = None + prev: Optional[Dict[str, Any]] = None if links := collections_result.get("links"): - next = collections_result["links"].pop("next") - prev = collections_result["links"].pop("prev") + next = None + prev = None + for link in links: + if link["rel"] == "next": + next = link + elif link["rel"] == "prev": + prev = link linked_collections: List[Collection] = [] collections = collections_result["collections"] @@ -120,7 +125,7 @@ async def all_collections( # noqa: C901 linked_collections.append(coll) - links = await PagingLinks( + links = await CollectionSearchPagingLinks( request=request, next=next, prev=prev, diff --git a/stac_fastapi/pgstac/models/links.py b/stac_fastapi/pgstac/models/links.py index 0e6d9071..10e0f3b9 100644 --- a/stac_fastapi/pgstac/models/links.py +++ b/stac_fastapi/pgstac/models/links.py @@ -173,6 +173,60 @@ def link_prev(self) -> Optional[Dict[str, Any]]: return None +@attr.s +class CollectionSearchPagingLinks(BaseLinks): + next: Optional[Dict[str, Any]] = attr.ib(kw_only=True, default=None) + prev: Optional[Dict[str, Any]] = attr.ib(kw_only=True, default=None) + + def link_next(self) -> Optional[Dict[str, Any]]: + """Create link for next page.""" + if self.next is not None: + method = self.request.method + if method == "GET": + # if offset is equal to default value (0), drop it + if self.next["body"].get("offset", -1) == 0: + _ = self.next["body"].pop("offset") + + href = merge_params(self.url, self.next["body"]) + + # if next link is equal to this link, skip it + if href == self.url: + print(self.request.body()) + return None + + link = { + "rel": Relations.next.value, + "type": MimeTypes.geojson.value, + "method": method, + "href": href, + } + return link + + return None + + def link_prev(self): + if self.prev is not None: + method = self.request.method + if method == "GET": + # if offset is equal to default value (0), drop it + if self.prev["body"].get("offset", -1) == 0: + _ = self.prev["body"].pop("offset") + + href = merge_params(self.url, self.prev["body"]) + + # if prev link is equal to this link, skip it + if href == self.url: + return None + return { + "rel": Relations.previous.value, + "type": MimeTypes.geojson.value, + "method": method, + "href": href, + } + + return None + + @attr.s class CollectionLinksBase(BaseLinks): """Create inferred links specific to collections.""" diff --git a/tests/resources/test_collection.py b/tests/resources/test_collection.py index 4921c2ab..f67f6983 100644 --- a/tests/resources/test_collection.py +++ b/tests/resources/test_collection.py @@ -313,5 +313,15 @@ async def test_get_collections_search_limit_offset( "/collections", params={"limit": 1}, ) - assert len(resp.json()["collections"]) == 1 - assert resp.json()["collections"][0]["id"] == load_test_collection.id + response = resp.json() + assert len(response["collections"]) == 1 + assert response["collections"][0]["id"] == load_test_collection["id"] + + # check next link + next_link = [link["href"] for link in response["links"] if link["rel"] == "next"][0] + next_url = next_link.replace(str(app_client.base_url), "") + next_resp = await app_client.get(next_url) + next_response = next_resp.json() + + assert len(next_response["collections"]) == 1 + assert next_response["collections"][0]["id"] == load_test2_collection.id