2018-02-28 21:39:01 +00:00
|
|
|
"""Tests for the intent helpers."""
|
2018-07-01 15:51:40 +00:00
|
|
|
|
2019-04-30 16:20:38 +00:00
|
|
|
import pytest
|
2019-12-09 15:52:24 +00:00
|
|
|
import voluptuous as vol
|
2019-04-30 16:20:38 +00:00
|
|
|
|
2023-01-19 23:15:01 +00:00
|
|
|
from homeassistant.components.switch import SwitchDeviceClass
|
2023-01-07 21:20:21 +00:00
|
|
|
from homeassistant.const import ATTR_FRIENDLY_NAME
|
2018-02-28 21:39:01 +00:00
|
|
|
from homeassistant.core import State
|
2023-01-19 23:15:01 +00:00
|
|
|
from homeassistant.helpers import (
|
|
|
|
area_registry,
|
|
|
|
config_validation as cv,
|
2023-01-26 15:48:49 +00:00
|
|
|
device_registry,
|
2023-01-19 23:15:01 +00:00
|
|
|
entity_registry,
|
|
|
|
intent,
|
|
|
|
)
|
2018-07-01 15:51:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
class MockIntentHandler(intent.IntentHandler):
|
|
|
|
"""Provide a mock intent handler."""
|
|
|
|
|
|
|
|
def __init__(self, slot_schema):
|
|
|
|
"""Initialize the mock handler."""
|
|
|
|
self.slot_schema = slot_schema
|
2018-02-28 21:39:01 +00:00
|
|
|
|
|
|
|
|
2023-01-19 23:15:01 +00:00
|
|
|
async def test_async_match_states(hass):
|
2018-02-28 21:39:01 +00:00
|
|
|
"""Test async_match_state helper."""
|
2023-01-19 23:15:01 +00:00
|
|
|
areas = area_registry.async_get(hass)
|
|
|
|
area_kitchen = areas.async_get_or_create("kitchen")
|
2023-01-31 04:46:25 +00:00
|
|
|
areas.async_update(area_kitchen.id, aliases={"food room"})
|
2023-01-19 23:15:01 +00:00
|
|
|
area_bedroom = areas.async_get_or_create("bedroom")
|
|
|
|
|
2023-01-07 21:20:21 +00:00
|
|
|
state1 = State(
|
|
|
|
"light.kitchen", "on", attributes={ATTR_FRIENDLY_NAME: "kitchen light"}
|
|
|
|
)
|
|
|
|
state2 = State(
|
2023-01-19 23:15:01 +00:00
|
|
|
"switch.bedroom", "on", attributes={ATTR_FRIENDLY_NAME: "bedroom switch"}
|
|
|
|
)
|
|
|
|
|
|
|
|
# Put entities into different areas
|
|
|
|
entities = entity_registry.async_get(hass)
|
|
|
|
entities.async_get_or_create("light", "demo", "1234", suggested_object_id="kitchen")
|
|
|
|
entities.async_update_entity(state1.entity_id, area_id=area_kitchen.id)
|
|
|
|
|
|
|
|
entities.async_get_or_create(
|
2023-01-26 15:48:49 +00:00
|
|
|
"switch", "demo", "5678", suggested_object_id="bedroom"
|
2023-01-19 23:15:01 +00:00
|
|
|
)
|
|
|
|
entities.async_update_entity(
|
|
|
|
state2.entity_id,
|
|
|
|
area_id=area_bedroom.id,
|
|
|
|
device_class=SwitchDeviceClass.OUTLET,
|
|
|
|
aliases={"kill switch"},
|
|
|
|
)
|
|
|
|
|
|
|
|
# Match on name
|
2023-01-31 16:59:00 +00:00
|
|
|
assert list(
|
2023-01-19 23:15:01 +00:00
|
|
|
intent.async_match_states(hass, name="kitchen light", states=[state1, state2])
|
2023-01-31 16:59:00 +00:00
|
|
|
) == [state1]
|
2023-01-19 23:15:01 +00:00
|
|
|
|
|
|
|
# Test alias
|
2023-01-31 16:59:00 +00:00
|
|
|
assert list(
|
2023-01-19 23:15:01 +00:00
|
|
|
intent.async_match_states(hass, name="kill switch", states=[state1, state2])
|
2023-01-31 16:59:00 +00:00
|
|
|
) == [state2]
|
2023-01-19 23:15:01 +00:00
|
|
|
|
|
|
|
# Name + area
|
2023-01-31 16:59:00 +00:00
|
|
|
assert list(
|
2023-01-19 23:15:01 +00:00
|
|
|
intent.async_match_states(
|
|
|
|
hass, name="kitchen light", area_name="kitchen", states=[state1, state2]
|
|
|
|
)
|
2023-01-31 16:59:00 +00:00
|
|
|
) == [state1]
|
2018-02-28 21:39:01 +00:00
|
|
|
|
2023-01-31 04:46:25 +00:00
|
|
|
# Test area alias
|
2023-01-31 16:59:00 +00:00
|
|
|
assert list(
|
2023-01-31 04:46:25 +00:00
|
|
|
intent.async_match_states(
|
|
|
|
hass, name="kitchen light", area_name="food room", states=[state1, state2]
|
|
|
|
)
|
2023-01-31 16:59:00 +00:00
|
|
|
) == [state1]
|
2023-01-31 04:46:25 +00:00
|
|
|
|
2023-01-19 23:15:01 +00:00
|
|
|
# Wrong area
|
|
|
|
assert not list(
|
|
|
|
intent.async_match_states(
|
|
|
|
hass, name="kitchen light", area_name="bedroom", states=[state1, state2]
|
|
|
|
)
|
|
|
|
)
|
2018-07-01 15:51:40 +00:00
|
|
|
|
2023-01-19 23:15:01 +00:00
|
|
|
# Domain + area
|
2023-01-31 16:59:00 +00:00
|
|
|
assert list(
|
2023-01-19 23:15:01 +00:00
|
|
|
intent.async_match_states(
|
|
|
|
hass, domains={"switch"}, area_name="bedroom", states=[state1, state2]
|
|
|
|
)
|
2023-01-31 16:59:00 +00:00
|
|
|
) == [state2]
|
2023-01-19 23:15:01 +00:00
|
|
|
|
|
|
|
# Device class + area
|
2023-01-31 16:59:00 +00:00
|
|
|
assert list(
|
2023-01-19 23:15:01 +00:00
|
|
|
intent.async_match_states(
|
|
|
|
hass,
|
|
|
|
device_classes={SwitchDeviceClass.OUTLET},
|
|
|
|
area_name="bedroom",
|
|
|
|
states=[state1, state2],
|
|
|
|
)
|
2023-01-31 16:59:00 +00:00
|
|
|
) == [state2]
|
2023-01-07 21:20:21 +00:00
|
|
|
|
2018-07-01 15:51:40 +00:00
|
|
|
|
2023-01-26 15:48:49 +00:00
|
|
|
async def test_match_device_area(hass):
|
|
|
|
"""Test async_match_state with a device in an area."""
|
|
|
|
areas = area_registry.async_get(hass)
|
|
|
|
area_kitchen = areas.async_get_or_create("kitchen")
|
|
|
|
area_bedroom = areas.async_get_or_create("bedroom")
|
|
|
|
|
|
|
|
devices = device_registry.async_get(hass)
|
|
|
|
kitchen_device = devices.async_get_or_create(
|
|
|
|
config_entry_id="1234", connections=set(), identifiers={("demo", "id-1234")}
|
|
|
|
)
|
|
|
|
devices.async_update_device(kitchen_device.id, area_id=area_kitchen.id)
|
|
|
|
|
|
|
|
state1 = State(
|
|
|
|
"light.kitchen", "on", attributes={ATTR_FRIENDLY_NAME: "kitchen light"}
|
|
|
|
)
|
|
|
|
state2 = State(
|
|
|
|
"light.bedroom", "on", attributes={ATTR_FRIENDLY_NAME: "bedroom light"}
|
|
|
|
)
|
|
|
|
state3 = State(
|
|
|
|
"light.living_room", "on", attributes={ATTR_FRIENDLY_NAME: "living room light"}
|
|
|
|
)
|
|
|
|
entities = entity_registry.async_get(hass)
|
|
|
|
entities.async_get_or_create("light", "demo", "1234", suggested_object_id="kitchen")
|
|
|
|
entities.async_update_entity(state1.entity_id, device_id=kitchen_device.id)
|
|
|
|
|
|
|
|
entities.async_get_or_create("light", "demo", "5678", suggested_object_id="bedroom")
|
|
|
|
entities.async_update_entity(state2.entity_id, area_id=area_bedroom.id)
|
|
|
|
|
|
|
|
# Match on area/domain
|
2023-01-31 16:59:00 +00:00
|
|
|
assert list(
|
2023-01-26 15:48:49 +00:00
|
|
|
intent.async_match_states(
|
|
|
|
hass,
|
|
|
|
domains={"light"},
|
|
|
|
area_name="kitchen",
|
|
|
|
states=[state1, state2, state3],
|
|
|
|
)
|
2023-01-31 16:59:00 +00:00
|
|
|
) == [state1]
|
2023-01-26 15:48:49 +00:00
|
|
|
|
|
|
|
|
2019-04-30 16:20:38 +00:00
|
|
|
def test_async_validate_slots():
|
|
|
|
"""Test async_validate_slots of IntentHandler."""
|
2019-07-31 19:25:30 +00:00
|
|
|
handler1 = MockIntentHandler({vol.Required("name"): cv.string})
|
2019-04-30 16:20:38 +00:00
|
|
|
|
|
|
|
with pytest.raises(vol.error.MultipleInvalid):
|
|
|
|
handler1.async_validate_slots({})
|
|
|
|
with pytest.raises(vol.error.MultipleInvalid):
|
2019-07-31 19:25:30 +00:00
|
|
|
handler1.async_validate_slots({"name": 1})
|
2019-04-30 16:20:38 +00:00
|
|
|
with pytest.raises(vol.error.MultipleInvalid):
|
2019-07-31 19:25:30 +00:00
|
|
|
handler1.async_validate_slots({"name": "kitchen"})
|
|
|
|
handler1.async_validate_slots({"name": {"value": "kitchen"}})
|
|
|
|
handler1.async_validate_slots(
|
|
|
|
{"name": {"value": "kitchen"}, "probability": {"value": "0.5"}}
|
|
|
|
)
|