Repository: CS-SI/eodag
Pull request #1313 (2024-09-05 09:25:15)

fix(providers): usage of `hydrological_year` in provider `wekeo_ecmwf`
- Add mapping for parameter `hydrological_year` to provider `wekeo_ecmwf` and fix a typo in the `orderLink`
- Pass down the `_dc_qs` for the `PostJsonSearch` when downloading the product
- Manage leap years when calculating `hydrological_year`

Follow examples of queries and the generated `_dc_qs`. These tests can also be found in `tests.units.test_search_plugins.TestSearchPluginPostJsonSearch.test_plugins_search_postjsonsearch_query_params_wekeo`.

## Using the `datetime`

```bash
curl --location 'http://localhost:5000/search?provider=wekeo_ecmwf' --header 'Content-Type: application/json' --data '{
    "collections": [
        "GRIDDED_GLACIERS_MASS_CHANGE"
    ],
    "limit": 10,
    "page": 1,
    "datetime": "1980-01-01T00:00:00Z/1981-12-31T23:59:59Z",
    "query": {
        "variable": {
            "eq": "glacier_mass_change"
        },
        "format": {
            "eq": "zip"
        },
        "version": {
            "eq": "wgms_fog_2022_09"
        }
    }
}'
```

Generated `_dc_qs`:

```json
{
    "dataset_id": "EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE",
    "variable": "glacier_mass_change",
    "format": "zip",
    "product_version": "wgms_fog_2022_09",
    "hydrological_year": [
        "1980_81"
    ]
}
```

## Using parameter `hydrological_year` (single value)

```bash
curl --location 'http://localhost:5000/search?provider=wekeo_ecmwf' \
--header 'Content-Type: application/json' \
--data '{
    "collections": [
        "GRIDDED_GLACIERS_MASS_CHANGE"
    ],
    "limit": 10,
    "page": 1,
    "query": {
        "variable": {
            "eq": "glacier_mass_change"
        },
        "format": {
            "eq": "zip"
        },
        "version": {
            "eq": "wgms_fog_2022_09"
        },
        "hydrological_year": {
            "eq": [
                "2020_21"
            ]
        }
    }
}'
```

Generated `_dc_qs`:

```json
{
    "dataset_id": "EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE",
    "variable": "glacier_mass_change",
    "format": "zip",
    "product_version": "wgms_fog_2022_09",
    "hydrological_year": [
        "2020_21"
    ]
}
```
## Using parameter `hydrological_year` (multiple values)

```bash
curl --location 'http://localhost:5000/search?provider=wekeo_ecmwf' \
--header 'Content-Type: application/json' \
--data '{
    "collections": [
        "GRIDDED_GLACIERS_MASS_CHANGE"
    ],
    "limit": 10,
    "page": 1,
    "query": {
        "variable": {
            "eq": "glacier_mass_change"
        },
        "format": {
            "eq": "zip"
        },
        "version": {
            "eq": "wgms_fog_2022_09"
        },
        "hydrological_year": {
            "eq": [
                "1990_91", "2020_21"
            ]
        }
    }
}'
```

Generated `_dc_qs`:

```json
{
    "dataset_id": "EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE",
    "variable": "glacier_mass_change",
    "format": "zip",
    "product_version": "wgms_fog_2022_09",
    "hydrological_year": [
        "1990_91",
        "2020_21"
    ]
}
```





github-actions[bot]: ## Test Results
0 tests  ±0   0 :white_check_mark: ±0   0s :stopwatch: ±0s
0 suites ±0   0 :zzz: ±0 
0 files   ±0   0 :x: ±0 

Results for commit 5b319521. ± Comparison against base commit 6c46430c.

[test-results]:data:application/gzip;base64,H4sIAB962WYC/1WMyw6CMBBFf4V07YJaKsWfMX1NMhGombYr479LkOB0d8+5yXkLwDlmce/6SydyxXJCqGQLpvXA7SiZ70eu3rfiia9GgMW5EZEo0WGorplNnvvxv7Yzi+3MWz4tC5YNhHZKTvoqrTVjHG7BuwFU9EqFqBUY40YjwcIkPl9eey0A+wAAAA==

