1
0
mirror of https://github.com/home-assistant/core.git synced 2026-02-21 18:38:17 +00:00
Files
core/tests/helpers/template/extensions/test_devices.py

330 lines
11 KiB
Python

"""Test device template functions."""
from __future__ import annotations
import pytest
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.template import TemplateError
from tests.common import MockConfigEntry
from tests.helpers.template.helpers import assert_result_info, render_to_info
async def test_device_entities(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test device_entities function."""
config_entry = MockConfigEntry(domain="light")
config_entry.add_to_hass(hass)
# Test non existing device ids
info = render_to_info(hass, "{{ device_entities('abc123') }}")
assert_result_info(info, [])
assert info.rate_limit is None
info = render_to_info(hass, "{{ device_entities(56) }}")
assert_result_info(info, [])
assert info.rate_limit is None
# Test device without entities
device_entry = device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
)
info = render_to_info(hass, f"{{{{ device_entities('{device_entry.id}') }}}}")
assert_result_info(info, [])
assert info.rate_limit is None
# Test device with single entity, which has no state
entity_registry.async_get_or_create(
"light",
"hue",
"5678",
config_entry=config_entry,
device_id=device_entry.id,
)
info = render_to_info(hass, f"{{{{ device_entities('{device_entry.id}') }}}}")
assert_result_info(info, ["light.hue_5678"], [])
assert info.rate_limit is None
info = render_to_info(
hass,
(
f"{{{{ device_entities('{device_entry.id}') | expand "
"| sort(attribute='entity_id') | map(attribute='entity_id') | join(', ') }}"
),
)
assert_result_info(info, "", ["light.hue_5678"])
assert info.rate_limit is None
# Test device with single entity, with state
hass.states.async_set("light.hue_5678", "happy")
info = render_to_info(
hass,
(
f"{{{{ device_entities('{device_entry.id}') | expand "
"| sort(attribute='entity_id') | map(attribute='entity_id') | join(', ') }}"
),
)
assert_result_info(info, "light.hue_5678", ["light.hue_5678"])
assert info.rate_limit is None
# Test device with multiple entities, which have a state
entity_registry.async_get_or_create(
"light",
"hue",
"ABCD",
config_entry=config_entry,
device_id=device_entry.id,
)
hass.states.async_set("light.hue_abcd", "camper")
info = render_to_info(hass, f"{{{{ device_entities('{device_entry.id}') }}}}")
assert_result_info(info, ["light.hue_5678", "light.hue_abcd"], [])
assert info.rate_limit is None
info = render_to_info(
hass,
(
f"{{{{ device_entities('{device_entry.id}') | expand "
"| sort(attribute='entity_id') | map(attribute='entity_id') | join(', ') }}"
),
)
assert_result_info(
info, "light.hue_5678, light.hue_abcd", ["light.hue_5678", "light.hue_abcd"]
)
assert info.rate_limit is None
async def test_device_id(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test device_id function."""
config_entry = MockConfigEntry(domain="light")
config_entry.add_to_hass(hass)
device_entry = device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
model="test",
name="test",
)
entity_entry = entity_registry.async_get_or_create(
"sensor", "test", "test", suggested_object_id="test", device_id=device_entry.id
)
entity_entry_no_device = entity_registry.async_get_or_create(
"sensor", "test", "test_no_device", suggested_object_id="test"
)
info = render_to_info(hass, "{{ 'sensor.fail' | device_id }}")
assert_result_info(info, None)
assert info.rate_limit is None
info = render_to_info(hass, "{{ 56 | device_id }}")
assert_result_info(info, None)
info = render_to_info(hass, "{{ 'not_a_real_entity_id' | device_id }}")
assert_result_info(info, None)
info = render_to_info(
hass, f"{{{{ device_id('{entity_entry_no_device.entity_id}') }}}}"
)
assert_result_info(info, None)
assert info.rate_limit is None
info = render_to_info(hass, f"{{{{ device_id('{entity_entry.entity_id}') }}}}")
assert_result_info(info, device_entry.id)
assert info.rate_limit is None
info = render_to_info(hass, "{{ device_id('test') }}")
assert_result_info(info, device_entry.id)
assert info.rate_limit is None
async def test_device_name(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test device_name function."""
config_entry = MockConfigEntry(domain="light")
config_entry.add_to_hass(hass)
# Test non existing entity id
info = render_to_info(hass, "{{ device_name('sensor.fake') }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test non existing device id
info = render_to_info(hass, "{{ device_name('1234567890') }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test wrong value type
info = render_to_info(hass, "{{ device_name(56) }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test device with single entity
device_entry = device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
name="A light",
)
entity_entry = entity_registry.async_get_or_create(
"light",
"hue",
"5678",
config_entry=config_entry,
device_id=device_entry.id,
)
info = render_to_info(hass, f"{{{{ device_name('{device_entry.id}') }}}}")
assert_result_info(info, device_entry.name)
assert info.rate_limit is None
info = render_to_info(hass, f"{{{{ device_name('{entity_entry.entity_id}') }}}}")
assert_result_info(info, device_entry.name)
assert info.rate_limit is None
# Test device after renaming
device_entry = device_registry.async_update_device(
device_entry.id,
name_by_user="My light",
)
info = render_to_info(hass, f"{{{{ device_name('{device_entry.id}') }}}}")
assert_result_info(info, device_entry.name_by_user)
assert info.rate_limit is None
info = render_to_info(hass, f"{{{{ device_name('{entity_entry.entity_id}') }}}}")
assert_result_info(info, device_entry.name_by_user)
assert info.rate_limit is None
async def test_device_attr(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test device_attr and is_device_attr functions."""
config_entry = MockConfigEntry(domain="light")
config_entry.add_to_hass(hass)
# Test non existing device ids (device_attr)
info = render_to_info(hass, "{{ device_attr('abc123', 'id') }}")
assert_result_info(info, None)
assert info.rate_limit is None
info = render_to_info(hass, "{{ device_attr(56, 'id') }}")
with pytest.raises(TemplateError):
assert_result_info(info, None)
# Test non existing device ids (is_device_attr)
info = render_to_info(hass, "{{ is_device_attr('abc123', 'id', 'test') }}")
assert_result_info(info, False)
assert info.rate_limit is None
info = render_to_info(hass, "{{ is_device_attr(56, 'id', 'test') }}")
with pytest.raises(TemplateError):
assert_result_info(info, False)
# Test non existing entity id (device_attr)
info = render_to_info(hass, "{{ device_attr('entity.test', 'id') }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test non existing entity id (is_device_attr)
info = render_to_info(hass, "{{ is_device_attr('entity.test', 'id', 'test') }}")
assert_result_info(info, False)
assert info.rate_limit is None
device_entry = device_registry.async_get_or_create(
config_entry_id=config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
model="test",
)
entity_entry = entity_registry.async_get_or_create(
"sensor", "test", "test", suggested_object_id="test", device_id=device_entry.id
)
# Test non existent device attribute (device_attr)
info = render_to_info(
hass, f"{{{{ device_attr('{device_entry.id}', 'invalid_attr') }}}}"
)
assert_result_info(info, None)
assert info.rate_limit is None
# Test non existent device attribute (is_device_attr)
info = render_to_info(
hass, f"{{{{ is_device_attr('{device_entry.id}', 'invalid_attr', 'test') }}}}"
)
assert_result_info(info, False)
assert info.rate_limit is None
# Test None device attribute (device_attr)
info = render_to_info(
hass, f"{{{{ device_attr('{device_entry.id}', 'manufacturer') }}}}"
)
assert_result_info(info, None)
assert info.rate_limit is None
# Test None device attribute mismatch (is_device_attr)
info = render_to_info(
hass, f"{{{{ is_device_attr('{device_entry.id}', 'manufacturer', 'test') }}}}"
)
assert_result_info(info, False)
assert info.rate_limit is None
# Test None device attribute match (is_device_attr)
info = render_to_info(
hass, f"{{{{ is_device_attr('{device_entry.id}', 'manufacturer', None) }}}}"
)
assert_result_info(info, True)
assert info.rate_limit is None
# Test valid device attribute match (device_attr)
info = render_to_info(hass, f"{{{{ device_attr('{device_entry.id}', 'model') }}}}")
assert_result_info(info, "test")
assert info.rate_limit is None
# Test valid device attribute match (device_attr)
info = render_to_info(
hass, f"{{{{ device_attr('{entity_entry.entity_id}', 'model') }}}}"
)
assert_result_info(info, "test")
assert info.rate_limit is None
# Test valid device attribute mismatch (is_device_attr)
info = render_to_info(
hass, f"{{{{ is_device_attr('{device_entry.id}', 'model', 'fail') }}}}"
)
assert_result_info(info, False)
assert info.rate_limit is None
# Test valid device attribute match (is_device_attr)
info = render_to_info(
hass, f"{{{{ is_device_attr('{device_entry.id}', 'model', 'test') }}}}"
)
assert_result_info(info, True)
assert info.rate_limit is None
# Test filter syntax (device_attr)
info = render_to_info(
hass, f"{{{{ '{entity_entry.entity_id}' | device_attr('model') }}}}"
)
assert_result_info(info, "test")
assert info.rate_limit is None
# Test test syntax (is_device_attr)
info = render_to_info(
hass,
(
f"{{{{ ['{device_entry.id}'] | select('is_device_attr', 'model', 'test') "
"| list }}"
),
)
assert_result_info(info, [device_entry.id])
assert info.rate_limit is None