mirror of
https://github.com/home-assistant/core.git
synced 2025-07-14 16:57:10 +00:00
Improve tests for binary sensor template (#147657)
This commit is contained in:
parent
4cab3a0465
commit
b8500b338a
@ -1,9 +1,10 @@
|
|||||||
"""The tests for the Template Binary sensor platform."""
|
"""The tests for the Template Binary sensor platform."""
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from datetime import UTC, datetime, timedelta
|
from datetime import UTC, datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
from unittest.mock import patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
@ -22,8 +23,8 @@ from homeassistant.const import (
|
|||||||
from homeassistant.core import Context, CoreState, HomeAssistant, State
|
from homeassistant.core import Context, CoreState, HomeAssistant, State
|
||||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
from homeassistant.helpers.entity_component import async_update_entity
|
from homeassistant.helpers.entity_component import async_update_entity
|
||||||
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util import dt as dt_util
|
|
||||||
|
|
||||||
from tests.common import (
|
from tests.common import (
|
||||||
MockConfigEntry,
|
MockConfigEntry,
|
||||||
@ -33,6 +34,16 @@ from tests.common import (
|
|||||||
mock_restore_cache_with_extra_data,
|
mock_restore_cache_with_extra_data,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_BEER_TRIGGER_VALUE_TEMPLATE = (
|
||||||
|
"{% if trigger.event.data.beer < 0 %}"
|
||||||
|
"{{ 1 / 0 == 10 }}"
|
||||||
|
"{% elif trigger.event.data.beer == 0 %}"
|
||||||
|
"{{ None }}"
|
||||||
|
"{% else %}"
|
||||||
|
"{{ trigger.event.data.beer == 2 }}"
|
||||||
|
"{% endif %}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("count", [1])
|
@pytest.mark.parametrize("count", [1])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@ -70,7 +81,9 @@ from tests.common import (
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_setup_minimal(hass: HomeAssistant, entity_id, name, attributes) -> None:
|
async def test_setup_minimal(
|
||||||
|
hass: HomeAssistant, entity_id: str, name: str, attributes: dict[str, str]
|
||||||
|
) -> None:
|
||||||
"""Test the setup."""
|
"""Test the setup."""
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
@ -115,7 +128,7 @@ async def test_setup_minimal(hass: HomeAssistant, entity_id, name, attributes) -
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_setup(hass: HomeAssistant, entity_id) -> None:
|
async def test_setup(hass: HomeAssistant, entity_id: str) -> None:
|
||||||
"""Test the setup."""
|
"""Test the setup."""
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
@ -232,11 +245,59 @@ async def test_setup_config_entry(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_setup_invalid_sensors(hass: HomeAssistant, count) -> None:
|
async def test_setup_invalid_sensors(hass: HomeAssistant, count: int) -> None:
|
||||||
"""Test setup with no sensors."""
|
"""Test setup with no sensors."""
|
||||||
assert len(hass.states.async_entity_ids("binary_sensor")) == count
|
assert len(hass.states.async_entity_ids("binary_sensor")) == count
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("state_template", "expected_result"),
|
||||||
|
[
|
||||||
|
("{{ None }}", STATE_OFF),
|
||||||
|
("{{ True }}", STATE_ON),
|
||||||
|
("{{ False }}", STATE_OFF),
|
||||||
|
("{{ 1 }}", STATE_ON),
|
||||||
|
(
|
||||||
|
"{% if states('binary_sensor.three') in ('unknown','unavailable') %}"
|
||||||
|
"{{ None }}"
|
||||||
|
"{% else %}"
|
||||||
|
"{{ states('binary_sensor.three') == 'off' }}"
|
||||||
|
"{% endif %}",
|
||||||
|
STATE_OFF,
|
||||||
|
),
|
||||||
|
("{{ 1 / 0 == 10 }}", STATE_UNAVAILABLE),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_state(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
state_template: str,
|
||||||
|
expected_result: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test the config flow."""
|
||||||
|
hass.states.async_set("binary_sensor.one", "on")
|
||||||
|
hass.states.async_set("binary_sensor.two", "off")
|
||||||
|
hass.states.async_set("binary_sensor.three", "unknown")
|
||||||
|
|
||||||
|
template_config_entry = MockConfigEntry(
|
||||||
|
data={},
|
||||||
|
domain=template.DOMAIN,
|
||||||
|
options={
|
||||||
|
"name": "My template",
|
||||||
|
"state": state_template,
|
||||||
|
"template_type": binary_sensor.DOMAIN,
|
||||||
|
},
|
||||||
|
title="My template",
|
||||||
|
)
|
||||||
|
template_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
assert await hass.config_entries.async_setup(template_config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("binary_sensor.my_template")
|
||||||
|
assert state is not None
|
||||||
|
assert state.state == expected_result
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("count", [1])
|
@pytest.mark.parametrize("count", [1])
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("config", "domain", "entity_id"),
|
("config", "domain", "entity_id"),
|
||||||
@ -279,7 +340,7 @@ async def test_setup_invalid_sensors(hass: HomeAssistant, count) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_icon_template(hass: HomeAssistant, entity_id) -> None:
|
async def test_icon_template(hass: HomeAssistant, entity_id: str) -> None:
|
||||||
"""Test icon template."""
|
"""Test icon template."""
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes.get("icon") == ""
|
assert state.attributes.get("icon") == ""
|
||||||
@ -332,7 +393,7 @@ async def test_icon_template(hass: HomeAssistant, entity_id) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_entity_picture_template(hass: HomeAssistant, entity_id) -> None:
|
async def test_entity_picture_template(hass: HomeAssistant, entity_id: str) -> None:
|
||||||
"""Test entity_picture template."""
|
"""Test entity_picture template."""
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes.get("entity_picture") == ""
|
assert state.attributes.get("entity_picture") == ""
|
||||||
@ -381,7 +442,7 @@ async def test_entity_picture_template(hass: HomeAssistant, entity_id) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_attribute_templates(hass: HomeAssistant, entity_id) -> None:
|
async def test_attribute_templates(hass: HomeAssistant, entity_id: str) -> None:
|
||||||
"""Test attribute_templates template."""
|
"""Test attribute_templates template."""
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.attributes.get("test_attribute") == "It ."
|
assert state.attributes.get("test_attribute") == "It ."
|
||||||
@ -394,7 +455,7 @@ async def test_attribute_templates(hass: HomeAssistant, entity_id) -> None:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def setup_mock():
|
def setup_mock() -> Generator[Mock]:
|
||||||
"""Do setup of sensor mock."""
|
"""Do setup of sensor mock."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.template.binary_sensor."
|
"homeassistant.components.template.binary_sensor."
|
||||||
@ -426,7 +487,7 @@ async def setup_mock():
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_match_all(hass: HomeAssistant, setup_mock) -> None:
|
async def test_match_all(hass: HomeAssistant, setup_mock: Mock) -> None:
|
||||||
"""Test template that is rerendered on any state lifecycle."""
|
"""Test template that is rerendered on any state lifecycle."""
|
||||||
init_calls = len(setup_mock.mock_calls)
|
init_calls = len(setup_mock.mock_calls)
|
||||||
|
|
||||||
@ -565,7 +626,9 @@ async def test_event(hass: HomeAssistant) -> None:
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_template_delay_on_off(hass: HomeAssistant) -> None:
|
async def test_template_delay_on_off(
|
||||||
|
hass: HomeAssistant, freezer: FrozenDateTimeFactory
|
||||||
|
) -> None:
|
||||||
"""Test binary sensor template delay on."""
|
"""Test binary sensor template delay on."""
|
||||||
# Ensure the initial state is not on
|
# Ensure the initial state is not on
|
||||||
assert hass.states.get("binary_sensor.test_on").state != STATE_ON
|
assert hass.states.get("binary_sensor.test_on").state != STATE_ON
|
||||||
@ -577,8 +640,8 @@ async def test_template_delay_on_off(hass: HomeAssistant) -> None:
|
|||||||
assert hass.states.get("binary_sensor.test_on").state == STATE_OFF
|
assert hass.states.get("binary_sensor.test_on").state == STATE_OFF
|
||||||
assert hass.states.get("binary_sensor.test_off").state == STATE_ON
|
assert hass.states.get("binary_sensor.test_off").state == STATE_ON
|
||||||
|
|
||||||
future = dt_util.utcnow() + timedelta(seconds=5)
|
freezer.tick(timedelta(seconds=5))
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get("binary_sensor.test_on").state == STATE_ON
|
assert hass.states.get("binary_sensor.test_on").state == STATE_ON
|
||||||
assert hass.states.get("binary_sensor.test_off").state == STATE_ON
|
assert hass.states.get("binary_sensor.test_off").state == STATE_ON
|
||||||
@ -599,8 +662,8 @@ async def test_template_delay_on_off(hass: HomeAssistant) -> None:
|
|||||||
assert hass.states.get("binary_sensor.test_on").state == STATE_OFF
|
assert hass.states.get("binary_sensor.test_on").state == STATE_OFF
|
||||||
assert hass.states.get("binary_sensor.test_off").state == STATE_ON
|
assert hass.states.get("binary_sensor.test_off").state == STATE_ON
|
||||||
|
|
||||||
future = dt_util.utcnow() + timedelta(seconds=5)
|
freezer.tick(timedelta(seconds=5))
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get("binary_sensor.test_on").state == STATE_OFF
|
assert hass.states.get("binary_sensor.test_on").state == STATE_OFF
|
||||||
assert hass.states.get("binary_sensor.test_off").state == STATE_OFF
|
assert hass.states.get("binary_sensor.test_off").state == STATE_OFF
|
||||||
@ -645,7 +708,7 @@ async def test_template_delay_on_off(hass: HomeAssistant) -> None:
|
|||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_available_without_availability_template(
|
async def test_available_without_availability_template(
|
||||||
hass: HomeAssistant, entity_id
|
hass: HomeAssistant, entity_id: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Ensure availability is true without an availability_template."""
|
"""Ensure availability is true without an availability_template."""
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
@ -694,7 +757,7 @@ async def test_available_without_availability_template(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_availability_template(hass: HomeAssistant, entity_id) -> None:
|
async def test_availability_template(hass: HomeAssistant, entity_id: str) -> None:
|
||||||
"""Test availability template."""
|
"""Test availability template."""
|
||||||
hass.states.async_set("sensor.test_state", STATE_OFF)
|
hass.states.async_set("sensor.test_state", STATE_OFF)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -731,7 +794,7 @@ async def test_availability_template(hass: HomeAssistant, entity_id) -> None:
|
|||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_invalid_attribute_template(
|
async def test_invalid_attribute_template(
|
||||||
hass: HomeAssistant, caplog_setup_text
|
hass: HomeAssistant, caplog_setup_text: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that errors are logged if rendering template fails."""
|
"""Test that errors are logged if rendering template fails."""
|
||||||
hass.states.async_set("binary_sensor.test_sensor", STATE_ON)
|
hass.states.async_set("binary_sensor.test_sensor", STATE_ON)
|
||||||
@ -759,7 +822,7 @@ async def test_invalid_attribute_template(
|
|||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_invalid_availability_template_keeps_component_available(
|
async def test_invalid_availability_template_keeps_component_available(
|
||||||
hass: HomeAssistant, caplog_setup_text
|
hass: HomeAssistant, caplog_setup_text: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that an invalid availability keeps the device available."""
|
"""Test that an invalid availability keeps the device available."""
|
||||||
|
|
||||||
@ -767,9 +830,7 @@ async def test_invalid_availability_template_keeps_component_available(
|
|||||||
assert "UndefinedError: 'x' is undefined" in caplog_setup_text
|
assert "UndefinedError: 'x' is undefined" in caplog_setup_text
|
||||||
|
|
||||||
|
|
||||||
async def test_no_update_template_match_all(
|
async def test_no_update_template_match_all(hass: HomeAssistant) -> None:
|
||||||
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
|
|
||||||
) -> None:
|
|
||||||
"""Test that we do not update sensors that match on all."""
|
"""Test that we do not update sensors that match on all."""
|
||||||
|
|
||||||
hass.set_state(CoreState.not_running)
|
hass.set_state(CoreState.not_running)
|
||||||
@ -966,7 +1027,7 @@ async def test_template_validation_error(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_availability_icon_picture(hass: HomeAssistant, entity_id) -> None:
|
async def test_availability_icon_picture(hass: HomeAssistant, entity_id: str) -> None:
|
||||||
"""Test name, icon and picture templates are rendered at setup."""
|
"""Test name, icon and picture templates are rendered at setup."""
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state.state == "unavailable"
|
assert state.state == "unavailable"
|
||||||
@ -996,7 +1057,7 @@ async def test_availability_icon_picture(hass: HomeAssistant, entity_id) -> None
|
|||||||
"template": {
|
"template": {
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"state": "{{ states.sensor.test_state.state == 'on' }}",
|
"state": "{{ states.sensor.test_state.state }}",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1029,17 +1090,29 @@ async def test_availability_icon_picture(hass: HomeAssistant, entity_id) -> None
|
|||||||
({"delay_on": 5}, STATE_ON, STATE_OFF, STATE_OFF),
|
({"delay_on": 5}, STATE_ON, STATE_OFF, STATE_OFF),
|
||||||
({"delay_on": 5}, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN),
|
({"delay_on": 5}, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN),
|
||||||
({"delay_on": 5}, STATE_ON, STATE_UNKNOWN, STATE_UNKNOWN),
|
({"delay_on": 5}, STATE_ON, STATE_UNKNOWN, STATE_UNKNOWN),
|
||||||
|
({}, None, STATE_ON, STATE_OFF),
|
||||||
|
({}, None, STATE_OFF, STATE_OFF),
|
||||||
|
({}, None, STATE_UNAVAILABLE, STATE_OFF),
|
||||||
|
({}, None, STATE_UNKNOWN, STATE_OFF),
|
||||||
|
({"delay_off": 5}, None, STATE_ON, STATE_ON),
|
||||||
|
({"delay_off": 5}, None, STATE_OFF, STATE_OFF),
|
||||||
|
({"delay_off": 5}, None, STATE_UNAVAILABLE, STATE_UNKNOWN),
|
||||||
|
({"delay_off": 5}, None, STATE_UNKNOWN, STATE_UNKNOWN),
|
||||||
|
({"delay_on": 5}, None, STATE_ON, STATE_OFF),
|
||||||
|
({"delay_on": 5}, None, STATE_OFF, STATE_OFF),
|
||||||
|
({"delay_on": 5}, None, STATE_UNAVAILABLE, STATE_OFF),
|
||||||
|
({"delay_on": 5}, None, STATE_UNKNOWN, STATE_OFF),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_restore_state(
|
async def test_restore_state(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
count,
|
count: int,
|
||||||
domain,
|
domain: str,
|
||||||
config,
|
config: ConfigType,
|
||||||
extra_config,
|
extra_config: ConfigType,
|
||||||
source_state,
|
source_state: str | None,
|
||||||
restored_state,
|
restored_state: str,
|
||||||
initial_state,
|
initial_state: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test restoring template binary sensor."""
|
"""Test restoring template binary sensor."""
|
||||||
|
|
||||||
@ -1088,7 +1161,7 @@ async def test_restore_state(
|
|||||||
"friendly_name": "Hello Name",
|
"friendly_name": "Hello Name",
|
||||||
"unique_id": "hello_name-id",
|
"unique_id": "hello_name-id",
|
||||||
"device_class": "battery",
|
"device_class": "battery",
|
||||||
"value_template": "{{ trigger.event.data.beer == 2 }}",
|
"value_template": _BEER_TRIGGER_VALUE_TEMPLATE,
|
||||||
"entity_picture_template": "{{ '/local/dogs.png' }}",
|
"entity_picture_template": "{{ '/local/dogs.png' }}",
|
||||||
"icon_template": "{{ 'mdi:pirate' }}",
|
"icon_template": "{{ 'mdi:pirate' }}",
|
||||||
"attribute_templates": {
|
"attribute_templates": {
|
||||||
@ -1101,7 +1174,7 @@ async def test_restore_state(
|
|||||||
"name": "via list",
|
"name": "via list",
|
||||||
"unique_id": "via_list-id",
|
"unique_id": "via_list-id",
|
||||||
"device_class": "battery",
|
"device_class": "battery",
|
||||||
"state": "{{ trigger.event.data.beer == 2 }}",
|
"state": _BEER_TRIGGER_VALUE_TEMPLATE,
|
||||||
"picture": "{{ '/local/dogs.png' }}",
|
"picture": "{{ '/local/dogs.png' }}",
|
||||||
"icon": "{{ 'mdi:pirate' }}",
|
"icon": "{{ 'mdi:pirate' }}",
|
||||||
"attributes": {
|
"attributes": {
|
||||||
@ -1123,9 +1196,34 @@ async def test_restore_state(
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
(
|
||||||
|
"beer_count",
|
||||||
|
"final_state",
|
||||||
|
"icon_attr",
|
||||||
|
"entity_picture_attr",
|
||||||
|
"plus_one_attr",
|
||||||
|
"another_attr",
|
||||||
|
"another_attr_update",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
(2, STATE_ON, "mdi:pirate", "/local/dogs.png", 3, 1, "si"),
|
||||||
|
(1, STATE_OFF, "mdi:pirate", "/local/dogs.png", 2, 1, "si"),
|
||||||
|
(0, STATE_OFF, "mdi:pirate", "/local/dogs.png", 1, 1, "si"),
|
||||||
|
(-1, STATE_UNAVAILABLE, None, None, None, None, None),
|
||||||
|
],
|
||||||
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_trigger_entity(
|
async def test_trigger_entity(
|
||||||
hass: HomeAssistant, entity_registry: er.EntityRegistry
|
hass: HomeAssistant,
|
||||||
|
beer_count: int,
|
||||||
|
final_state: str,
|
||||||
|
icon_attr: str | None,
|
||||||
|
entity_picture_attr: str | None,
|
||||||
|
plus_one_attr: int | None,
|
||||||
|
another_attr: int | None,
|
||||||
|
another_attr_update: str | None,
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test trigger entity works."""
|
"""Test trigger entity works."""
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -1138,15 +1236,15 @@ async def test_trigger_entity(
|
|||||||
assert state.state == STATE_UNKNOWN
|
assert state.state == STATE_UNKNOWN
|
||||||
|
|
||||||
context = Context()
|
context = Context()
|
||||||
hass.bus.async_fire("test_event", {"beer": 2}, context=context)
|
hass.bus.async_fire("test_event", {"beer": beer_count}, context=context)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.hello_name")
|
state = hass.states.get("binary_sensor.hello_name")
|
||||||
assert state.state == STATE_ON
|
assert state.state == final_state
|
||||||
assert state.attributes.get("device_class") == "battery"
|
assert state.attributes.get("device_class") == "battery"
|
||||||
assert state.attributes.get("icon") == "mdi:pirate"
|
assert state.attributes.get("icon") == icon_attr
|
||||||
assert state.attributes.get("entity_picture") == "/local/dogs.png"
|
assert state.attributes.get("entity_picture") == entity_picture_attr
|
||||||
assert state.attributes.get("plus_one") == 3
|
assert state.attributes.get("plus_one") == plus_one_attr
|
||||||
assert state.context is context
|
assert state.context is context
|
||||||
|
|
||||||
assert len(entity_registry.entities) == 2
|
assert len(entity_registry.entities) == 2
|
||||||
@ -1160,20 +1258,20 @@ async def test_trigger_entity(
|
|||||||
)
|
)
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.via_list")
|
state = hass.states.get("binary_sensor.via_list")
|
||||||
assert state.state == STATE_ON
|
assert state.state == final_state
|
||||||
assert state.attributes.get("device_class") == "battery"
|
assert state.attributes.get("device_class") == "battery"
|
||||||
assert state.attributes.get("icon") == "mdi:pirate"
|
assert state.attributes.get("icon") == icon_attr
|
||||||
assert state.attributes.get("entity_picture") == "/local/dogs.png"
|
assert state.attributes.get("entity_picture") == entity_picture_attr
|
||||||
assert state.attributes.get("plus_one") == 3
|
assert state.attributes.get("plus_one") == plus_one_attr
|
||||||
assert state.attributes.get("another") == 1
|
assert state.attributes.get("another") == another_attr
|
||||||
assert state.context is context
|
assert state.context is context
|
||||||
|
|
||||||
# Even if state itself didn't change, attributes might have changed
|
# Even if state itself didn't change, attributes might have changed
|
||||||
hass.bus.async_fire("test_event", {"beer": 2, "uno_mas": "si"})
|
hass.bus.async_fire("test_event", {"beer": beer_count, "uno_mas": "si"})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
state = hass.states.get("binary_sensor.via_list")
|
state = hass.states.get("binary_sensor.via_list")
|
||||||
assert state.state == STATE_ON
|
assert state.state == final_state
|
||||||
assert state.attributes.get("another") == "si"
|
assert state.attributes.get("another") == another_attr_update
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
|
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
|
||||||
@ -1185,7 +1283,7 @@ async def test_trigger_entity(
|
|||||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"state": "{{ trigger.event.data.beer == 2 }}",
|
"state": _BEER_TRIGGER_VALUE_TEMPLATE,
|
||||||
"device_class": "motion",
|
"device_class": "motion",
|
||||||
"delay_on": '{{ ({ "seconds": 6 / 2 }) }}',
|
"delay_on": '{{ ({ "seconds": 6 / 2 }) }}',
|
||||||
"auto_off": '{{ ({ "seconds": 1 + 1 }) }}',
|
"auto_off": '{{ ({ "seconds": 1 + 1 }) }}',
|
||||||
@ -1195,34 +1293,50 @@ async def test_trigger_entity(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_template_with_trigger_templated_delay_on(hass: HomeAssistant) -> None:
|
@pytest.mark.parametrize(
|
||||||
|
("beer_count", "first_state", "second_state", "final_state"),
|
||||||
|
[
|
||||||
|
(2, STATE_UNKNOWN, STATE_ON, STATE_OFF),
|
||||||
|
(1, STATE_OFF, STATE_OFF, STATE_OFF),
|
||||||
|
(0, STATE_OFF, STATE_OFF, STATE_OFF),
|
||||||
|
(-1, STATE_UNAVAILABLE, STATE_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_template_with_trigger_templated_delay_on(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
beer_count: int,
|
||||||
|
first_state: str,
|
||||||
|
second_state: str,
|
||||||
|
final_state: str,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
|
) -> None:
|
||||||
"""Test binary sensor template with template delay on."""
|
"""Test binary sensor template with template delay on."""
|
||||||
state = hass.states.get("binary_sensor.test")
|
state = hass.states.get("binary_sensor.test")
|
||||||
assert state.state == STATE_UNKNOWN
|
assert state.state == STATE_UNKNOWN
|
||||||
|
|
||||||
context = Context()
|
context = Context()
|
||||||
hass.bus.async_fire("test_event", {"beer": 2}, context=context)
|
hass.bus.async_fire("test_event", {"beer": beer_count}, context=context)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# State should still be unknown
|
# State should still be unknown
|
||||||
state = hass.states.get("binary_sensor.test")
|
state = hass.states.get("binary_sensor.test")
|
||||||
assert state.state == STATE_UNKNOWN
|
assert state.state == first_state
|
||||||
|
|
||||||
# Now wait for the on delay
|
# Now wait for the on delay
|
||||||
future = dt_util.utcnow() + timedelta(seconds=3)
|
freezer.tick(timedelta(seconds=3))
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.test")
|
state = hass.states.get("binary_sensor.test")
|
||||||
assert state.state == STATE_ON
|
assert state.state == second_state
|
||||||
|
|
||||||
# Now wait for the auto-off
|
# Now wait for the auto-off
|
||||||
future = dt_util.utcnow() + timedelta(seconds=2)
|
freezer.tick(timedelta(seconds=2))
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.test")
|
state = hass.states.get("binary_sensor.test")
|
||||||
assert state.state == STATE_OFF
|
assert state.state == final_state
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
|
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
|
||||||
@ -1261,10 +1375,9 @@ async def test_template_with_trigger_templated_delay_on(hass: HomeAssistant) ->
|
|||||||
)
|
)
|
||||||
@pytest.mark.usefixtures("start_ha")
|
@pytest.mark.usefixtures("start_ha")
|
||||||
async def test_trigger_template_delay_with_multiple_triggers(
|
async def test_trigger_template_delay_with_multiple_triggers(
|
||||||
hass: HomeAssistant, delay_state: str
|
hass: HomeAssistant, delay_state: str, freezer: FrozenDateTimeFactory
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test trigger based binary sensor with multiple triggers occurring during the delay."""
|
"""Test trigger based binary sensor with multiple triggers occurring during the delay."""
|
||||||
future = dt_util.utcnow()
|
|
||||||
for _ in range(10):
|
for _ in range(10):
|
||||||
# State should still be unknown
|
# State should still be unknown
|
||||||
state = hass.states.get("binary_sensor.test")
|
state = hass.states.get("binary_sensor.test")
|
||||||
@ -1273,8 +1386,8 @@ async def test_trigger_template_delay_with_multiple_triggers(
|
|||||||
hass.bus.async_fire("test_event", {"beer": 2}, context=Context())
|
hass.bus.async_fire("test_event", {"beer": 2}, context=Context())
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
future += timedelta(seconds=1)
|
freezer.tick(timedelta(seconds=1))
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get("binary_sensor.test")
|
state = hass.states.get("binary_sensor.test")
|
||||||
@ -1290,7 +1403,7 @@ async def test_trigger_template_delay_with_multiple_triggers(
|
|||||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"state": "{{ trigger.event.data.beer == 2 }}",
|
"state": _BEER_TRIGGER_VALUE_TEMPLATE,
|
||||||
"device_class": "motion",
|
"device_class": "motion",
|
||||||
"picture": "{{ '/local/dogs.png' }}",
|
"picture": "{{ '/local/dogs.png' }}",
|
||||||
"icon": "{{ 'mdi:pirate' }}",
|
"icon": "{{ 'mdi:pirate' }}",
|
||||||
@ -1314,12 +1427,12 @@ async def test_trigger_template_delay_with_multiple_triggers(
|
|||||||
)
|
)
|
||||||
async def test_trigger_entity_restore_state(
|
async def test_trigger_entity_restore_state(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
count,
|
count: int,
|
||||||
domain,
|
domain: str,
|
||||||
config,
|
config: ConfigType,
|
||||||
restored_state,
|
restored_state: str,
|
||||||
initial_state,
|
initial_state: str,
|
||||||
initial_attributes,
|
initial_attributes: list[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test restoring trigger template binary sensor."""
|
"""Test restoring trigger template binary sensor."""
|
||||||
|
|
||||||
@ -1378,7 +1491,7 @@ async def test_trigger_entity_restore_state(
|
|||||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"state": "{{ trigger.event.data.beer == 2 }}",
|
"state": _BEER_TRIGGER_VALUE_TEMPLATE,
|
||||||
"device_class": "motion",
|
"device_class": "motion",
|
||||||
"auto_off": '{{ ({ "seconds": 1 + 1 }) }}',
|
"auto_off": '{{ ({ "seconds": 1 + 1 }) }}',
|
||||||
},
|
},
|
||||||
@ -1389,10 +1502,10 @@ async def test_trigger_entity_restore_state(
|
|||||||
@pytest.mark.parametrize("restored_state", [STATE_ON, STATE_OFF])
|
@pytest.mark.parametrize("restored_state", [STATE_ON, STATE_OFF])
|
||||||
async def test_trigger_entity_restore_state_auto_off(
|
async def test_trigger_entity_restore_state_auto_off(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
count,
|
count: int,
|
||||||
domain,
|
domain: str,
|
||||||
config,
|
config: ConfigType,
|
||||||
restored_state,
|
restored_state: str,
|
||||||
freezer: FrozenDateTimeFactory,
|
freezer: FrozenDateTimeFactory,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test restoring trigger template binary sensor."""
|
"""Test restoring trigger template binary sensor."""
|
||||||
@ -1442,7 +1555,7 @@ async def test_trigger_entity_restore_state_auto_off(
|
|||||||
"trigger": {"platform": "event", "event_type": "test_event"},
|
"trigger": {"platform": "event", "event_type": "test_event"},
|
||||||
"binary_sensor": {
|
"binary_sensor": {
|
||||||
"name": "test",
|
"name": "test",
|
||||||
"state": "{{ trigger.event.data.beer == 2 }}",
|
"state": _BEER_TRIGGER_VALUE_TEMPLATE,
|
||||||
"device_class": "motion",
|
"device_class": "motion",
|
||||||
"auto_off": '{{ ({ "seconds": 1 + 1 }) }}',
|
"auto_off": '{{ ({ "seconds": 1 + 1 }) }}',
|
||||||
},
|
},
|
||||||
@ -1451,7 +1564,11 @@ async def test_trigger_entity_restore_state_auto_off(
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_trigger_entity_restore_state_auto_off_expired(
|
async def test_trigger_entity_restore_state_auto_off_expired(
|
||||||
hass: HomeAssistant, count, domain, config, freezer: FrozenDateTimeFactory
|
hass: HomeAssistant,
|
||||||
|
count: int,
|
||||||
|
domain: str,
|
||||||
|
config: ConfigType,
|
||||||
|
freezer: FrozenDateTimeFactory,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test restoring trigger template binary sensor."""
|
"""Test restoring trigger template binary sensor."""
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user