From a8eec23ca48d94f801420e0857f1508f53970499 Mon Sep 17 00:00:00 2001 From: Vincent Sarago Date: Fri, 31 May 2024 17:00:03 +0200 Subject: [PATCH] set default value for Query attribute for `QueryExtensionPostRequest` model (#701) --- CHANGES.md | 6 ++ .../extensions/core/query/request.py | 2 +- stac_fastapi/extensions/tests/test_query.py | 95 +++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 stac_fastapi/extensions/tests/test_query.py diff --git a/CHANGES.md b/CHANGES.md index 46d284fe0..0229dcfcb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,12 @@ ## [Unreleased] - TBD +## [3.0.0a2] - 2024-05-31 + +### Fixed + +* Fix missing default (`None`) for optional `query` attribute in `QueryExtensionPostRequest` model ([#701](https://github.com/stac-utils/stac-fastapi/pull/701)) + ## [3.0.0a1] - 2024-05-22 ### Changed diff --git a/stac_fastapi/extensions/stac_fastapi/extensions/core/query/request.py b/stac_fastapi/extensions/stac_fastapi/extensions/core/query/request.py index 8b282884a..7f8425e70 100644 --- a/stac_fastapi/extensions/stac_fastapi/extensions/core/query/request.py +++ b/stac_fastapi/extensions/stac_fastapi/extensions/core/query/request.py @@ -18,4 +18,4 @@ class QueryExtensionGetRequest(APIRequest): class QueryExtensionPostRequest(BaseModel): """Query Extension POST request model.""" - query: Optional[Dict[str, Dict[str, Any]]] + query: Optional[Dict[str, Dict[str, Any]]] = None diff --git a/stac_fastapi/extensions/tests/test_query.py b/stac_fastapi/extensions/tests/test_query.py new file mode 100644 index 000000000..7674547a1 --- /dev/null +++ b/stac_fastapi/extensions/tests/test_query.py @@ -0,0 +1,95 @@ +import json +from typing import Iterator +from urllib.parse import quote_plus, unquote_plus + +import pytest +from starlette.testclient import TestClient + +from stac_fastapi.api.app import StacApi +from stac_fastapi.api.models import create_get_request_model, create_post_request_model +from stac_fastapi.extensions.core import QueryExtension +from stac_fastapi.types.config import ApiSettings +from stac_fastapi.types.core import BaseCoreClient + + +class DummyCoreClient(BaseCoreClient): + def all_collections(self, *args, **kwargs): + raise NotImplementedError + + def get_collection(self, *args, **kwargs): + raise NotImplementedError + + def get_item(self, *args, **kwargs): + raise NotImplementedError + + def get_search(self, *args, **kwargs): + return kwargs.pop("query", None) + + def post_search(self, *args, **kwargs): + return args[0].query + + def item_collection(self, *args, **kwargs): + raise NotImplementedError + + +@pytest.fixture +def client() -> Iterator[TestClient]: + settings = ApiSettings() + extensions = [QueryExtension()] + + api = StacApi( + settings=settings, + client=DummyCoreClient(), + extensions=extensions, + search_get_request_model=create_get_request_model(extensions), + search_post_request_model=create_post_request_model(extensions), + ) + with TestClient(api.app) as client: + yield client + + +def test_search_query_get(client: TestClient): + """Test search GET endpoints with query ext.""" + response = client.get( + "/search", + params={"collections": ["test"]}, + ) + assert response.is_success + assert not response.text + + response = client.get( + "/search", + params={ + "collections": ["test"], + "query": quote_plus( + json.dumps({"eo:cloud_cover": {"gte": 95}}), + ), + }, + ) + assert response.is_success, response.json() + query = json.loads(unquote_plus(response.json())) + assert query["eo:cloud_cover"] == {"gte": 95} + + +def test_search_query_post(client: TestClient): + """Test search POST endpoints with query ext.""" + response = client.post( + "/search", + json={ + "collections": ["test"], + }, + ) + + assert response.is_success + assert not response.text + + response = client.post( + "/search", + json={ + "collections": ["test"], + "query": {"eo:cloud_cover": {"gte": 95}}, + }, + ) + + assert response.is_success, response.json() + assert response.json()["eo:cloud_cover"] == {"gte": 95}