Repository: CS-SI/eodag
Pull request #774 (2023-07-27 13:51:01)

fix: missing provider in stac downloadLink
Fixes #748 

In server mode, add provider as downloadlink query-arg in assets if specified in search

github-actions[bot]: ## Test Results
       4 files  ±0         4 suites  ±0   4m 46s [:stopwatch:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v2.8.0/README.md#the-symbols "duration of all tests") +35s
   394 tests +1     392 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v2.8.0/README.md#the-symbols "passed tests") +1    2 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v2.8.0/README.md#the-symbols "skipped / disabled tests") ±0  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v2.8.0/README.md#the-symbols "failed tests") ±0 
1 576 runs  +4  1 518 [:heavy_check_mark:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v2.8.0/README.md#the-symbols "passed tests") +2  58 [:zzz:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v2.8.0/README.md#the-symbols "skipped / disabled tests") +2  0 [:x:](https://github.com/EnricoMi/publish-unit-test-result-action/blob/v2.8.0/README.md#the-symbols "failed tests") ±0 

Results for commit 4767ca91. ± Comparison against base commit ff32294c.

[test-results]:data:application/gzip;base64,H4sIAGB3wmQC/03Myw7CIBCF4VdpWLsoMFzqyxg6QELsxVBYGd9dqC12+X+TOW/iw+Q2cu/g1pEth9TC5mhSWJeSTMsC5ZTqkQ9w1mPLiDuxPz3Dq/408CZMBfoGLsY1HhLzUjepUPKoc5MKqhv9NkWDy+be10lc5zmkEgSUVGgG6i36kRlGR+e4QAnQC0CL3AJXWgvy+QJMzKm3CAEAAA==

github-actions[bot]: <strong>Code Coverage (Ubuntu)</strong>

| File | Coverage |   |
| - | :-: | :-: |
| **All files** | `83%` | :white_check_mark: |

_Minimum allowed coverage is `70%`_

<p align="right">Generated by :monkey: cobertura-action against 4767ca91fdcfb2a21bee35c644054cdc3d437885 </p>
github-actions[bot]: <strong>Code Coverage (Windows)</strong>

| File | Coverage |   |
| - | :-: | :-: |
| **All files** | `77%` | :white_check_mark: |

_Minimum allowed coverage is `70%`_

<p align="right">Generated by :monkey: cobertura-action against 4767ca91fdcfb2a21bee35c644054cdc3d437885 </p>

Patch:
diff --git a/eodag/rest/stac.py b/eodag/rest/stac.py
index 4817c602..6e8fcbe5 100644
--- a/eodag/rest/stac.py
+++ b/eodag/rest/stac.py
@@ -20,6 +20,7 @@ import logging
 import os
 import re
 from collections import defaultdict
+from urllib.parse import parse_qs, urlencode, urlparse
 
 import dateutil.parser
 import geojson
@@ -218,9 +219,24 @@ class StacItem(StacCommon):
             product_item = jsonpath_parse_dict_items(
                 item_model, {"product": product.__dict__}
             )
+            # add origin assets to product assets
             origin_assets = product_item["assets"].pop("origin_assets")
             if getattr(product, "assets", False):
                 product_item["assets"] = dict(product_item["assets"], **origin_assets)
+            # append provider query-arg to download link if specified
+            if self.provider:
+                parts = urlparse(product_item["assets"]["downloadLink"]["href"])
+                query_dict = parse_qs(parts.query)
+                query_dict.update(provider=self.provider)
+                without_arg_url = (
+                    f"{parts.scheme}://{parts.netloc}{parts.path}"
+                    if parts.scheme
+                    else f"{parts.netloc}{parts.path}"
+                )
+                product_item["assets"]["downloadLink"][
+                    "href"
+                ] = f"{without_arg_url}?{urlencode(query_dict, doseq=True)}"
+
             # apply conversion if needed
             for prop_key, prop_val in need_conversion.items():
                 conv_func, conv_args = prop_val


Test patch:
diff --git a/tests/units/test_http_server.py b/tests/units/test_http_server.py
index f302ef06..67ca1d48 100644
--- a/tests/units/test_http_server.py
+++ b/tests/units/test_http_server.py
@@ -541,6 +541,52 @@ class RequestTestCase(unittest.TestCase):
         self.assertIn("matched", response["context"])
         self.assertIn("returned", response["context"])
 
+    def test_search_provider_in_downloadlink(self):
+        """Search through eodag server and check that specified provider appears in downloadLink"""
+        # with provider (get)
+        response = self._request_valid(
+            f"search?collections={self.tested_product_type}&provider=onda"
+        )
+        response_items = [f for f in response["features"]]
+        self.assertTrue(
+            all(
+                [
+                    i["assets"]["downloadLink"]["href"].endswith(
+                        "download?provider=onda"
+                    )
+                    for i in response_items
+                ]
+            )
+        )
+        # with provider (post)
+        response = self._request_valid(
+            "search",
+            protocol="POST",
+            post_data={"collections": [self.tested_product_type], "provider": "onda"},
+        )
+        response_items = [f for f in response["features"]]
+        self.assertTrue(
+            all(
+                [
+                    i["assets"]["downloadLink"]["href"].endswith(
+                        "download?provider=onda"
+                    )
+                    for i in response_items
+                ]
+            )
+        )
+        # without provider
+        response = self._request_valid(f"search?collections={self.tested_product_type}")
+        response_items = [f for f in response["features"]]
+        self.assertTrue(
+            all(
+                [
+                    i["assets"]["downloadLink"]["href"].endswith("download")
+                    for i in response_items
+                ]
+            )
+        )
+
     @mock.patch(
         "eodag.rest.utils.eodag_api.guess_product_type", autospec=True, return_value=[]
     )