Cleanup tests for Jewish calendar integration (#138793)

This commit is contained in:
Tsvi Mostovicz 2025-04-19 13:46:04 +03:00 committed by GitHub
parent 6f99b1d69b
commit 6499ad6cdb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 460 additions and 699 deletions

View File

@ -197,6 +197,11 @@ class JewishCalendarSensor(JewishCalendarEntity, SensorEntity):
super().__init__(config_entry, description) super().__init__(config_entry, description)
self._attrs: dict[str, str] = {} self._attrs: dict[str, str] = {}
async def async_added_to_hass(self) -> None:
"""Call when entity is added to hass."""
await super().async_added_to_hass()
await self.async_update()
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update the state of the sensor.""" """Update the state of the sensor."""
now = dt_util.now() now = dt_util.now()

View File

@ -1,57 +1 @@
"""Tests for the jewish_calendar component.""" """Tests for the jewish_calendar component."""
from collections import namedtuple
from datetime import datetime
from homeassistant.components import jewish_calendar
from homeassistant.util import dt as dt_util
_LatLng = namedtuple("_LatLng", ["lat", "lng"]) # noqa: PYI024
HDATE_DEFAULT_ALTITUDE = 754
NYC_LATLNG = _LatLng(40.7128, -74.0060)
JERUSALEM_LATLNG = _LatLng(31.778, 35.235)
def make_nyc_test_params(dtime, results, havdalah_offset=0):
"""Make test params for NYC."""
if isinstance(results, dict):
time_zone = dt_util.get_time_zone("America/New_York")
results = {
key: value.replace(tzinfo=time_zone)
if isinstance(value, datetime)
else value
for key, value in results.items()
}
return (
dtime,
jewish_calendar.DEFAULT_CANDLE_LIGHT,
havdalah_offset,
True,
"America/New_York",
NYC_LATLNG.lat,
NYC_LATLNG.lng,
results,
)
def make_jerusalem_test_params(dtime, results, havdalah_offset=0):
"""Make test params for Jerusalem."""
if isinstance(results, dict):
time_zone = dt_util.get_time_zone("Asia/Jerusalem")
results = {
key: value.replace(tzinfo=time_zone)
if isinstance(value, datetime)
else value
for key, value in results.items()
}
return (
dtime,
40,
havdalah_offset,
False,
"Asia/Jerusalem",
JERUSALEM_LATLNG.lat,
JERUSALEM_LATLNG.lng,
results,
)

View File

@ -1,22 +1,39 @@
"""Common fixtures for the jewish_calendar tests.""" """Common fixtures for the jewish_calendar tests."""
from collections.abc import Generator from collections.abc import AsyncGenerator, Generator, Iterable
import datetime as dt
from typing import NamedTuple
from unittest.mock import AsyncMock, patch from unittest.mock import AsyncMock, patch
from freezegun import freeze_time
import pytest import pytest
from homeassistant.components.jewish_calendar.const import DEFAULT_NAME, DOMAIN from homeassistant.components.jewish_calendar.const import (
CONF_CANDLE_LIGHT_MINUTES,
CONF_DIASPORA,
CONF_HAVDALAH_OFFSET_MINUTES,
DEFAULT_NAME,
DOMAIN,
)
from homeassistant.const import CONF_LANGUAGE, CONF_TIME_ZONE
from homeassistant.core import HomeAssistant
from homeassistant.util import dt as dt_util
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@pytest.fixture class _LocationData(NamedTuple):
def mock_config_entry() -> MockConfigEntry: timezone: str
"""Return the default mocked config entry.""" diaspora: bool
return MockConfigEntry( lat: float
title=DEFAULT_NAME, lng: float
domain=DOMAIN, candle_lighting: int
)
LOCATIONS = {
"Jerusalem": _LocationData("Asia/Jerusalem", False, 31.7683, 35.2137, 40),
"New York": _LocationData("America/New_York", True, 40.7128, -74.006, 18),
}
@pytest.fixture @pytest.fixture
@ -26,3 +43,109 @@ def mock_setup_entry() -> Generator[AsyncMock]:
"homeassistant.components.jewish_calendar.async_setup_entry", return_value=True "homeassistant.components.jewish_calendar.async_setup_entry", return_value=True
) as mock_setup_entry: ) as mock_setup_entry:
yield mock_setup_entry yield mock_setup_entry
@pytest.fixture
def location_data(request: pytest.FixtureRequest) -> _LocationData | None:
"""Return data based on location name."""
if not hasattr(request, "param"):
return None
return LOCATIONS[request.param]
@pytest.fixture
def tz_info(hass: HomeAssistant, location_data: _LocationData | None) -> dt.tzinfo:
"""Return time zone info."""
if location_data is None:
return dt_util.get_time_zone(hass.config.time_zone)
return dt_util.get_time_zone(location_data.timezone)
@pytest.fixture(name="test_time")
def _test_time(
request: pytest.FixtureRequest, tz_info: dt.tzinfo
) -> dt.datetime | None:
"""Return localized test time based."""
if not hasattr(request, "param"):
return None
return request.param.replace(tzinfo=tz_info)
@pytest.fixture
def results(request: pytest.FixtureRequest, tz_info: dt.tzinfo) -> Iterable:
"""Return localized results."""
if not hasattr(request, "param"):
return None
if isinstance(request.param, dict):
return {
key: value.replace(tzinfo=tz_info)
if isinstance(value, dt.datetime)
else value
for key, value in request.param.items()
}
return request.param
@pytest.fixture
def havdalah_offset() -> int | None:
"""Return None if default havdalah offset is not specified."""
return None
@pytest.fixture
def language() -> str:
"""Return default language value, unless language is parametrized."""
return "english"
@pytest.fixture(autouse=True)
async def setup_hass(hass: HomeAssistant, location_data: _LocationData | None) -> None:
"""Set up Home Assistant for testing the jewish_calendar integration."""
if location_data:
await hass.config.async_set_time_zone(location_data.timezone)
hass.config.latitude = location_data.lat
hass.config.longitude = location_data.lng
@pytest.fixture
def config_entry(
location_data: _LocationData | None,
language: str,
havdalah_offset: int | None,
) -> MockConfigEntry:
"""Set up the jewish_calendar integration for testing."""
param_data = {}
param_options = {}
if location_data:
param_data = {
CONF_DIASPORA: location_data.diaspora,
CONF_TIME_ZONE: location_data.timezone,
}
param_options[CONF_CANDLE_LIGHT_MINUTES] = location_data.candle_lighting
if havdalah_offset:
param_options[CONF_HAVDALAH_OFFSET_MINUTES] = havdalah_offset
return MockConfigEntry(
title=DEFAULT_NAME,
domain=DOMAIN,
data={CONF_LANGUAGE: language, **param_data},
options=param_options,
)
@pytest.fixture
async def setup_at_time(
test_time: dt.datetime, hass: HomeAssistant, config_entry: MockConfigEntry
) -> AsyncGenerator[None]:
"""Set up the jewish_calendar integration at a specific time."""
with freeze_time(test_time):
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
yield

View File

@ -1,301 +1,145 @@
"""The tests for the Jewish calendar binary sensors.""" """The tests for the Jewish calendar binary sensors."""
from datetime import datetime as dt, timedelta from datetime import datetime as dt, timedelta
import logging from typing import Any
from freezegun import freeze_time from freezegun.api import FrozenDateTimeFactory
import pytest import pytest
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.jewish_calendar.const import ( from homeassistant.components.jewish_calendar.const import DOMAIN
CONF_CANDLE_LIGHT_MINUTES, from homeassistant.const import CONF_PLATFORM, STATE_OFF, STATE_ON
CONF_DIASPORA,
CONF_HAVDALAH_OFFSET_MINUTES,
DEFAULT_NAME,
DOMAIN,
)
from homeassistant.const import CONF_LANGUAGE, CONF_PLATFORM, STATE_OFF, STATE_ON
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from . import make_jerusalem_test_params, make_nyc_test_params
from tests.common import MockConfigEntry, async_fire_time_changed
_LOGGER = logging.getLogger(__name__)
from tests.common import async_fire_time_changed
MELACHA_PARAMS = [ MELACHA_PARAMS = [
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 1, 16, 0), dt(2018, 9, 1, 16, 0),
{ {"state": STATE_ON, "update": dt(2018, 9, 1, 20, 14), "new_state": STATE_OFF},
"state": STATE_ON, id="currently_first_shabbat",
"update": dt(2018, 9, 1, 20, 14),
"new_state": STATE_OFF,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 1, 20, 21), dt(2018, 9, 1, 20, 21),
{ {"state": STATE_OFF, "update": dt(2018, 9, 2, 6, 21), "new_state": STATE_OFF},
"state": STATE_OFF, id="after_first_shabbat",
"update": dt(2018, 9, 2, 6, 21),
"new_state": STATE_OFF,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 7, 13, 1), dt(2018, 9, 7, 13, 1),
{ {"state": STATE_OFF, "update": dt(2018, 9, 7, 19, 4), "new_state": STATE_ON},
"state": STATE_OFF, id="friday_upcoming_shabbat",
"update": dt(2018, 9, 7, 19, 4),
"new_state": STATE_ON,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 8, 21, 25), dt(2018, 9, 8, 21, 25),
{ {"state": STATE_OFF, "update": dt(2018, 9, 9, 6, 27), "new_state": STATE_OFF},
"state": STATE_OFF, id="upcoming_rosh_hashana",
"update": dt(2018, 9, 9, 6, 27),
"new_state": STATE_OFF,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 9, 21, 25), dt(2018, 9, 9, 21, 25),
{ {"state": STATE_ON, "update": dt(2018, 9, 10, 6, 28), "new_state": STATE_ON},
"state": STATE_ON, id="currently_rosh_hashana",
"update": dt(2018, 9, 10, 6, 28),
"new_state": STATE_ON,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 10, 21, 25), dt(2018, 9, 10, 21, 25),
{ {"state": STATE_ON, "update": dt(2018, 9, 11, 6, 29), "new_state": STATE_ON},
"state": STATE_ON, id="second_day_rosh_hashana_night",
"update": dt(2018, 9, 11, 6, 29),
"new_state": STATE_ON,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 11, 11, 25), dt(2018, 9, 11, 11, 25),
{ {"state": STATE_ON, "update": dt(2018, 9, 11, 19, 57), "new_state": STATE_OFF},
"state": STATE_ON, id="second_day_rosh_hashana_day",
"update": dt(2018, 9, 11, 19, 57),
"new_state": STATE_OFF,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 29, 16, 25), dt(2018, 9, 29, 16, 25),
{ {"state": STATE_ON, "update": dt(2018, 9, 29, 19, 25), "new_state": STATE_OFF},
"state": STATE_ON, id="currently_shabbat_chol_hamoed",
"update": dt(2018, 9, 29, 19, 25),
"new_state": STATE_OFF,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 29, 21, 25), dt(2018, 9, 29, 21, 25),
{ {"state": STATE_OFF, "update": dt(2018, 9, 30, 6, 48), "new_state": STATE_OFF},
"state": STATE_OFF, id="upcoming_two_day_yomtov_in_diaspora",
"update": dt(2018, 9, 30, 6, 48),
"new_state": STATE_OFF,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 30, 21, 25), dt(2018, 9, 30, 21, 25),
{ {"state": STATE_ON, "update": dt(2018, 10, 1, 6, 49), "new_state": STATE_ON},
"state": STATE_ON, id="currently_first_day_of_two_day_yomtov_in_diaspora",
"update": dt(2018, 10, 1, 6, 49),
"new_state": STATE_ON,
},
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 10, 1, 21, 25), dt(2018, 10, 1, 21, 25),
{ {"state": STATE_ON, "update": dt(2018, 10, 2, 6, 50), "new_state": STATE_ON},
"state": STATE_ON, id="currently_second_day_of_two_day_yomtov_in_diaspora",
"update": dt(2018, 10, 2, 6, 50),
"new_state": STATE_ON,
},
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2018, 9, 29, 21, 25), dt(2018, 9, 29, 21, 25),
{ {"state": STATE_OFF, "update": dt(2018, 9, 30, 6, 29), "new_state": STATE_OFF},
"state": STATE_OFF, id="upcoming_one_day_yom_tov_in_israel",
"update": dt(2018, 9, 30, 6, 29),
"new_state": STATE_OFF,
},
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2018, 10, 1, 11, 25), dt(2018, 10, 1, 11, 25),
{ {"state": STATE_ON, "update": dt(2018, 10, 1, 19, 2), "new_state": STATE_OFF},
"state": STATE_ON, id="currently_one_day_yom_tov_in_israel",
"update": dt(2018, 10, 1, 19, 2),
"new_state": STATE_OFF,
},
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2018, 10, 1, 21, 25), dt(2018, 10, 1, 21, 25),
{ {"state": STATE_OFF, "update": dt(2018, 10, 2, 6, 31), "new_state": STATE_OFF},
"state": STATE_OFF, id="after_one_day_yom_tov_in_israel",
"update": dt(2018, 10, 2, 6, 31),
"new_state": STATE_OFF,
},
), ),
] ]
MELACHA_TEST_IDS = [
"currently_first_shabbat",
"after_first_shabbat",
"friday_upcoming_shabbat",
"upcoming_rosh_hashana",
"currently_rosh_hashana",
"second_day_rosh_hashana_night",
"second_day_rosh_hashana_day",
"currently_shabbat_chol_hamoed",
"upcoming_two_day_yomtov_in_diaspora",
"currently_first_day_of_two_day_yomtov_in_diaspora",
"currently_second_day_of_two_day_yomtov_in_diaspora",
"upcoming_one_day_yom_tov_in_israel",
"currently_one_day_yom_tov_in_israel",
"after_one_day_yom_tov_in_israel",
]
@pytest.mark.parametrize( @pytest.mark.parametrize(
( ("location_data", "test_time", "results"), MELACHA_PARAMS, indirect=True
"now",
"candle_lighting",
"havdalah",
"diaspora",
"tzname",
"latitude",
"longitude",
"result",
),
MELACHA_PARAMS,
ids=MELACHA_TEST_IDS,
) )
@pytest.mark.usefixtures("setup_at_time")
async def test_issur_melacha_sensor( async def test_issur_melacha_sensor(
hass: HomeAssistant, hass: HomeAssistant, freezer: FrozenDateTimeFactory, results: dict[str, Any]
now,
candle_lighting,
havdalah,
diaspora,
tzname,
latitude,
longitude,
result,
) -> None: ) -> None:
"""Test Issur Melacha sensor output.""" """Test Issur Melacha sensor output."""
time_zone = dt_util.get_time_zone(tzname) sensor_id = "binary_sensor.jewish_calendar_issur_melacha_in_effect"
test_time = now.replace(tzinfo=time_zone) assert hass.states.get(sensor_id).state == results["state"]
await hass.config.async_set_time_zone(tzname) freezer.move_to(results["update"])
hass.config.latitude = latitude async_fire_time_changed(hass)
hass.config.longitude = longitude
with freeze_time(test_time):
entry = MockConfigEntry(
title=DEFAULT_NAME,
domain=DOMAIN,
data={
CONF_LANGUAGE: "english",
CONF_DIASPORA: diaspora,
CONF_CANDLE_LIGHT_MINUTES: candle_lighting,
CONF_HAVDALAH_OFFSET_MINUTES: havdalah,
},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get(sensor_id).state == results["new_state"]
assert (
hass.states.get(
"binary_sensor.jewish_calendar_issur_melacha_in_effect"
).state
== result["state"]
)
with freeze_time(result["update"]):
async_fire_time_changed(hass, result["update"])
await hass.async_block_till_done()
assert (
hass.states.get(
"binary_sensor.jewish_calendar_issur_melacha_in_effect"
).state
== result["new_state"]
)
@pytest.mark.parametrize( @pytest.mark.parametrize(
( ("location_data", "test_time", "results"),
"now",
"candle_lighting",
"havdalah",
"diaspora",
"tzname",
"latitude",
"longitude",
"result",
),
[ [
make_nyc_test_params( ("New York", dt(2020, 10, 23, 17, 44, 59, 999999), [STATE_OFF, STATE_ON]),
dt(2020, 10, 23, 17, 44, 59, 999999), [STATE_OFF, STATE_ON] ("New York", dt(2020, 10, 24, 18, 42, 59, 999999), [STATE_ON, STATE_OFF]),
),
make_nyc_test_params(
dt(2020, 10, 24, 18, 42, 59, 999999), [STATE_ON, STATE_OFF]
),
], ],
ids=["before_candle_lighting", "before_havdalah"], ids=["before_candle_lighting", "before_havdalah"],
indirect=True,
) )
@pytest.mark.usefixtures("setup_at_time")
async def test_issur_melacha_sensor_update( async def test_issur_melacha_sensor_update(
hass: HomeAssistant, hass: HomeAssistant, freezer: FrozenDateTimeFactory, results: list[str]
now,
candle_lighting,
havdalah,
diaspora,
tzname,
latitude,
longitude,
result,
) -> None: ) -> None:
"""Test Issur Melacha sensor output.""" """Test Issur Melacha sensor output."""
time_zone = dt_util.get_time_zone(tzname) sensor_id = "binary_sensor.jewish_calendar_issur_melacha_in_effect"
test_time = now.replace(tzinfo=time_zone) assert hass.states.get(sensor_id).state == results[0]
await hass.config.async_set_time_zone(tzname) freezer.tick(timedelta(microseconds=1))
hass.config.latitude = latitude async_fire_time_changed(hass)
hass.config.longitude = longitude
with freeze_time(test_time):
entry = MockConfigEntry(
title=DEFAULT_NAME,
domain=DOMAIN,
data={
CONF_LANGUAGE: "english",
CONF_DIASPORA: diaspora,
CONF_CANDLE_LIGHT_MINUTES: candle_lighting,
CONF_HAVDALAH_OFFSET_MINUTES: havdalah,
},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert ( assert hass.states.get(sensor_id).state == results[1]
hass.states.get(
"binary_sensor.jewish_calendar_issur_melacha_in_effect"
).state
== result[0]
)
test_time += timedelta(microseconds=1)
with freeze_time(test_time):
async_fire_time_changed(hass, test_time)
await hass.async_block_till_done()
assert (
hass.states.get(
"binary_sensor.jewish_calendar_issur_melacha_in_effect"
).state
== result[1]
)
async def test_no_discovery_info( async def test_no_discovery_info(

View File

@ -57,10 +57,10 @@ async def test_step_user(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> No
async def test_single_instance_allowed( async def test_single_instance_allowed(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry, config_entry: MockConfigEntry,
) -> None: ) -> None:
"""Test we abort if already setup.""" """Test we abort if already setup."""
mock_config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER} DOMAIN, context={"source": SOURCE_USER}
@ -70,11 +70,11 @@ async def test_single_instance_allowed(
assert result.get("reason") == "single_instance_allowed" assert result.get("reason") == "single_instance_allowed"
async def test_options(hass: HomeAssistant, mock_config_entry: MockConfigEntry) -> None: async def test_options(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
"""Test updating options.""" """Test updating options."""
mock_config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
result = await hass.config_entries.options.async_init(mock_config_entry.entry_id) result = await hass.config_entries.options.async_init(config_entry.entry_id)
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "init" assert result["step_id"] == "init"
@ -95,16 +95,16 @@ async def test_options(hass: HomeAssistant, mock_config_entry: MockConfigEntry)
async def test_options_reconfigure( async def test_options_reconfigure(
hass: HomeAssistant, mock_config_entry: MockConfigEntry hass: HomeAssistant, config_entry: MockConfigEntry
) -> None: ) -> None:
"""Test that updating the options of the Jewish Calendar integration triggers a value update.""" """Test that updating the options of the Jewish Calendar integration triggers a value update."""
mock_config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert CONF_CANDLE_LIGHT_MINUTES not in mock_config_entry.options assert CONF_CANDLE_LIGHT_MINUTES not in config_entry.options
# Update the CONF_CANDLE_LIGHT_MINUTES option to a new value # Update the CONF_CANDLE_LIGHT_MINUTES option to a new value
result = await hass.config_entries.options.async_init(mock_config_entry.entry_id) result = await hass.config_entries.options.async_init(config_entry.entry_id)
result = await hass.config_entries.options.async_configure( result = await hass.config_entries.options.async_configure(
result["flow_id"], result["flow_id"],
user_input={ user_input={
@ -114,21 +114,17 @@ async def test_options_reconfigure(
assert result["result"] assert result["result"]
# The value of the "upcoming_shabbat_candle_lighting" sensor should be the new value # The value of the "upcoming_shabbat_candle_lighting" sensor should be the new value
assert ( assert config_entry.options[CONF_CANDLE_LIGHT_MINUTES] == DEFAULT_CANDLE_LIGHT + 1
mock_config_entry.options[CONF_CANDLE_LIGHT_MINUTES] == DEFAULT_CANDLE_LIGHT + 1
)
async def test_reconfigure( async def test_reconfigure(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test starting a reconfigure flow.""" """Test starting a reconfigure flow."""
mock_config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
# init user flow # init user flow
result = await mock_config_entry.start_reconfigure_flow(hass) result = await config_entry.start_reconfigure_flow(hass)
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reconfigure" assert result["step_id"] == "reconfigure"
@ -141,4 +137,4 @@ async def test_reconfigure(
) )
assert result["type"] is FlowResultType.ABORT assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful" assert result["reason"] == "reconfigure_successful"
assert mock_config_entry.data[CONF_DIASPORA] is not DEFAULT_DIASPORA assert config_entry.data[CONF_DIASPORA] is not DEFAULT_DIASPORA

