From 7e5a1da0123ffce60e9c5771dc5b079bd4518f14 Mon Sep 17 00:00:00 2001 From: Jules Dejaeghere Date: Sun, 30 Jun 2024 17:01:18 +0200 Subject: [PATCH] Add tests --- src/open_irceline/api.py | 1 - src/open_irceline/forecast.py | 9 +- tests/conftest.py | 25 - tests/fixtures/forecast_wms_capabilities.xml | 3291 +++++++++++++++++ tests/fixtures/forecast_wms_feature_info.json | 17 + .../forecast_wms_feature_info_invalid.json | 17 + .../forecast_wms_feature_info_no_field.json | 8 + tests/test_api_forecast.py | 125 + 8 files changed, 3462 insertions(+), 31 deletions(-) create mode 100644 tests/fixtures/forecast_wms_feature_info.json create mode 100644 tests/fixtures/forecast_wms_feature_info_invalid.json create mode 100644 tests/fixtures/forecast_wms_feature_info_no_field.json create mode 100644 tests/test_api_forecast.py diff --git a/src/open_irceline/api.py b/src/open_irceline/api.py index 3333c21..ed49bde 100644 --- a/src/open_irceline/api.py +++ b/src/open_irceline/api.py @@ -47,7 +47,6 @@ class IrcelineBaseClient(ABC): headers = dict() if 'User-Agent' not in headers: headers |= {'User-Agent': _user_agent} - try: async with async_timeout.timeout(60): response = await self._session.request( diff --git a/src/open_irceline/forecast.py b/src/open_irceline/forecast.py index 6ffcf48..d4ba038 100644 --- a/src/open_irceline/forecast.py +++ b/src/open_irceline/forecast.py @@ -5,7 +5,7 @@ from xml.etree import ElementTree from aiohttp import ClientResponse, ClientResponseError -from .api import IrcelineBaseClient, _rio_wfs_base_url, _forecast_wms_base_url, IrcelineApiError +from .api import IrcelineBaseClient, _forecast_wms_base_url, IrcelineApiError from .data import ForecastFeature, FeatureValue @@ -40,14 +40,13 @@ class IrcelineForecastClient(IrcelineBaseClient): for feature, d in product(features, range(4)): querystring = base_querystring | {"layers": f"{feature}_d{d}", "query_layers": f"{feature}_d{d}"} - print(querystring) try: - r: ClientResponse = await self._api_wrapper(_rio_wfs_base_url, querystring) + r: ClientResponse = await self._api_wrapper(_forecast_wms_base_url, querystring) r: dict = await r.json() result[(feature, timestamp + timedelta(days=d))] = FeatureValue( value=r.get('features', [{}])[0].get('properties', {}).get('GRAY_INDEX'), timestamp=datetime.fromisoformat(r.get('timeStamp')) if 'timeStamp' in r else None) - except (IrcelineApiError, ClientResponseError): + except (IrcelineApiError, ClientResponseError, IndexError): result[(feature, timestamp + timedelta(days=d))] = FeatureValue(value=None, timestamp=None) return result @@ -72,5 +71,5 @@ class IrcelineForecastClient(IrcelineBaseClient): return set() path = './/Capability/Layer/Layer/Name' - feature_type_names = {t.text for t in root.findall(path) if t.text.endswith('_d0')} + feature_type_names = {t.text for t in root.findall(path)} return feature_type_names diff --git a/tests/conftest.py b/tests/conftest.py index 0689299..b5a4eee 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,28 +27,3 @@ def get_mock_session(json_file=None, text_file=None): mock_session.request = AsyncMock(return_value=mock_response) return mock_session - -def create_mock_response(*args, **kwargs): - etag = 'my-etag-here' - mock_response = Mock() - if '20240619' not in kwargs.get('url', ''): - mock_response.status = 404 - mock_response.raise_for_status = Mock(side_effect=aiohttp.ClientResponseError(Mock(), Mock())) - elif etag in kwargs.get('headers', {}).get('If-None-Match', ''): - mock_response.text = AsyncMock(return_value='') - mock_response.status = 304 - else: - mock_response.text = AsyncMock(return_value=get_api_data('forecast.csv', plain=True)) - mock_response.status = 200 - - if '20240619' in kwargs.get('url', ''): - mock_response.headers = {'ETag': etag} - else: - mock_response.headers = dict() - return mock_response - - -def get_mock_session_many_csv(): - mock_session = Mock(aiohttp.ClientSession) - mock_session.request = AsyncMock(side_effect=create_mock_response) - return mock_session diff --git a/tests/fixtures/forecast_wms_capabilities.xml b/tests/fixtures/forecast_wms_capabilities.xml index e69de29..3e3f691 100644 --- a/tests/fixtures/forecast_wms_capabilities.xml +++ b/tests/fixtures/forecast_wms_capabilities.xml @@ -0,0 +1,3291 @@ + + + + + OGC:WMS + IRCEL - CELINE - Web Map Service + A compliant implementation of WMS plus most of the SLD extension (dynamic styling). Can also generate + PDF, SVG, KML, GeoRSS + + + WFS + WMS + GEOSERVER + + + + + IRCEL - CELINE + Belgian Interregional Environment Agency + + + + +
Gaucheretstraat 92-94 Rue Gaucheret
+ Brussels + + 1030 + Belgium +
+ +(32)(0)2 227 57 01 + + info@irceline.be +
+ NONE + https://creativecommons.org/licenses/by/4.0/ +
+ + + + application/vnd.ogc.wms_xml + text/xml + + + + + + + + + + + + + image/png + application/atom xml + application/atom+xml + application/json;type=utfgrid + application/openlayers + application/openlayers2 + application/openlayers3 + application/pdf + application/rss xml + application/rss+xml + application/vnd.google-earth.kml + application/vnd.google-earth.kml xml + application/vnd.google-earth.kml+xml + application/vnd.google-earth.kml+xml;mode=networklink + application/vnd.google-earth.kmz + application/vnd.google-earth.kmz xml + application/vnd.google-earth.kmz+xml + application/vnd.google-earth.kmz;mode=networklink + atom + image/geotiff + image/geotiff8 + image/gif + image/gif;subtype=animated + image/jpeg + image/png8 + image/png; mode=8bit + image/svg + image/svg xml + image/svg+xml + image/tiff + image/tiff8 + image/vnd.jpeg-png + image/vnd.jpeg-png8 + kml + kmz + openlayers + rss + text/html; subtype=openlayers + text/html; subtype=openlayers2 + text/html; subtype=openlayers3 + utfgrid + + + + + + + + + + text/plain + application/vnd.ogc.gml + text/xml + application/vnd.ogc.gml/3.1.1 + text/xml; subtype=gml/3.1.1 + text/html + application/json + + + + + + + + + + + + + application/vnd.ogc.wms_xml + + + + + + + + + + image/png + image/jpeg + application/json + image/gif + + + + + + + + + + application/vnd.ogc.sld+xml + + + + + + + + + + + application/vnd.ogc.se_xml + application/vnd.ogc.se_inimage + application/vnd.ogc.se_blank + application/json + + + + IRCEL - CELINE - Web Map Service + A compliant implementation of WMS plus most of the SLD extension (dynamic styling). Can also + generate PDF, SVG, KML, GeoRSS + + + EPSG:3857 + EPSG:4258 + EPSG:4326 + EPSG:31370 + EPSG:900913 + + + + + http://geo.irceline.be + + belaqi + belaqi_forecast + + + belaqi_forecast + WCS + ImageMosaic + + EPSG:31370 + + + + 2023-01-27T00:00:00.000Z/2024-07-03T00:00:00.000Z/P1D + + + + belaqi_d0 + belaqi_forecast_d0 + + + WCS + ImageMosaic + belaqi_forecast_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + belaqi_d1 + belaqi_d1 + + + WCS + ImageMosaic + belaqi_forecast_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + belaqi_d2 + belaqi_d2 + + + WCS + ImageMosaic + belaqi_forecast_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + belaqi_d3 + belaqi_d3 + + + WCS + ImageMosaic + belaqi_forecast_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + belaqi_forecast + belaqi_forecast + + + WCS + ImageMosaic + belaqi_forecast + + EPSG:31370 + + + + 2023-01-27T00:00:00.000Z/2024-07-03T00:00:00.000Z/P1D + + + + belaqi_forecast_chimv2022_d0 + belaqi_forecast_chimv2022_d0 + + + belaqi_forecast_chimv2022_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + belaqi_forecast_chimv2022_d1 + belaqi_forecast_chimv2022_d1 + + + belaqi_forecast_chimv2022_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + belaqi_forecast_chimv2022_d2 + belaqi_forecast_chimv2022_d2 + + + belaqi_forecast_chimv2022_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + belaqi_forecast_chimv2022_d3 + belaqi_forecast_chimv2022_d3 + + + belaqi_forecast_chimv2022_d3 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + belaqi_vl + belaqi_vl + + + WCS + ImageMosaic + belaqi_forecast_vl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + belaqi_wl + belaqi_forecast_wl + + + WCS + ImageMosaic + belaqi_forecast_wl + + EPSG:31370 + + + + 2020-03-02T00:00:00.000Z/2020-06-05T00:00:00.000Z/P1D + + + + belaqi_wl_d0 + belaqi_wl_d0 + + + WCS + ImageMosaic + belaqi_forecast_wl_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + belaqi_wl_d1 + belaqi_wl_d1 + + + WCS + ImageMosaic + belaqi_forecast_wl_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + belaqi_wl_d2 + belaqi_wl_d2 + + + WCS + ImageMosaic + belaqi_forecast_wl_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + belaqi_wl_d3 + belaqi_wl_d3 + + + WCS + ImageMosaic + belaqi_forecast_wl_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + euaqi_d0 + euaqi_d0 + + + WCS + ImageMosaic + euaqi_forecast_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + euaqi_d1 + euaqi_d1 + euaqi_forecast_d1 + + WCS + ImageMosaic + euaqi_forecast_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + euaqi_d2 + euaqi_d2 + euaqi_forecast_d2 + + WCS + ImageMosaic + euaqi_forecast_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + euaqi_d3 + euaqi_d3 + euaqi_forecast_d3 + + WCS + ImageMosaic + euaqi_forecast_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + euaqi_forecast + euaqi_forecast + + + WCS + ImageMosaic + euaqi_forecast + + EPSG:31370 + + + + 2021-10-17T00:00:00.000Z/2024-07-03T00:00:00.000Z/P1D + + + + no2_dmean_chimv2022_d0 + no2_dmean_chimv2022_d0 + + + no2_dmean_chimv2022_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + no2_dmean_chimv2022_d1 + no2_dmean_chimv2022_d1 + + + no2_dmean_chimv2022_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + no2_dmean_chimv2022_d2 + no2_dmean_chimv2022_d2 + + + no2_dmean_chimv2022_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + no2_dmean_chimv2022_d3 + no2_dmean_chimv2022_d3 + + + no2_dmean_chimv2022_d3 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + no2_dmean_d0 + no2_dmean_d0 + + + no2_dmean_d0 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + no2_dmean_d1 + no2_dmean_d1 + + + no2_dmean_d1 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_dmean_d2 + no2_dmean_d2 + + + no2_dmean_d2 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_dmean_d3 + no2_dmean_d3 + + + no2_dmean_d3 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_dmean_wl_d0 + no2_dmean_wl_d0 + + + no2_dmean_wl_d0 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + no2_dmean_wl_d1 + no2_dmean_wl_d1 + + + no2_dmean_wl_d1 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + no2_dmean_wl_d2 + no2_dmean_wl_d2 + + + no2_dmean_wl_d2 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + no2_dmean_wl_d3 + no2_dmean_wl_d3 + + + no2_dmean_wl_d3 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + no2_maxhmean + no2_maxhmean + + + WCS + ImageMosaic + no2_maxhmean + + EPSG:31370 + + + + 2022-12-11T00:00:00.000Z/2022-12-17T00:00:00.000Z/P1D + + + + no2_maxhmean_d0 + no2_maxhmean_d0 + + + WCS + ImageMosaic + no2_maxhmean_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_maxhmean_d1 + no2_maxhmean_d1 + + + WCS + ImageMosaic + no2_maxhmean_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_maxhmean_d2 + no2_maxhmean_d2 + + + WCS + ImageMosaic + no2_maxhmean_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_maxhmean_d3 + no2_maxhmean_d3 + + + WCS + ImageMosaic + no2_maxhmean_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_maxhmean_tf_d0 + no2_maxhmean_tf_d0 + + + no2_maxhmean_tf_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + no2_maxhmean_tf_d1 + no2_maxhmean_tf_d1 + + + no2_maxhmean_tf_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + no2_maxhmean_tf_d2 + no2_maxhmean_tf_d2 + + + no2_maxhmean_tf_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + no2_maxhmean_vl + no2_maxhmean_vl + + + WCS + ImageMosaic + no2_maxhmean_vl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + no2_maxhmean_wl + no2_maxhmean_wl + + + WCS + ImageMosaic + no2_maxhmean_wl + + EPSG:31370 + + + + 2020-06-02T00:00:00.000Z/2020-06-05T00:00:00.000Z/P1D + + + + no2_maxhmean_wl_d0 + no2_maxhmean_wl_d0 + + + WCS + ImageMosaic + no2_maxhmean_wl_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_maxhmean_wl_d1 + no2_maxhmean_wl_d1 + + + WCS + ImageMosaic + no2_maxhmean_wl_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_maxhmean_wl_d2 + no2_maxhmean_wl_d2 + + + WCS + ImageMosaic + no2_maxhmean_wl_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + no2_maxhmean_wl_d3 + no2_maxhmean_wl_d3 + + + WCS + ImageMosaic + no2_maxhmean_wl_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_max8hmean_chimv2022_d0 + o3_max8hmean_chimv2022_d0 + + + o3_max8hmean_chimv2022_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_max8hmean_chimv2022_d1 + o3_max8hmean_chimv2022_d1 + + + o3_max8hmean_chimv2022_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_max8hmean_chimv2022_d2 + o3_max8hmean_chimv2022_d2 + + + o3_max8hmean_chimv2022_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_max8hmean_chimv2022_d3 + o3_max8hmean_chimv2022_d3 + + + o3_max8hmean_chimv2022_d3 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_max8hmean_d0 + o3_max8hmean_d0 + + + o3_max8hmean_d0 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_max8hmean_d1 + o3_max8hmean_d1 + + + o3_max8hmean_d1 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_max8hmean_d2 + o3_max8hmean_d2 + + + o3_max8hmean_d2 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_max8hmean_d3 + o3_max8hmean_d3 + + + o3_max8hmean_d3 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_max8hmean_wl_d0 + o3_max8hmean_wl_d0 + + + o3_max8hmean_wl_d0 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + o3_max8hmean_wl_d1 + o3_max8hmean_wl_d1 + + + o3_max8hmean_wl_d1 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + o3_max8hmean_wl_d2 + o3_max8hmean_wl_d2 + + + o3_max8hmean_wl_d2 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + o3_max8hmean_wl_d3 + o3_max8hmean_wl_d3 + + + o3_max8hmean_wl_d3 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1H + + + + o3_maxhmean + o3_maxhmean + + + WCS + ImageMosaic + o3_maxhmean + + EPSG:31370 + + + + 2018-05-08T00:00:00.000Z/2022-12-17T00:00:00.000Z/P1D + + + + + o3_maxhmean_chimv2022_d0 + o3_maxhmean_chimv2022_d0 + + + o3_maxhmean_chimv2022_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_maxhmean_chimv2022_d1 + o3_maxhmean_chimv2022_d1 + + + o3_maxhmean_chimv2022_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_maxhmean_chimv2022_d2 + o3_maxhmean_chimv2022_d2 + + + o3_maxhmean_chimv2022_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_maxhmean_chimv2022_d3 + o3_maxhmean_chimv2022_d3 + + + o3_maxhmean_chimv2022_d3 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + o3_maxhmean_d0 + o3_maxhmean_d0 + + + o3_maxhmean_d0 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_maxhmean_d1 + o3_maxhmean_d1 + + + WCS + ImageMosaic + o3_maxhmean_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_maxhmean_d2 + o3_maxhmean_d2 + + + WCS + ImageMosaic + o3_maxhmean_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_maxhmean_d3 + o3_maxhmean_d3 + + + WCS + ImageMosaic + o3_maxhmean_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_maxhmean_tf_d0 + o3_maxhmean_tf_d0 + + + o3_maxhmean_tf_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + o3_maxhmean_tf_d1 + o3_maxhmean_tf_d1 + + + o3_maxhmean_tf_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + o3_maxhmean_tf_d2 + o3_maxhmean_tf_d2 + + + o3_maxhmean_tf_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + o3_maxhmean_vl + o3_maxhmean_vl + + + WCS + ImageMosaic + o3_maxhmean_vl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + o3_maxhmean_wl + o3_maxhmean_wl + + + WCS + ImageMosaic + o3_maxhmean_wl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + o3_maxhmean_wl_d0 + o3_maxhmean_wl_d0 + + + WCS + ImageMosaic + o3_maxhmean_wl_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_maxhmean_wl_d1 + o3_maxhmean_wl_d1 + + + WCS + ImageMosaic + o3_maxhmean_wl_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_maxhmean_wl_d2 + o3_maxhmean_wl_d2 + + + WCS + ImageMosaic + o3_maxhmean_wl_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + o3_maxhmean_wl_d3 + o3_maxhmean_wl_d3 + + + WCS + ImageMosaic + o3_maxhmean_wl_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm10_dmean + pm10_dmean + + + WCS + ImageMosaic + pm10_dmean + + EPSG:31370 + + + + 2018-05-08T00:00:00.000Z/2022-12-17T00:00:00.000Z/PT1H + + + + pm10_dmean_chimv2022_d0 + pm10_dmean_chimv2022_d0 + + + pm10_dmean_chimv2022_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm10_dmean_chimv2022_d1 + pm10_dmean_chimv2022_d1 + + + pm10_dmean_chimv2022_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm10_dmean_chimv2022_d2 + pm10_dmean_chimv2022_d2 + + + pm10_dmean_chimv2022_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm10_dmean_chimv2022_d3 + pm10_dmean_chimv2022_d3 + + + pm10_dmean_chimv2022_d3 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm10_dmean_d0 + pm10_dmean_d0 + + + pm10_dmean_d0 + WCS + ImageMosaic + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + pm10_dmean_d1 + pm10_dmean_d1 + + + WCS + ImageMosaic + pm10_dmean_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + pm10_dmean_d2 + pm10_dmean_d2 + + + WCS + ImageMosaic + pm10_dmean_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + pm10_dmean_d3 + pm10_dmean_d3 + + + WCS + ImageMosaic + pm10_dmean_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + pm10_dmean_tf_d0 + pm10_dmean_tf_d0 + + + pm10_dmean_tf_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + + + pm10_dmean_tf_d1 + pm10_dmean_tf_d1 + + + pm10_dmean_tf_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + pm10_dmean_tf_d2 + pm10_dmean_tf_d2 + + + pm10_dmean_tf_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + pm10_dmean_vl + pm10_dmean_vl + + + WCS + ImageMosaic + pm10_dmean_vl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + pm10_dmean_wl + pm10_dmean_wl + + + WCS + ImageMosaic + pm10_dmean_wl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + pm10_dmean_wl_d0 + pm10_dmean_wl_d0 + + + WCS + ImageMosaic + pm10_dmean_wl_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm10_dmean_wl_d1 + pm10_dmean_wl_d1 + + + WCS + ImageMosaic + pm10_dmean_wl_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm10_dmean_wl_d2 + pm10_dmean_wl_d2 + + + WCS + ImageMosaic + pm10_dmean_wl_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm10_dmean_wl_d3 + pm10_dmean_wl_d3 + + + WCS + ImageMosaic + pm10_dmean_wl_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm25_dmean + pm25_dmean + + + WCS + ImageMosaic + pm25_dmean + + EPSG:31370 + + + + 2018-05-08T00:00:00.000Z/2022-12-17T00:00:00.000Z/PT1H + + + + pm25_dmean_chimv2022_d0 + pm25_dmean_chimv2022_d0 + + + pm25_dmean_chimv2022_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm25_dmean_chimv2022_d1 + pm25_dmean_chimv2022_d1 + + + pm25_dmean_chimv2022_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm25_dmean_chimv2022_d2 + pm25_dmean_chimv2022_d2 + + + pm25_dmean_chimv2022_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm25_dmean_chimv2022_d3 + pm25_dmean_chimv2022_d3 + + + pm25_dmean_chimv2022_d3 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T11:40:01.000Z/2024-06-30T11:40:01.000Z/P1DT1H1M + + + + + pm25_dmean_d0 + pm25_dmean_d0 + + + WCS + ImageMosaic + pm25_dmean_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + pm25_dmean_d1 + pm25_dmean_d1 + + + WCS + ImageMosaic + pm25_dmean_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + pm25_dmean_d2 + pm25_dmean_d2 + + + WCS + ImageMosaic + pm25_dmean_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + pm25_dmean_d3 + pm25_dmean_d3 + + + WCS + ImageMosaic + pm25_dmean_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1DT1H1M + + + + + pm25_dmean_tf_d0 + pm25_dmean_tf_d0 + + + pm25_dmean_tf_d0 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + pm25_dmean_tf_d1 + pm25_dmean_tf_d1 + + + pm25_dmean_tf_d1 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + pm25_dmean_tf_d2 + pm25_dmean_tf_d2 + + + pm25_dmean_tf_d2 + WCS + ImageMosaic + + EPSG:3035 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/P1D + + + + pm25_dmean_vl + pm25_dmean_vl + + + WCS + ImageMosaic + pm25_dmean_vl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + pm25_dmean_wl + pm25_dmean_wl + + + WCS + ImageMosaic + pm25_dmean_wl + + EPSG:31370 + + + + 2019-12-03T00:00:00.000Z/2020-03-05T00:00:00.000Z/P1D + + + + pm25_dmean_wl_d0 + pm25_dmean_wl_d0 + + + WCS + ImageMosaic + pm25_dmean_wl_d0 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm25_dmean_wl_d1 + pm25_dmean_wl_d1 + + + WCS + ImageMosaic + pm25_dmean_wl_d1 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm25_dmean_wl_d2 + pm25_dmean_wl_d2 + + + WCS + ImageMosaic + pm25_dmean_wl_d2 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + pm25_dmean_wl_d3 + pm25_dmean_wl_d3 + + + WCS + ImageMosaic + pm25_dmean_wl_d3 + + EPSG:31370 + + + + 2024-06-30T12:15:13.000Z/2024-06-30T12:15:13.000Z/PT1M + + + + +
diff --git a/tests/fixtures/forecast_wms_feature_info.json b/tests/fixtures/forecast_wms_feature_info.json new file mode 100644 index 0000000..afe1241 --- /dev/null +++ b/tests/fixtures/forecast_wms_feature_info.json @@ -0,0 +1,17 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": "", + "geometry": null, + "properties": { + "GRAY_INDEX": 10.853286743164062 + } + } + ], + "totalFeatures": "unknown", + "numberReturned": 1, + "timeStamp": "2024-06-30T13:00:21.520Z", + "crs": null +} \ No newline at end of file diff --git a/tests/fixtures/forecast_wms_feature_info_invalid.json b/tests/fixtures/forecast_wms_feature_info_invalid.json new file mode 100644 index 0000000..cb7521b --- /dev/null +++ b/tests/fixtures/forecast_wms_feature_info_invalid.json @@ -0,0 +1,17 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "id": "", + "geometry": null, + "properties": { + "WRONG": 10.853286743164062 + } + } + ], + "totalFeatures": "unknown", + "numberReturned": 1, + "timeStamp": "2024-06-30T13:00:21.520Z", + "crs": null +} \ No newline at end of file diff --git a/tests/fixtures/forecast_wms_feature_info_no_field.json b/tests/fixtures/forecast_wms_feature_info_no_field.json new file mode 100644 index 0000000..670d110 --- /dev/null +++ b/tests/fixtures/forecast_wms_feature_info_no_field.json @@ -0,0 +1,8 @@ +{ + "type": "FeatureCollection", + "features": [], + "totalFeatures": "unknown", + "numberReturned": 1, + "timeStamp": "2024-06-30T13:00:21.520Z", + "crs": null +} \ No newline at end of file diff --git a/tests/test_api_forecast.py b/tests/test_api_forecast.py new file mode 100644 index 0000000..628636a --- /dev/null +++ b/tests/test_api_forecast.py @@ -0,0 +1,125 @@ +from datetime import datetime +from itertools import product +from unittest.mock import call + +from freezegun import freeze_time + +from src.open_irceline import IrcelineForecastClient, ForecastFeature, FeatureValue +from src.open_irceline.api import _user_agent, _forecast_wms_base_url +from tests.conftest import get_api_data, get_mock_session + + +def test_parse_capabilities(): + data = get_api_data('forecast_wms_capabilities.xml', plain=True) + result = IrcelineForecastClient._parse_capabilities(data) + + expected = {'o3_maxhmean_wl_d3', 'pm25_dmean_wl_d0', 'o3_max8hmean_chimv2022_d2', 'no2_maxhmean_tf_d2', + 'belaqi_forecast_chimv2022_d2', 'pm25_dmean_chimv2022_d3', 'pm10_dmean_chimv2022_d0', + 'no2_maxhmean_wl_d0', 'no2_maxhmean_d2', 'no2_dmean_chimv2022_d2', 'o3_maxhmean_chimv2022_d3', + 'pm25_dmean_wl_d3', 'o3_maxhmean_chimv2022_d0', 'pm25_dmean', 'pm25_dmean_tf_d0', 'no2_dmean_wl_d2', + 'o3_max8hmean_chimv2022_d3', 'pm25_dmean_d2', 'o3_max8hmean_chimv2022_d0', 'o3_maxhmean_wl_d2', + 'no2_maxhmean_wl_d1', 'pm10_dmean_tf_d2', 'pm25_dmean_d1', 'o3_maxhmean_chimv2022_d2', + 'pm10_dmean_chimv2022_d2', 'o3_maxhmean_vl', 'belaqi_wl_d2', 'pm10_dmean_wl', 'pm10_dmean_d2', + 'no2_dmean_wl_d0', 'no2_dmean_d1', 'o3_maxhmean_d2', 'o3_maxhmean_wl', 'pm25_dmean_wl_d2', + 'o3_maxhmean_d3', 'o3_max8hmean_wl_d3', 'belaqi_d0', 'no2_maxhmean_wl_d2', 'no2_maxhmean_wl', + 'pm10_dmean_wl_d1', 'no2_dmean_chimv2022_d3', 'o3_maxhmean_tf_d1', 'pm25_dmean_vl', 'pm10_dmean_d0', + 'o3_max8hmean_d0', 'o3_max8hmean_d2', 'no2_maxhmean_vl', 'o3_max8hmean_chimv2022_d1', 'pm10_dmean', + 'pm10_dmean_wl_d2', 'euaqi_d3', 'belaqi_d1', 'o3_max8hmean_d1', 'o3_maxhmean_chimv2022_d1', 'belaqi_vl', + 'belaqi_wl_d0', 'no2_dmean_chimv2022_d0', 'pm25_dmean_wl_d1', 'pm25_dmean_tf_d2', 'no2_dmean_d2', + 'o3_maxhmean', 'belaqi_wl', 'no2_maxhmean_d0', 'no2_maxhmean_d3', 'o3_max8hmean_d3', 'euaqi_forecast', + 'o3_max8hmean_wl_d1', 'pm10_dmean_chimv2022_d3', 'no2_maxhmean_wl_d3', 'o3_maxhmean_d1', + 'no2_dmean_wl_d1', 'o3_maxhmean_wl_d1', 'no2_dmean_d3', 'belaqi_d3', 'belaqi', 'pm25_dmean_d3', + 'belaqi_forecast', 'no2_dmean_d0', 'pm25_dmean_chimv2022_d1', 'belaqi_wl_d1', 'pm10_dmean_d3', + 'no2_dmean_wl_d3', 'pm25_dmean_tf_d1', 'euaqi_d0', 'o3_maxhmean_wl_d0', 'belaqi_forecast_chimv2022_d3', + 'no2_dmean_chimv2022_d1', 'o3_max8hmean_wl_d0', 'o3_max8hmean_wl_d2', 'pm10_dmean_chimv2022_d1', + 'pm10_dmean_wl_d3', 'pm25_dmean_wl', 'belaqi_forecast_chimv2022_d1', 'euaqi_d2', 'pm10_dmean_d1', + 'belaqi_wl_d3', 'belaqi_forecast_chimv2022_d0', 'o3_maxhmean_tf_d0', 'euaqi_d1', 'no2_maxhmean', + 'pm25_dmean_chimv2022_d2', 'belaqi_d2', 'pm25_dmean_d0', 'no2_maxhmean_tf_d0', 'pm10_dmean_tf_d0', + 'pm25_dmean_chimv2022_d0', 'o3_maxhmean_d0', 'pm10_dmean_tf_d1', 'pm10_dmean_vl', 'no2_maxhmean_tf_d1', + 'o3_maxhmean_tf_d2', 'pm10_dmean_wl_d0', 'no2_maxhmean_d1'} + + assert result == expected + + for f, d in product(ForecastFeature, range(4)): + assert f"{f.split(':')[1]}_d{d}" in result + + +async def test_aget_capabilities(): + session = get_mock_session(text_file='forecast_wms_capabilities.xml') + + client = IrcelineForecastClient(session) + _ = await client.get_capabilities() + + session.request.assert_called_once_with( + method='GET', + url=_forecast_wms_base_url, + params={"service": "WMS", + "version": "1.1.1", + "request": "GetCapabilities"}, + headers={'User-Agent': _user_agent} + ) + + +@freeze_time(datetime.fromisoformat("2024-06-30T13:00:21.520Z")) +async def test_api_forecast_error(): + pos = (50.4657, 4.8647) + session = get_mock_session('forecast_wms_feature_info_invalid.json') + + client = IrcelineForecastClient(session) + + features = [ForecastFeature.NO2_DMEAN, ForecastFeature.O3_MAXHMEAN] + result = await client.get_data(features, pos) + + for k, v in result.items(): + assert v == FeatureValue(timestamp=datetime.fromisoformat("2024-06-30T13:00:21.520Z"), value=None) + + +async def test_api_forecast_no_field(): + pos = (50.4657, 4.8647) + session = get_mock_session('forecast_wms_feature_info_no_field.json') + + client = IrcelineForecastClient(session) + + features = [ForecastFeature.NO2_DMEAN, ForecastFeature.O3_MAXHMEAN] + result = await client.get_data(features, pos) + + for k, v in result.items(): + assert v == FeatureValue(timestamp=None, value=None) + + +async def test_api_forecast(): + pos = (50.4657, 4.8647) + lat, lon = pos + session = get_mock_session('forecast_wms_feature_info.json') + + client = IrcelineForecastClient(session) + + features = [ForecastFeature.NO2_DMEAN, ForecastFeature.O3_MAXHMEAN] + _ = await client.get_data(features, pos) + + base = {"service": "WMS", + "version": "1.1.1", + "request": "GetFeatureInfo", + "info_format": "application/json", + "width": "1", + "height": "1", + "srs": "EPSG:4326", + "bbox": f"{lon},{lat},{lon + 0.00001},{lat + 0.00001}", + "X": "1", + "Y": "1"} + + calls = [call( + method='GET', + url=_forecast_wms_base_url, + params=base | {"layers": f"{feature}_d{d}", + "query_layers": f"{feature}_d{d}"}, + headers={'User-Agent': _user_agent}, + ) + for feature, d in product(features, range(4))] + + session.request.assert_has_calls(calls, any_order=True) + + +def test_parse_capabilities_with_error(): + result = IrcelineForecastClient._parse_capabilities("wow there no valid XML") + assert result == set()