From 14390247e6e3cd5b7f8599a4bc5d51a75b7a652c Mon Sep 17 00:00:00 2001 From: YP30 <58120331+YP30@users.noreply.github.com> Date: Sun, 20 Sep 2026 17:12:29 +0200 Subject: [PATCH] Normalize test fixtures for irm_kmi (#182692) --- tests/components/irm_kmi/__init__.py | 14 +- tests/components/irm_kmi/conftest.py | 91 +- tests/components/irm_kmi/const.py | 15 + .../irm_kmi/snapshots/test_weather.ambr | 1262 ++++++++--------- tests/components/irm_kmi/test_config_flow.py | 94 +- tests/components/irm_kmi/test_init.py | 26 +- tests/components/irm_kmi/test_weather.py | 95 +- 7 files changed, 776 insertions(+), 821 deletions(-) create mode 100644 tests/components/irm_kmi/const.py diff --git a/tests/components/irm_kmi/__init__.py b/tests/components/irm_kmi/__init__.py index 629c80d5d9e8..8498864b3cc4 100644 --- a/tests/components/irm_kmi/__init__.py +++ b/tests/components/irm_kmi/__init__.py @@ -1 +1,13 @@ -"""Tests of IRM KMI integration.""" +"""Tests for the IRM KMI integration.""" + +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry + + +async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None: + """Set up the integration.""" + config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() diff --git a/tests/components/irm_kmi/conftest.py b/tests/components/irm_kmi/conftest.py index 078c7bc59550..61a835cc9fd2 100644 --- a/tests/components/irm_kmi/conftest.py +++ b/tests/components/irm_kmi/conftest.py @@ -1,9 +1,8 @@ """Fixtures for the IRM KMI integration tests.""" from collections.abc import Generator -from unittest.mock import MagicMock, patch +from unittest.mock import AsyncMock, MagicMock, patch -from irm_kmi_api import IrmKmiApiError import pytest from homeassistant.components.irm_kmi.const import DOMAIN @@ -14,6 +13,8 @@ from homeassistant.const import ( CONF_UNIQUE_ID, ) +from .const import CURRENT_WEATHER + from tests.common import MockConfigEntry, load_json_object_fixture @@ -21,13 +22,13 @@ from tests.common import MockConfigEntry, load_json_object_fixture def mock_config_entry() -> MockConfigEntry: """Return the default mocked config entry.""" return MockConfigEntry( - title="Home", + title="Brussels", domain=DOMAIN, data={ CONF_LOCATION: {ATTR_LATITUDE: 50.84, ATTR_LONGITUDE: 4.35}, - CONF_UNIQUE_ID: "city country", + CONF_UNIQUE_ID: "brussels be", }, - unique_id="50.84-4.35", + unique_id="brussels be", ) @@ -39,82 +40,40 @@ def mock_setup_entry() -> Generator[None]: @pytest.fixture -def mock_get_forecast_in_benelux(): - """Mock get_forecasts_coord() returning valid data in Benelux.""" +def mock_config_flow_forecast() -> Generator[AsyncMock]: + """Mock the config flow forecast fetch for a location in Belgium.""" with patch( "homeassistant.components.irm_kmi.config_flow.IrmKmiApiClient.get_forecasts_coord", return_value={"cityName": "Brussels", "country": "BE"}, - ): - yield + ) as get_forecasts_coord: + yield get_forecasts_coord @pytest.fixture -def mock_get_forecast_out_benelux_then_in_belgium(): - """Mock get_forecasts_coord() returning outside then inside Benelux.""" - with patch( - "homeassistant.components.irm_kmi.config_flow.IrmKmiApiClient.get_forecasts_coord", - side_effect=[ - {"cityName": "Outside the Benelux (Brussels)", "country": "BE"}, - {"cityName": "Brussels", "country": "BE"}, - ], - ): - yield - - -@pytest.fixture -def mock_get_forecast_api_error(): - """Mock get_forecasts_coord() so that it raises an error.""" - with patch( - "homeassistant.components.irm_kmi.config_flow.IrmKmiApiClient.get_forecasts_coord", - side_effect=IrmKmiApiError, - ): - yield - - -@pytest.fixture -def mock_irm_kmi_api(request: pytest.FixtureRequest) -> Generator[MagicMock]: - """Return a mocked IrmKmi api client.""" - fixture: str = "forecast.json" - - forecast = load_json_object_fixture(fixture, "irm_kmi") +def mock_irm_kmi_api() -> Generator[MagicMock]: + """Return a mocked IRM KMI client serving parsed data.""" with patch( "homeassistant.components.irm_kmi.IrmKmiApiClientHa", autospec=True ) as irm_kmi_api_mock: irm_kmi = irm_kmi_api_mock.return_value - irm_kmi.get_forecasts_coord.return_value = forecast + irm_kmi.get_country.return_value = "BE" + irm_kmi.get_current_weather.return_value = CURRENT_WEATHER + irm_kmi.get_daily_forecast.return_value = [] + irm_kmi.get_hourly_forecast.return_value = [] yield irm_kmi @pytest.fixture -def mock_irm_kmi_api_nl(): - """Mock get_forecasts_coord() to return a Netherlands forecast.""" - fixture: str = "forecast_nl.json" - forecast = load_json_object_fixture(fixture, "irm_kmi") - with patch( - "homeassistant.components.irm_kmi.coordinator.IrmKmiApiClientHa.get_forecasts_coord", - return_value=forecast, - ): - yield +def forecast_fixture() -> str: + """Return the name of the recorded forecast to serve.""" + return "forecast.json" @pytest.fixture -def mock_irm_kmi_api_high_low_temp(): - """Mock get_forecasts_coord() to return high_low_temp forecast.""" - fixture: str = "high_low_temp.json" - forecast = load_json_object_fixture(fixture, "irm_kmi") +def mock_get_forecasts_coord(forecast_fixture: str) -> Generator[AsyncMock]: + """Mock get_forecasts_coord() to return a recorded forecast.""" with patch( - "homeassistant.components.irm_kmi.coordinator.IrmKmiApiClientHa.get_forecasts_coord", - return_value=forecast, - ): - yield - - -@pytest.fixture -def mock_exception_irm_kmi_api(request: pytest.FixtureRequest) -> Generator[MagicMock]: - """Return a mocked IrmKmi api client that raises on refresh.""" - with patch( - "homeassistant.components.irm_kmi.IrmKmiApiClientHa", autospec=True - ) as irm_kmi_api_mock: - irm_kmi = irm_kmi_api_mock.return_value - irm_kmi.refresh_forecasts_coord.side_effect = IrmKmiApiError - yield irm_kmi + "homeassistant.components.irm_kmi.IrmKmiApiClientHa.get_forecasts_coord", + return_value=load_json_object_fixture(forecast_fixture, DOMAIN), + ) as get_forecasts_coord: + yield get_forecasts_coord diff --git a/tests/components/irm_kmi/const.py b/tests/components/irm_kmi/const.py new file mode 100644 index 000000000000..9ae16dce3dce --- /dev/null +++ b/tests/components/irm_kmi/const.py @@ -0,0 +1,15 @@ +"""Constants shared by the IRM KMI integration tests.""" + +from irm_kmi_api import CurrentWeatherData + +WEATHER_ENTITY_ID = "weather.brussels" + +CURRENT_WEATHER = CurrentWeatherData( + condition="cloudy", + temperature=7.2, + wind_speed=25.0, + wind_gust_speed=50.0, + wind_bearing=180.0, + uv_index=0.7, + pressure=1015.0, +) diff --git a/tests/components/irm_kmi/snapshots/test_weather.ambr b/tests/components/irm_kmi/snapshots/test_weather.ambr index 6c920f163691..8ca052609256 100644 --- a/tests/components/irm_kmi/snapshots/test_weather.ambr +++ b/tests/components/irm_kmi/snapshots/test_weather.ambr @@ -1,638 +1,630 @@ # serializer version: 1 -# name: test_forecast_service[daily] - dict({ - 'weather.home': dict({ - 'forecast': list([ - dict({ - 'condition': 'pouring', - 'condition_2': None, - 'condition_evol': , - 'datetime': '2023-12-28', - 'is_daytime': True, - 'precipitation': 0.1, - 'precipitation_probability': None, - 'sunrise': '2023-12-28T08:47:43+01:00', - 'sunset': '2023-12-28T16:34:06+01:00', - 'temperature': 11.0, - 'templow': 9.0, - 'text': ''' - Waarschuwingen - Vanavond zijn er in het noordwesten zware windstoten mogelijk van 75-90 km/uur (code geel). - - Vanochtend is het half bewolkt met in het noorden kans op een bui. De wind komt uit het zuidwesten en is matig tot vrij krachtig, aan de kust krachtig tot hard, windkracht 6-7, af en toe even stormachtig, windkracht 8. Aan de kust komen windstoten voor van ongeveer 80 km/uur. - Vanmiddag is het half tot zwaar bewolkt met kans op een bui, vooral in het noorden en westen. De middagtemperatuur ligt rond 11°C. De wind komt uit het zuidwesten en is meestal vrij krachtig, aan de kust krachtig tot hard, windkracht 6-7, vooral later ook af en toe stormachtig, windkracht 8. Aan de kust zijn er windstoten tot ongeveer 80 km/uur. - Vanavond zijn er buien, alleen in het zuidoosten is het overwegend droog. De wind komt uit het zuidwesten en is meestal vrij krachtig, aan de kust hard tot stormachtig, windkracht 7 tot 8. Vooral in het noordwesten zijn windstoten mogelijk van 75-90 km/uur. - - Komende nacht komen er enkele buien voor. Met een minimumtemperatuur van ongeveer 8°C is het zacht. De wind komt uit het zuidwesten en is matig tot vrij krachtig, aan zee krachtig tot hard, windkracht 6-7, met zware windstoten tot ongeveer 80 km/uur. - - Morgenochtend is het half tot zwaar bewolkt en zijn er enkele buien. De wind komt uit het zuidwesten en is matig tot vrij krachtig, aan zee krachtig hard, windkracht 6-7, met vooral in het noordwesten mogelijk zware windstoten tot ongeveer 80 km/uur. - Morgenmiddag is er af en toe ruimte voor de zon en blijft het op de meeste plaatsen droog, alleen in het zuidoosten kan een enkele bui vallen. Met middagtemperaturen van ongeveer 10°C blijft het zacht. De wind uit het zuidwesten is matig tot vrij krachtig, aan zee krachtig tot hard, windkracht 6-7, met in het Waddengebied zware windstoten tot ongeveer 80 km/uur. - Morgenavond is het half tot zwaar bewolkt met een enkele bui. De wind komt uit het zuidwesten en is meest matig, aan de kust krachtig tot hard, windkracht 6-7, boven de Wadden eerst stormachtig, windkracht 8. - (Bron: KNMI, 2023-12-28T06:56:00+01:00) +# name: test_forecast_service[daily-forecast_nl.json] + list([ + dict({ + 'condition': 'pouring', + 'condition_2': None, + 'condition_evol': , + 'datetime': '2023-12-28', + 'is_daytime': True, + 'precipitation': 0.1, + 'precipitation_probability': None, + 'sunrise': '2023-12-28T08:47:43+01:00', + 'sunset': '2023-12-28T16:34:06+01:00', + 'temperature': 11.0, + 'templow': 9.0, + 'text': ''' + Waarschuwingen + Vanavond zijn er in het noordwesten zware windstoten mogelijk van 75-90 km/uur (code geel). + + Vanochtend is het half bewolkt met in het noorden kans op een bui. De wind komt uit het zuidwesten en is matig tot vrij krachtig, aan de kust krachtig tot hard, windkracht 6-7, af en toe even stormachtig, windkracht 8. Aan de kust komen windstoten voor van ongeveer 80 km/uur. + Vanmiddag is het half tot zwaar bewolkt met kans op een bui, vooral in het noorden en westen. De middagtemperatuur ligt rond 11°C. De wind komt uit het zuidwesten en is meestal vrij krachtig, aan de kust krachtig tot hard, windkracht 6-7, vooral later ook af en toe stormachtig, windkracht 8. Aan de kust zijn er windstoten tot ongeveer 80 km/uur. + Vanavond zijn er buien, alleen in het zuidoosten is het overwegend droog. De wind komt uit het zuidwesten en is meestal vrij krachtig, aan de kust hard tot stormachtig, windkracht 7 tot 8. Vooral in het noordwesten zijn windstoten mogelijk van 75-90 km/uur. + + Komende nacht komen er enkele buien voor. Met een minimumtemperatuur van ongeveer 8°C is het zacht. De wind komt uit het zuidwesten en is matig tot vrij krachtig, aan zee krachtig tot hard, windkracht 6-7, met zware windstoten tot ongeveer 80 km/uur. + + Morgenochtend is het half tot zwaar bewolkt en zijn er enkele buien. De wind komt uit het zuidwesten en is matig tot vrij krachtig, aan zee krachtig hard, windkracht 6-7, met vooral in het noordwesten mogelijk zware windstoten tot ongeveer 80 km/uur. + Morgenmiddag is er af en toe ruimte voor de zon en blijft het op de meeste plaatsen droog, alleen in het zuidoosten kan een enkele bui vallen. Met middagtemperaturen van ongeveer 10°C blijft het zacht. De wind uit het zuidwesten is matig tot vrij krachtig, aan zee krachtig tot hard, windkracht 6-7, met in het Waddengebied zware windstoten tot ongeveer 80 km/uur. + Morgenavond is het half tot zwaar bewolkt met een enkele bui. De wind komt uit het zuidwesten en is meest matig, aan de kust krachtig tot hard, windkracht 6-7, boven de Wadden eerst stormachtig, windkracht 8. + (Bron: KNMI, 2023-12-28T06:56:00+01:00) - ''', - 'wind_bearing': 225.0, - 'wind_gust_speed': 33.0, - 'wind_speed': 32.0, - }), - dict({ - 'condition': 'partlycloudy', - 'condition_2': None, - 'condition_evol': , - 'datetime': '2023-12-29', - 'is_daytime': True, - 'precipitation': 3.8, - 'precipitation_probability': None, - 'sunrise': '2023-12-29T08:47:48+01:00', - 'sunset': '2023-12-29T16:35:00+01:00', - 'temperature': 10.0, - 'text': '', - 'wind_bearing': 248.0, - 'wind_gust_speed': 28.0, - 'wind_speed': 26.0, - }), - dict({ - 'condition': 'pouring', - 'condition_2': None, - 'condition_evol': , - 'datetime': '2023-12-30', - 'is_daytime': True, - 'precipitation': 1.7, - 'precipitation_probability': None, - 'sunrise': '2023-12-30T08:47:49+01:00', - 'sunset': '2023-12-30T16:35:57+01:00', - 'temperature': 10.0, - 'templow': 5.0, - 'text': '', - 'wind_bearing': 225.0, - 'wind_gust_speed': 25.0, - 'wind_speed': 22.0, - }), - dict({ - 'condition': 'pouring', - 'condition_2': None, - 'condition_evol': , - 'datetime': '2023-12-31', - 'is_daytime': True, - 'precipitation': 4.2, - 'precipitation_probability': None, - 'sunrise': '2023-12-31T08:47:47+01:00', - 'sunset': '2023-12-31T16:36:56+01:00', - 'temperature': 9.0, - 'templow': 7.0, - 'text': '', - 'wind_bearing': 203.0, - 'wind_gust_speed': 31.0, - 'wind_speed': 30.0, - }), - dict({ - 'condition': 'pouring', - 'condition_2': None, - 'condition_evol': , - 'datetime': '2024-01-01', - 'is_daytime': True, - 'precipitation': 2.2, - 'precipitation_probability': None, - 'sunrise': '2024-01-01T08:47:42+01:00', - 'sunset': '2024-01-01T16:37:59+01:00', - 'temperature': 7.0, - 'templow': 5.0, - 'text': '', - 'wind_bearing': 225.0, - 'wind_gust_speed': 28.0, - 'wind_speed': 23.0, - }), - dict({ - 'condition': 'pouring', - 'condition_2': None, - 'condition_evol': , - 'datetime': '2024-01-02', - 'is_daytime': True, - 'precipitation': 1.4, - 'precipitation_probability': None, - 'sunrise': '2024-01-02T08:47:32+01:00', - 'sunset': '2024-01-02T16:39:04+01:00', - 'temperature': 6.0, - 'templow': 3.0, - 'text': '', - 'wind_bearing': 225.0, - 'wind_gust_speed': 16.0, - 'wind_speed': 15.0, - }), - dict({ - 'condition': 'pouring', - 'condition_2': None, - 'condition_evol': , - 'datetime': '2024-01-03', - 'is_daytime': True, - 'precipitation': 1.0, - 'precipitation_probability': None, - 'sunrise': '2024-01-03T08:47:20+01:00', - 'sunset': '2024-01-03T16:40:12+01:00', - 'temperature': 6.0, - 'templow': 3.0, - 'text': '', - 'wind_bearing': 203.0, - 'wind_gust_speed': 14.0, - 'wind_speed': 13.0, - }), - ]), + ''', + 'wind_bearing': 225.0, + 'wind_gust_speed': 33.0, + 'wind_speed': 32.0, }), - }) -# --- -# name: test_forecast_service[hourly] - dict({ - 'weather.home': dict({ - 'forecast': list([ - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-22T15:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1008.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 33.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-22T16:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1008.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 32.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-22T17:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1007.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 32.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-22T18:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1007.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-22T19:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-22T20:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-22T21:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'pouring', - 'datetime': '2025-09-22T22:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.7, - 'precipitation_probability': 70, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'pouring', - 'datetime': '2025-09-22T23:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.1, - 'precipitation_probability': 10, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 37.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-23T00:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 20, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'pouring', - 'datetime': '2025-09-23T01:00:00+02:00', - 'is_daytime': False, - 'precipitation': 1.9, - 'precipitation_probability': 80, - 'pressure': 1005.0, - 'temperature': 10.0, - 'wind_bearing': 225.0, - 'wind_speed': 31.0, - }), - dict({ - 'condition': 'pouring', - 'datetime': '2025-09-23T02:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.6, - 'precipitation_probability': 70, - 'pressure': 1005.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 38.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T03:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-23T04:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 34.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T05:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 9.0, - 'wind_bearing': 248.0, - 'wind_speed': 35.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-23T06:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 9.0, - 'wind_bearing': 248.0, - 'wind_speed': 34.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T07:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 9.0, - 'wind_bearing': 248.0, - 'wind_speed': 32.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T08:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 9.0, - 'wind_bearing': 248.0, - 'wind_speed': 31.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T09:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 9.0, - 'wind_bearing': 248.0, - 'wind_speed': 31.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-23T10:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 9.0, - 'wind_bearing': 248.0, - 'wind_speed': 32.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T11:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 32.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T12:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 34.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T13:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 33.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T14:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 31.0, - }), - dict({ - 'condition': 'sunny', - 'datetime': '2025-09-23T15:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 10.0, - 'wind_bearing': 248.0, - 'wind_speed': 28.0, - }), - dict({ - 'condition': 'sunny', - 'datetime': '2025-09-23T16:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 9.0, - 'wind_bearing': 248.0, - 'wind_speed': 24.0, - }), - dict({ - 'condition': 'clear-night', - 'datetime': '2025-09-23T17:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 8.0, - 'wind_bearing': 225.0, - 'wind_speed': 20.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T18:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 8.0, - 'wind_bearing': 225.0, - 'wind_speed': 18.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-23T19:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1005.0, - 'temperature': 8.0, - 'wind_bearing': 203.0, - 'wind_speed': 15.0, - }), - dict({ - 'condition': 'pouring', - 'datetime': '2025-09-23T20:00:00+02:00', - 'is_daytime': False, - 'precipitation': 5.7, - 'precipitation_probability': 100, - 'pressure': 1005.0, - 'temperature': 8.0, - 'wind_bearing': 248.0, - 'wind_speed': 22.0, - }), - dict({ - 'condition': 'pouring', - 'datetime': '2025-09-23T21:00:00+02:00', - 'is_daytime': False, - 'precipitation': 3.8, - 'precipitation_probability': 100, - 'pressure': 1006.0, - 'temperature': 7.0, - 'wind_bearing': 270.0, - 'wind_speed': 26.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-23T22:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1006.0, - 'temperature': 8.0, - 'wind_bearing': 248.0, - 'wind_speed': 24.0, - }), - dict({ - 'condition': 'cloudy', - 'datetime': '2025-09-23T23:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1007.0, - 'temperature': 7.0, - 'wind_bearing': 248.0, - 'wind_speed': 22.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-24T00:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1008.0, - 'temperature': 8.0, - 'wind_bearing': 270.0, - 'wind_speed': 26.0, - }), - dict({ - 'condition': 'clear-night', - 'datetime': '2025-09-24T01:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1007.0, - 'temperature': 7.0, - 'wind_bearing': 270.0, - 'wind_speed': 26.0, - }), - dict({ - 'condition': 'clear-night', - 'datetime': '2025-09-24T02:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1008.0, - 'temperature': 7.0, - 'wind_bearing': 270.0, - 'wind_speed': 24.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-24T03:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1008.0, - 'temperature': 7.0, - 'wind_bearing': 270.0, - 'wind_speed': 24.0, - }), - dict({ - 'condition': 'clear-night', - 'datetime': '2025-09-24T04:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1009.0, - 'temperature': 7.0, - 'wind_bearing': 248.0, - 'wind_speed': 23.0, - }), - dict({ - 'condition': 'clear-night', - 'datetime': '2025-09-24T05:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1009.0, - 'temperature': 6.0, - 'wind_bearing': 248.0, - 'wind_speed': 23.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-24T06:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1009.0, - 'temperature': 6.0, - 'wind_bearing': 248.0, - 'wind_speed': 21.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-24T07:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1010.0, - 'temperature': 6.0, - 'wind_bearing': 248.0, - 'wind_speed': 20.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-24T08:00:00+02:00', - 'is_daytime': False, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1011.0, - 'temperature': 6.0, - 'wind_bearing': 248.0, - 'wind_speed': 17.0, - }), - dict({ - 'condition': 'sunny', - 'datetime': '2025-09-24T09:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1011.0, - 'temperature': 6.0, - 'wind_bearing': 248.0, - 'wind_speed': 13.0, - }), - dict({ - 'condition': 'partlycloudy', - 'datetime': '2025-09-24T10:00:00+02:00', - 'is_daytime': True, - 'precipitation': 0.0, - 'precipitation_probability': 0, - 'pressure': 1012.0, - 'temperature': 5.0, - 'wind_bearing': 225.0, - 'wind_speed': 12.0, - }), - ]), + dict({ + 'condition': 'partlycloudy', + 'condition_2': None, + 'condition_evol': , + 'datetime': '2023-12-29', + 'is_daytime': True, + 'precipitation': 3.8, + 'precipitation_probability': None, + 'sunrise': '2023-12-29T08:47:48+01:00', + 'sunset': '2023-12-29T16:35:00+01:00', + 'temperature': 10.0, + 'text': '', + 'wind_bearing': 248.0, + 'wind_gust_speed': 28.0, + 'wind_speed': 26.0, }), - }) + dict({ + 'condition': 'pouring', + 'condition_2': None, + 'condition_evol': , + 'datetime': '2023-12-30', + 'is_daytime': True, + 'precipitation': 1.7, + 'precipitation_probability': None, + 'sunrise': '2023-12-30T08:47:49+01:00', + 'sunset': '2023-12-30T16:35:57+01:00', + 'temperature': 10.0, + 'templow': 5.0, + 'text': '', + 'wind_bearing': 225.0, + 'wind_gust_speed': 25.0, + 'wind_speed': 22.0, + }), + dict({ + 'condition': 'pouring', + 'condition_2': None, + 'condition_evol': , + 'datetime': '2023-12-31', + 'is_daytime': True, + 'precipitation': 4.2, + 'precipitation_probability': None, + 'sunrise': '2023-12-31T08:47:47+01:00', + 'sunset': '2023-12-31T16:36:56+01:00', + 'temperature': 9.0, + 'templow': 7.0, + 'text': '', + 'wind_bearing': 203.0, + 'wind_gust_speed': 31.0, + 'wind_speed': 30.0, + }), + dict({ + 'condition': 'pouring', + 'condition_2': None, + 'condition_evol': , + 'datetime': '2024-01-01', + 'is_daytime': True, + 'precipitation': 2.2, + 'precipitation_probability': None, + 'sunrise': '2024-01-01T08:47:42+01:00', + 'sunset': '2024-01-01T16:37:59+01:00', + 'temperature': 7.0, + 'templow': 5.0, + 'text': '', + 'wind_bearing': 225.0, + 'wind_gust_speed': 28.0, + 'wind_speed': 23.0, + }), + dict({ + 'condition': 'pouring', + 'condition_2': None, + 'condition_evol': , + 'datetime': '2024-01-02', + 'is_daytime': True, + 'precipitation': 1.4, + 'precipitation_probability': None, + 'sunrise': '2024-01-02T08:47:32+01:00', + 'sunset': '2024-01-02T16:39:04+01:00', + 'temperature': 6.0, + 'templow': 3.0, + 'text': '', + 'wind_bearing': 225.0, + 'wind_gust_speed': 16.0, + 'wind_speed': 15.0, + }), + dict({ + 'condition': 'pouring', + 'condition_2': None, + 'condition_evol': , + 'datetime': '2024-01-03', + 'is_daytime': True, + 'precipitation': 1.0, + 'precipitation_probability': None, + 'sunrise': '2024-01-03T08:47:20+01:00', + 'sunset': '2024-01-03T16:40:12+01:00', + 'temperature': 6.0, + 'templow': 3.0, + 'text': '', + 'wind_bearing': 203.0, + 'wind_gust_speed': 14.0, + 'wind_speed': 13.0, + }), + ]) # --- -# name: test_weather_nl[weather.home-entry] +# name: test_forecast_service[hourly-forecast_nl.json] + list([ + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-22T15:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1008.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 33.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-22T16:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1008.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 32.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-22T17:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1007.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 32.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-22T18:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1007.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-22T19:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-22T20:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-22T21:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'pouring', + 'datetime': '2025-09-22T22:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.7, + 'precipitation_probability': 70, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'pouring', + 'datetime': '2025-09-22T23:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.1, + 'precipitation_probability': 10, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 37.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-23T00:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 20, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'pouring', + 'datetime': '2025-09-23T01:00:00+02:00', + 'is_daytime': False, + 'precipitation': 1.9, + 'precipitation_probability': 80, + 'pressure': 1005.0, + 'temperature': 10.0, + 'wind_bearing': 225.0, + 'wind_speed': 31.0, + }), + dict({ + 'condition': 'pouring', + 'datetime': '2025-09-23T02:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.6, + 'precipitation_probability': 70, + 'pressure': 1005.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 38.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T03:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-23T04:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 34.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T05:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 9.0, + 'wind_bearing': 248.0, + 'wind_speed': 35.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-23T06:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 9.0, + 'wind_bearing': 248.0, + 'wind_speed': 34.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T07:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 9.0, + 'wind_bearing': 248.0, + 'wind_speed': 32.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T08:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 9.0, + 'wind_bearing': 248.0, + 'wind_speed': 31.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T09:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 9.0, + 'wind_bearing': 248.0, + 'wind_speed': 31.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-23T10:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 9.0, + 'wind_bearing': 248.0, + 'wind_speed': 32.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T11:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 32.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T12:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 34.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T13:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 33.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T14:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 31.0, + }), + dict({ + 'condition': 'sunny', + 'datetime': '2025-09-23T15:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 10.0, + 'wind_bearing': 248.0, + 'wind_speed': 28.0, + }), + dict({ + 'condition': 'sunny', + 'datetime': '2025-09-23T16:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 9.0, + 'wind_bearing': 248.0, + 'wind_speed': 24.0, + }), + dict({ + 'condition': 'clear-night', + 'datetime': '2025-09-23T17:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 8.0, + 'wind_bearing': 225.0, + 'wind_speed': 20.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T18:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 8.0, + 'wind_bearing': 225.0, + 'wind_speed': 18.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-23T19:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1005.0, + 'temperature': 8.0, + 'wind_bearing': 203.0, + 'wind_speed': 15.0, + }), + dict({ + 'condition': 'pouring', + 'datetime': '2025-09-23T20:00:00+02:00', + 'is_daytime': False, + 'precipitation': 5.7, + 'precipitation_probability': 100, + 'pressure': 1005.0, + 'temperature': 8.0, + 'wind_bearing': 248.0, + 'wind_speed': 22.0, + }), + dict({ + 'condition': 'pouring', + 'datetime': '2025-09-23T21:00:00+02:00', + 'is_daytime': False, + 'precipitation': 3.8, + 'precipitation_probability': 100, + 'pressure': 1006.0, + 'temperature': 7.0, + 'wind_bearing': 270.0, + 'wind_speed': 26.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-23T22:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1006.0, + 'temperature': 8.0, + 'wind_bearing': 248.0, + 'wind_speed': 24.0, + }), + dict({ + 'condition': 'cloudy', + 'datetime': '2025-09-23T23:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1007.0, + 'temperature': 7.0, + 'wind_bearing': 248.0, + 'wind_speed': 22.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-24T00:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1008.0, + 'temperature': 8.0, + 'wind_bearing': 270.0, + 'wind_speed': 26.0, + }), + dict({ + 'condition': 'clear-night', + 'datetime': '2025-09-24T01:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1007.0, + 'temperature': 7.0, + 'wind_bearing': 270.0, + 'wind_speed': 26.0, + }), + dict({ + 'condition': 'clear-night', + 'datetime': '2025-09-24T02:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1008.0, + 'temperature': 7.0, + 'wind_bearing': 270.0, + 'wind_speed': 24.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-24T03:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1008.0, + 'temperature': 7.0, + 'wind_bearing': 270.0, + 'wind_speed': 24.0, + }), + dict({ + 'condition': 'clear-night', + 'datetime': '2025-09-24T04:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1009.0, + 'temperature': 7.0, + 'wind_bearing': 248.0, + 'wind_speed': 23.0, + }), + dict({ + 'condition': 'clear-night', + 'datetime': '2025-09-24T05:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1009.0, + 'temperature': 6.0, + 'wind_bearing': 248.0, + 'wind_speed': 23.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-24T06:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1009.0, + 'temperature': 6.0, + 'wind_bearing': 248.0, + 'wind_speed': 21.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-24T07:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1010.0, + 'temperature': 6.0, + 'wind_bearing': 248.0, + 'wind_speed': 20.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-24T08:00:00+02:00', + 'is_daytime': False, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1011.0, + 'temperature': 6.0, + 'wind_bearing': 248.0, + 'wind_speed': 17.0, + }), + dict({ + 'condition': 'sunny', + 'datetime': '2025-09-24T09:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1011.0, + 'temperature': 6.0, + 'wind_bearing': 248.0, + 'wind_speed': 13.0, + }), + dict({ + 'condition': 'partlycloudy', + 'datetime': '2025-09-24T10:00:00+02:00', + 'is_daytime': True, + 'precipitation': 0.0, + 'precipitation_probability': 0, + 'pressure': 1012.0, + 'temperature': 5.0, + 'wind_bearing': 225.0, + 'wind_speed': 12.0, + }), + ]) +# --- +# name: test_weather_nl[forecast_nl.json][weather.brussels-entry] EntityRegistryEntrySnapshot({ 'aliases': list([ None, @@ -646,7 +638,7 @@ 'disabled_by': None, 'domain': 'weather', 'entity_category': None, - 'entity_id': 'weather.home', + 'entity_id': 'weather.brussels', 'has_entity_name': True, 'hidden_by': None, 'icon': None, @@ -665,15 +657,15 @@ 'suggested_object_id': None, 'supported_features': , 'translation_key': None, - 'unique_id': 'city country', + 'unique_id': 'brussels be', 'unit_of_measurement': None, }) # --- -# name: test_weather_nl[weather.home-state] +# name: test_weather_nl[forecast_nl.json][weather.brussels-state] StateSnapshot({ 'attributes': ReadOnlyDict({ : 'Weather data from the Royal Meteorological Institute of Belgium meteo.be', - : 'Home', + : 'Brussels', : , : 1008.0, : , @@ -687,7 +679,7 @@ : , }), 'context': , - 'entity_id': 'weather.home', + 'entity_id': 'weather.brussels', 'last_changed': , 'last_reported': , 'last_updated': , diff --git a/tests/components/irm_kmi/test_config_flow.py b/tests/components/irm_kmi/test_config_flow.py index e46f6bc8904b..301aa323e202 100644 --- a/tests/components/irm_kmi/test_config_flow.py +++ b/tests/components/irm_kmi/test_config_flow.py @@ -1,7 +1,8 @@ """Tests for the IRM KMI config flow.""" -from unittest.mock import MagicMock +from unittest.mock import AsyncMock +from irm_kmi_api import IrmKmiApiError import pytest from homeassistant.components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE, DOMAIN @@ -15,55 +16,43 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType -from tests.common import MockConfigEntry +from tests.common import MockConfigEntry, async_load_json_object_fixture -@pytest.mark.usefixtures("mock_setup_entry") -async def test_full_user_flow( - hass: HomeAssistant, mock_get_forecast_in_benelux: MagicMock -) -> None: +@pytest.mark.usefixtures("mock_setup_entry", "mock_config_flow_forecast") +async def test_full_user_flow(hass: HomeAssistant) -> None: """Test the full user configuration flow.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) - assert result.get("type") is FlowResultType.FORM - assert result.get("step_id") == "user" + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={CONF_LOCATION: {ATTR_LATITUDE: 50.123, ATTR_LONGITUDE: 4.456}}, ) - assert result.get("type") is FlowResultType.CREATE_ENTRY - assert result.get("title") == "Brussels" - assert result.get("data") == { + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Brussels" + assert result["data"] == { CONF_LOCATION: {ATTR_LATITUDE: 50.123, ATTR_LONGITUDE: 4.456}, CONF_UNIQUE_ID: "brussels be", } - - -@pytest.mark.usefixtures("mock_setup_entry") -async def test_user_flow_home( - hass: HomeAssistant, mock_get_forecast_in_benelux: MagicMock -) -> None: - """Test the full user configuration flow.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_USER} - ) - - result = await hass.config_entries.flow.async_configure( - result["flow_id"], - user_input={CONF_LOCATION: {ATTR_LATITUDE: 50.123, ATTR_LONGITUDE: 4.456}}, - ) - assert result.get("type") is FlowResultType.CREATE_ENTRY - assert result.get("title") == "Brussels" + assert result["result"].unique_id == "brussels be" @pytest.mark.usefixtures("mock_setup_entry") async def test_config_flow_location_out_benelux( - hass: HomeAssistant, mock_get_forecast_out_benelux_then_in_belgium: MagicMock + hass: HomeAssistant, mock_config_flow_forecast: AsyncMock ) -> None: - """Test configuration flow with a zone outside of Benelux.""" + """Test configuration flow with a location outside of Benelux.""" + mock_config_flow_forecast.side_effect = [ + await async_load_json_object_fixture( + hass, "forecast_out_of_benelux.json", DOMAIN + ), + mock_config_flow_forecast.return_value, + ] result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) @@ -73,22 +62,24 @@ async def test_config_flow_location_out_benelux( user_input={CONF_LOCATION: {ATTR_LATITUDE: 0.123, ATTR_LONGITUDE: 0.456}}, ) - assert result.get("type") is FlowResultType.FORM - assert result.get("step_id") == "user" - assert CONF_LOCATION in result.get("errors") + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + assert result["errors"] == {CONF_LOCATION: "out_of_benelux"} result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={CONF_LOCATION: {ATTR_LATITUDE: 50.123, ATTR_LONGITUDE: 4.456}}, ) - assert result.get("type") is FlowResultType.CREATE_ENTRY + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "Brussels" @pytest.mark.usefixtures("mock_setup_entry") async def test_config_flow_with_api_error( - hass: HomeAssistant, mock_get_forecast_api_error: MagicMock + hass: HomeAssistant, mock_config_flow_forecast: AsyncMock ) -> None: """Test when API returns an error during the configuration flow.""" + mock_config_flow_forecast.side_effect = IrmKmiApiError result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) @@ -98,34 +89,27 @@ async def test_config_flow_with_api_error( user_input={CONF_LOCATION: {ATTR_LATITUDE: 50.123, ATTR_LONGITUDE: 4.456}}, ) - assert result.get("type") is FlowResultType.ABORT + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "api_error" -@pytest.mark.usefixtures("mock_setup_entry") -async def test_setup_twice_same_location( - hass: HomeAssistant, mock_get_forecast_in_benelux: MagicMock +@pytest.mark.usefixtures("mock_setup_entry", "mock_config_flow_forecast") +async def test_flow_already_configured( + hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: - """Test when the user tries to set up the weather twice for the same location.""" + """Test the flow aborts when the location is already configured.""" + mock_config_entry.add_to_hass(hass) + result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) result = await hass.config_entries.flow.async_configure( result["flow_id"], - user_input={CONF_LOCATION: {ATTR_LATITUDE: 50.5, ATTR_LONGITUDE: 4.6}}, + user_input={CONF_LOCATION: {ATTR_LATITUDE: 50.123, ATTR_LONGITUDE: 4.456}}, ) - assert result.get("type") is FlowResultType.CREATE_ENTRY - - # Set up a second time - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_USER} - ) - - result = await hass.config_entries.flow.async_configure( - result["flow_id"], - user_input={CONF_LOCATION: {ATTR_LATITUDE: 50.5, ATTR_LONGITUDE: 4.6}}, - ) - assert result.get("type") is FlowResultType.ABORT + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured" async def test_option_flow( @@ -136,9 +120,7 @@ async def test_option_flow( assert not mock_config_entry.options - result = await hass.config_entries.options.async_init( - mock_config_entry.entry_id, data=None - ) + result = await hass.config_entries.options.async_init(mock_config_entry.entry_id) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "init" diff --git a/tests/components/irm_kmi/test_init.py b/tests/components/irm_kmi/test_init.py index 4fa310ab81a8..8adedfdda389 100644 --- a/tests/components/irm_kmi/test_init.py +++ b/tests/components/irm_kmi/test_init.py @@ -1,43 +1,43 @@ """Tests for the IRM KMI integration.""" -from unittest.mock import AsyncMock +from unittest.mock import MagicMock + +from irm_kmi_api import IrmKmiApiError +import pytest -from homeassistant.components.irm_kmi.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant +from . import setup_integration + from tests.common import MockConfigEntry +@pytest.mark.usefixtures("mock_irm_kmi_api") async def test_load_unload_config_entry( hass: HomeAssistant, mock_config_entry: MockConfigEntry, - mock_irm_kmi_api: AsyncMock, ) -> None: """Test the IRM KMI configuration entry loading/unloading.""" - mock_config_entry.add_to_hass(hass) - - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() + await setup_integration(hass, mock_config_entry) assert mock_config_entry.state is ConfigEntryState.LOADED await hass.config_entries.async_unload(mock_config_entry.entry_id) await hass.async_block_till_done() - assert not hass.data.get(DOMAIN) assert mock_config_entry.state is ConfigEntryState.NOT_LOADED async def test_config_entry_not_ready( hass: HomeAssistant, mock_config_entry: MockConfigEntry, - mock_exception_irm_kmi_api: AsyncMock, + mock_irm_kmi_api: MagicMock, ) -> None: """Test the IRM KMI configuration entry not ready.""" - mock_config_entry.add_to_hass(hass) - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() + mock_irm_kmi_api.refresh_forecasts_coord.side_effect = IrmKmiApiError - assert mock_exception_irm_kmi_api.refresh_forecasts_coord.call_count == 1 + await setup_integration(hass, mock_config_entry) + + assert mock_irm_kmi_api.refresh_forecasts_coord.call_count == 1 assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY diff --git a/tests/components/irm_kmi/test_weather.py b/tests/components/irm_kmi/test_weather.py index 44456f4f4b96..7b9ea4d44ddc 100644 --- a/tests/components/irm_kmi/test_weather.py +++ b/tests/components/irm_kmi/test_weather.py @@ -1,6 +1,6 @@ """Test for the weather entity of the IRM KMI integration.""" -from unittest.mock import AsyncMock +from typing import Any import pytest from syrupy.assertion import SnapshotAssertion @@ -13,26 +13,46 @@ from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant import homeassistant.helpers.entity_registry as er +from . import setup_integration +from .const import WEATHER_ENTITY_ID + from tests.common import MockConfigEntry, snapshot_platform +async def _get_forecast( + hass: HomeAssistant, forecast_type: str +) -> list[dict[str, Any]]: + """Return the forecast from weather.get_forecasts.""" + response = await hass.services.async_call( + WEATHER_DOMAIN, + SERVICE_GET_FORECASTS, + { + ATTR_ENTITY_ID: WEATHER_ENTITY_ID, + "type": forecast_type, + }, + blocking=True, + return_response=True, + ) + return response[WEATHER_ENTITY_ID]["forecast"] + + +@pytest.mark.usefixtures("mock_get_forecasts_coord") +@pytest.mark.parametrize("forecast_fixture", ["forecast_nl.json"]) @pytest.mark.freeze_time("2023-12-28T15:30:00+01:00") async def test_weather_nl( hass: HomeAssistant, mock_config_entry: MockConfigEntry, - mock_irm_kmi_api_nl: AsyncMock, snapshot: SnapshotAssertion, entity_registry: er.EntityRegistry, ) -> None: """Test weather with forecast from the Netherland.""" - mock_config_entry.add_to_hass(hass) - - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() + await setup_integration(hass, mock_config_entry) await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) +@pytest.mark.usefixtures("mock_get_forecasts_coord") +@pytest.mark.parametrize("forecast_fixture", ["forecast_nl.json"]) @pytest.mark.parametrize( "forecast_type", ["daily", "hourly"], @@ -41,60 +61,35 @@ async def test_weather_nl( async def test_forecast_service( hass: HomeAssistant, snapshot: SnapshotAssertion, - mock_irm_kmi_api_nl: AsyncMock, mock_config_entry: MockConfigEntry, forecast_type: str, ) -> None: """Test multiple forecast.""" - mock_config_entry.add_to_hass(hass) + await setup_integration(hass, mock_config_entry) - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() - - response = await hass.services.async_call( - WEATHER_DOMAIN, - SERVICE_GET_FORECASTS, - { - ATTR_ENTITY_ID: "weather.home", - "type": forecast_type, - }, - blocking=True, - return_response=True, - ) - assert response == snapshot + assert await _get_forecast(hass, forecast_type) == snapshot +@pytest.mark.usefixtures("mock_get_forecasts_coord") +@pytest.mark.parametrize("forecast_fixture", ["high_low_temp.json"]) @pytest.mark.freeze_time("2024-01-21T14:15:00+01:00") -@pytest.mark.parametrize( - "forecast_type", - ["daily", "hourly"], -) -async def test_weather_higher_temp_at_night( +async def test_daily_forecast_night_low_above_day_high( hass: HomeAssistant, mock_config_entry: MockConfigEntry, - mock_irm_kmi_api_high_low_temp: AsyncMock, - forecast_type: str, ) -> None: - """Test templow is always lower than temperature.""" + """Test a night low above the day high is swapped into the first day.""" # Test case for https://github.com/jdejaegh/irm-kmi-ha/issues/8 - mock_config_entry.add_to_hass(hass) + await setup_integration(hass, mock_config_entry) - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() - - response = await hass.services.async_call( - WEATHER_DOMAIN, - SERVICE_GET_FORECASTS, - { - ATTR_ENTITY_ID: "weather.home", - "type": forecast_type, - }, - blocking=True, - return_response=True, - ) - for forecast in response["weather.home"]["forecast"]: - assert ( - forecast.get("native_temperature") is None - or forecast.get("native_templow") is None - or forecast["native_temperature"] >= forecast["native_templow"] - ) + assert [ + (forecast["temperature"], forecast["templow"]) + for forecast in await _get_forecast(hass, "daily") + ] == [ + (4.0, 3.0), + (10.0, 1.0), + (8.0, 3.0), + (12.0, 10.0), + (8.0, 2.0), + (8.0, 6.0), + (6.0, -2.0), + ]