View File

@ -21,24 +21,24 @@ from tests.common import MockConfigEntry
async def test_migrate_unique_id( async def test_migrate_unique_id(
hass: HomeAssistant, hass: HomeAssistant,
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
config_entry: MockConfigEntry,
old_key: str, old_key: str,
new_key: str, new_key: str,
) -> None: ) -> None:
"""Test unique id migration.""" """Test unique id migration."""
entry = MockConfigEntry(domain=DOMAIN, data={}) config_entry.add_to_hass(hass)
entry.add_to_hass(hass)
entity: er.RegistryEntry = entity_registry.async_get_or_create( entity: er.RegistryEntry = entity_registry.async_get_or_create(
domain=SENSOR_DOMAIN, domain=SENSOR_DOMAIN,
platform=DOMAIN, platform=DOMAIN,
unique_id=f"{entry.entry_id}-{old_key}", unique_id=f"{config_entry.entry_id}-{old_key}",
config_entry=entry, config_entry=config_entry,
) )
assert entity.unique_id.endswith(f"-{old_key}") assert entity.unique_id.endswith(f"-{old_key}")
await hass.config_entries.async_setup(entry.entry_id) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
entity_migrated = entity_registry.async_get(entity.entity_id) entity_migrated = entity_registry.async_get(entity.entity_id)
assert entity_migrated assert entity_migrated
assert entity_migrated.unique_id == f"{entry.entry_id}-{new_key}" assert entity_migrated.unique_id == f"{config_entry.entry_id}-{new_key}"

