core/tests/components/conversation/test_init.py

317 lines
10 KiB
Python
Raw Normal View History

2016-03-09 09:25:50 +00:00
"""The tests for the Conversation component."""
# pylint: disable=protected-access
import pytest
from homeassistant.core import DOMAIN as HASS_DOMAIN
from homeassistant.setup import async_setup_component
2015-09-01 07:18:26 +00:00
from homeassistant.components import conversation
2019-07-31 19:25:30 +00:00
from homeassistant.components.cover import SERVICE_OPEN_COVER
from homeassistant.helpers import intent
from tests.common import async_mock_intent, async_mock_service
async def test_calling_intent(hass):
"""Test calling an intent from a conversation."""
2019-07-31 19:25:30 +00:00
intents = async_mock_intent(hass, "OrderBeer")
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "homeassistant", {})
assert result
2019-07-31 19:25:30 +00:00
result = await async_setup_component(
hass,
"conversation",
{"conversation": {"intents": {"OrderBeer": ["I would like the {type} beer"]}}},
)
assert result
await hass.services.async_call(
2019-07-31 19:25:30 +00:00
"conversation",
"process",
{conversation.ATTR_TEXT: "I would like the Grolsch beer"},
)
await hass.async_block_till_done()
assert len(intents) == 1
intent = intents[0]
2019-07-31 19:25:30 +00:00
assert intent.platform == "conversation"
assert intent.intent_type == "OrderBeer"
assert intent.slots == {"type": {"value": "Grolsch"}}
assert intent.text_input == "I would like the Grolsch beer"
async def test_register_before_setup(hass):
"""Test calling an intent from a conversation."""
2019-07-31 19:25:30 +00:00
intents = async_mock_intent(hass, "OrderBeer")
hass.components.conversation.async_register("OrderBeer", ["A {type} beer, please"])
result = await async_setup_component(
hass,
"conversation",
{"conversation": {"intents": {"OrderBeer": ["I would like the {type} beer"]}}},
)
assert result
await hass.services.async_call(
2019-07-31 19:25:30 +00:00
"conversation", "process", {conversation.ATTR_TEXT: "A Grolsch beer, please"}
)
await hass.async_block_till_done()
assert len(intents) == 1
intent = intents[0]
2019-07-31 19:25:30 +00:00
assert intent.platform == "conversation"
assert intent.intent_type == "OrderBeer"
assert intent.slots == {"type": {"value": "Grolsch"}}
assert intent.text_input == "A Grolsch beer, please"
await hass.services.async_call(
2019-07-31 19:25:30 +00:00
"conversation",
"process",
{conversation.ATTR_TEXT: "I would like the Grolsch beer"},
)
await hass.async_block_till_done()
assert len(intents) == 2
intent = intents[1]
2019-07-31 19:25:30 +00:00
assert intent.platform == "conversation"
assert intent.intent_type == "OrderBeer"
assert intent.slots == {"type": {"value": "Grolsch"}}
assert intent.text_input == "I would like the Grolsch beer"
async def test_http_processing_intent(hass, hass_client):
"""Test processing intent via HTTP API."""
2019-07-31 19:25:30 +00:00
class TestIntentHandler(intent.IntentHandler):
"""Test Intent Handler."""
2019-07-31 19:25:30 +00:00
intent_type = "OrderBeer"
async def async_handle(self, intent):
"""Handle the intent."""
response = intent.create_response()
response.async_set_speech(
2019-07-31 19:25:30 +00:00
"I've ordered a {}!".format(intent.slots["type"]["value"])
)
response.async_set_card(
2019-07-31 19:25:30 +00:00
"Beer ordered", "You chose a {}.".format(intent.slots["type"]["value"])
)
return response
intent.async_register(hass, TestIntentHandler())
2019-07-31 19:25:30 +00:00
result = await async_setup_component(
hass,
"conversation",
{"conversation": {"intents": {"OrderBeer": ["I would like the {type} beer"]}}},
)
assert result
client = await hass_client()
2019-07-31 19:25:30 +00:00
resp = await client.post(
"/api/conversation/process", json={"text": "I would like the Grolsch beer"}
)
assert resp.status == 200
data = await resp.json()
assert data == {
2019-07-31 19:25:30 +00:00
"card": {
"simple": {"content": "You chose a Grolsch.", "title": "Beer ordered"}
},
"speech": {"plain": {"extra_data": None, "speech": "I've ordered a Grolsch!"}},
}
2019-07-31 19:25:30 +00:00
@pytest.mark.parametrize("sentence", ("turn on kitchen", "turn kitchen on"))
async def test_turn_on_intent(hass, sentence):
"""Test calling the turn on intent."""
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "homeassistant", {})
assert result
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "conversation", {})
assert result
2019-07-31 19:25:30 +00:00
hass.states.async_set("light.kitchen", "off")
calls = async_mock_service(hass, HASS_DOMAIN, "turn_on")
await hass.services.async_call(
2019-07-31 19:25:30 +00:00
"conversation", "process", {conversation.ATTR_TEXT: sentence}
)
await hass.async_block_till_done()
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
2019-07-31 19:25:30 +00:00
assert call.service == "turn_on"
assert call.data == {"entity_id": "light.kitchen"}
async def test_cover_intents_loading(hass):
"""Test Cover Intents Loading."""
with pytest.raises(intent.UnknownIntent):
await intent.async_handle(
2019-07-31 19:25:30 +00:00
hass, "test", "HassOpenCover", {"name": {"value": "garage door"}}
)
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "cover", {})
assert result
2019-07-31 19:25:30 +00:00
hass.states.async_set("cover.garage_door", "closed")
calls = async_mock_service(hass, "cover", SERVICE_OPEN_COVER)
response = await intent.async_handle(
2019-07-31 19:25:30 +00:00
hass, "test", "HassOpenCover", {"name": {"value": "garage door"}}
)
await hass.async_block_till_done()
2019-07-31 19:25:30 +00:00
assert response.speech["plain"]["speech"] == "Opened garage door"
assert len(calls) == 1
call = calls[0]
2019-07-31 19:25:30 +00:00
assert call.domain == "cover"
assert call.service == "open_cover"
assert call.data == {"entity_id": "cover.garage_door"}
2019-07-31 19:25:30 +00:00
@pytest.mark.parametrize("sentence", ("turn off kitchen", "turn kitchen off"))
async def test_turn_off_intent(hass, sentence):
"""Test calling the turn on intent."""
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "homeassistant", {})
assert result
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "conversation", {})
assert result
2019-07-31 19:25:30 +00:00
hass.states.async_set("light.kitchen", "on")
calls = async_mock_service(hass, HASS_DOMAIN, "turn_off")
await hass.services.async_call(
2019-07-31 19:25:30 +00:00
"conversation", "process", {conversation.ATTR_TEXT: sentence}
)
await hass.async_block_till_done()
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
2019-07-31 19:25:30 +00:00
assert call.service == "turn_off"
assert call.data == {"entity_id": "light.kitchen"}
2019-07-31 19:25:30 +00:00
@pytest.mark.parametrize("sentence", ("toggle kitchen", "kitchen toggle"))
async def test_toggle_intent(hass, sentence):
"""Test calling the turn on intent."""
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "homeassistant", {})
assert result
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "conversation", {})
assert result
2019-07-31 19:25:30 +00:00
hass.states.async_set("light.kitchen", "on")
calls = async_mock_service(hass, HASS_DOMAIN, "toggle")
await hass.services.async_call(
2019-07-31 19:25:30 +00:00
"conversation", "process", {conversation.ATTR_TEXT: sentence}
)
await hass.async_block_till_done()
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
2019-07-31 19:25:30 +00:00
assert call.service == "toggle"
assert call.data == {"entity_id": "light.kitchen"}
async def test_http_api(hass, hass_client):
"""Test the HTTP conversation API."""
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "homeassistant", {})
assert result
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "conversation", {})
assert result
client = await hass_client()
2019-07-31 19:25:30 +00:00
hass.states.async_set("light.kitchen", "off")
calls = async_mock_service(hass, HASS_DOMAIN, "turn_on")
2019-07-31 19:25:30 +00:00
resp = await client.post(
"/api/conversation/process", json={"text": "Turn the kitchen on"}
)
assert resp.status == 200
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
2019-07-31 19:25:30 +00:00
assert call.service == "turn_on"
assert call.data == {"entity_id": "light.kitchen"}
async def test_http_api_wrong_data(hass, hass_client):
"""Test the HTTP conversation API."""
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "homeassistant", {})
assert result
2019-07-31 19:25:30 +00:00
result = await async_setup_component(hass, "conversation", {})
assert result
client = await hass_client()
2019-07-31 19:25:30 +00:00
resp = await client.post("/api/conversation/process", json={"text": 123})
assert resp.status == 400
2019-07-31 19:25:30 +00:00
resp = await client.post("/api/conversation/process", json={})
assert resp.status == 400
def test_create_matcher():
"""Test the create matcher method."""
# Basic sentence
2019-07-31 19:25:30 +00:00
pattern = conversation.create_matcher("Hello world")
assert pattern.match("Hello world") is not None
# Match a part
2019-07-31 19:25:30 +00:00
pattern = conversation.create_matcher("Hello {name}")
match = pattern.match("hello world")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "world"
no_match = pattern.match("Hello world, how are you?")
assert no_match is None
# Optional and matching part
2019-07-31 19:25:30 +00:00
pattern = conversation.create_matcher("Turn on [the] {name}")
match = pattern.match("turn on the kitchen lights")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen lights"
match = pattern.match("turn on kitchen lights")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen lights"
match = pattern.match("turn off kitchen lights")
assert match is None
# Two different optional parts, 1 matching part
2019-07-31 19:25:30 +00:00
pattern = conversation.create_matcher("Turn on [the] [a] {name}")
match = pattern.match("turn on the kitchen lights")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen lights"
match = pattern.match("turn on kitchen lights")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen lights"
match = pattern.match("turn on a kitchen light")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen light"
# Strip plural
2019-07-31 19:25:30 +00:00
pattern = conversation.create_matcher("Turn {name}[s] on")
match = pattern.match("turn kitchen lights on")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen light"
# Optional 2 words
2019-07-31 19:25:30 +00:00
pattern = conversation.create_matcher("Turn [the great] {name} on")
match = pattern.match("turn the great kitchen lights on")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen lights"
match = pattern.match("turn kitchen lights on")
assert match is not None
2019-07-31 19:25:30 +00:00
assert match.groupdict()["name"] == "kitchen lights"