Repository: CS-SI/eodag
Pull request #636 (2023-02-09 09:03:59)

fix: cloud cover disabled for radar product types and onda queryable params
Related to #389 
- Fixes cloud cover disabled for radar product types
- Fixes `onda` queryable paramaters configuration

github-actions[bot]: ## Unit Test Results
  1 files   -     1    1 suites   - 1   43s [:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "duration of all tests") - 4m 13s
61 tests  - 295  60 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests")  - 293  0 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests")  - 3  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") ±0  1 [:fire:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "test errors") +1 
61 runs   - 651  60 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "passed tests")  - 646  0 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "skipped / disabled tests")  - 6  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "failed tests") ±0  1 [:fire:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v1.20/README.md#the-symbols "test errors") +1 

For more details on these errors, see [this check](https://github.com/CS-SI/eodag/runs/11219472612).

Results for commit d826949a. ± Comparison against base commit 9aaf0cde.

<details>
  <summary>This pull request <b>removes</b> 296 and <b>adds</b> 1 tests. <i>Note that renamed tests count towards both.</i></summary>

```
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_by_cloudcover
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_by_date
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_by_geom
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_by_property
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_crunch_filter_date
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_crunch_filter_lastest_by_name
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_crunch_filter_overlap
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_crunch_filter_property
tests.integration.test_search_stac_static.TestSearchStacStatic ‑ test_search_stac_static_load_child
…
```

```
pytest ‑ internal
```
</details>

[test-results]:data:application/gzip;base64,H4sIAOq35GMC/1WNSQ7CMBAEvxL5zMFbzITPIMuLNCKJkZcT4u/YAeLkNlUt1byIx9klchvYZSCpYN7BlqgzhrWiFJXrktum2B/uqRjTDO3mgc9quvAa55NwMYb4exHLuhfbfQp+Re9tfMhtfKyZsCyYKxALXE1y0uwqlQKvgMOowQlJQYDmYuRUgDOWvD8g6gUcAAEAAA==


Patch:
diff --git a/eodag/plugins/search/qssearch.py b/eodag/plugins/search/qssearch.py
index 2f24683a..2dd54d81 100644
--- a/eodag/plugins/search/qssearch.py
+++ b/eodag/plugins/search/qssearch.py
@@ -496,7 +496,9 @@ class QueryStringSearch(Search):
                     format_metadata(operand, **kwargs)
                     for operand in operands
                     if any(
-                        re.search(rf"{{{kw}[}}#]", operand) and val is not None
+                        re.search(rf"{{{kw}[}}#]", operand)
+                        and val is not None
+                        and isinstance(self.config.metadata_mapping.get(kw, []), list)
                         for kw, val in kwargs.items()
                     )
                 )
@@ -1104,10 +1106,14 @@ class PostJsonSearch(QueryStringSearch):
                     items_per_page=items_per_page, page=page, **kwargs
                 )
 