View File

@ -1,94 +1,62 @@
"""The tests for the Jewish calendar sensors.""" """The tests for the Jewish calendar sensors."""
from datetime import datetime as dt, timedelta from datetime import datetime as dt
from typing import Any
from freezegun import freeze_time
from hdate.holidays import HolidayDatabase from hdate.holidays import HolidayDatabase
from hdate.parasha import Parasha from hdate.parasha import Parasha
import pytest import pytest
from homeassistant.components.jewish_calendar.const import ( from homeassistant.components.jewish_calendar.const import DOMAIN
CONF_CANDLE_LIGHT_MINUTES,
CONF_DIASPORA,
CONF_HAVDALAH_OFFSET_MINUTES,
DEFAULT_NAME,
DOMAIN,
)
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import CONF_LANGUAGE, CONF_PLATFORM from homeassistant.const import CONF_PLATFORM
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from . import make_jerusalem_test_params, make_nyc_test_params from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, async_fire_time_changed
async def test_jewish_calendar_min_config(hass: HomeAssistant) -> None: @pytest.mark.parametrize("language", ["english", "hebrew"])
async def test_min_config(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
"""Test minimum jewish calendar configuration.""" """Test minimum jewish calendar configuration."""
entry = MockConfigEntry(title=DEFAULT_NAME, domain=DOMAIN, data={}) config_entry.add_to_hass(hass)
entry.add_to_hass(hass) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert hass.states.get("sensor.jewish_calendar_date") is not None
async def test_jewish_calendar_hebrew(hass: HomeAssistant) -> None:
"""Test jewish calendar sensor with language set to hebrew."""
entry = MockConfigEntry(
title=DEFAULT_NAME, domain=DOMAIN, data={"language": "hebrew"}
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
assert hass.states.get("sensor.jewish_calendar_date") is not None assert hass.states.get("sensor.jewish_calendar_date") is not None
TEST_PARAMS = [ TEST_PARAMS = [
( pytest.param(
"Jerusalem",
dt(2018, 9, 3), dt(2018, 9, 3),
"UTC", {"state": "23 Elul 5778"},
31.778,
35.235,
"english", "english",
"date", "date",
False, id="date_output",
"23 Elul 5778",
None,
), ),
( pytest.param(
"Jerusalem",
dt(2018, 9, 3), dt(2018, 9, 3),
"UTC", {"state": 'כ"ג אלול ה\' תשע"ח'},
31.778,
35.235,
"hebrew", "hebrew",
"date", "date",
False, id="date_output_hebrew",
'כ"ג אלול ה\' תשע"ח',
None,
), ),
( pytest.param(
"Jerusalem",
dt(2018, 9, 10), dt(2018, 9, 10),
"UTC", {"state": "א' ראש השנה"},
31.778,
35.235,
"hebrew", "hebrew",
"holiday", "holiday",
False, id="holiday",
"א' ראש השנה",
None,
), ),
( pytest.param(
"Jerusalem",
dt(2018, 9, 10), dt(2018, 9, 10),
"UTC",
31.778,
35.235,
"english",
"holiday",
False,
"Rosh Hashana I",
{ {
"state": "Rosh Hashana I",
"attr": {
"device_class": "enum", "device_class": "enum",
"friendly_name": "Jewish Calendar Holiday", "friendly_name": "Jewish Calendar Holiday",
"icon": "mdi:calendar-star", "icon": "mdi:calendar-star",
@ -96,17 +64,17 @@ TEST_PARAMS = [
"type": "YOM_TOV", "type": "YOM_TOV",
"options": HolidayDatabase(False).get_all_names("english"), "options": HolidayDatabase(False).get_all_names("english"),
}, },
), },
(
dt(2024, 12, 31),
"UTC",
31.778,
35.235,
"english", "english",
"holiday", "holiday",
False, id="holiday_english",
"Chanukah, Rosh Chodesh", ),
pytest.param(
"Jerusalem",
dt(2024, 12, 31),
{ {
"state": "Chanukah, Rosh Chodesh",
"attr": {
"device_class": "enum", "device_class": "enum",
"friendly_name": "Jewish Calendar Holiday", "friendly_name": "Jewish Calendar Holiday",
"icon": "mdi:calendar-star", "icon": "mdi:calendar-star",
@ -114,169 +82,103 @@ TEST_PARAMS = [
"type": "MELACHA_PERMITTED_HOLIDAY, ROSH_CHODESH", "type": "MELACHA_PERMITTED_HOLIDAY, ROSH_CHODESH",
"options": HolidayDatabase(False).get_all_names("english"), "options": HolidayDatabase(False).get_all_names("english"),
}, },
},
"english",
"holiday",
id="holiday_multiple",
), ),
( pytest.param(
"Jerusalem",
dt(2018, 9, 8), dt(2018, 9, 8),
"UTC",
31.778,
35.235,
"hebrew",
"parshat_hashavua",
False,
"נצבים",
{ {
"state": "נצבים",
"attr": {
"device_class": "enum", "device_class": "enum",
"friendly_name": "Jewish Calendar Parshat Hashavua", "friendly_name": "Jewish Calendar Parshat Hashavua",
"icon": "mdi:book-open-variant", "icon": "mdi:book-open-variant",
"options": list(Parasha), "options": list(Parasha),
}, },
), },
(
dt(2018, 9, 8),
"America/New_York",
40.7128,
-74.0060,
"hebrew",
"t_set_hakochavim",
True,
dt(2018, 9, 8, 19, 47),
None,
),
(
dt(2018, 9, 8),
"Asia/Jerusalem",
31.778,
35.235,
"hebrew",
"t_set_hakochavim",
False,
dt(2018, 9, 8, 19, 21),
None,
),
(
dt(2018, 10, 14),
"Asia/Jerusalem",
31.778,
35.235,
"hebrew", "hebrew",
"parshat_hashavua", "parshat_hashavua",
False, id="torah_reading",
"לך לך",
None,
), ),
( pytest.param(
"New York",
dt(2018, 9, 8),
{"state": dt(2018, 9, 8, 19, 47)},
"hebrew",
"t_set_hakochavim",
id="first_stars_ny",
),
pytest.param(
"Jerusalem",
dt(2018, 9, 8),
{"state": dt(2018, 9, 8, 19, 21)},
"hebrew",
"t_set_hakochavim",
id="first_stars_jerusalem",
),
pytest.param(
"Jerusalem",
dt(2018, 10, 14),
{"state": "לך לך"},
"hebrew",
"parshat_hashavua",
id="torah_reading_weekday",
),
pytest.param(
"Jerusalem",
dt(2018, 10, 14, 17, 0, 0), dt(2018, 10, 14, 17, 0, 0),
"Asia/Jerusalem", {"state": "ה' מרחשוון ה' תשע\"ט"},
31.778,
35.235,
"hebrew", "hebrew",
"date", "date",
False, id="date_before_sunset",
"ה' מרחשוון ה' תשע\"ט",
None,
), ),
( pytest.param(
"Jerusalem",
dt(2018, 10, 14, 19, 0, 0), dt(2018, 10, 14, 19, 0, 0),
"Asia/Jerusalem",
31.778,
35.235,
"hebrew",
"date",
False,
"ו' מרחשוון ה' תשע\"ט",
{ {
"state": "ו' מרחשוון ה' תשע\"ט",
"attr": {
"hebrew_year": "5779", "hebrew_year": "5779",
"hebrew_month_name": "מרחשוון", "hebrew_month_name": "מרחשוון",
"hebrew_day": "6", "hebrew_day": "6",
"icon": "mdi:star-david", "icon": "mdi:star-david",
"friendly_name": "Jewish Calendar Date", "friendly_name": "Jewish Calendar Date",
}, },
},
"hebrew",
"date",
id="date_after_sunset",
), ),
] ]
TEST_IDS = [
"date_output",
"date_output_hebrew",
"holiday",
"holiday_english",
"holiday_multiple",
"torah_reading",
"first_stars_ny",
"first_stars_jerusalem",
"torah_reading_weekday",
"date_before_sunset",
"date_after_sunset",
]
@pytest.mark.parametrize( @pytest.mark.parametrize(
( ("location_data", "test_time", "results", "language", "sensor"),
"now",
"tzname",
"latitude",
"longitude",
"language",
"sensor",
"diaspora",
"result",
"attrs",
),
TEST_PARAMS, TEST_PARAMS,
ids=TEST_IDS, indirect=["location_data", "test_time", "results"],
) )
@pytest.mark.usefixtures("entity_registry_enabled_by_default") @pytest.mark.usefixtures("entity_registry_enabled_by_default", "setup_at_time")
async def test_jewish_calendar_sensor( async def test_jewish_calendar_sensor(
hass: HomeAssistant, hass: HomeAssistant, results: dict[str, Any], sensor: str
now,
tzname,
latitude,
longitude,
language,
sensor,
diaspora,
result,
attrs,
) -> None: ) -> None:
"""Test Jewish calendar sensor output.""" """Test Jewish calendar sensor output."""
time_zone = dt_util.get_time_zone(tzname) result = results["state"]
test_time = now.replace(tzinfo=time_zone) if isinstance(result, dt):
result = dt_util.as_utc(result).isoformat()
await hass.config.async_set_time_zone(tzname)
hass.config.latitude = latitude
hass.config.longitude = longitude
with freeze_time(test_time):
entry = MockConfigEntry(
title=DEFAULT_NAME,
domain=DOMAIN,
data={
CONF_LANGUAGE: language,
CONF_DIASPORA: diaspora,
},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
future = test_time + timedelta(seconds=30)
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
result = (
dt_util.as_utc(result.replace(tzinfo=time_zone)).isoformat()
if isinstance(result, dt)
else result
)
sensor_object = hass.states.get(f"sensor.jewish_calendar_{sensor}") sensor_object = hass.states.get(f"sensor.jewish_calendar_{sensor}")
assert sensor_object.state == result assert sensor_object.state == result
if attrs: if attrs := results.get("attr"):
assert sensor_object.attributes == attrs assert sensor_object.attributes == attrs
SHABBAT_PARAMS = [ SHABBAT_PARAMS = [
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 1, 16, 0), dt(2018, 9, 1, 16, 0),
{ {
"english_upcoming_candle_lighting": dt(2018, 8, 31, 19, 12), "english_upcoming_candle_lighting": dt(2018, 8, 31, 19, 12),
@ -286,8 +188,11 @@ SHABBAT_PARAMS = [
"english_parshat_hashavua": "Ki Tavo", "english_parshat_hashavua": "Ki Tavo",
"hebrew_parshat_hashavua": "כי תבוא", "hebrew_parshat_hashavua": "כי תבוא",
}, },
None,
id="currently_first_shabbat",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 1, 16, 0), dt(2018, 9, 1, 16, 0),
{ {
"english_upcoming_candle_lighting": dt(2018, 8, 31, 19, 12), "english_upcoming_candle_lighting": dt(2018, 8, 31, 19, 12),
@ -297,9 +202,11 @@ SHABBAT_PARAMS = [
"english_parshat_hashavua": "Ki Tavo", "english_parshat_hashavua": "Ki Tavo",
"hebrew_parshat_hashavua": "כי תבוא", "hebrew_parshat_hashavua": "כי תבוא",
}, },
havdalah_offset=50, 50, # Havdalah offset
id="currently_first_shabbat_with_havdalah_offset",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 1, 20, 0), dt(2018, 9, 1, 20, 0),
{ {
"english_upcoming_shabbat_candle_lighting": dt(2018, 8, 31, 19, 12), "english_upcoming_shabbat_candle_lighting": dt(2018, 8, 31, 19, 12),
@ -309,8 +216,11 @@ SHABBAT_PARAMS = [
"english_parshat_hashavua": "Ki Tavo", "english_parshat_hashavua": "Ki Tavo",
"hebrew_parshat_hashavua": "כי תבוא", "hebrew_parshat_hashavua": "כי תבוא",
}, },
None,
id="currently_first_shabbat_bein_hashmashot_lagging_date",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 1, 20, 21), dt(2018, 9, 1, 20, 21),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 7, 19), "english_upcoming_candle_lighting": dt(2018, 9, 7, 19),
@ -320,8 +230,11 @@ SHABBAT_PARAMS = [
"english_parshat_hashavua": "Nitzavim", "english_parshat_hashavua": "Nitzavim",
"hebrew_parshat_hashavua": "נצבים", "hebrew_parshat_hashavua": "נצבים",
}, },
None,
id="after_first_shabbat",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 7, 13, 1), dt(2018, 9, 7, 13, 1),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 7, 19), "english_upcoming_candle_lighting": dt(2018, 9, 7, 19),
@ -331,8 +244,11 @@ SHABBAT_PARAMS = [
"english_parshat_hashavua": "Nitzavim", "english_parshat_hashavua": "Nitzavim",
"hebrew_parshat_hashavua": "נצבים", "hebrew_parshat_hashavua": "נצבים",
}, },
None,
id="friday_upcoming_shabbat",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 8, 21, 25), dt(2018, 9, 8, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 9, 18, 57), "english_upcoming_candle_lighting": dt(2018, 9, 9, 18, 57),
@ -344,8 +260,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Erev Rosh Hashana", "english_holiday": "Erev Rosh Hashana",
"hebrew_holiday": "ערב ראש השנה", "hebrew_holiday": "ערב ראש השנה",
}, },
None,
id="upcoming_rosh_hashana",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 9, 21, 25), dt(2018, 9, 9, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 9, 18, 57), "english_upcoming_candle_lighting": dt(2018, 9, 9, 18, 57),
@ -357,8 +276,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Rosh Hashana I", "english_holiday": "Rosh Hashana I",
"hebrew_holiday": "א' ראש השנה", "hebrew_holiday": "א' ראש השנה",
}, },
None,
id="currently_rosh_hashana",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 10, 21, 25), dt(2018, 9, 10, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 9, 18, 57), "english_upcoming_candle_lighting": dt(2018, 9, 9, 18, 57),
@ -370,8 +292,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Rosh Hashana II", "english_holiday": "Rosh Hashana II",
"hebrew_holiday": "ב' ראש השנה", "hebrew_holiday": "ב' ראש השנה",
}, },
None,
id="second_day_rosh_hashana",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 28, 21, 25), dt(2018, 9, 28, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 28, 18, 25), "english_upcoming_candle_lighting": dt(2018, 9, 28, 18, 25),
@ -381,8 +306,11 @@ SHABBAT_PARAMS = [
"english_parshat_hashavua": "none", "english_parshat_hashavua": "none",
"hebrew_parshat_hashavua": "none", "hebrew_parshat_hashavua": "none",
}, },
None,
id="currently_shabbat_chol_hamoed",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 29, 21, 25), dt(2018, 9, 29, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 30, 18, 22), "english_upcoming_candle_lighting": dt(2018, 9, 30, 18, 22),
@ -394,8 +322,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Hoshana Raba", "english_holiday": "Hoshana Raba",
"hebrew_holiday": "הושענא רבה", "hebrew_holiday": "הושענא רבה",
}, },
None,
id="upcoming_two_day_yomtov_in_diaspora",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 9, 30, 21, 25), dt(2018, 9, 30, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 30, 18, 22), "english_upcoming_candle_lighting": dt(2018, 9, 30, 18, 22),
@ -407,8 +338,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Shmini Atzeret", "english_holiday": "Shmini Atzeret",
"hebrew_holiday": "שמיני עצרת", "hebrew_holiday": "שמיני עצרת",
}, },
None,
id="currently_first_day_of_two_day_yomtov_in_diaspora",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2018, 10, 1, 21, 25), dt(2018, 10, 1, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 30, 18, 22), "english_upcoming_candle_lighting": dt(2018, 9, 30, 18, 22),
@ -420,11 +354,14 @@ SHABBAT_PARAMS = [
"english_holiday": "Simchat Torah", "english_holiday": "Simchat Torah",
"hebrew_holiday": "שמחת תורה", "hebrew_holiday": "שמחת תורה",
}, },
None,
id="currently_second_day_of_two_day_yomtov_in_diaspora",
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2018, 9, 29, 21, 25), dt(2018, 9, 29, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 30, 17, 45), "english_upcoming_candle_lighting": dt(2018, 9, 30, 17, 46),
"english_upcoming_havdalah": dt(2018, 10, 1, 19, 1), "english_upcoming_havdalah": dt(2018, 10, 1, 19, 1),
"english_upcoming_shabbat_candle_lighting": dt(2018, 10, 5, 17, 39), "english_upcoming_shabbat_candle_lighting": dt(2018, 10, 5, 17, 39),
"english_upcoming_shabbat_havdalah": dt(2018, 10, 6, 18, 54), "english_upcoming_shabbat_havdalah": dt(2018, 10, 6, 18, 54),
@ -433,11 +370,14 @@ SHABBAT_PARAMS = [
"english_holiday": "Hoshana Raba", "english_holiday": "Hoshana Raba",
"hebrew_holiday": "הושענא רבה", "hebrew_holiday": "הושענא רבה",
}, },
None,
id="upcoming_one_day_yom_tov_in_israel",
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2018, 9, 30, 21, 25), dt(2018, 9, 30, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 9, 30, 17, 45), "english_upcoming_candle_lighting": dt(2018, 9, 30, 17, 46),
"english_upcoming_havdalah": dt(2018, 10, 1, 19, 1), "english_upcoming_havdalah": dt(2018, 10, 1, 19, 1),
"english_upcoming_shabbat_candle_lighting": dt(2018, 10, 5, 17, 39), "english_upcoming_shabbat_candle_lighting": dt(2018, 10, 5, 17, 39),
"english_upcoming_shabbat_havdalah": dt(2018, 10, 6, 18, 54), "english_upcoming_shabbat_havdalah": dt(2018, 10, 6, 18, 54),
@ -446,8 +386,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Shmini Atzeret, Simchat Torah", "english_holiday": "Shmini Atzeret, Simchat Torah",
"hebrew_holiday": "שמיני עצרת, שמחת תורה", "hebrew_holiday": "שמיני עצרת, שמחת תורה",
}, },
None,
id="currently_one_day_yom_tov_in_israel",
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2018, 10, 1, 21, 25), dt(2018, 10, 1, 21, 25),
{ {
"english_upcoming_candle_lighting": dt(2018, 10, 5, 17, 39), "english_upcoming_candle_lighting": dt(2018, 10, 5, 17, 39),
@ -457,8 +400,11 @@ SHABBAT_PARAMS = [
"english_parshat_hashavua": "Bereshit", "english_parshat_hashavua": "Bereshit",
"hebrew_parshat_hashavua": "בראשית", "hebrew_parshat_hashavua": "בראשית",
}, },
None,
id="after_one_day_yom_tov_in_israel",
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2016, 6, 11, 8, 25), dt(2016, 6, 11, 8, 25),
{ {
"english_upcoming_candle_lighting": dt(2016, 6, 10, 20, 9), "english_upcoming_candle_lighting": dt(2016, 6, 10, 20, 9),
@ -470,8 +416,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Erev Shavuot", "english_holiday": "Erev Shavuot",
"hebrew_holiday": "ערב שבועות", "hebrew_holiday": "ערב שבועות",
}, },
None,
id="currently_first_day_of_three_day_type1_yomtov_in_diaspora", # Type 1 = Sat/Sun/Mon
), ),
make_nyc_test_params( pytest.param(
"New York",
dt(2016, 6, 12, 8, 25), dt(2016, 6, 12, 8, 25),
{ {
"english_upcoming_candle_lighting": dt(2016, 6, 10, 20, 9), "english_upcoming_candle_lighting": dt(2016, 6, 10, 20, 9),
@ -483,8 +432,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Shavuot", "english_holiday": "Shavuot",
"hebrew_holiday": "שבועות", "hebrew_holiday": "שבועות",
}, },
None,
id="currently_second_day_of_three_day_type1_yomtov_in_diaspora", # Type 1 = Sat/Sun/Mon
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2017, 9, 21, 8, 25), dt(2017, 9, 21, 8, 25),
{ {
"english_upcoming_candle_lighting": dt(2017, 9, 20, 17, 58), "english_upcoming_candle_lighting": dt(2017, 9, 20, 17, 58),
@ -496,8 +448,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Rosh Hashana I", "english_holiday": "Rosh Hashana I",
"hebrew_holiday": "א' ראש השנה", "hebrew_holiday": "א' ראש השנה",
}, },
None,
id="currently_first_day_of_three_day_type2_yomtov_in_israel", # Type 2 = Thurs/Fri/Sat
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2017, 9, 22, 8, 25), dt(2017, 9, 22, 8, 25),
{ {
"english_upcoming_candle_lighting": dt(2017, 9, 20, 17, 58), "english_upcoming_candle_lighting": dt(2017, 9, 20, 17, 58),
@ -509,8 +464,11 @@ SHABBAT_PARAMS = [
"english_holiday": "Rosh Hashana II", "english_holiday": "Rosh Hashana II",
"hebrew_holiday": "ב' ראש השנה", "hebrew_holiday": "ב' ראש השנה",
}, },
None,
id="currently_second_day_of_three_day_type2_yomtov_in_israel", # Type 2 = Thurs/Fri/Sat
), ),
make_jerusalem_test_params( pytest.param(
"Jerusalem",
dt(2017, 9, 23, 8, 25), dt(2017, 9, 23, 8, 25),
{ {
"english_upcoming_candle_lighting": dt(2017, 9, 20, 17, 58), "english_upcoming_candle_lighting": dt(2017, 9, 20, 17, 58),
@ -522,179 +480,70 @@ SHABBAT_PARAMS = [
"english_holiday": "", "english_holiday": "",
"hebrew_holiday": "", "hebrew_holiday": "",
}, },
None,
id="currently_third_day_of_three_day_type2_yomtov_in_israel", # Type 2 = Thurs/Fri/Sat
), ),
] ]
SHABBAT_TEST_IDS = [
"currently_first_shabbat",
"currently_first_shabbat_with_havdalah_offset",
"currently_first_shabbat_bein_hashmashot_lagging_date",
"after_first_shabbat",
"friday_upcoming_shabbat",
"upcoming_rosh_hashana",
"currently_rosh_hashana",
"second_day_rosh_hashana",
"currently_shabbat_chol_hamoed",
"upcoming_two_day_yomtov_in_diaspora",
"currently_first_day_of_two_day_yomtov_in_diaspora",
"currently_second_day_of_two_day_yomtov_in_diaspora",
"upcoming_one_day_yom_tov_in_israel",
"currently_one_day_yom_tov_in_israel",
"after_one_day_yom_tov_in_israel",
# Type 1 = Sat/Sun/Mon
"currently_first_day_of_three_day_type1_yomtov_in_diaspora",
"currently_second_day_of_three_day_type1_yomtov_in_diaspora",
# Type 2 = Thurs/Fri/Sat
"currently_first_day_of_three_day_type2_yomtov_in_israel",
"currently_second_day_of_three_day_type2_yomtov_in_israel",
"currently_third_day_of_three_day_type2_yomtov_in_israel",
]
@pytest.mark.parametrize("language", ["english", "hebrew"]) @pytest.mark.parametrize("language", ["english", "hebrew"])
@pytest.mark.parametrize( @pytest.mark.parametrize(
( ("location_data", "test_time", "results", "havdalah_offset"),
"now",
"candle_lighting",
"havdalah",
"diaspora",
"tzname",
"latitude",
"longitude",
"result",
),
SHABBAT_PARAMS, SHABBAT_PARAMS,
ids=SHABBAT_TEST_IDS, indirect=("location_data", "test_time", "results"),
) )
@pytest.mark.usefixtures("entity_registry_enabled_by_default") @pytest.mark.usefixtures("entity_registry_enabled_by_default", "setup_at_time")
async def test_shabbat_times_sensor( async def test_shabbat_times_sensor(
hass: HomeAssistant, hass: HomeAssistant, results: dict[str, Any], language: str
language,
now,
candle_lighting,
havdalah,
diaspora,
tzname,
latitude,
longitude,
result,
) -> None: ) -> None:
"""Test sensor output for upcoming shabbat/yomtov times.""" """Test sensor output for upcoming shabbat/yomtov times."""
time_zone = dt_util.get_time_zone(tzname) for sensor_type, result_value in results.items():
test_time = now.replace(tzinfo=time_zone)
await hass.config.async_set_time_zone(tzname)
hass.config.latitude = latitude
hass.config.longitude = longitude
with freeze_time(test_time):
entry = MockConfigEntry(
title=DEFAULT_NAME,
domain=DOMAIN,
data={
CONF_LANGUAGE: language,
CONF_DIASPORA: diaspora,
},
options={
CONF_CANDLE_LIGHT_MINUTES: candle_lighting,
CONF_HAVDALAH_OFFSET_MINUTES: havdalah,
},
)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
future = test_time + timedelta(seconds=30)
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
for sensor_type, result_value in result.items():
if not sensor_type.startswith(language): if not sensor_type.startswith(language):
continue continue
sensor_type = sensor_type.replace(f"{language}_", "") sensor_type = sensor_type.replace(f"{language}_", "")
result_value = ( if isinstance(result_value, dt):
dt_util.as_utc(result_value).isoformat() result_value = dt_util.as_utc(result_value).isoformat()
if isinstance(result_value, dt)
else result_value
)
assert hass.states.get(f"sensor.jewish_calendar_{sensor_type}").state == str( assert hass.states.get(f"sensor.jewish_calendar_{sensor_type}").state == str(
result_value result_value
), f"Value for {sensor_type}" ), f"Value for {sensor_type}"
OMER_PARAMS = [ @pytest.mark.parametrize(
(dt(2019, 4, 21, 0), "1"), ("test_time", "results"),
(dt(2019, 4, 21, 23), "2"), [
(dt(2019, 5, 23, 0), "33"), pytest.param(dt(2019, 4, 21, 0), "1", id="first_day_of_omer"),
(dt(2019, 6, 8, 0), "49"), pytest.param(dt(2019, 4, 21, 23), "2", id="first_day_of_omer_after_tzeit"),
(dt(2019, 6, 9, 0), "0"), pytest.param(dt(2019, 5, 23, 0), "33", id="lag_baomer"),
(dt(2019, 1, 1, 0), "0"), pytest.param(dt(2019, 6, 8, 0), "49", id="last_day_of_omer"),
] pytest.param(dt(2019, 6, 9, 0), "0", id="shavuot_no_omer"),
OMER_TEST_IDS = [ pytest.param(dt(2019, 1, 1, 0), "0", id="jan_1st_no_omer"),
"first_day_of_omer", ],
"first_day_of_omer_after_tzeit", indirect=True,
"lag_baomer", )
"last_day_of_omer", @pytest.mark.usefixtures("entity_registry_enabled_by_default", "setup_at_time")
"shavuot_no_omer", async def test_omer_sensor(hass: HomeAssistant, results: str) -> None:
"jan_1st_no_omer",
]
@pytest.mark.parametrize(("test_time", "result"), OMER_PARAMS, ids=OMER_TEST_IDS)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_omer_sensor(hass: HomeAssistant, test_time, result) -> None:
"""Test Omer Count sensor output.""" """Test Omer Count sensor output."""
test_time = test_time.replace(tzinfo=dt_util.get_time_zone(hass.config.time_zone)) assert hass.states.get("sensor.jewish_calendar_day_of_the_omer").state == results
with freeze_time(test_time):
entry = MockConfigEntry(title=DEFAULT_NAME, domain=DOMAIN)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
future = test_time + timedelta(seconds=30)
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get("sensor.jewish_calendar_day_of_the_omer").state == result
DAFYOMI_PARAMS = [ @pytest.mark.parametrize(
(dt(2014, 4, 28, 0), "Beitzah 29"), ("test_time", "results"),
(dt(2020, 1, 4, 0), "Niddah 73"), [
(dt(2020, 1, 5, 0), "Berachos 2"), pytest.param(dt(2014, 4, 28, 0), "Beitzah 29", id="randomly_picked_date"),
(dt(2020, 3, 7, 0), "Berachos 64"), pytest.param(dt(2020, 1, 4, 0), "Niddah 73", id="end_of_cycle13"),
(dt(2020, 3, 8, 0), "Shabbos 2"), pytest.param(dt(2020, 1, 5, 0), "Berachos 2", id="start_of_cycle14"),
] pytest.param(dt(2020, 3, 7, 0), "Berachos 64", id="cycle14_end_of_berachos"),
DAFYOMI_TEST_IDS = [ pytest.param(dt(2020, 3, 8, 0), "Shabbos 2", id="cycle14_start_of_shabbos"),
"randomly_picked_date", ],
"end_of_cycle13", indirect=True,
"start_of_cycle14", )
"cycle14_end_of_berachos", @pytest.mark.usefixtures("entity_registry_enabled_by_default", "setup_at_time")
"cycle14_start_of_shabbos", async def test_dafyomi_sensor(hass: HomeAssistant, results: str) -> None:
]
@pytest.mark.parametrize(("test_time", "result"), DAFYOMI_PARAMS, ids=DAFYOMI_TEST_IDS)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_dafyomi_sensor(hass: HomeAssistant, test_time, result) -> None:
"""Test Daf Yomi sensor output.""" """Test Daf Yomi sensor output."""
test_time = test_time.replace(tzinfo=dt_util.get_time_zone(hass.config.time_zone)) assert hass.states.get("sensor.jewish_calendar_daf_yomi").state == results
with freeze_time(test_time):
entry = MockConfigEntry(title=DEFAULT_NAME, domain=DOMAIN)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
future = test_time + timedelta(seconds=30)
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get("sensor.jewish_calendar_daf_yomi").state == result
async def test_no_discovery_info( async def test_no_discovery_info(

View File

@ -33,15 +33,15 @@ from tests.common import MockConfigEntry
) )
async def test_get_omer_blessing( async def test_get_omer_blessing(
hass: HomeAssistant, hass: HomeAssistant,
mock_config_entry: MockConfigEntry, config_entry: MockConfigEntry,
test_date: dt.date, test_date: dt.date,
nusach: str, nusach: str,
language: Language, language: Language,
expected: str, expected: str,
) -> None: ) -> None:
"""Test get omer blessing.""" """Test get omer blessing."""
mock_config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
result = await hass.services.async_call( result = await hass.services.async_call(