Skip to content

Commit

Permalink
More binary sensor tests
Browse files Browse the repository at this point in the history
  • Loading branch information
pnbruckner committed Mar 10, 2024
1 parent 98a670a commit aaea2c9
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 2 deletions.
140 changes: 139 additions & 1 deletion tests/test_binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
"""Test binary_sensor module."""
from __future__ import annotations

from datetime import datetime, time, timedelta
from datetime import date, datetime, time, timedelta
from unittest.mock import patch
import pytest
from pytest import LogCaptureFixture

from astral import LocationInfo
from astral.location import Location

from pytest_homeassistant_custom_component.common import (
async_fire_time_changed,
Expand Down Expand Up @@ -85,3 +89,137 @@ async def test_yaml_binary_sensor(
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == STATE_ON


@pytest.mark.parametrize(
"elevation,expected_state",
(
(85, STATE_OFF),
(-85, STATE_ON),
),
)
async def test_always_on_or_off(
hass: HomeAssistant,
entity_registry: EntityRegistry,
caplog: LogCaptureFixture,
elevation: float,
expected_state: str,
) -> None:
"""Test a binary sensor that is always on or off."""
config = NY_CONFIG | {
"binary_sensors": [
{
"unique_id": "bs1",
"elevation": elevation,
}
]
}

tz = dt_util.get_time_zone(NY_CONFIG["time_zone"])
base_time = dt_util.now(tz)

# Set time to 00:00:00 tommorow.
now = datetime.combine((base_time + timedelta(1)).date(), time()).replace(tzinfo=tz)

with patch("homeassistant.util.dt.now", return_value=now):
with assert_setup_component(1, DOMAIN):
await async_setup_component(hass, DOMAIN, {DOMAIN: [config]})
await hass.async_block_till_done()

config_entry = hass.config_entries.async_entries(DOMAIN)[0]
entity_id = entity_registry.async_get_entity_id(
"binary_sensor", DOMAIN, f"{config_entry.entry_id}-bs1"
)
assert entity_id

# Check that state is as expected.
state = hass.states.get(entity_id)
assert state
assert state.state == expected_state
assert state.attributes["next_change"] is None

# Check that there is an appropraite ERROR message.
assert any(
rec.levelname == "ERROR" and "Sun elevation never reaches" in rec.message
for rec in caplog.get_records("call")
)

# Move time to noon.
noon = now.replace(hour=12)
with patch("homeassistant.util.dt.now", return_value=noon):
async_fire_time_changed(hass, noon)
await hass.async_block_till_done()

# Check that state is still the same.
state = hass.states.get(entity_id)
assert state
assert state.state == expected_state
assert state.attributes["next_change"] is None

# Check that there is an appropraite ERROR message.
assert any(
rec.levelname == "ERROR" and "Sun elevation never reaches" in rec.message
for rec in caplog.get_records("call")
)


@pytest.mark.parametrize(
"func,offset,expected_state", (("midnight", -1, STATE_ON), ("noon", 1, STATE_OFF))
)
async def test_next_change_greater_than_one_day(
hass: HomeAssistant,
entity_registry: EntityRegistry,
caplog: LogCaptureFixture,
func: str,
offset: int,
expected_state: str,
) -> None:
"""Test when binary sensor won't change for more than one day."""
config = NY_CONFIG | {
"binary_sensors": [
{
"unique_id": "bs1",
}
]
}

tz_str = NY_CONFIG["time_zone"]
lat = NY_CONFIG["latitude"]
lon = NY_CONFIG["longitude"]
obs_elv = NY_CONFIG["elevation"]
loc = Location(LocationInfo("", "", tz_str, lat, lon))
tz = dt_util.get_time_zone(tz_str)

# Get next year's September 20, since on this date neither the min nor max elevation
# is near their extremes in New York, NY. Then get the min or max sun elevations.
now_date = date(dt_util.now().year + 1, 9, 20)
elv = loc.solar_elevation(getattr(loc, func)(now_date), obs_elv)

# Configure sensor with an elevation threshold just below or above.
config["binary_sensors"][0]["elevation"] = elv + offset

# Set time to midnight on that date.
now = datetime.combine(now_date, time()).replace(tzinfo=tz)

with patch("homeassistant.util.dt.now", return_value=now):
with assert_setup_component(1, DOMAIN):
await async_setup_component(hass, DOMAIN, {DOMAIN: [config]})
await hass.async_block_till_done()

config_entry = hass.config_entries.async_entries(DOMAIN)[0]
entity_id = entity_registry.async_get_entity_id(
"binary_sensor", DOMAIN, f"{config_entry.entry_id}-bs1"
)
assert entity_id

# Check that state is on & next_change has a value.
state = hass.states.get(entity_id)
assert state
assert state.state == expected_state
assert state.attributes["next_change"]

# Check that there is an appropraite WARNING message.
assert any(
rec.levelname == "WARNING" and "Sun elevation will not reach" in rec.message
for rec in caplog.get_records("call")
)
10 changes: 9 additions & 1 deletion tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@

from custom_components.sun2.const import DOMAIN

from .const import HOME_CONFIG, HW_CONFIG, HW_LOC, NY_CONFIG, NY_LOC, TWINE_CONFIG, TWINE_LOC
from .const import (
HOME_CONFIG,
HW_CONFIG,
HW_LOC,
NY_CONFIG,
NY_LOC,
TWINE_CONFIG,
TWINE_LOC,
)


async def test_basic_yaml_config(
Expand Down

0 comments on commit aaea2c9

Please sign in to comment.