dalpasso: > It is normal that the format of the parameter is different than the other configured for provider wekeo ?
> 
> For instance with `statistic`:
> 
> ```yaml
>     statistic:
>         - '{{"statistic": {statistic}}}'
>         - '$.null'
> ```

I used he same format of `hydrological_model` but it's indeed better to use the same format as other `wekeo` parameter. I have changed the format and tested that the resulting behavior is the same.
github-actions[bot]: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports/data/add_mapping_hydrological_year_to_wekeo/./badge.svg)


## Code Coverage (Ubuntu)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         312      59  81.09%   655-714, 816-867, 871
config.py                                      367      27  92.64%   82-84, 93, 101, 105-107, 175, 186, 452-454, 514-517, 560-561, 570-571, 676, 739-744, 746
crunch.py                                        5       5  0.00%    20-24
api/__init__.py                                  0       0  100.00%
api/core.py                                    773      74  90.43%   636, 680-683, 721, 765, 799, 852-857, 883, 974, 1042, 1180, 1263-1275, 1311, 1313, 1341, 1345-1356, 1369-1375, 1458-1461, 1494-1514, 1566, 1583-1587, 1599-1602, 1624-1631, 1945, 1976-1982, 2233, 2237-2240, 2251-2253, 2285
api/search_result.py                            51       4  92.16%   73, 82, 89, 103
api/product/__init__.py                          6       0  100.00%
api/product/_assets.py                          48       5  89.58%   75, 147, 155, 158-162
api/product/_product.py                        187      20  89.30%   70-72, 237-238, 313, 342, 399, 413-416, 429, 453-456, 499-505
api/product/metadata_mapping.py                676      81  88.02%   130-132, 227, 259-260, 306-307, 317-329, 331, 342, 348-360, 405-406, 443, 464-467, 490, 498-499, 575-576, 600-601, 607-610, 625-626, 775, 821, 992-997, 1124, 1138-1158, 1178, 1183, 1290, 1312, 1326, 1339-1358, 1397, 1449, 1481-1485, 1500
api/product/drivers/__init__.py                  6       0  100.00%
api/product/drivers/base.py                      6       1  83.33%   38
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 21       2  90.48%   48, 55
plugins/manager.py                             130      12  90.77%   104-109, 159, 197, 219, 223, 247, 281-282
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           91       8  91.21%   149-151, 198-199, 225-227
plugins/apis/usgs.py                           180      31  82.78%   132, 234, 268, 303-305, 310, 336-337, 342, 372-379, 390-395, 417-423, 425-431, 454
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py              19       0  100.00%
plugins/authentication/base.py                  17       2  88.24%   34, 47
plugins/authentication/generic.py               14       2  85.71%   40, 50
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              48       4  91.67%   134, 160-165
plugins/authentication/oauth.py                 13       7  46.15%   32-34, 38-41
plugins/authentication/openid_connect.py       187      17  90.91%   119, 133-158, 166, 320-323, 349
plugins/authentication/qsauth.py                34       1  97.06%   83
plugins/authentication/sas_auth.py              47       1  97.87%   76
plugins/authentication/token.py                 89      16  82.02%   79, 107, 109, 132-145, 201-205
plugins/authentication/token_exchange.py        36      20  44.44%   74-80, 92-122
plugins/crunch/__init__.py                       0       0  100.00%
plugins/crunch/base.py                          10       1  90.00%   40
plugins/crunch/filter_date.py                   59      14  76.27%   49-54, 66, 75, 84, 87, 99-101, 110-112, 119
plugins/crunch/filter_latest_intersect.py       47       8  82.98%   51-52, 68, 77-80, 82, 89-92
plugins/crunch/filter_latest_tpl_name.py        31       1  96.77%   83
plugins/crunch/filter_overlap.py                66      18  72.73%   28-30, 68-71, 78-81, 87, 95, 106-122
plugins/crunch/filter_property.py               30       7  76.67%   54-59, 62-63, 79-83
plugins/download/__init__.py                     0       0  100.00%
plugins/download/aws.py                        489     163  66.67%   265, 278, 345-348, 362-366, 408-410, 414, 446-447, 453-457, 486, 518, 522, 529, 559-567, 571, 603-611, 618-620, 654-728, 746-807, 818-823, 835-848, 873, 888-890, 893, 903-911, 919-932, 942-973, 980-992, 1030, 1056, 1101-1103, 1323
plugins/download/base.py                       253      51  79.84%   136, 164, 296-297, 314-320, 351-355, 361-362, 404, 407-421, 433, 437, 501-505, 535-536, 544-561, 568-576, 578-582, 625, 647, 669, 677
plugins/download/creodias_s3.py                 17       9  47.06%   44-58
plugins/download/http.py                       534     129  75.84%   195-207, 209-210, 242-245, 306-309, 311-312, 319-324, 342-357, 374-376, 388, 436, 443-449, 467, 481, 495, 503-505, 521-526, 537, 555, 597-601, 623, 663, 708, 722-728, 757-821, 839, 872-881, 903-904, 931-936, 942, 945, 961, 978-979, 1009-1010, 1017, 1078-1084, 1139-1140, 1146, 1156, 1192, 1228, 1246-1262, 1288-1290
plugins/download/s3rest.py                     116      24  79.31%   113, 149, 156, 191, 221-228, 231-233, 237, 248-254, 262-263, 266-270, 293, 314-317
plugins/search/__init__.py                      22       0  100.00%
plugins/search/base.py                         128      13  89.84%   102, 106, 117, 255, 275, 331-332, 352, 355-363
plugins/search/build_search_result.py          181      23  87.29%   95, 136-137, 143, 154, 288-291, 320, 373-390, 450, 453, 463, 480, 508, 510
plugins/search/cop_marine.py                   197      47  76.14%   55, 63-65, 71-72, 88, 90, 93, 128-130, 142-143, 183-192, 196, 199, 203, 221, 249, 253, 268, 272, 276, 280, 284-288, 294-297, 300-314, 331, 354, 357, 363
plugins/search/creodias_s3.py                   55       3  94.55%   53, 71, 105
plugins/search/csw.py                          105      81  22.86%   58-59, 63-64, 72-120, 126-139, 147-179, 197-238
plugins/search/data_request_search.py          200      67  66.50%   90-93, 109, 120, 124-125, 136, 141, 146, 153, 166-169, 223-224, 228, 238-244, 249, 275-278, 286-297, 314, 316, 323-324, 326-327, 345-349, 382, 392, 403, 416, 422-437, 442
plugins/search/qssearch.py                     682      93  86.36%   388, 392-398, 406-407, 513-525, 569, 585, 595, 614-629, 666-669, 740-741, 789, 808, 815, 827, 884, 905, 908-909, 918-919, 928-929, 938-939, 966, 1037-1042, 1046-1055, 1089, 1111, 1171, 1220, 1294-1298, 1358, 1361, 1367-1368, 1389, 1416-1428, 1435, 1467-1469, 1479-1485, 1515, 1538, 1553, 1575, 1658-1661, 1666-1669, 1696-1697, 1712
plugins/search/static_stac_search.py            72      10  86.11%   98-125, 141, 154
rest/__init__.py                                 4       2  50.00%   21-22
rest/cache.py                                   33       7  78.79%   35-37, 53-55, 59, 68
rest/config.py                                  26       0  100.00%
rest/constants.py                                7       0  100.00%
rest/core.py                                   234      26  88.89%   269, 355, 456, 672, 679-727
rest/server.py                                 283      53  81.27%   108, 131-133, 246-248, 304-305, 317-333, 425-430, 458, 623-630, 659, 703-704, 727, 798-800, 817-822, 851, 853, 857-858, 862-863
rest/stac.py                                   473     116  75.48%   318, 340, 392-395, 422-449, 480-482, 505, 537-538, 620-660, 682-698, 772-785, 792, 846-847, 908, 973-975, 1179, 1187-1199, 1210-1232, 1243-1288, 1447-1448
rest/types/__init__.py                           0       0  100.00%
rest/types/collections_search.py                13      13  0.00%    18-44
rest/types/eodag_search.py                     179       5  97.21%   232-236, 289, 292, 360
rest/types/queryables.py                        56       1  98.21%   164
rest/types/stac_search.py                      126       7  94.44%   129, 175, 190-192, 200, 204
rest/utils/__init__.py                          93      12  87.10%   108-109, 128-130, 182, 192-206
rest/utils/cql_evaluate.py                      48       5  89.58%   69, 76, 90, 97, 105
rest/utils/rfc3339.py                           23       3  86.96%   48, 60, 62
types/__init__.py                              114      14  87.72%   53, 70, 129-132, 199, 213-222, 232, 253, 266
types/bbox.py                                   43      19  55.81%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                           9       0  100.00%
types/queryables.py                             81       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/whoosh.py                                 15       0  100.00%
utils/__init__.py                              500      37  92.60%   85, 90, 194-195, 204-231, 234, 248, 328-332, 406-410, 429-431, 510, 525, 561-562, 926-929, 937-938, 976-977, 1148
utils/constraints.py                           119      37  68.91%   89-98, 139, 144, 148, 159, 182-184, 194, 208-224, 233-244
utils/exceptions.py                             35       1  97.14%   93
utils/import_system.py                          28      19  32.14%   64-78, 89-99
utils/logging.py                                28       1  96.43%   41
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/repr.py                                   30       8  73.33%   36, 38, 42, 76, 94-101
utils/requests.py                               55      11  80.00%   64, 88, 90, 92, 94, 96, 112, 120-122, 130
utils/rest.py                                   36       1  97.22%   55
utils/stac_reader.py                           111      45  59.46%   56-57, 63-85, 95-97, 101, 137, 153-156, 203-212, 222-252
TOTAL                                         9610    1646  82.87%
```

</details>


### Diff against develop

```
Filename                           Stmts    Miss  Cover
-------------------------------  -------  ------  --------
api/core.py                           +1       0  +0.02%
api/product/metadata_mapping.py       +1       0  +0.02%
TOTAL                                 +2       0  +100.00%
```


Results for commit: 33dec24617908e5362b09ce31c5b6a83a12005a5


_Minimum allowed coverage is `70%`_


:recycle: This comment has been updated with latest results


<!-- Sticky Pull Request Commentartifacts/unit-test-results-python3.12-ubuntu-latest/coverage.xml -->
github-actions[bot]: ![badge](https://raw.githubusercontent.com/CS-SI/eodag/_xml_coverage_reports_win/data/add_mapping_hydrological_year_to_wekeo/./badge.svg)


## Code Coverage (Windows)

<details>


```
Filename                                     Stmts    Miss  Cover    Missing
-----------------------------------------  -------  ------  -------  --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__init__.py                                      8       0  100.00%
cli.py                                         312      59  81.09%   655-714, 816-867, 871
config.py                                      367      28  92.37%   82-84, 93, 101, 105-107, 175, 186, 452-454, 514-517, 560-561, 570-571, 676, 707, 739-744, 746
crunch.py                                        5       5  0.00%    20-24
api/__init__.py                                  0       0  100.00%
api/core.py                                    773      74  90.43%   636, 680-683, 721, 765, 799, 852-857, 883, 974, 1042, 1180, 1263-1275, 1311, 1313, 1341, 1345-1356, 1369-1375, 1458-1461, 1494-1514, 1566, 1583-1587, 1599-1602, 1624-1631, 1945, 1976-1982, 2233, 2237-2240, 2251-2253, 2285
api/search_result.py                            51       4  92.16%   73, 82, 89, 103
api/product/__init__.py                          6       0  100.00%
api/product/_assets.py                          48       5  89.58%   75, 147, 155, 158-162
api/product/_product.py                        187      20  89.30%   70-72, 237-238, 313, 342, 399, 413-416, 429, 453-456, 499-505
api/product/metadata_mapping.py                676      81  88.02%   130-132, 227, 259-260, 306-307, 317-329, 331, 342, 348-360, 405-406, 443, 464-467, 490, 498-499, 575-576, 600-601, 607-610, 625-626, 775, 821, 992-997, 1124, 1138-1158, 1178, 1183, 1290, 1312, 1326, 1339-1358, 1397, 1449, 1481-1485, 1500
api/product/drivers/__init__.py                  6       0  100.00%
api/product/drivers/base.py                      6       1  83.33%   38
plugins/__init__.py                              0       0  100.00%
plugins/base.py                                 21       3  85.71%   48, 55, 68
plugins/manager.py                             130      12  90.77%   104-109, 159, 197, 219, 223, 247, 281-282
plugins/apis/__init__.py                         0       0  100.00%
plugins/apis/base.py                             4       0  100.00%
plugins/apis/ecmwf.py                           91       8  91.21%   149-151, 198-199, 225-227
plugins/apis/usgs.py                           180      31  82.78%   132, 234, 268, 303-305, 310, 336-337, 342, 372-379, 390-395, 417-423, 425-431, 454
plugins/authentication/__init__.py               6       1  83.33%   31
plugins/authentication/aws_auth.py              19       0  100.00%
plugins/authentication/base.py                  17       2  88.24%   34, 47
plugins/authentication/generic.py               14       2  85.71%   40, 50
plugins/authentication/header.py                19       0  100.00%
plugins/authentication/keycloak.py              48       4  91.67%   134, 160-165
plugins/authentication/oauth.py                 13       7  46.15%   32-34, 38-41
plugins/authentication/openid_connect.py       187      17  90.91%   119, 133-158, 166, 320-323, 349
plugins/authentication/qsauth.py                34       1  97.06%   83
plugins/authentication/sas_auth.py              47       1  97.87%   76
plugins/authentication/token.py                 89      16  82.02%   79, 107, 109, 132-145, 201-205
plugins/authentication/token_exchange.py        36      20  44.44%   74-80, 92-122
plugins/crunch/__init__.py                       0       0  100.00%
plugins/crunch/base.py                          10       1  90.00%   40
plugins/crunch/filter_date.py                   59      14  76.27%   49-54, 66, 75, 84, 87, 99-101, 110-112, 119
plugins/crunch/filter_latest_intersect.py       47      33  29.79%   48-53, 66-111
plugins/crunch/filter_latest_tpl_name.py        31       1  96.77%   83
plugins/crunch/filter_overlap.py                66      18  72.73%   28-30, 68-71, 78-81, 87, 95, 106-122
plugins/crunch/filter_property.py               30       7  76.67%   54-59, 62-63, 79-83
plugins/download/__init__.py                     0       0  100.00%
plugins/download/aws.py                        489     163  66.67%   265, 278, 345-348, 362-366, 408-410, 414, 446-447, 453-457, 486, 518, 522, 529, 559-567, 571, 603-611, 618-620, 654-728, 746-807, 818-823, 835-848, 873, 888-890, 893, 903-911, 919-932, 942-973, 980-992, 1030, 1056, 1101-1103, 1323
plugins/download/base.py                       253      53  79.05%   136, 164, 231-233, 296-297, 314-320, 351-355, 361-362, 404, 407-421, 433, 437, 501-505, 535-536, 544-561, 568-576, 578-582, 625, 647, 669, 677
plugins/download/creodias_s3.py                 17       9  47.06%   44-58
plugins/download/http.py                       534     130  75.66%   195-207, 209-210, 242-245, 306-309, 311-312, 319-324, 342-357, 374-376, 388, 436, 443-449, 467, 481, 495, 503-505, 521-526, 537, 555, 597-601, 623, 663, 708, 722-728, 757-821, 839, 872-881, 903-904, 931-936, 942, 945, 961, 978-979, 992, 1009-1010, 1017, 1078-1084, 1139-1140, 1146, 1156, 1192, 1228, 1246-1262, 1288-1290
plugins/download/s3rest.py                     116      24  79.31%   113, 149, 156, 191, 221-228, 231-233, 237, 248-254, 262-263, 266-270, 293, 314-317
plugins/search/__init__.py                      22       0  100.00%
plugins/search/base.py                         128      14  89.06%   102, 106, 117, 255, 275, 331-332, 352, 355-363, 365
plugins/search/build_search_result.py          181      30  83.43%   95, 136-137, 143, 154, 288-291, 320, 373-390, 450, 453, 463, 480, 500-515
plugins/search/cop_marine.py                   197      47  76.14%   55, 63-65, 71-72, 88, 90, 93, 128-130, 142-143, 183-192, 196, 199, 203, 221, 249, 253, 268, 272, 276, 280, 284-288, 294-297, 300-314, 331, 354, 357, 363
plugins/search/creodias_s3.py                   55       3  94.55%   53, 71, 105
plugins/search/csw.py                          105      81  22.86%   58-59, 63-64, 72-120, 126-139, 147-179, 197-238
plugins/search/data_request_search.py          200      67  66.50%   90-93, 109, 120, 124-125, 136, 141, 146, 153, 166-169, 223-224, 228, 238-244, 249, 275-278, 286-297, 314, 316, 323-324, 326-327, 345-349, 382, 392, 403, 416, 422-437, 442
plugins/search/qssearch.py                     682     122  82.11%   388, 392-398, 406-407, 513-525, 569, 572, 585, 595, 614-629, 666-669, 740-741, 789, 808, 815, 827, 884, 905, 908-909, 918-919, 928-929, 938-939, 966, 1037-1042, 1046-1055, 1089, 1111, 1171, 1220, 1294-1298, 1358, 1361, 1367-1368, 1389, 1416-1428, 1435, 1467-1469, 1479-1485, 1515, 1538, 1553, 1575, 1641-1741
plugins/search/static_stac_search.py            72      10  86.11%   98-125, 141, 154
rest/__init__.py                                 4       2  50.00%   21-22
rest/cache.py                                   33      22  33.33%   35-37, 44-70
rest/config.py                                  26       1  96.15%   36
rest/constants.py                                7       0  100.00%
rest/core.py                                   234     129  44.87%   162, 164, 166, 171-172, 193-202, 213-219, 260-314, 327-365, 396-430, 445-461, 479-490, 504-535, 552, 594-633, 672, 679-727
rest/server.py                                 283     283  0.00%    18-874
rest/stac.py                                   473     177  62.58%   252, 318, 340, 392-395, 422-449, 480-482, 505, 537-538, 620-660, 682-698, 725, 772-785, 792, 846-847, 853, 906, 908, 964, 973-975, 991-993, 1000-1002, 1014-1016, 1028-1045, 1053-1074, 1082-1104, 1111-1128, 1147-1170, 1179, 1187-1199, 1210-1232, 1243-1288, 1332-1365, 1441-1467
rest/types/__init__.py                           0       0  100.00%
rest/types/collections_search.py                13      13  0.00%    18-44
rest/types/eodag_search.py                     179      14  92.18%   232-236, 269-271, 289, 292, 298, 302, 360, 372-375
rest/types/queryables.py                        56      13  76.79%   51-52, 59-60, 67-68, 94-99, 108-109, 164
rest/types/stac_search.py                      126      11  91.27%   127-129, 175, 190-192, 200, 204, 252, 255
rest/utils/__init__.py                          93      30  67.74%   79-85, 105, 108-109, 128-130, 143, 150, 175-183, 190-211
rest/utils/cql_evaluate.py                      48       5  89.58%   69, 76, 90, 97, 105
rest/utils/rfc3339.py                           23       5  78.26%   43-44, 48, 60, 62
types/__init__.py                              114      39  65.79%   53, 66-70, 81-93, 120-122, 129-132, 172, 199, 209-225, 230, 232, 253, 258, 266, 276
types/bbox.py                                   43      19  55.81%   46-61, 72-74, 85-87, 99-101, 113-115, 123
types/download_args.py                           9       0  100.00%
types/queryables.py                             81       0  100.00%
types/search_args.py                            70      18  74.29%   60-64, 71-88, 103
types/whoosh.py                                 15       0  100.00%
utils/__init__.py                              500      37  92.60%   85, 90, 194-195, 204-231, 234, 248, 328-332, 406-410, 429-431, 510, 525, 561-562, 926-929, 937-938, 976-977, 1148
utils/constraints.py                           119      37  68.91%   89-98, 139, 144, 148, 159, 182-184, 194, 208-224, 233-244
utils/exceptions.py                             35       1  97.14%   93
utils/import_system.py                          28      19  32.14%   64-78, 89-99
utils/logging.py                                28       1  96.43%   41
utils/notebook.py                               44      23  47.73%   25-29, 36-41, 58-62, 72-78, 83-87
utils/repr.py                                   30       8  73.33%   36, 38, 42, 76, 94-101
utils/requests.py                               55      11  80.00%   64, 88, 90, 92, 94, 96, 112, 120-122, 130
utils/rest.py                                   36       1  97.22%   55
utils/stac_reader.py                           111      45  59.46%   56-57, 63-85, 95-97, 101, 137, 153-156, 203-212, 222-252
TOTAL                                         9610    2193  77.18%
```

</details>


### Diff against develop

```
Filename                           Stmts    Miss  Cover
-------------------------------  -------  ------  --------
api/core.py                           +1       0  +0.02%
api/product/metadata_mapping.py       +1       0  +0.02%
TOTAL                                 +2       0  +100.00%
```


Results for commit: 33dec24617908e5362b09ce31c5b6a83a12005a5


_Minimum allowed coverage is `70%`_


:recycle: This comment has been updated with latest results


<!-- Sticky Pull Request Commentartifacts/unit-test-results-python3.12-windows-latest/coverage.xml -->

Patch:
diff --git a/eodag/api/core.py b/eodag/api/core.py
index a0455f1d..91bd0196 100644
--- a/eodag/api/core.py
+++ b/eodag/api/core.py
@@ -53,6 +53,7 @@ from eodag.config import (
 from eodag.plugins.manager import PluginManager
 from eodag.plugins.search import PreparedSearch
 from eodag.plugins.search.build_search_result import BuildPostSearchResult
+from eodag.plugins.search.qssearch import PostJsonSearch
 from eodag.types import model_fields_to_annotated
 from eodag.types.queryables import CommonQueryables
 from eodag.types.whoosh import EODAGQueryParser
@@ -1561,7 +1562,7 @@ class EODataAccessGateway:
                 "max_items_per_page", DEFAULT_MAX_ITEMS_PER_PAGE
             )
             kwargs.update(items_per_page=items_per_page)
-            if isinstance(plugin, BuildPostSearchResult):
+            if isinstance(plugin, PostJsonSearch):
                 kwargs.update(
                     items_per_page=items_per_page,
                     _dc_qs=_dc_qs,
diff --git a/eodag/api/product/metadata_mapping.py b/eodag/api/product/metadata_mapping.py
index 885d5c10..7501f8f4 100644
--- a/eodag/api/product/metadata_mapping.py
+++ b/eodag/api/product/metadata_mapping.py
@@ -41,6 +41,7 @@ import geojson
 import orjson
 import pyproj
 from dateutil.parser import isoparse
+from dateutil.relativedelta import relativedelta
 from dateutil.tz import UTC, tzutc
 from jsonpath_ng.jsonpath import Child, JSONPath
 from lxml import etree
@@ -831,7 +832,7 @@ def format_metadata(search_param: str, *args: Any, **kwargs: Any) -> str:
         def convert_get_hydrological_year(date: str):
             utc_date = MetadataFormatter.convert_to_iso_utc_datetime(date)
             date_object = datetime.strptime(utc_date, "%Y-%m-%dT%H:%M:%S.%fZ")
-            date_object_second_year = date_object + timedelta(days=365)
+            date_object_second_year = date_object + relativedelta(years=1)
             return [
                 f'{date_object.strftime("%Y")}_{date_object_second_year.strftime("%y")}'
             ]
diff --git a/eodag/resources/providers.yml b/eodag/resources/providers.yml
index bab25da3..ffe362a0 100644
--- a/eodag/resources/providers.yml
+++ b/eodag/resources/providers.yml
@@ -4886,6 +4886,9 @@
       statistic:
         - '{{"statistic": {statistic}}}'
         - '$.null'
+      hydrological_year:
+        - '{{"hydrological_year": {hydrological_year}}}'
+        - '$.null'
   products:
     SATELLITE_CARBON_DIOXIDE:
       productType: EO:ECMWF:DAT:SATELLITE_CARBON_DIOXIDE


Test patch:
diff --git a/tests/units/test_search_plugins.py b/tests/units/test_search_plugins.py
index b979cbae..477d319a 100644
--- a/tests/units/test_search_plugins.py
+++ b/tests/units/test_search_plugins.py
@@ -1057,6 +1057,105 @@ class TestSearchPluginPostJsonSearch(BaseSearchPluginTest):
             verify=True,
         )
 
+    @mock.patch("eodag.plugins.search.qssearch.PostJsonSearch._request", autospec=True)
+    def test_plugins_search_postjsonsearch_query_params_wekeo(self, mock__request):
+        """A query with PostJsonSearch (here wekeo) must generate query params corresponding to the
+        search criteria"""
+        provider = "wekeo_ecmwf"
+        product_type = "GRIDDED_GLACIERS_MASS_CHANGE"
+        search_plugin = self.get_search_plugin(product_type, provider)
+        auth_plugin = self.get_auth_plugin(provider)
+
+        mock__request.return_value = mock.Mock()
+
+        def _test_query_params(search_criteria, raw_result, expected_query_params):
+            mock__request.reset_mock()
+            mock__request.return_value.json.side_effect = [raw_result]
+            results, _ = search_plugin.query(
+                prep=PreparedSearch(
+                    page=1,
+                    items_per_page=10,
+                    auth_plugin=auth_plugin,
+                ),
+                **search_criteria,
+            )
+            self.assertDictEqual(
+                mock__request.call_args_list[0].args[1].query_params,
+                expected_query_params,
+            )
+
+        raw_result = {
+            "properties": {"itemsPerPage": 1, "startIndex": 0, "totalResults": 1},
+            "features": [
+                {
+                    "type": "Feature",
+                    "properties": {
+                        "startdate": "1975-01-01T00:00:00Z",
+                        "enddate": "2024-09-30T00:00:00Z",
+                    },
+                    "id": "derived-gridded-glacier-mass-change-576f8a153a25a83d9d3a5cfb03c4a759",
+                }
+            ],
+        }
+
+        # Test #1: using the datetime
+        search_criteria = {
+            "productType": product_type,
+            "startTimeFromAscendingNode": "1980-01-01",
+            "completionTimeFromAscendingNode": "1981-12-31",
+            "variable": "glacier_mass_change",
+            "format": "zip",
+            "version": "wgms_fog_2022_09",
+        }
+        expected_query_params = {
+            "dataset_id": "EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE",
+            "hydrological_year": ["1980_81"],
+            "variable": "glacier_mass_change",
+            "format": "zip",
+            "product_version": "wgms_fog_2022_09",
+            "itemsPerPage": 10,
+            "startIndex": 0,
+        }
+        _test_query_params(search_criteria, raw_result, expected_query_params)
+
+        # Test #2: using parameter hydrological_year (single value)
+        search_criteria = {
+            "productType": product_type,
+            "variable": "glacier_mass_change",
+            "format": "zip",
+            "version": "wgms_fog_2022_09",
+            "hydrological_year": ["2020_21"],
+        }
+        expected_query_params = {
+            "dataset_id": "EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE",
+            "hydrological_year": ["2020_21"],
+            "variable": "glacier_mass_change",
+            "format": "zip",
+            "product_version": "wgms_fog_2022_09",
+            "itemsPerPage": 10,
+            "startIndex": 0,
+        }
+        _test_query_params(search_criteria, raw_result, expected_query_params)
+
+        # Test #3: using parameter hydrological_year (multiple values)
+        search_criteria = {
+            "productType": product_type,
+            "variable": "glacier_mass_change",
+            "format": "zip",
+            "version": "wgms_fog_2022_09",
+            "hydrological_year": ["1990_91", "2020_21"],
+        }
+        expected_query_params = {
+            "dataset_id": "EO:ECMWF:DAT:DERIVED_GRIDDED_GLACIER_MASS_CHANGE",
+            "hydrological_year": ["1990_91", "2020_21"],
+            "variable": "glacier_mass_change",
+            "format": "zip",
+            "product_version": "wgms_fog_2022_09",
+            "itemsPerPage": 10,
+            "startIndex": 0,
+        }
+        _test_query_params(search_criteria, raw_result, expected_query_params)
+
 
 class TestSearchPluginODataV4Search(BaseSearchPluginTest):
     def setUp(self):