diff --git a/homeassistant/components/islamic_prayer_times/__init__.py b/homeassistant/components/islamic_prayer_times/__init__.py index 7fd5ed4129f..95a7db632b1 100644 --- a/homeassistant/components/islamic_prayer_times/__init__.py +++ b/homeassistant/components/islamic_prayer_times/__init__.py @@ -1,22 +1,13 @@ """The islamic_prayer_times component.""" -from datetime import timedelta -import logging - -from prayer_times_calculator import PrayerTimesCalculator, exceptions -from requests.exceptions import ConnectionError as ConnError +from __future__ import annotations from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.dispatcher import async_dispatcher_send -from homeassistant.helpers.event import async_call_later, async_track_point_in_time -import homeassistant.util.dt as dt_util -from .const import CONF_CALC_METHOD, DATA_UPDATED, DEFAULT_CALC_METHOD, DOMAIN - -_LOGGER = logging.getLogger(__name__) +from .const import DOMAIN +from .coordinator import IslamicPrayerDataUpdateCoordinator PLATFORMS = [Platform.SENSOR] @@ -25,154 +16,32 @@ CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Set up the Islamic Prayer Component.""" - client = IslamicPrayerClient(hass, config_entry) - hass.data[DOMAIN] = client - await client.async_setup() + coordinator = IslamicPrayerDataUpdateCoordinator(hass) + await coordinator.async_config_entry_first_refresh() + + hass.data.setdefault(DOMAIN, coordinator) + config_entry.async_on_unload( + config_entry.add_update_listener(async_options_updated) + ) + hass.config_entries.async_setup_platforms(config_entry, PLATFORMS) return True async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Unload Islamic Prayer entry from config_entry.""" - if hass.data[DOMAIN].event_unsub: - hass.data[DOMAIN].event_unsub() - hass.data.pop(DOMAIN) - return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) + if unload_ok := await hass.config_entries.async_unload_platforms( + config_entry, PLATFORMS + ): + coordinator: IslamicPrayerDataUpdateCoordinator = hass.data.pop(DOMAIN) + if coordinator.event_unsub: + coordinator.event_unsub() + return unload_ok -class IslamicPrayerClient: - """Islamic Prayer Client Object.""" - - def __init__(self, hass, config_entry): - """Initialize the Islamic Prayer client.""" - self.hass = hass - self.config_entry = config_entry - self.prayer_times_info = {} - self.available = True - self.event_unsub = None - - @property - def calc_method(self): - """Return the calculation method.""" - return self.config_entry.options[CONF_CALC_METHOD] - - def get_new_prayer_times(self): - """Fetch prayer times for today.""" - calc = PrayerTimesCalculator( - latitude=self.hass.config.latitude, - longitude=self.hass.config.longitude, - calculation_method=self.calc_method, - date=str(dt_util.now().date()), - ) - return calc.fetch_prayer_times() - - async def async_schedule_future_update(self): - """Schedule future update for sensors. - - Midnight is a calculated time. The specifics of the calculation - depends on the method of the prayer time calculation. This calculated - midnight is the time at which the time to pray the Isha prayers have - expired. - - Calculated Midnight: The Islamic midnight. - Traditional Midnight: 12:00AM - - Update logic for prayer times: - - If the Calculated Midnight is before the traditional midnight then wait - until the traditional midnight to run the update. This way the day - will have changed over and we don't need to do any fancy calculations. - - If the Calculated Midnight is after the traditional midnight, then wait - until after the calculated Midnight. We don't want to update the prayer - times too early or else the timings might be incorrect. - - Example: - calculated midnight = 11:23PM (before traditional midnight) - Update time: 12:00AM - - calculated midnight = 1:35AM (after traditional midnight) - update time: 1:36AM. - - """ - _LOGGER.debug("Scheduling next update for Islamic prayer times") - - now = dt_util.utcnow() - - midnight_dt = self.prayer_times_info["Midnight"] - - if now > dt_util.as_utc(midnight_dt): - next_update_at = midnight_dt + timedelta(days=1, minutes=1) - _LOGGER.debug( - "Midnight is after day the changes so schedule update for after" - " Midnight the next day" - ) - else: - _LOGGER.debug( - "Midnight is before the day changes so schedule update for the next" - " start of day" - ) - next_update_at = dt_util.start_of_local_day(now + timedelta(days=1)) - - _LOGGER.info("Next update scheduled for: %s", next_update_at) - - self.event_unsub = async_track_point_in_time( - self.hass, self.async_update, next_update_at - ) - - async def async_update(self, *_): - """Update sensors with new prayer times.""" - try: - prayer_times = await self.hass.async_add_executor_job( - self.get_new_prayer_times - ) - self.available = True - except (exceptions.InvalidResponseError, ConnError): - self.available = False - _LOGGER.debug("Error retrieving prayer times") - async_call_later(self.hass, 60, self.async_update) - return - - for prayer, time in prayer_times.items(): - self.prayer_times_info[prayer] = dt_util.parse_datetime( - f"{dt_util.now().date()} {time}" - ) - await self.async_schedule_future_update() - - _LOGGER.debug("New prayer times retrieved. Updating sensors") - async_dispatcher_send(self.hass, DATA_UPDATED) - - async def async_setup(self): - """Set up the Islamic prayer client.""" - await self.async_add_options() - - try: - await self.hass.async_add_executor_job(self.get_new_prayer_times) - except (exceptions.InvalidResponseError, ConnError) as err: - raise ConfigEntryNotReady from err - - await self.async_update() - self.config_entry.add_update_listener(self.async_options_updated) - - await self.hass.config_entries.async_forward_entry_setups( - self.config_entry, PLATFORMS - ) - - return True - - async def async_add_options(self): - """Add options for entry.""" - if not self.config_entry.options: - data = dict(self.config_entry.data) - calc_method = data.pop(CONF_CALC_METHOD, DEFAULT_CALC_METHOD) - - self.hass.config_entries.async_update_entry( - self.config_entry, data=data, options={CONF_CALC_METHOD: calc_method} - ) - - @staticmethod - async def async_options_updated(hass: HomeAssistant, entry: ConfigEntry) -> None: - """Triggered by config entry options updates.""" - if hass.data[DOMAIN].event_unsub: - hass.data[DOMAIN].event_unsub() - await hass.data[DOMAIN].async_update() +async def async_options_updated(hass: HomeAssistant, entry: ConfigEntry) -> None: + """Triggered by config entry options updates.""" + coordinator: IslamicPrayerDataUpdateCoordinator = hass.data[DOMAIN] + if coordinator.event_unsub: + coordinator.event_unsub() + await coordinator.async_request_refresh() diff --git a/homeassistant/components/islamic_prayer_times/config_flow.py b/homeassistant/components/islamic_prayer_times/config_flow.py index 5278750d36e..d0d314fe67d 100644 --- a/homeassistant/components/islamic_prayer_times/config_flow.py +++ b/homeassistant/components/islamic_prayer_times/config_flow.py @@ -1,10 +1,13 @@ """Config flow for Islamic Prayer Times integration.""" from __future__ import annotations +from typing import Any + import voluptuous as vol from homeassistant import config_entries from homeassistant.core import callback +from homeassistant.data_entry_flow import FlowResult from .const import CALC_METHODS, CONF_CALC_METHOD, DEFAULT_CALC_METHOD, DOMAIN, NAME @@ -22,7 +25,9 @@ class IslamicPrayerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """Get the options flow for this handler.""" return IslamicPrayerOptionsFlowHandler(config_entry) - async def async_step_user(self, user_input=None): + async def async_step_user( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: """Handle a flow initialized by the user.""" if self._async_current_entries(): return self.async_abort(reason="single_instance_allowed") @@ -40,7 +45,9 @@ class IslamicPrayerOptionsFlowHandler(config_entries.OptionsFlow): """Initialize options flow.""" self.config_entry = config_entry - async def async_step_init(self, user_input=None): + async def async_step_init( + self, user_input: dict[str, Any] | None = None + ) -> FlowResult: """Manage options.""" if user_input is not None: return self.async_create_entry(title="", data=user_input) diff --git a/homeassistant/components/islamic_prayer_times/const.py b/homeassistant/components/islamic_prayer_times/const.py index e037f486aaa..2a73a33bef8 100644 --- a/homeassistant/components/islamic_prayer_times/const.py +++ b/homeassistant/components/islamic_prayer_times/const.py @@ -1,23 +1,12 @@ """Constants for the Islamic Prayer component.""" +from typing import Final + from prayer_times_calculator import PrayerTimesCalculator -DOMAIN = "islamic_prayer_times" -NAME = "Islamic Prayer Times" -PRAYER_TIMES_ICON = "mdi:calendar-clock" +DOMAIN: Final = "islamic_prayer_times" +NAME: Final = "Islamic Prayer Times" -SENSOR_TYPES = { - "Fajr": "prayer", - "Sunrise": "time", - "Dhuhr": "prayer", - "Asr": "prayer", - "Maghrib": "prayer", - "Isha": "prayer", - "Midnight": "time", -} - -CONF_CALC_METHOD = "calculation_method" +CONF_CALC_METHOD: Final = "calculation_method" CALC_METHODS: list[str] = list(PrayerTimesCalculator.CALCULATION_METHODS) -DEFAULT_CALC_METHOD = "isna" - -DATA_UPDATED = "Islamic_prayer_data_updated" +DEFAULT_CALC_METHOD: Final = "isna" diff --git a/homeassistant/components/islamic_prayer_times/coordinator.py b/homeassistant/components/islamic_prayer_times/coordinator.py new file mode 100644 index 00000000000..1a8b0bf7036 --- /dev/null +++ b/homeassistant/components/islamic_prayer_times/coordinator.py @@ -0,0 +1,121 @@ +"""Coordinator for the Islamic prayer times integration.""" +from __future__ import annotations + +from datetime import datetime, timedelta +import logging + +from prayer_times_calculator import PrayerTimesCalculator, exceptions +from requests.exceptions import ConnectionError as ConnError + +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback +from homeassistant.helpers.event import async_call_later, async_track_point_in_time +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +import homeassistant.util.dt as dt_util + +from .const import CONF_CALC_METHOD, DEFAULT_CALC_METHOD, DOMAIN + +_LOGGER = logging.getLogger(__name__) + + +class IslamicPrayerDataUpdateCoordinator(DataUpdateCoordinator[dict[str, datetime]]): + """Islamic Prayer Client Object.""" + + config_entry: ConfigEntry + + def __init__(self, hass: HomeAssistant) -> None: + """Initialize the Islamic Prayer client.""" + self.event_unsub: CALLBACK_TYPE | None = None + super().__init__( + hass, + _LOGGER, + name=DOMAIN, + ) + + @property + def calc_method(self) -> str: + """Return the calculation method.""" + return self.config_entry.options.get(CONF_CALC_METHOD, DEFAULT_CALC_METHOD) + + def get_new_prayer_times(self) -> dict[str, str]: + """Fetch prayer times for today.""" + calc = PrayerTimesCalculator( + latitude=self.hass.config.latitude, + longitude=self.hass.config.longitude, + calculation_method=self.calc_method, + date=str(dt_util.now().date()), + ) + return calc.fetch_prayer_times() + + @callback + def async_schedule_future_update(self, midnight_dt: datetime) -> None: + """Schedule future update for sensors. + + Midnight is a calculated time. The specifics of the calculation + depends on the method of the prayer time calculation. This calculated + midnight is the time at which the time to pray the Isha prayers have + expired. + + Calculated Midnight: The Islamic midnight. + Traditional Midnight: 12:00AM + + Update logic for prayer times: + + If the Calculated Midnight is before the traditional midnight then wait + until the traditional midnight to run the update. This way the day + will have changed over and we don't need to do any fancy calculations. + + If the Calculated Midnight is after the traditional midnight, then wait + until after the calculated Midnight. We don't want to update the prayer + times too early or else the timings might be incorrect. + + Example: + calculated midnight = 11:23PM (before traditional midnight) + Update time: 12:00AM + + calculated midnight = 1:35AM (after traditional midnight) + update time: 1:36AM. + + """ + _LOGGER.debug("Scheduling next update for Islamic prayer times") + + now = dt_util.utcnow() + + if now > midnight_dt: + next_update_at = midnight_dt + timedelta(days=1, minutes=1) + _LOGGER.debug( + "Midnight is after the day changes so schedule update for after Midnight the next day" + ) + else: + _LOGGER.debug( + "Midnight is before the day changes so schedule update for the next start of day" + ) + next_update_at = dt_util.start_of_local_day(now + timedelta(days=1)) + + _LOGGER.debug("Next update scheduled for: %s", next_update_at) + + self.event_unsub = async_track_point_in_time( + self.hass, self.async_request_update, next_update_at + ) + + async def async_request_update(self, *_) -> None: + """Request update from coordinator.""" + await self.async_request_refresh() + + async def _async_update_data(self) -> dict[str, datetime]: + """Update sensors with new prayer times.""" + try: + prayer_times = await self.hass.async_add_executor_job( + self.get_new_prayer_times + ) + except (exceptions.InvalidResponseError, ConnError) as err: + async_call_later(self.hass, 60, self.async_request_update) + raise UpdateFailed from err + + prayer_times_info: dict[str, datetime] = {} + for prayer, time in prayer_times.items(): + if prayer_time := dt_util.parse_datetime(f"{dt_util.now().date()} {time}"): + prayer_times_info[prayer] = dt_util.as_utc(prayer_time) + + self.async_schedule_future_update(prayer_times_info["Midnight"]) + return prayer_times_info diff --git a/homeassistant/components/islamic_prayer_times/sensor.py b/homeassistant/components/islamic_prayer_times/sensor.py index a90a2c53c52..abaefec4082 100644 --- a/homeassistant/components/islamic_prayer_times/sensor.py +++ b/homeassistant/components/islamic_prayer_times/sensor.py @@ -1,12 +1,51 @@ """Platform to retrieve Islamic prayer times information for Home Assistant.""" -from homeassistant.components.sensor import SensorDeviceClass, SensorEntity +from datetime import datetime + +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorEntityDescription, +) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.device_registry import DeviceEntryType +from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -import homeassistant.util.dt as dt_util +from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DATA_UPDATED, DOMAIN, PRAYER_TIMES_ICON, SENSOR_TYPES +from . import IslamicPrayerDataUpdateCoordinator +from .const import DOMAIN, NAME + +SENSOR_TYPES: tuple[SensorEntityDescription, ...] = ( + SensorEntityDescription( + key="Fajr", + name="Fajr prayer", + ), + SensorEntityDescription( + key="Sunrise", + name="Sunrise time", + ), + SensorEntityDescription( + key="Dhuhr", + name="Dhuhr prayer", + ), + SensorEntityDescription( + key="Asr", + name="Asr prayer", + ), + SensorEntityDescription( + key="Maghrib", + name="Maghrib prayer", + ), + SensorEntityDescription( + key="Isha", + name="Isha prayer", + ), + SensorEntityDescription( + key="Midnight", + name="Midnight time", + ), +) async def async_setup_entry( @@ -16,46 +55,38 @@ async def async_setup_entry( ) -> None: """Set up the Islamic prayer times sensor platform.""" - client = hass.data[DOMAIN] + coordinator: IslamicPrayerDataUpdateCoordinator = hass.data[DOMAIN] - entities = [] - for sensor_type in SENSOR_TYPES: - entities.append(IslamicPrayerTimeSensor(sensor_type, client)) - - async_add_entities(entities, True) + async_add_entities( + IslamicPrayerTimeSensor(coordinator, description) + for description in SENSOR_TYPES + ) -class IslamicPrayerTimeSensor(SensorEntity): +class IslamicPrayerTimeSensor( + CoordinatorEntity[IslamicPrayerDataUpdateCoordinator], SensorEntity +): """Representation of an Islamic prayer time sensor.""" _attr_device_class = SensorDeviceClass.TIMESTAMP - _attr_icon = PRAYER_TIMES_ICON - _attr_should_poll = False + _attr_has_entity_name = True - def __init__(self, sensor_type, client): + def __init__( + self, + coordinator: IslamicPrayerDataUpdateCoordinator, + description: SensorEntityDescription, + ) -> None: """Initialize the Islamic prayer time sensor.""" - self.sensor_type = sensor_type - self.client = client + super().__init__(coordinator) + self.entity_description = description + self._attr_unique_id = description.key + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, coordinator.config_entry.entry_id)}, + name=NAME, + entry_type=DeviceEntryType.SERVICE, + ) @property - def name(self): - """Return the name of the sensor.""" - return f"{self.sensor_type} {SENSOR_TYPES[self.sensor_type]}" - - @property - def unique_id(self): - """Return the unique id of the entity.""" - return self.sensor_type - - @property - def native_value(self): + def native_value(self) -> datetime: """Return the state of the sensor.""" - return self.client.prayer_times_info.get(self.sensor_type).astimezone( - dt_util.UTC - ) - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - self.async_on_remove( - async_dispatcher_connect(self.hass, DATA_UPDATED, self.async_write_ha_state) - ) + return self.coordinator.data[self.entity_description.key] diff --git a/tests/components/islamic_prayer_times/__init__.py b/tests/components/islamic_prayer_times/__init__.py index 3afc2207ffa..386d20ab98e 100644 --- a/tests/components/islamic_prayer_times/__init__.py +++ b/tests/components/islamic_prayer_times/__init__.py @@ -15,13 +15,13 @@ PRAYER_TIMES = { } PRAYER_TIMES_TIMESTAMPS = { - "Fajr": datetime(2020, 1, 1, 6, 10, 0), - "Sunrise": datetime(2020, 1, 1, 7, 25, 0), - "Dhuhr": datetime(2020, 1, 1, 12, 30, 0), - "Asr": datetime(2020, 1, 1, 15, 32, 0), - "Maghrib": datetime(2020, 1, 1, 17, 35, 0), - "Isha": datetime(2020, 1, 1, 18, 53, 0), - "Midnight": datetime(2020, 1, 1, 00, 45, 0), + "Fajr": datetime(2020, 1, 1, 6, 10, 0, tzinfo=dt_util.UTC), + "Sunrise": datetime(2020, 1, 1, 7, 25, 0, tzinfo=dt_util.UTC), + "Dhuhr": datetime(2020, 1, 1, 12, 30, 0, tzinfo=dt_util.UTC), + "Asr": datetime(2020, 1, 1, 15, 32, 0, tzinfo=dt_util.UTC), + "Maghrib": datetime(2020, 1, 1, 17, 35, 0, tzinfo=dt_util.UTC), + "Isha": datetime(2020, 1, 1, 18, 53, 0, tzinfo=dt_util.UTC), + "Midnight": datetime(2020, 1, 1, 00, 45, 0, tzinfo=dt_util.UTC), } NEW_PRAYER_TIMES = { @@ -35,13 +35,13 @@ NEW_PRAYER_TIMES = { } NEW_PRAYER_TIMES_TIMESTAMPS = { - "Fajr": datetime(2020, 1, 1, 6, 00, 0), - "Sunrise": datetime(2020, 1, 1, 7, 25, 0), - "Dhuhr": datetime(2020, 1, 1, 12, 30, 0), - "Asr": datetime(2020, 1, 1, 15, 32, 0), - "Maghrib": datetime(2020, 1, 1, 17, 45, 0), - "Isha": datetime(2020, 1, 1, 18, 53, 0), - "Midnight": datetime(2020, 1, 1, 00, 43, 0), + "Fajr": datetime(2020, 1, 1, 6, 00, 0, tzinfo=dt_util.UTC), + "Sunrise": datetime(2020, 1, 1, 7, 25, 0, tzinfo=dt_util.UTC), + "Dhuhr": datetime(2020, 1, 1, 12, 30, 0, tzinfo=dt_util.UTC), + "Asr": datetime(2020, 1, 1, 15, 32, 0, tzinfo=dt_util.UTC), + "Maghrib": datetime(2020, 1, 1, 17, 45, 0, tzinfo=dt_util.UTC), + "Isha": datetime(2020, 1, 1, 18, 53, 0, tzinfo=dt_util.UTC), + "Midnight": datetime(2020, 1, 1, 00, 43, 0, tzinfo=dt_util.UTC), } NOW = datetime(2020, 1, 1, 00, 00, 0, tzinfo=dt_util.UTC) diff --git a/tests/components/islamic_prayer_times/test_config_flow.py b/tests/components/islamic_prayer_times/test_config_flow.py index 947e5002ea9..66430938734 100644 --- a/tests/components/islamic_prayer_times/test_config_flow.py +++ b/tests/components/islamic_prayer_times/test_config_flow.py @@ -1,27 +1,16 @@ """Tests for Islamic Prayer Times config flow.""" from unittest.mock import patch -import pytest - from homeassistant import config_entries, data_entry_flow from homeassistant.components import islamic_prayer_times -from homeassistant.components.islamic_prayer_times import config_flow # noqa: F401 from homeassistant.components.islamic_prayer_times.const import CONF_CALC_METHOD, DOMAIN from homeassistant.core import HomeAssistant +from . import PRAYER_TIMES + from tests.common import MockConfigEntry -@pytest.fixture(name="mock_setup", autouse=True) -def mock_setup(): - """Mock entry setup.""" - with patch( - "homeassistant.components.islamic_prayer_times.async_setup_entry", - return_value=True, - ): - yield - - async def test_flow_works(hass: HomeAssistant) -> None: """Test user config.""" result = await hass.config_entries.flow.async_init( @@ -30,9 +19,13 @@ async def test_flow_works(hass: HomeAssistant) -> None: assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["step_id"] == "user" - result = await hass.config_entries.flow.async_configure( - result["flow_id"], user_input={} - ) + with patch( + "homeassistant.components.islamic_prayer_times.async_setup_entry", + return_value=True, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], user_input={} + ) assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["title"] == "Islamic Prayer Times" @@ -47,6 +40,13 @@ async def test_options(hass: HomeAssistant) -> None: ) entry.add_to_hass(hass) + with patch( + "prayer_times_calculator.PrayerTimesCalculator.fetch_prayer_times", + return_value=PRAYER_TIMES, + ): + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + result = await hass.config_entries.options.async_init(entry.entry_id) assert result["type"] == data_entry_flow.FlowResultType.FORM diff --git a/tests/components/islamic_prayer_times/test_init.py b/tests/components/islamic_prayer_times/test_init.py index b46f2740c36..d641a22590d 100644 --- a/tests/components/islamic_prayer_times/test_init.py +++ b/tests/components/islamic_prayer_times/test_init.py @@ -22,7 +22,7 @@ from tests.common import MockConfigEntry, async_fire_time_changed @pytest.fixture(autouse=True) -def set_utc(hass): +def set_utc(hass: HomeAssistant) -> None: """Set timezone to UTC.""" hass.config.set_time_zone("UTC") @@ -44,9 +44,6 @@ async def test_successful_config_entry(hass: HomeAssistant) -> None: await hass.async_block_till_done() assert entry.state is config_entries.ConfigEntryState.LOADED - assert entry.options == { - islamic_prayer_times.CONF_CALC_METHOD: islamic_prayer_times.DEFAULT_CALC_METHOD - } async def test_setup_failed(hass: HomeAssistant) -> None: @@ -100,10 +97,7 @@ async def test_islamic_prayer_times_timestamp_format(hass: HomeAssistant) -> Non await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - assert ( - hass.data[islamic_prayer_times.DOMAIN].prayer_times_info - == PRAYER_TIMES_TIMESTAMPS - ) + assert hass.data[islamic_prayer_times.DOMAIN].data == PRAYER_TIMES_TIMESTAMPS async def test_update(hass: HomeAssistant) -> None: @@ -115,7 +109,6 @@ async def test_update(hass: HomeAssistant) -> None: "prayer_times_calculator.PrayerTimesCalculator.fetch_prayer_times" ) as FetchPrayerTimes, freeze_time(NOW): FetchPrayerTimes.side_effect = [ - PRAYER_TIMES, PRAYER_TIMES, NEW_PRAYER_TIMES, ] @@ -124,13 +117,10 @@ async def test_update(hass: HomeAssistant) -> None: await hass.async_block_till_done() pt_data = hass.data[islamic_prayer_times.DOMAIN] - assert pt_data.prayer_times_info == PRAYER_TIMES_TIMESTAMPS + assert pt_data.data == PRAYER_TIMES_TIMESTAMPS - future = pt_data.prayer_times_info["Midnight"] + timedelta(days=1, minutes=1) + future = pt_data.data["Midnight"] + timedelta(days=1, minutes=1) async_fire_time_changed(hass, future) await hass.async_block_till_done() - assert ( - hass.data[islamic_prayer_times.DOMAIN].prayer_times_info - == NEW_PRAYER_TIMES_TIMESTAMPS - ) + assert pt_data.data == NEW_PRAYER_TIMES_TIMESTAMPS diff --git a/tests/components/islamic_prayer_times/test_sensor.py b/tests/components/islamic_prayer_times/test_sensor.py index 56dd0e3805f..3b291c9973d 100644 --- a/tests/components/islamic_prayer_times/test_sensor.py +++ b/tests/components/islamic_prayer_times/test_sensor.py @@ -4,8 +4,10 @@ from unittest.mock import patch from freezegun import freeze_time import pytest -from homeassistant.components import islamic_prayer_times +from homeassistant.components.islamic_prayer_times.const import DOMAIN +from homeassistant.components.islamic_prayer_times.sensor import SENSOR_TYPES from homeassistant.core import HomeAssistant +from homeassistant.util import slugify import homeassistant.util.dt as dt_util from . import NOW, PRAYER_TIMES, PRAYER_TIMES_TIMESTAMPS @@ -14,14 +16,14 @@ from tests.common import MockConfigEntry @pytest.fixture(autouse=True) -def set_utc(hass): +def set_utc(hass: HomeAssistant) -> None: """Set timezone to UTC.""" hass.config.set_time_zone("UTC") async def test_islamic_prayer_times_sensors(hass: HomeAssistant) -> None: """Test minimum Islamic prayer times configuration.""" - entry = MockConfigEntry(domain=islamic_prayer_times.DOMAIN, data={}) + entry = MockConfigEntry(domain=DOMAIN, data={}) entry.add_to_hass(hass) with patch( @@ -31,10 +33,10 @@ async def test_islamic_prayer_times_sensors(hass: HomeAssistant) -> None: await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() - for prayer in PRAYER_TIMES: + for prayer in SENSOR_TYPES: assert ( - hass.states.get( - f"sensor.{prayer}_{islamic_prayer_times.const.SENSOR_TYPES[prayer]}" - ).state - == PRAYER_TIMES_TIMESTAMPS[prayer].astimezone(dt_util.UTC).isoformat() + hass.states.get(f"sensor.{DOMAIN}_{slugify(prayer.name)}").state + == PRAYER_TIMES_TIMESTAMPS[prayer.key] + .astimezone(dt_util.UTC) + .isoformat() )