from datetime import datetime from unittest.mock import AsyncMock, MagicMock from freezegun import freeze_time from homeassistant.core import HomeAssistant from pytest_homeassistant_custom_component.common import MockConfigEntry from custom_components.irm_kmi import IrmKmiCoordinator from custom_components.irm_kmi.binary_sensor import IrmKmiWarning from custom_components.irm_kmi.const import CONF_LANGUAGE_OVERRIDE from custom_components.irm_kmi.sensor import IrmKmiNextSunMove, IrmKmiNextWarning from tests.conftest import get_api_with_data, get_radar_animation_data @freeze_time(datetime.fromisoformat('2024-01-12T07:55:00+01:00')) async def test_warning_data( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: api = get_api_with_data("be_forecast_warning.json") coordinator = IrmKmiCoordinator(hass, mock_config_entry) result = api.get_warnings('en') coordinator.data = {'warnings': result} warning = IrmKmiWarning(coordinator, mock_config_entry) warning.hass = hass assert warning.is_on assert len(warning.extra_state_attributes['warnings']) == 2 for w in warning.extra_state_attributes['warnings']: assert w['is_active'] assert warning.extra_state_attributes['active_warnings_friendly_names'] == "Fog, Ice or snow" @freeze_time(datetime.fromisoformat('2024-01-12T07:55:00+01:00')) async def test_warning_data_unknown_lang( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: api = get_api_with_data("be_forecast_warning.json") coordinator = IrmKmiCoordinator(hass, mock_config_entry) api.get_pollen = AsyncMock() api.get_animation_data = MagicMock(return_value=get_radar_animation_data()) coordinator._api = api result = await coordinator.process_api_data() coordinator.data = {'warnings': result['warnings']} warning = IrmKmiWarning(coordinator, mock_config_entry) warning.hass = hass assert warning.is_on assert len(warning.extra_state_attributes['warnings']) == 2 for w in warning.extra_state_attributes['warnings']: assert w['is_active'] assert warning.extra_state_attributes['active_warnings_friendly_names'] == "Fog, Ice or snow" @freeze_time(datetime.fromisoformat('2024-01-11T20:00:00+01:00')) async def test_next_warning_when_data_available( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: api = get_api_with_data("be_forecast_warning.json") await hass.config_entries.async_add(mock_config_entry) hass.config_entries.async_update_entry(mock_config_entry, data=mock_config_entry.data | {CONF_LANGUAGE_OVERRIDE: 'de'}) coordinator = IrmKmiCoordinator(hass, mock_config_entry) api.get_pollen = AsyncMock() api.get_animation_data = MagicMock(return_value=get_radar_animation_data()) coordinator._api = api result = await coordinator.process_api_data() coordinator.data = {'warnings': result['warnings']} warning = IrmKmiNextWarning(coordinator, mock_config_entry) warning.hass = hass # This somehow fixes the following error that popped since 2024.12.0 # ValueError: Entity cannot have a translation key for # unit of measurement before being added to the entity platform warning._attr_translation_key = None assert warning.state == "2024-01-12T06:00:00+00:00" assert len(warning.extra_state_attributes['next_warnings']) == 2 assert warning.extra_state_attributes['next_warnings_friendly_names'] == "Nebel, Glätte" @freeze_time(datetime.fromisoformat('2024-01-12T07:30:00+01:00')) async def test_next_warning_none_when_only_active_warnings( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: api = get_api_with_data("be_forecast_warning.json") coordinator = IrmKmiCoordinator(hass, mock_config_entry) api.get_pollen = AsyncMock() api.get_animation_data = MagicMock(return_value=get_radar_animation_data()) coordinator._api = api result = await coordinator.process_api_data() coordinator.data = {'warnings': result['warnings']} warning = IrmKmiNextWarning(coordinator, mock_config_entry) warning.hass = hass # This somehow fixes the following error that popped since 2024.12.0 # ValueError: Entity cannot have a translation key for # unit of measurement before being added to the entity platform warning._attr_translation_key = None assert warning.state is None assert len(warning.extra_state_attributes['next_warnings']) == 0 assert warning.extra_state_attributes['next_warnings_friendly_names'] == "" @freeze_time(datetime.fromisoformat('2024-01-12T07:30:00+01:00')) async def test_next_warning_none_when_no_warnings( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: coordinator = IrmKmiCoordinator(hass, mock_config_entry) coordinator.data = {'warnings': []} warning = IrmKmiNextWarning(coordinator, mock_config_entry) warning.hass = hass # This somehow fixes the following error that popped since 2024.12.0 # ValueError: Entity cannot have a translation key for # unit of measurement before being added to the entity platform warning._attr_translation_key = None assert warning.state is None assert len(warning.extra_state_attributes['next_warnings']) == 0 assert warning.extra_state_attributes['next_warnings_friendly_names'] == "" coordinator.data = dict() warning = IrmKmiNextWarning(coordinator, mock_config_entry) warning.hass = hass # This somehow fixes the following error that popped since 2024.12.0 # ValueError: Entity cannot have a translation key for # unit of measurement before being added to the entity platform warning._attr_translation_key = None assert warning.state is None assert len(warning.extra_state_attributes['next_warnings']) == 0 assert warning.extra_state_attributes['next_warnings_friendly_names'] == "" @freeze_time(datetime.fromisoformat('2023-12-26T18:30:00+01:00')) async def test_next_sunrise_sunset( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: api = get_api_with_data("forecast.json") coordinator = IrmKmiCoordinator(hass, mock_config_entry) api.get_pollen = AsyncMock() api.get_animation_data = MagicMock(return_value=get_radar_animation_data()) coordinator._api = api result = await coordinator.process_api_data() coordinator.data = {'daily_forecast': result['daily_forecast']} sunset = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunset') sunrise = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunrise') # This somehow fixes the following error that popped since 2024.12.0 # ValueError: Entity cannot have a translation key for # unit of measurement before being added to the entity platform sunrise._attr_translation_key = None sunset._attr_translation_key = None assert datetime.fromisoformat(sunrise.state) == datetime.fromisoformat('2023-12-27T08:44:00+01:00') assert datetime.fromisoformat(sunset.state) == datetime.fromisoformat('2023-12-27T16:43:00+01:00') @freeze_time(datetime.fromisoformat('2023-12-26T15:30:00+01:00')) async def test_next_sunrise_sunset_bis( hass: HomeAssistant, mock_config_entry: MockConfigEntry ) -> None: api = get_api_with_data("forecast.json") coordinator = IrmKmiCoordinator(hass, mock_config_entry) api.get_pollen = AsyncMock() api.get_animation_data = MagicMock(return_value=get_radar_animation_data()) coordinator._api = api result = await coordinator.process_api_data() coordinator.data = {'daily_forecast': result['daily_forecast']} sunset = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunset') sunrise = IrmKmiNextSunMove(coordinator, mock_config_entry, 'sunrise') # This somehow fixes the following error that popped since 2024.12.0 # ValueError: Entity cannot have a translation key for # unit of measurement before being added to the entity platform sunrise._attr_translation_key = None sunset._attr_translation_key = None assert datetime.fromisoformat(sunrise.state) == datetime.fromisoformat('2023-12-27T08:44:00+01:00') assert datetime.fromisoformat(sunset.state) == datetime.fromisoformat('2023-12-26T16:42:00+01:00')