@@ -274,5 +274,119 @@ def test_search_post(
274274 output_query == expected_output_query
275275 ), "Query should be combined with the filter expression."
276276
277- # Reset test
278- mock_upstream .reset_mock ()
277+
278+ @pytest .mark .parametrize (
279+ "filter_template_expr, auth_filter, anon_filter" ,
280+ [
281+ # Simple filter, not templated
282+ [
283+ "(properties.private = false)" ,
284+ "(properties.private = false)" ,
285+ "(properties.private = false)" ,
286+ ],
287+ # Simple filter, templated
288+ [
289+ "{{ '(properties.private = false)' if token is none else true }}" ,
290+ "true" ,
291+ "(properties.private = false)" ,
292+ ],
293+ # Complex filter, not templated
294+ [
295+ """{
296+ "op": "=",
297+ "args": [{"property": "private"}, true]
298+ }""" ,
299+ """{
300+ "op": "=",
301+ "args": [{"property": "private"}, true]
302+ }""" ,
303+ """{
304+ "op": "=",
305+ "args": [{"property": "private"}, true]
306+ }""" ,
307+ ],
308+ # Complex filter, templated
309+ [
310+ """{{ '{"op": "=", "args": [{"property": "private"}, true]}' if token is none else true }}""" ,
311+ "true" ,
312+ """{"op": "=", "args": [{"property": "private"}, true]}""" ,
313+ ],
314+ ],
315+ )
316+ @pytest .mark .parametrize ("is_authenticated" , [True , False ])
317+ @pytest .mark .parametrize (
318+ "input_query" ,
319+ [
320+ # Not using filter
321+ {
322+ "collections" : "example-collection" ,
323+ "bbox" : "160.6,-55.95,-170,-25.89" ,
324+ "datetime" : "2021-06-01T00:00:00Z/2021-06-30T23:59:59Z" ,
325+ },
326+ # Using filter
327+ # {
328+ # "filter-lang": "cql2-json",
329+ # "filter": {
330+ # "op": "and",
331+ # "args": [
332+ # {"op": "=", "args": [{"property": "collection"}, "landsat-8-l1"]},
333+ # {"op": "<=", "args": [{"property": "eo:cloud_cover"}, 20]},
334+ # {"op": "=", "args": [{"property": "platform"}, "landsat-8"]},
335+ # ],
336+ # },
337+ # "limit": 5,
338+ # },
339+ ],
340+ )
341+ def test_search_get (
342+ mock_upstream ,
343+ source_api_server ,
344+ filter_template_expr ,
345+ auth_filter ,
346+ anon_filter ,
347+ is_authenticated ,
348+ input_query ,
349+ token_builder ,
350+ ):
351+ """Test filter is applied to search with fimple filtering."""
352+ # Setup app
353+ app = app_factory (
354+ upstream_url = source_api_server ,
355+ items_filter = {
356+ "cls" : "stac_auth_proxy.filters.Template" ,
357+ "args" : [filter_template_expr .strip ()],
358+ },
359+ default_public = True ,
360+ )
361+
362+ # Query API
363+ headers = (
364+ {"Authorization" : f"Bearer { token_builder ({})} " } if is_authenticated else {}
365+ )
366+ response = TestClient (app , headers = headers ).get ("/search" , params = input_query )
367+ response .raise_for_status ()
368+
369+ # Retrieve query from upstream
370+ assert mock_upstream .call_count == 1
371+ [r ] = cast (list [Request ], mock_upstream .call_args [0 ])
372+ assert r .read ().decode () == ""
373+ upstream_querystring = dict (r .url .params )
374+
375+ # Parse query from upstream
376+ input_filter = input_query .get ("filter" )
377+ expected_filter = auth_filter if is_authenticated else anon_filter
378+ expected_filter_exprs = [
379+ cql2 .Expr (expr ).to_text ()
380+ for expr in [input_filter , expected_filter .strip ()]
381+ if expr
382+ ]
383+
384+ # TODO: Use QS, not dict
385+ expected_output_query = {
386+ ** input_query ,
387+ "filter" : cql2 .Expr (" AND " .join (expected_filter_exprs )).to_text (),
388+ }
389+
390+ assert (
391+ upstream_querystring == expected_output_query
392+ ), "Query should be combined with the filter expression."
0 commit comments