mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Rewrite tts tests (#90355)
This commit is contained in:
parent
c193402ba7
commit
a91aef9d52
@ -1,12 +1,11 @@
|
||||
"""The tests for the TTS component."""
|
||||
from http import HTTPStatus
|
||||
from unittest.mock import PropertyMock, patch
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import media_source, tts
|
||||
from homeassistant.components.demo.tts import DemoProvider
|
||||
from homeassistant.components.media_player import (
|
||||
ATTR_MEDIA_ANNOUNCE,
|
||||
ATTR_MEDIA_CONTENT_ID,
|
||||
@ -18,10 +17,17 @@ from homeassistant.components.media_player import (
|
||||
from homeassistant.config import async_process_ha_core_config
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util.network import normalize_url
|
||||
|
||||
from tests.common import assert_setup_component, async_mock_service
|
||||
from tests.common import (
|
||||
MockModule,
|
||||
assert_setup_component,
|
||||
async_mock_service,
|
||||
mock_integration,
|
||||
mock_platform,
|
||||
)
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
ORIG_WRITE_TAGS = tts.SpeechManager.write_tags
|
||||
@ -36,10 +42,68 @@ async def get_media_source_url(hass, media_content_id):
|
||||
return resolved.url
|
||||
|
||||
|
||||
SUPPORT_LANGUAGES = ["de", "en", "en_US"]
|
||||
|
||||
DEFAULT_LANG = "en"
|
||||
|
||||
|
||||
class MockProvider(tts.Provider):
|
||||
"""Test speech API provider."""
|
||||
|
||||
def __init__(self, lang: str) -> None:
|
||||
"""Initialize test provider."""
|
||||
self._lang = lang
|
||||
self.name = "Test"
|
||||
|
||||
@property
|
||||
def default_language(self) -> str:
|
||||
"""Return the default language."""
|
||||
return self._lang
|
||||
|
||||
@property
|
||||
def supported_languages(self) -> list[str]:
|
||||
"""Return list of supported languages."""
|
||||
return SUPPORT_LANGUAGES
|
||||
|
||||
@property
|
||||
def supported_options(self) -> list[str]:
|
||||
"""Return list of supported options like voice, emotions."""
|
||||
return ["voice", "age"]
|
||||
|
||||
def get_tts_audio(
|
||||
self, message: str, language: str, options: dict[str, Any] | None = None
|
||||
) -> tts.TtsAudioType:
|
||||
"""Load TTS dat."""
|
||||
return ("mp3", b"")
|
||||
|
||||
|
||||
class MockTTS:
|
||||
"""A mock TTS platform."""
|
||||
|
||||
PLATFORM_SCHEMA = tts.PLATFORM_SCHEMA.extend(
|
||||
{vol.Optional(tts.CONF_LANG, default=DEFAULT_LANG): vol.In(SUPPORT_LANGUAGES)}
|
||||
)
|
||||
|
||||
def __init__(self, provider=None) -> None:
|
||||
"""Initialize."""
|
||||
if provider is None:
|
||||
provider = MockProvider
|
||||
self._provider = provider
|
||||
|
||||
async def async_get_engine(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType,
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> tts.Provider:
|
||||
"""Set up a mock speech component."""
|
||||
return self._provider(config.get(tts.CONF_LANG, DEFAULT_LANG))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def demo_provider():
|
||||
"""Demo TTS provider."""
|
||||
return DemoProvider("en")
|
||||
def test_provider():
|
||||
"""Test TTS provider."""
|
||||
return MockProvider("en")
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
@ -52,49 +116,52 @@ async def internal_url_mock(hass):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def setup_tts(hass):
|
||||
async def mock_tts(hass):
|
||||
"""Mock TTS."""
|
||||
with patch("homeassistant.components.demo.async_setup", return_value=True):
|
||||
assert await async_setup_component(
|
||||
hass, tts.DOMAIN, {"tts": {"platform": "demo"}}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
mock_integration(hass, MockModule(domain="test"))
|
||||
mock_platform(hass, "test.tts", MockTTS())
|
||||
|
||||
|
||||
async def test_setup_component_demo(hass: HomeAssistant, setup_tts) -> None:
|
||||
"""Set up the demo platform with defaults."""
|
||||
assert hass.services.has_service(tts.DOMAIN, "demo_say")
|
||||
@pytest.fixture
|
||||
async def setup_tts(hass, mock_tts):
|
||||
"""Mock TTS."""
|
||||
assert await async_setup_component(hass, tts.DOMAIN, {"tts": {"platform": "test"}})
|
||||
|
||||
|
||||
async def test_setup_component(hass: HomeAssistant, setup_tts) -> None:
|
||||
"""Set up a TTS platform with defaults."""
|
||||
assert hass.services.has_service(tts.DOMAIN, "test_say")
|
||||
assert hass.services.has_service(tts.DOMAIN, "clear_cache")
|
||||
assert f"{tts.DOMAIN}.demo" in hass.config.components
|
||||
assert f"{tts.DOMAIN}.test" in hass.config.components
|
||||
|
||||
|
||||
async def test_setup_component_demo_no_access_cache_folder(
|
||||
hass: HomeAssistant, mock_init_cache_dir
|
||||
async def test_setup_component_no_access_cache_folder(
|
||||
hass: HomeAssistant, mock_init_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform with defaults."""
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
"""Set up a TTS platform with defaults."""
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
mock_init_cache_dir.side_effect = OSError(2, "No access")
|
||||
assert not await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
assert not hass.services.has_service(tts.DOMAIN, "demo_say")
|
||||
assert not hass.services.has_service(tts.DOMAIN, "test_say")
|
||||
assert not hass.services.has_service(tts.DOMAIN, "clear_cache")
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service."""
|
||||
"""Set up a TTS platform and call service."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -107,28 +174,28 @@ async def test_setup_component_and_test_service(
|
||||
assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
|
||||
assert (
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_config_language(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service."""
|
||||
"""Set up a TTS platform and call service."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "language": "de"}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "language": "de"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -139,31 +206,28 @@ async def test_setup_component_and_test_service_with_config_language(
|
||||
assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
|
||||
assert (
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3"
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3"
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_config_language_special(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service with extend language."""
|
||||
import homeassistant.components.demo.tts as demo_tts
|
||||
|
||||
demo_tts.SUPPORT_LANGUAGES.append("en_US")
|
||||
"""Set up a TTS platform and call service with extend language."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "language": "en_US"}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "language": "en_US"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -174,38 +238,38 @@ async def test_setup_component_and_test_service_with_config_language_special(
|
||||
assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
|
||||
assert (
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_demo.mp3"
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_test.mp3"
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_wrong_conf_language(
|
||||
hass: HomeAssistant,
|
||||
hass: HomeAssistant, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service with wrong config."""
|
||||
config = {tts.DOMAIN: {"platform": "demo", "language": "ru"}}
|
||||
"""Set up a TTS platform and call service with wrong config."""
|
||||
config = {tts.DOMAIN: {"platform": "test", "language": "ru"}}
|
||||
|
||||
with assert_setup_component(0, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_service_language(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service."""
|
||||
"""Set up a TTS platform and call service."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -217,21 +281,21 @@ async def test_setup_component_and_test_service_with_service_language(
|
||||
assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
|
||||
assert (
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3"
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3"
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_test_service_with_wrong_service_language(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service."""
|
||||
"""Set up a TTS platform and call service."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
@ -239,7 +303,7 @@ async def test_setup_component_test_service_with_wrong_service_language(
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -249,24 +313,24 @@ async def test_setup_component_test_service_with_wrong_service_language(
|
||||
)
|
||||
assert len(calls) == 0
|
||||
assert not (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_lang_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_lang_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_service_options(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service with options."""
|
||||
"""Set up a TTS platform and call service with options."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -281,32 +345,37 @@ async def test_setup_component_and_test_service_with_service_options(
|
||||
assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
|
||||
assert (
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== f"/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3"
|
||||
== f"/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
empty_cache_dir
|
||||
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3"
|
||||
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_with_service_options_def(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service with default options."""
|
||||
"""Set up a TTS platform and call service with default options."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN), patch(
|
||||
"homeassistant.components.demo.tts.DemoProvider.default_options",
|
||||
new_callable=PropertyMock(return_value={"voice": "alex"}),
|
||||
):
|
||||
class MockProviderWithDefaults(MockProvider):
|
||||
@property
|
||||
def default_options(self):
|
||||
return {"voice": "alex"}
|
||||
|
||||
mock_integration(hass, MockModule(domain="test"))
|
||||
mock_platform(hass, "test.tts", MockTTS(MockProviderWithDefaults))
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -320,22 +389,22 @@ async def test_setup_component_and_test_with_service_options_def(
|
||||
assert calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
|
||||
assert (
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== f"/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3"
|
||||
== f"/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
empty_cache_dir
|
||||
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3"
|
||||
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_service_options_wrong(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service with wrong options."""
|
||||
"""Set up a TTS platform and call service with wrong options."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
@ -343,7 +412,7 @@ async def test_setup_component_and_test_service_with_service_options_wrong(
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -358,24 +427,24 @@ async def test_setup_component_and_test_service_with_service_options_wrong(
|
||||
await hass.async_block_till_done()
|
||||
assert not (
|
||||
empty_cache_dir
|
||||
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3"
|
||||
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_base_url_set(
|
||||
hass: HomeAssistant,
|
||||
hass: HomeAssistant, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform with ``base_url`` set and call service."""
|
||||
"""Set up a TTS platform with ``base_url`` set and call service."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "base_url": "http://fnord"}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "base_url": "http://fnord"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -388,24 +457,24 @@ async def test_setup_component_and_test_service_with_base_url_set(
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== "http://fnord"
|
||||
"/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491"
|
||||
"_en_-_demo.mp3"
|
||||
"_en_-_test.mp3"
|
||||
)
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_clear_cache(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service clear cache."""
|
||||
"""Set up a TTS platform and call service clear cache."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -417,7 +486,7 @@ async def test_setup_component_and_test_service_clear_cache(
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
await hass.services.async_call(
|
||||
@ -425,17 +494,17 @@ async def test_setup_component_and_test_service_clear_cache(
|
||||
)
|
||||
|
||||
assert not (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_receive_voice(
|
||||
hass: HomeAssistant, demo_provider, hass_client: ClientSessionGenerator
|
||||
hass: HomeAssistant, test_provider, hass_client: ClientSessionGenerator, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service and receive voice."""
|
||||
"""Set up a TTS platform and call service and receive voice."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
@ -444,7 +513,7 @@ async def test_setup_component_and_test_service_with_receive_voice(
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: message,
|
||||
@ -456,39 +525,39 @@ async def test_setup_component_and_test_service_with_receive_voice(
|
||||
url = await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
client = await hass_client()
|
||||
req = await client.get(url)
|
||||
_, demo_data = demo_provider.get_tts_audio("bla", "en")
|
||||
demo_data = tts.SpeechManager.write_tags(
|
||||
"42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3",
|
||||
demo_data,
|
||||
demo_provider,
|
||||
_, tts_data = test_provider.get_tts_audio("bla", "en")
|
||||
tts_data = tts.SpeechManager.write_tags(
|
||||
"42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3",
|
||||
tts_data,
|
||||
test_provider,
|
||||
message,
|
||||
"en",
|
||||
None,
|
||||
)
|
||||
assert req.status == HTTPStatus.OK
|
||||
assert await req.read() == demo_data
|
||||
assert await req.read() == tts_data
|
||||
|
||||
extension, data = await tts.async_get_media_source_audio(
|
||||
hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]
|
||||
)
|
||||
assert extension == "mp3"
|
||||
assert demo_data == data
|
||||
assert tts_data == data
|
||||
|
||||
|
||||
async def test_setup_component_and_test_service_with_receive_voice_german(
|
||||
hass: HomeAssistant, demo_provider, hass_client: ClientSessionGenerator
|
||||
hass: HomeAssistant, test_provider, hass_client: ClientSessionGenerator, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and call service and receive voice."""
|
||||
"""Set up a TTS platform and call service and receive voice."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "language": "de"}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "language": "de"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -499,67 +568,67 @@ async def test_setup_component_and_test_service_with_receive_voice_german(
|
||||
url = await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
client = await hass_client()
|
||||
req = await client.get(url)
|
||||
_, demo_data = demo_provider.get_tts_audio("bla", "de")
|
||||
demo_data = tts.SpeechManager.write_tags(
|
||||
"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3",
|
||||
demo_data,
|
||||
demo_provider,
|
||||
_, tts_data = test_provider.get_tts_audio("bla", "de")
|
||||
tts_data = tts.SpeechManager.write_tags(
|
||||
"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3",
|
||||
tts_data,
|
||||
test_provider,
|
||||
"There is someone at the door.",
|
||||
"de",
|
||||
None,
|
||||
)
|
||||
assert req.status == HTTPStatus.OK
|
||||
assert await req.read() == demo_data
|
||||
assert await req.read() == tts_data
|
||||
|
||||
|
||||
async def test_setup_component_and_web_view_wrong_file(
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and receive wrong file from web."""
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
"""Set up a TTS platform and receive wrong file from web."""
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
client = await hass_client()
|
||||
|
||||
url = "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
url = "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
|
||||
req = await client.get(url)
|
||||
assert req.status == HTTPStatus.NOT_FOUND
|
||||
|
||||
|
||||
async def test_setup_component_and_web_view_wrong_filename(
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and receive wrong filename from web."""
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
"""Set up a TTS platform and receive wrong filename from web."""
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
client = await hass_client()
|
||||
|
||||
url = "/api/tts_proxy/265944dsk32c1b2a621be5930510bb2cd_en_-_demo.mp3"
|
||||
url = "/api/tts_proxy/265944dsk32c1b2a621be5930510bb2cd_en_-_test.mp3"
|
||||
|
||||
req = await client.get(url)
|
||||
assert req.status == HTTPStatus.NOT_FOUND
|
||||
|
||||
|
||||
async def test_setup_component_test_without_cache(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up demo platform without cache."""
|
||||
"""Set up a TTS platform without cache."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "cache": False}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "cache": False}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -569,24 +638,24 @@ async def test_setup_component_test_without_cache(
|
||||
assert len(calls) == 1
|
||||
await hass.async_block_till_done()
|
||||
assert not (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_test_with_cache_call_service_without_cache(
|
||||
hass: HomeAssistant, empty_cache_dir
|
||||
hass: HomeAssistant, empty_cache_dir, mock_tts
|
||||
) -> None:
|
||||
"""Set up demo platform with cache and call service without cache."""
|
||||
"""Set up a TTS platform with cache and call service without cache."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "cache": True}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "cache": True}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -597,36 +666,43 @@ async def test_setup_component_test_with_cache_call_service_without_cache(
|
||||
assert len(calls) == 1
|
||||
await hass.async_block_till_done()
|
||||
assert not (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
).is_file()
|
||||
|
||||
|
||||
async def test_setup_component_test_with_cache_dir(
|
||||
hass: HomeAssistant, empty_cache_dir, demo_provider
|
||||
hass: HomeAssistant, empty_cache_dir, test_provider
|
||||
) -> None:
|
||||
"""Set up demo platform with cache and call service without cache."""
|
||||
"""Set up a TTS platform with cache and call service without cache."""
|
||||
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA)
|
||||
|
||||
_, demo_data = demo_provider.get_tts_audio("bla", "en")
|
||||
_, tts_data = test_provider.get_tts_audio("bla", "en")
|
||||
cache_file = (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
)
|
||||
|
||||
with open(cache_file, "wb") as voice_file:
|
||||
voice_file.write(demo_data)
|
||||
voice_file.write(tts_data)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "cache": True}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "cache": True}}
|
||||
|
||||
class MockProviderBoom(MockProvider):
|
||||
def get_tts_audio(
|
||||
self, message: str, language: str, options: dict[str, Any] | None = None
|
||||
) -> tts.TtsAudioType:
|
||||
"""Load TTS dat."""
|
||||
# This should not be called, data should be fetched from cache
|
||||
raise Exception("Boom!")
|
||||
|
||||
mock_integration(hass, MockModule(domain="test"))
|
||||
mock_platform(hass, "test.tts", MockTTS(MockProviderBoom))
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.demo.tts.DemoProvider.get_tts_audio",
|
||||
return_value=(None, None),
|
||||
):
|
||||
await hass.services.async_call(
|
||||
tts.DOMAIN,
|
||||
"demo_say",
|
||||
"test_say",
|
||||
{
|
||||
"entity_id": "media_player.something",
|
||||
tts.ATTR_MESSAGE: "There is someone at the door.",
|
||||
@ -636,77 +712,85 @@ async def test_setup_component_test_with_cache_dir(
|
||||
assert len(calls) == 1
|
||||
assert (
|
||||
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
== "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
)
|
||||
|
||||
|
||||
async def test_setup_component_test_with_error_on_get_tts(hass: HomeAssistant) -> None:
|
||||
"""Set up demo platform with wrong get_tts_audio."""
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
"""Set up a TTS platform with wrong get_tts_audio."""
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN), patch(
|
||||
"homeassistant.components.demo.tts.DemoProvider.get_tts_audio",
|
||||
return_value=(None, None),
|
||||
):
|
||||
class MockProviderEmpty(MockProvider):
|
||||
def get_tts_audio(
|
||||
self, message: str, language: str, options: dict[str, Any] | None = None
|
||||
) -> tts.TtsAudioType:
|
||||
"""Load TTS dat."""
|
||||
return (None, None)
|
||||
|
||||
mock_integration(hass, MockModule(domain="test"))
|
||||
mock_platform(hass, "test.tts", MockTTS(MockProviderEmpty))
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
|
||||
async def test_setup_component_load_cache_retrieve_without_mem_cache(
|
||||
hass: HomeAssistant,
|
||||
demo_provider,
|
||||
test_provider,
|
||||
empty_cache_dir,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_tts,
|
||||
) -> None:
|
||||
"""Set up component and load cache and get without mem cache."""
|
||||
_, demo_data = demo_provider.get_tts_audio("bla", "en")
|
||||
_, tts_data = test_provider.get_tts_audio("bla", "en")
|
||||
cache_file = (
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
)
|
||||
|
||||
with open(cache_file, "wb") as voice_file:
|
||||
voice_file.write(demo_data)
|
||||
voice_file.write(tts_data)
|
||||
|
||||
config = {tts.DOMAIN: {"platform": "demo", "cache": True}}
|
||||
config = {tts.DOMAIN: {"platform": "test", "cache": True}}
|
||||
|
||||
with assert_setup_component(1, tts.DOMAIN):
|
||||
assert await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
client = await hass_client()
|
||||
|
||||
url = "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3"
|
||||
url = "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
|
||||
|
||||
req = await client.get(url)
|
||||
assert req.status == HTTPStatus.OK
|
||||
assert await req.read() == demo_data
|
||||
assert await req.read() == tts_data
|
||||
|
||||
|
||||
async def test_setup_component_and_web_get_url(
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and receive file from web."""
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
"""Set up a TTS platform and receive file from web."""
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
client = await hass_client()
|
||||
|
||||
url = "/api/tts_get_url"
|
||||
data = {"platform": "demo", "message": "There is someone at the door."}
|
||||
data = {"platform": "test", "message": "There is someone at the door."}
|
||||
|
||||
req = await client.post(url, json=data)
|
||||
assert req.status == HTTPStatus.OK
|
||||
response = await req.json()
|
||||
assert response == {
|
||||
"url": "http://example.local:8123/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3",
|
||||
"path": "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3",
|
||||
"url": "http://example.local:8123/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3",
|
||||
"path": "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3",
|
||||
}
|
||||
|
||||
|
||||
async def test_setup_component_and_web_get_url_bad_config(
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||
hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
|
||||
) -> None:
|
||||
"""Set up the demo platform and receive wrong file from web."""
|
||||
config = {tts.DOMAIN: {"platform": "demo"}}
|
||||
"""Set up a TTS platform and receive wrong file from web."""
|
||||
config = {tts.DOMAIN: {"platform": "test"}}
|
||||
|
||||
await async_setup_component(hass, tts.DOMAIN, config)
|
||||
|
||||
@ -719,25 +803,25 @@ async def test_setup_component_and_web_get_url_bad_config(
|
||||
assert req.status == HTTPStatus.BAD_REQUEST
|
||||
|
||||
|
||||
async def test_tags_with_wave(hass: HomeAssistant, demo_provider) -> None:
|
||||
"""Set up the demo platform and call service and receive voice."""
|
||||
async def test_tags_with_wave(hass: HomeAssistant, test_provider) -> None:
|
||||
"""Set up a TTS platform and call service and receive voice."""
|
||||
|
||||
# below data represents an empty wav file
|
||||
demo_data = bytes.fromhex(
|
||||
tts_data = bytes.fromhex(
|
||||
"52 49 46 46 24 00 00 00 57 41 56 45 66 6d 74 20 10 00 00 00 01 00 02 00"
|
||||
+ "22 56 00 00 88 58 01 00 04 00 10 00 64 61 74 61 00 00 00 00"
|
||||
)
|
||||
|
||||
tagged_data = ORIG_WRITE_TAGS(
|
||||
"42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.wav",
|
||||
demo_data,
|
||||
demo_provider,
|
||||
"42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.wav",
|
||||
tts_data,
|
||||
test_provider,
|
||||
"AI person is in front of your door.",
|
||||
"en",
|
||||
None,
|
||||
)
|
||||
|
||||
assert tagged_data != demo_data
|
||||
assert tagged_data != tts_data
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@ -781,10 +865,10 @@ def test_invalid_base_url(value) -> None:
|
||||
@pytest.mark.parametrize(
|
||||
("engine", "language", "options", "cache", "result_engine", "result_query"),
|
||||
(
|
||||
(None, None, None, None, "demo", ""),
|
||||
(None, "de", None, None, "demo", "language=de"),
|
||||
(None, "de", {"voice": "henk"}, None, "demo", "language=de&voice=henk"),
|
||||
(None, "de", None, True, "demo", "cache=true&language=de"),
|
||||
(None, None, None, None, "test", ""),
|
||||
(None, "de", None, None, "test", "language=de"),
|
||||
(None, "de", {"voice": "henk"}, None, "test", "language=de&voice=henk"),
|
||||
(None, "de", None, True, "test", "cache=true&language=de"),
|
||||
),
|
||||
)
|
||||
async def test_generate_media_source_id(
|
||||
|
Loading…
x
Reference in New Issue
Block a user