1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 21:06:19 +00:00

TTS Component / Google speech platform (#4837)

* TTS Component / Google speech platform

* Change file backend handling / cache

* Use mimetype / rename Provider function / allow cache on service call

* Add a memcache for faster response

* Add demo platform

* First version of unittest

* Address comments

* improve error handling / address comments

* Add google unittest & check http response code

* Change url param handling

* add test for other language

* Change hash to sha256 for same hash on every os/hardware

* add unittest for receive demo data

* add test for error cases

* Test case load from file to mem over aiohttp server

* Use cache SpeechManager level, address other comments

* Add service for clear cache

* Update service.yaml

* add support for spliting google message
This commit is contained in:
Pascal Vizeli
2016-12-13 08:23:08 +01:00
committed by Paulus Schoutsen
parent acb841a1f4
commit 2dec38d8d4
11 changed files with 1110 additions and 5 deletions

View File

@@ -0,0 +1,199 @@
"""The tests for the Google speech platform."""
import asyncio
import os
import shutil
from unittest.mock import patch
import homeassistant.components.tts as tts
from homeassistant.components.media_player import (
SERVICE_PLAY_MEDIA, ATTR_MEDIA_CONTENT_ID, DOMAIN as DOMAIN_MP)
from homeassistant.bootstrap import setup_component
from tests.common import (
get_test_home_assistant, assert_setup_component, mock_service)
class TestTTSGooglePlatform(object):
"""Test the Google speech component."""
def setup_method(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
self.url = "http://translate.google.com/translate_tts"
self.url_param = {
'tl': 'en',
'q': 'I%20person%20is%20on%20front%20of%20your%20door.',
'tk': 5,
'client': 'tw-ob',
'textlen': 34,
'total': 1,
'idx': 0,
'ie': 'UTF-8',
}
def teardown_method(self):
"""Stop everything that was started."""
default_tts = self.hass.config.path(tts.DEFAULT_CACHE_DIR)
if os.path.isdir(default_tts):
shutil.rmtree(default_tts)
self.hass.stop()
def test_setup_component(self):
"""Test setup component."""
config = {
tts.DOMAIN: {
'platform': 'google',
}
}
with assert_setup_component(1, tts.DOMAIN):
setup_component(self.hass, tts.DOMAIN, config)
@patch('gtts_token.gtts_token.Token.calculate_token', autospec=True,
return_value=5)
def test_service_say(self, mock_calculate, aioclient_mock):
"""Test service call say."""
calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
aioclient_mock.get(
self.url, params=self.url_param, status=200, content=b'test')
config = {
tts.DOMAIN: {
'platform': 'google',
}
}
with assert_setup_component(1, tts.DOMAIN):
setup_component(self.hass, tts.DOMAIN, config)
self.hass.services.call(tts.DOMAIN, 'google_say', {
tts.ATTR_MESSAGE: "I person is on front of your door.",
})
self.hass.block_till_done()
assert len(calls) == 1
assert len(aioclient_mock.mock_calls) == 1
assert calls[0].data[ATTR_MEDIA_CONTENT_ID].find(".mp3") != -1
@patch('gtts_token.gtts_token.Token.calculate_token', autospec=True,
return_value=5)
def test_service_say_german(self, mock_calculate, aioclient_mock):
"""Test service call say with german code."""
calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
self.url_param['tl'] = 'de'
aioclient_mock.get(
self.url, params=self.url_param, status=200, content=b'test')
config = {
tts.DOMAIN: {
'platform': 'google',
'language': 'de',
}
}
with assert_setup_component(1, tts.DOMAIN):
setup_component(self.hass, tts.DOMAIN, config)
self.hass.services.call(tts.DOMAIN, 'google_say', {
tts.ATTR_MESSAGE: "I person is on front of your door.",
})
self.hass.block_till_done()
assert len(calls) == 1
assert len(aioclient_mock.mock_calls) == 1
@patch('gtts_token.gtts_token.Token.calculate_token', autospec=True,
return_value=5)
def test_service_say_error(self, mock_calculate, aioclient_mock):
"""Test service call say with http response 400."""
calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
aioclient_mock.get(
self.url, params=self.url_param, status=400, content=b'test')
config = {
tts.DOMAIN: {
'platform': 'google',
}
}
with assert_setup_component(1, tts.DOMAIN):
setup_component(self.hass, tts.DOMAIN, config)
self.hass.services.call(tts.DOMAIN, 'google_say', {
tts.ATTR_MESSAGE: "I person is on front of your door.",
})
self.hass.block_till_done()
assert len(calls) == 0
assert len(aioclient_mock.mock_calls) == 1
@patch('gtts_token.gtts_token.Token.calculate_token', autospec=True,
return_value=5)
def test_service_say_timeout(self, mock_calculate, aioclient_mock):
"""Test service call say with http timeout."""
calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
aioclient_mock.get(
self.url, params=self.url_param, exc=asyncio.TimeoutError())
config = {
tts.DOMAIN: {
'platform': 'google',
}
}
with assert_setup_component(1, tts.DOMAIN):
setup_component(self.hass, tts.DOMAIN, config)
self.hass.services.call(tts.DOMAIN, 'google_say', {
tts.ATTR_MESSAGE: "I person is on front of your door.",
})
self.hass.block_till_done()
assert len(calls) == 0
assert len(aioclient_mock.mock_calls) == 1
@patch('gtts_token.gtts_token.Token.calculate_token', autospec=True,
return_value=5)
def test_service_say_long_size(self, mock_calculate, aioclient_mock):
"""Test service call say with a lot of text."""
calls = mock_service(self.hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
self.url_param['total'] = 9
self.url_param['q'] = "I%20person%20is%20on%20front%20of%20your%20door"
self.url_param['textlen'] = 33
for idx in range(0, 9):
self.url_param['idx'] = idx
aioclient_mock.get(
self.url, params=self.url_param, status=200, content=b'test')
config = {
tts.DOMAIN: {
'platform': 'google',
}
}
with assert_setup_component(1, tts.DOMAIN):
setup_component(self.hass, tts.DOMAIN, config)
self.hass.services.call(tts.DOMAIN, 'google_say', {
tts.ATTR_MESSAGE: ("I person is on front of your door."
"I person is on front of your door."
"I person is on front of your door."
"I person is on front of your door."
"I person is on front of your door."
"I person is on front of your door."
"I person is on front of your door."
"I person is on front of your door."
"I person is on front of your door."),
})
self.hass.block_till_done()
assert len(calls) == 1
assert len(aioclient_mock.mock_calls) == 9
assert calls[0].data[ATTR_MEDIA_CONTENT_ID].find(".mp3") != -1