-        # If we were not able to build query params but have search criteria, this means
-        # the provider does not support the search criteria given. If so, stop searching
-        # right away
-        if not qp and keywords:
+        # If we were not able to build query params but have queryable search criteria,
+        # this means the provider does not support the search criteria given. If so,
+        # stop searching right away
+        if not qp and any(
+            k
+            for k in keywords.keys()
+            if isinstance(self.config.metadata_mapping.get(k, []), list)
+        ):
             return [], 0
         self.query_params = qp
         self.search_urls, total_items = self.collect_search_urls(
diff --git a/eodag/resources/providers.yml b/eodag/resources/providers.yml
index f03df0f8..38708f5b 100644
--- a/eodag/resources/providers.yml
+++ b/eodag/resources/providers.yml
@@ -1424,14 +1424,22 @@
         - '$.Metadata.sensorOperationalMode'
 
       # OpenSearch Parameters for Acquistion Parameters Search (Table 6)
-      startTimeFromAscendingNode: '$.beginPosition'
-      completionTimeFromAscendingNode: '$.endPosition'
+      startTimeFromAscendingNode:
+        - null
+        - '$.beginPosition'
+      completionTimeFromAscendingNode:
+        - null
+        - '$.endPosition'
       polarizationChannels: '{$.Metadata.polarisationChannels#replace_str(","," ")}'
 
       # Custom parameters (not defined in the base document referenced above)
-      id: '{$.Metadata.filename#remove_extension}'
+      id:
+        - null
+        - '{$.Metadata.filename#remove_extension}'
       # The geographic extent of the product
-      geometry: '$.footprint'
+      geometry:
+        - null
+        - '$.footprint'
       # The url of the quicklook
       quicklook: '$.quicklook'
       # The url to download the product "as is" (literal or as a template to be completed either after the search result


Test patch:
diff --git a/tests/units/test_search_plugins.py b/tests/units/test_search_plugins.py
index 3c7e908b..47100118 100644
--- a/tests/units/test_search_plugins.py
+++ b/tests/units/test_search_plugins.py
@@ -245,6 +245,23 @@ class TestSearchPluginQueryStringSearch(BaseSearchPluginTest):
         # products count should not have been extracted from search results
         self.assertIsNone(getattr(self.peps_search_plugin, "total_items_nb", None))
 
+    @mock.patch(
+        "eodag.plugins.search.qssearch.QueryStringSearch._request", autospec=True
+    )
+    def test_plugins_search_querystringseach_search_cloudcover_peps(
+        self, mock__request
+    ):
+        """A query with a QueryStringSearch (here peps) must only use cloudCover filtering for non-radar product types"""  # noqa
+
+        self.peps_search_plugin.query(productType="S2_MSI_L1C", cloudCover=50)
+        mock__request.assert_called()
+        self.assertIn("cloudCover", mock__request.call_args_list[-1][0][1])
+        mock__request.reset_mock()
+
+        self.peps_search_plugin.query(productType="S1_SAR_GRD", cloudCover=50)
+        mock__request.assert_called()
+        self.assertNotIn("cloudCover", mock__request.call_args_list[-1][0][1])
+
     @mock.patch(
         "eodag.plugins.search.qssearch.QueryStringSearch._request", autospec=True
     )
@@ -461,6 +478,27 @@ class TestSearchPluginPostJsonSearch(BaseSearchPluginTest):
         # products count should not have been extracted from search results
         self.assertIsNone(getattr(self.awseos_search_plugin, "total_items_nb", None))
 
+    @mock.patch("eodag.plugins.search.qssearch.requests.post", autospec=True)
+    def test_plugins_search_postjsonsearch_search_cloudcover_awseos(
+        self, mock_requests_post
+    ):
+        """A query with a PostJsonSearch (here aws_eos) must only use cloudCover filtering for non-radar product types"""  # noqa
+
+        self.awseos_search_plugin.query(
+            auth=self.awseos_auth_plugin, productType="S2_MSI_L1C", cloudCover=50
+        )
+        mock_requests_post.assert_called()
+        self.assertIn("cloudCoverage", str(mock_requests_post.call_args_list[-1][1]))
+        mock_requests_post.reset_mock()
+
+        self.awseos_search_plugin.query(
+            auth=self.awseos_auth_plugin, productType="S1_SAR_GRD", cloudCover=50
+        )
+        mock_requests_post.assert_called()
+        self.assertNotIn(
+            "cloudCoverPercentage", str(mock_requests_post.call_args_list[-1][1])
+        )
+
 
 class TestSearchPluginODataV4Search(BaseSearchPluginTest):
     def setUp(self):
@@ -562,6 +600,21 @@ class TestSearchPluginODataV4Search(BaseSearchPluginTest):
         # products count non extracted from search results as count endpoint is specified
         self.assertFalse(hasattr(self.onda_search_plugin, "total_items_nb"))
 
+    @mock.patch(
+        "eodag.plugins.search.qssearch.QueryStringSearch._request", autospec=True
+    )
+    def test_plugins_search_odatav4search_search_cloudcover_onda(self, mock__request):
+        """A query with a ODataV4Search (here onda) must only use cloudCover filtering for non-radar product types"""
+
+        self.onda_search_plugin.query(productType="S2_MSI_L1C", cloudCover=50)
+        mock__request.assert_called()
+        self.assertIn("cloudCoverPercentage", mock__request.call_args_list[-1][0][1])
+        mock__request.reset_mock()
+
+        self.onda_search_plugin.query(productType="S1_SAR_GRD", cloudCover=50)
+        mock__request.assert_called()
+        self.assertNotIn("cloudCoverPercentage", mock__request.call_args_list[-1][0][1])
+
 
 class TestSearchPluginStacSearch(BaseSearchPluginTest):
     @mock.patch("eodag.plugins.search.qssearch.StacSearch._request", autospec=True)