/tests/components/test_alexa.py
Python | 323 lines | 302 code | 12 blank | 9 comment | 1 complexity | c7d0da5e1705f717b6a8e2485eb15fd6 MD5 | raw file
- """
- tests.components.test_alexa
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Tests Home Assistant Alexa component does what it should do.
- """
- # pylint: disable=protected-access,too-many-public-methods
- import unittest
- import json
- import requests
- from homeassistant import bootstrap, const
- from homeassistant.components import alexa, http
- from tests.common import get_test_instance_port, get_test_home_assistant
- API_PASSWORD = "test1234"
- SERVER_PORT = get_test_instance_port()
- API_URL = "http://127.0.0.1:{}{}".format(SERVER_PORT, alexa.API_ENDPOINT)
- HA_HEADERS = {const.HTTP_HEADER_HA_AUTH: API_PASSWORD}
- SESSION_ID = 'amzn1.echo-api.session.0000000-0000-0000-0000-00000000000'
- APPLICATION_ID = 'amzn1.echo-sdk-ams.app.000000-d0ed-0000-ad00-000000d00ebe'
- REQUEST_ID = 'amzn1.echo-api.request.0000000-0000-0000-0000-00000000000'
- hass = None
- calls = []
- def setUpModule(): # pylint: disable=invalid-name
- """ Initalize a Home Assistant server for testing this module. """
- global hass
- hass = get_test_home_assistant()
- bootstrap.setup_component(
- hass, http.DOMAIN,
- {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD,
- http.CONF_SERVER_PORT: SERVER_PORT}})
- hass.services.register('test', 'alexa', lambda call: calls.append(call))
- bootstrap.setup_component(hass, alexa.DOMAIN, {
- 'alexa': {
- 'intents': {
- 'WhereAreWeIntent': {
- 'speech': {
- 'type': 'plaintext',
- 'text':
- """
- {%- if is_state('device_tracker.paulus', 'home')
- and is_state('device_tracker.anne_therese',
- 'home') -%}
- You are both home, you silly
- {%- else -%}
- Anne Therese is at {{
- states("device_tracker.anne_therese")
- }} and Paulus is at {{
- states("device_tracker.paulus")
- }}
- {% endif %}
- """,
- }
- },
- 'GetZodiacHoroscopeIntent': {
- 'speech': {
- 'type': 'plaintext',
- 'text': 'You told us your sign is {{ ZodiacSign }}.',
- }
- },
- 'CallServiceIntent': {
- 'speech': {
- 'type': 'plaintext',
- 'text': 'Service called',
- },
- 'action': {
- 'service': 'test.alexa',
- 'data': {
- 'hello': 1
- },
- 'entity_id': 'switch.test',
- }
- }
- }
- }
- })
- hass.start()
- def tearDownModule(): # pylint: disable=invalid-name
- """ Stops the Home Assistant server. """
- hass.stop()
- def _req(data={}):
- return requests.post(API_URL, data=json.dumps(data), timeout=5,
- headers=HA_HEADERS)
- class TestAlexa(unittest.TestCase):
- """ Test Alexa. """
- def tearDown(self):
- hass.pool.block_till_done()
- def test_launch_request(self):
- data = {
- 'version': '1.0',
- 'session': {
- 'new': True,
- 'sessionId': SESSION_ID,
- 'application': {
- 'applicationId': APPLICATION_ID
- },
- 'attributes': {},
- 'user': {
- 'userId': 'amzn1.account.AM3B00000000000000000000000'
- }
- },
- 'request': {
- 'type': 'LaunchRequest',
- 'requestId': REQUEST_ID,
- 'timestamp': '2015-05-13T12:34:56Z'
- }
- }
- req = _req(data)
- self.assertEqual(200, req.status_code)
- resp = req.json()
- self.assertIn('outputSpeech', resp['response'])
- def test_intent_request_with_slots(self):
- data = {
- 'version': '1.0',
- 'session': {
- 'new': False,
- 'sessionId': SESSION_ID,
- 'application': {
- 'applicationId': APPLICATION_ID
- },
- 'attributes': {
- 'supportedHoroscopePeriods': {
- 'daily': True,
- 'weekly': False,
- 'monthly': False
- }
- },
- 'user': {
- 'userId': 'amzn1.account.AM3B00000000000000000000000'
- }
- },
- 'request': {
- 'type': 'IntentRequest',
- 'requestId': REQUEST_ID,
- 'timestamp': '2015-05-13T12:34:56Z',
- 'intent': {
- 'name': 'GetZodiacHoroscopeIntent',
- 'slots': {
- 'ZodiacSign': {
- 'name': 'ZodiacSign',
- 'value': 'virgo'
- }
- }
- }
- }
- }
- req = _req(data)
- self.assertEqual(200, req.status_code)
- text = req.json().get('response', {}).get('outputSpeech',
- {}).get('text')
- self.assertEqual('You told us your sign is virgo.', text)
- def test_intent_request_with_slots_but_no_value(self):
- data = {
- 'version': '1.0',
- 'session': {
- 'new': False,
- 'sessionId': SESSION_ID,
- 'application': {
- 'applicationId': APPLICATION_ID
- },
- 'attributes': {
- 'supportedHoroscopePeriods': {
- 'daily': True,
- 'weekly': False,
- 'monthly': False
- }
- },
- 'user': {
- 'userId': 'amzn1.account.AM3B00000000000000000000000'
- }
- },
- 'request': {
- 'type': 'IntentRequest',
- 'requestId': REQUEST_ID,
- 'timestamp': '2015-05-13T12:34:56Z',
- 'intent': {
- 'name': 'GetZodiacHoroscopeIntent',
- 'slots': {
- 'ZodiacSign': {
- 'name': 'ZodiacSign',
- }
- }
- }
- }
- }
- req = _req(data)
- self.assertEqual(200, req.status_code)
- text = req.json().get('response', {}).get('outputSpeech',
- {}).get('text')
- self.assertEqual('You told us your sign is .', text)
- def test_intent_request_without_slots(self):
- data = {
- 'version': '1.0',
- 'session': {
- 'new': False,
- 'sessionId': SESSION_ID,
- 'application': {
- 'applicationId': APPLICATION_ID
- },
- 'attributes': {
- 'supportedHoroscopePeriods': {
- 'daily': True,
- 'weekly': False,
- 'monthly': False
- }
- },
- 'user': {
- 'userId': 'amzn1.account.AM3B00000000000000000000000'
- }
- },
- 'request': {
- 'type': 'IntentRequest',
- 'requestId': REQUEST_ID,
- 'timestamp': '2015-05-13T12:34:56Z',
- 'intent': {
- 'name': 'WhereAreWeIntent',
- }
- }
- }
- req = _req(data)
- self.assertEqual(200, req.status_code)
- text = req.json().get('response', {}).get('outputSpeech',
- {}).get('text')
- self.assertEqual('Anne Therese is at unknown and Paulus is at unknown',
- text)
- hass.states.set('device_tracker.paulus', 'home')
- hass.states.set('device_tracker.anne_therese', 'home')
- req = _req(data)
- self.assertEqual(200, req.status_code)
- text = req.json().get('response', {}).get('outputSpeech',
- {}).get('text')
- self.assertEqual('You are both home, you silly', text)
- def test_intent_request_calling_service(self):
- data = {
- 'version': '1.0',
- 'session': {
- 'new': False,
- 'sessionId': SESSION_ID,
- 'application': {
- 'applicationId': APPLICATION_ID
- },
- 'attributes': {},
- 'user': {
- 'userId': 'amzn1.account.AM3B00000000000000000000000'
- }
- },
- 'request': {
- 'type': 'IntentRequest',
- 'requestId': REQUEST_ID,
- 'timestamp': '2015-05-13T12:34:56Z',
- 'intent': {
- 'name': 'CallServiceIntent',
- }
- }
- }
- call_count = len(calls)
- req = _req(data)
- self.assertEqual(200, req.status_code)
- self.assertEqual(call_count + 1, len(calls))
- call = calls[-1]
- self.assertEqual('test', call.domain)
- self.assertEqual('alexa', call.service)
- self.assertEqual(['switch.test'], call.data.get('entity_id'))
- self.assertEqual(1, call.data.get('hello'))
- def test_session_ended_request(self):
- data = {
- 'version': '1.0',
- 'session': {
- 'new': False,
- 'sessionId': SESSION_ID,
- 'application': {
- 'applicationId': APPLICATION_ID
- },
- 'attributes': {
- 'supportedHoroscopePeriods': {
- 'daily': True,
- 'weekly': False,
- 'monthly': False
- }
- },
- 'user': {
- 'userId': 'amzn1.account.AM3B00000000000000000000000'
- }
- },
- 'request': {
- 'type': 'SessionEndedRequest',
- 'requestId': REQUEST_ID,
- 'timestamp': '2015-05-13T12:34:56Z',
- 'reason': 'USER_INITIATED'
- }
- }
- req = _req(data)
- self.assertEqual(200, req.status_code)
- self.assertEqual('', req.text)