allow extra slot values in intents (#15246)

This commit is contained in:
David Thulke 2018-07-01 17:51:40 +02:00 committed by Paulus Schoutsen
parent 4c258ce08b
commit 136cc1d44d
3 changed files with 81 additions and 2 deletions

View File

@ -137,7 +137,8 @@ class IntentHandler:
if self._slot_schema is None: if self._slot_schema is None:
self._slot_schema = vol.Schema({ self._slot_schema = vol.Schema({
key: SLOT_SCHEMA.extend({'value': validator}) key: SLOT_SCHEMA.extend({'value': validator})
for key, validator in self.slot_schema.items()}) for key, validator in self.slot_schema.items()},
extra=vol.ALLOW_EXTRA)
return self._slot_schema(slots) return self._slot_schema(slots)

View File

@ -5,6 +5,7 @@ import logging
from homeassistant.bootstrap import async_setup_component from homeassistant.bootstrap import async_setup_component
from homeassistant.components.mqtt import MQTT_PUBLISH_SCHEMA from homeassistant.components.mqtt import MQTT_PUBLISH_SCHEMA
import homeassistant.components.snips as snips import homeassistant.components.snips as snips
from homeassistant.helpers.intent import (ServiceIntentHandler, async_register)
from tests.common import (async_fire_mqtt_message, async_mock_intent, from tests.common import (async_fire_mqtt_message, async_mock_intent,
async_mock_service) async_mock_service)
@ -124,6 +125,49 @@ async def test_snips_intent(hass, mqtt_mock):
assert intent.text_input == 'turn the lights green' assert intent.text_input == 'turn the lights green'
async def test_snips_service_intent(hass, mqtt_mock):
"""Test ServiceIntentHandler via Snips."""
hass.states.async_set('light.kitchen', 'off')
calls = async_mock_service(hass, 'light', 'turn_on')
result = await async_setup_component(hass, "snips", {
"snips": {},
})
assert result
payload = """
{
"input": "turn the light on",
"intent": {
"intentName": "Lights",
"probability": 0.85
},
"siteId": "default",
"slots": [
{
"slotName": "name",
"value": {
"kind": "Custom",
"value": "kitchen"
}
}
]
}
"""
async_register(hass, ServiceIntentHandler(
"Lights", "light", 'turn_on', "Turned {} on"))
async_fire_mqtt_message(hass, 'hermes/intent/Lights',
payload)
await hass.async_block_till_done()
assert len(calls) == 1
assert calls[0].domain == 'light'
assert calls[0].service == 'turn_on'
assert calls[0].data['entity_id'] == 'light.kitchen'
assert 'probability' not in calls[0].data
assert 'site_id' not in calls[0].data
async def test_snips_intent_with_duration(hass, mqtt_mock): async def test_snips_intent_with_duration(hass, mqtt_mock):
"""Test intent with Snips duration.""" """Test intent with Snips duration."""
result = await async_setup_component(hass, "snips", { result = await async_setup_component(hass, "snips", {

View File

@ -1,6 +1,18 @@
"""Tests for the intent helpers.""" """Tests for the intent helpers."""
import unittest
import voluptuous as vol
from homeassistant.core import State from homeassistant.core import State
from homeassistant.helpers import intent from homeassistant.helpers import (intent, config_validation as cv)
class MockIntentHandler(intent.IntentHandler):
"""Provide a mock intent handler."""
def __init__(self, slot_schema):
"""Initialize the mock handler."""
self.slot_schema = slot_schema
def test_async_match_state(): def test_async_match_state():
@ -10,3 +22,25 @@ def test_async_match_state():
state = intent.async_match_state(None, 'kitch', [state1, state2]) state = intent.async_match_state(None, 'kitch', [state1, state2])
assert state is state1 assert state is state1
class TestIntentHandler(unittest.TestCase):
"""Test the Home Assistant event helpers."""
def test_async_validate_slots(self):
"""Test async_validate_slots of IntentHandler."""
handler1 = MockIntentHandler({
vol.Required('name'): cv.string,
})
self.assertRaises(vol.error.MultipleInvalid,
handler1.async_validate_slots, {})
self.assertRaises(vol.error.MultipleInvalid,
handler1.async_validate_slots, {'name': 1})
self.assertRaises(vol.error.MultipleInvalid,
handler1.async_validate_slots, {'name': 'kitchen'})
handler1.async_validate_slots({'name': {'value': 'kitchen'}})
handler1.async_validate_slots({
'name': {'value': 'kitchen'},
'probability': {'value': '0.5'}
})