Rewrite tts tests (#90355)

This commit is contained in:
Erik Montnemery 2023-03-27 14:01:17 +02:00 committed by GitHub
parent c193402ba7
commit a91aef9d52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,12 +1,11 @@
"""The tests for the TTS component.""" """The tests for the TTS component."""
from http import HTTPStatus from http import HTTPStatus
from unittest.mock import PropertyMock, patch from typing import Any
import pytest import pytest
import voluptuous as vol import voluptuous as vol
from homeassistant.components import media_source, tts from homeassistant.components import media_source, tts
from homeassistant.components.demo.tts import DemoProvider
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
ATTR_MEDIA_ANNOUNCE, ATTR_MEDIA_ANNOUNCE,
ATTR_MEDIA_CONTENT_ID, 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.config import async_process_ha_core_config
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
from homeassistant.util.network import normalize_url 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 from tests.typing import ClientSessionGenerator
ORIG_WRITE_TAGS = tts.SpeechManager.write_tags ORIG_WRITE_TAGS = tts.SpeechManager.write_tags
@ -36,10 +42,68 @@ async def get_media_source_url(hass, media_content_id):
return resolved.url 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 @pytest.fixture
def demo_provider(): def test_provider():
"""Demo TTS provider.""" """Test TTS provider."""
return DemoProvider("en") return MockProvider("en")
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
@ -52,49 +116,52 @@ async def internal_url_mock(hass):
@pytest.fixture @pytest.fixture
async def setup_tts(hass): async def mock_tts(hass):
"""Mock TTS.""" """Mock TTS."""
with patch("homeassistant.components.demo.async_setup", return_value=True): mock_integration(hass, MockModule(domain="test"))
assert await async_setup_component( mock_platform(hass, "test.tts", MockTTS())
hass, tts.DOMAIN, {"tts": {"platform": "demo"}}
)
await hass.async_block_till_done()
async def test_setup_component_demo(hass: HomeAssistant, setup_tts) -> None: @pytest.fixture
"""Set up the demo platform with defaults.""" async def setup_tts(hass, mock_tts):
assert hass.services.has_service(tts.DOMAIN, "demo_say") """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 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( async def test_setup_component_no_access_cache_folder(
hass: HomeAssistant, mock_init_cache_dir hass: HomeAssistant, mock_init_cache_dir, mock_tts
) -> None: ) -> None:
"""Set up the demo platform with defaults.""" """Set up a TTS platform with defaults."""
config = {tts.DOMAIN: {"platform": "demo"}} config = {tts.DOMAIN: {"platform": "test"}}
mock_init_cache_dir.side_effect = OSError(2, "No access") mock_init_cache_dir.side_effect = OSError(2, "No access")
assert not await async_setup_component(hass, tts.DOMAIN, config) 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") assert not hass.services.has_service(tts.DOMAIN, "clear_cache")
async def test_setup_component_and_test_service( async def test_setup_component_and_test_service(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir, mock_tts
) -> None: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
assert ( assert (
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) 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() await hass.async_block_till_done()
assert ( assert (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_service_with_config_language( async def test_setup_component_and_test_service_with_config_language(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir, mock_tts
) -> None: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
assert ( assert (
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) 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() await hass.async_block_till_done()
assert ( assert (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_service_with_config_language_special( 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: ) -> None:
"""Set up the demo platform and call service with extend language.""" """Set up a TTS platform and call service with extend language."""
import homeassistant.components.demo.tts as demo_tts
demo_tts.SUPPORT_LANGUAGES.append("en_US")
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
assert ( assert (
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) 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() await hass.async_block_till_done()
assert ( assert (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en-us_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_service_with_wrong_conf_language( async def test_setup_component_and_test_service_with_wrong_conf_language(
hass: HomeAssistant, hass: HomeAssistant, mock_tts
) -> None: ) -> None:
"""Set up the demo platform and call service with wrong config.""" """Set up a TTS platform and call service with wrong config."""
config = {tts.DOMAIN: {"platform": "demo", "language": "ru"}} config = {tts.DOMAIN: {"platform": "test", "language": "ru"}}
with assert_setup_component(0, tts.DOMAIN): with assert_setup_component(0, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
async def test_setup_component_and_test_service_with_service_language( async def test_setup_component_and_test_service_with_service_language(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir, mock_tts
) -> None: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
assert ( assert (
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) 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() await hass.async_block_till_done()
assert ( assert (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_test_service_with_wrong_service_language( async def test_setup_component_test_service_with_wrong_service_language(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir, mock_tts
) -> None: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) 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): with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 len(calls) == 0
assert not ( assert not (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_lang_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_lang_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_service_with_service_options( async def test_setup_component_and_test_service_with_service_options(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir, mock_tts
) -> None: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
assert ( assert (
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) 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() await hass.async_block_till_done()
assert ( assert (
empty_cache_dir empty_cache_dir
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3" / f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_with_service_options_def( async def test_setup_component_and_test_with_service_options_def(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir
) -> None: ) -> 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) 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( class MockProviderWithDefaults(MockProvider):
"homeassistant.components.demo.tts.DemoProvider.default_options", @property
new_callable=PropertyMock(return_value={"voice": "alex"}), 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) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 calls[0].data[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
assert ( assert (
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) 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() await hass.async_block_till_done()
assert ( assert (
empty_cache_dir empty_cache_dir
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3" / f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_service_with_service_options_wrong( 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: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) 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): with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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() await hass.async_block_till_done()
assert not ( assert not (
empty_cache_dir empty_cache_dir
/ f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_demo.mp3" / f"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_{opt_hash}_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_service_with_base_url_set( async def test_setup_component_and_test_service_with_base_url_set(
hass: HomeAssistant, hass: HomeAssistant, mock_tts
) -> None: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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]) await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
== "http://fnord" == "http://fnord"
"/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491" "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491"
"_en_-_demo.mp3" "_en_-_test.mp3"
) )
async def test_setup_component_and_test_service_clear_cache( async def test_setup_component_and_test_service_clear_cache(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir, mock_tts
) -> None: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
await hass.async_block_till_done() await hass.async_block_till_done()
assert ( assert (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
).is_file() ).is_file()
await hass.services.async_call( await hass.services.async_call(
@ -425,17 +494,17 @@ async def test_setup_component_and_test_service_clear_cache(
) )
assert not ( assert not (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_and_test_service_with_receive_voice( 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: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) 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( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: message, 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]) url = await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
client = await hass_client() client = await hass_client()
req = await client.get(url) req = await client.get(url)
_, demo_data = demo_provider.get_tts_audio("bla", "en") _, tts_data = test_provider.get_tts_audio("bla", "en")
demo_data = tts.SpeechManager.write_tags( tts_data = tts.SpeechManager.write_tags(
"42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3", "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3",
demo_data, tts_data,
demo_provider, test_provider,
message, message,
"en", "en",
None, None,
) )
assert req.status == HTTPStatus.OK 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( extension, data = await tts.async_get_media_source_audio(
hass, calls[0].data[ATTR_MEDIA_CONTENT_ID] hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]
) )
assert extension == "mp3" assert extension == "mp3"
assert demo_data == data assert tts_data == data
async def test_setup_component_and_test_service_with_receive_voice_german( 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: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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]) url = await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID])
client = await hass_client() client = await hass_client()
req = await client.get(url) req = await client.get(url)
_, demo_data = demo_provider.get_tts_audio("bla", "de") _, tts_data = test_provider.get_tts_audio("bla", "de")
demo_data = tts.SpeechManager.write_tags( tts_data = tts.SpeechManager.write_tags(
"42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_demo.mp3", "42f18378fd4393d18c8dd11d03fa9563c1e54491_de_-_test.mp3",
demo_data, tts_data,
demo_provider, test_provider,
"There is someone at the door.", "There is someone at the door.",
"de", "de",
None, None,
) )
assert req.status == HTTPStatus.OK 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( async def test_setup_component_and_web_view_wrong_file(
hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
) -> None: ) -> None:
"""Set up the demo platform and receive wrong file from web.""" """Set up a TTS platform and receive wrong file from web."""
config = {tts.DOMAIN: {"platform": "demo"}} config = {tts.DOMAIN: {"platform": "test"}}
with assert_setup_component(1, tts.DOMAIN): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
client = await hass_client() 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) req = await client.get(url)
assert req.status == HTTPStatus.NOT_FOUND assert req.status == HTTPStatus.NOT_FOUND
async def test_setup_component_and_web_view_wrong_filename( async def test_setup_component_and_web_view_wrong_filename(
hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
) -> None: ) -> None:
"""Set up the demo platform and receive wrong filename from web.""" """Set up a TTS platform and receive wrong filename from web."""
config = {tts.DOMAIN: {"platform": "demo"}} config = {tts.DOMAIN: {"platform": "test"}}
with assert_setup_component(1, tts.DOMAIN): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
client = await hass_client() 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) req = await client.get(url)
assert req.status == HTTPStatus.NOT_FOUND assert req.status == HTTPStatus.NOT_FOUND
async def test_setup_component_test_without_cache( async def test_setup_component_test_without_cache(
hass: HomeAssistant, empty_cache_dir hass: HomeAssistant, empty_cache_dir, mock_tts
) -> None: ) -> None:
"""Set up demo platform without cache.""" """Set up a TTS platform without cache."""
calls = async_mock_service(hass, DOMAIN_MP, SERVICE_PLAY_MEDIA) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", 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 assert len(calls) == 1
await hass.async_block_till_done() await hass.async_block_till_done()
assert not ( assert not (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_test_with_cache_call_service_without_cache( 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: ) -> 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) 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
await hass.services.async_call( await hass.services.async_call(
tts.DOMAIN, tts.DOMAIN,
"demo_say", "test_say",
{ {
"entity_id": "media_player.something", "entity_id": "media_player.something",
tts.ATTR_MESSAGE: "There is someone at the door.", tts.ATTR_MESSAGE: "There is someone at the door.",
@ -597,116 +666,131 @@ async def test_setup_component_test_with_cache_call_service_without_cache(
assert len(calls) == 1 assert len(calls) == 1
await hass.async_block_till_done() await hass.async_block_till_done()
assert not ( assert not (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
).is_file() ).is_file()
async def test_setup_component_test_with_cache_dir( async def test_setup_component_test_with_cache_dir(
hass: HomeAssistant, empty_cache_dir, demo_provider hass: HomeAssistant, empty_cache_dir, test_provider
) -> None: ) -> 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) 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 = ( cache_file = (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
) )
with open(cache_file, "wb") as voice_file: 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
with patch( await hass.services.async_call(
"homeassistant.components.demo.tts.DemoProvider.get_tts_audio", tts.DOMAIN,
return_value=(None, None), "test_say",
): {
await hass.services.async_call( "entity_id": "media_player.something",
tts.DOMAIN, tts.ATTR_MESSAGE: "There is someone at the door.",
"demo_say", },
{ blocking=True,
"entity_id": "media_player.something", )
tts.ATTR_MESSAGE: "There is someone at the door.",
},
blocking=True,
)
assert len(calls) == 1 assert len(calls) == 1
assert ( assert (
await get_media_source_url(hass, calls[0].data[ATTR_MEDIA_CONTENT_ID]) 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: async def test_setup_component_test_with_error_on_get_tts(hass: HomeAssistant) -> None:
"""Set up demo platform with wrong get_tts_audio.""" """Set up a TTS platform with wrong get_tts_audio."""
config = {tts.DOMAIN: {"platform": "demo"}} config = {tts.DOMAIN: {"platform": "test"}}
with assert_setup_component(1, tts.DOMAIN), patch( class MockProviderEmpty(MockProvider):
"homeassistant.components.demo.tts.DemoProvider.get_tts_audio", def get_tts_audio(
return_value=(None, None), 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) assert await async_setup_component(hass, tts.DOMAIN, config)
async def test_setup_component_load_cache_retrieve_without_mem_cache( async def test_setup_component_load_cache_retrieve_without_mem_cache(
hass: HomeAssistant, hass: HomeAssistant,
demo_provider, test_provider,
empty_cache_dir, empty_cache_dir,
hass_client: ClientSessionGenerator, hass_client: ClientSessionGenerator,
mock_tts,
) -> None: ) -> None:
"""Set up component and load cache and get without mem cache.""" """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 = ( cache_file = (
empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.mp3" empty_cache_dir / "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3"
) )
with open(cache_file, "wb") as voice_file: 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): with assert_setup_component(1, tts.DOMAIN):
assert await async_setup_component(hass, tts.DOMAIN, config) assert await async_setup_component(hass, tts.DOMAIN, config)
client = await hass_client() 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) req = await client.get(url)
assert req.status == HTTPStatus.OK 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( async def test_setup_component_and_web_get_url(
hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
) -> None: ) -> None:
"""Set up the demo platform and receive file from web.""" """Set up a TTS platform and receive file from web."""
config = {tts.DOMAIN: {"platform": "demo"}} config = {tts.DOMAIN: {"platform": "test"}}
await async_setup_component(hass, tts.DOMAIN, config) await async_setup_component(hass, tts.DOMAIN, config)
client = await hass_client() client = await hass_client()
url = "/api/tts_get_url" 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) req = await client.post(url, json=data)
assert req.status == HTTPStatus.OK assert req.status == HTTPStatus.OK
response = await req.json() response = await req.json()
assert response == { assert response == {
"url": "http://example.local:8123/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_-_demo.mp3", "path": "/api/tts_proxy/42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.mp3",
} }
async def test_setup_component_and_web_get_url_bad_config( async def test_setup_component_and_web_get_url_bad_config(
hass: HomeAssistant, hass_client: ClientSessionGenerator hass: HomeAssistant, hass_client: ClientSessionGenerator, mock_tts
) -> None: ) -> None:
"""Set up the demo platform and receive wrong file from web.""" """Set up a TTS platform and receive wrong file from web."""
config = {tts.DOMAIN: {"platform": "demo"}} config = {tts.DOMAIN: {"platform": "test"}}
await async_setup_component(hass, tts.DOMAIN, config) 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 assert req.status == HTTPStatus.BAD_REQUEST
async def test_tags_with_wave(hass: HomeAssistant, demo_provider) -> None: async def test_tags_with_wave(hass: HomeAssistant, test_provider) -> None:
"""Set up the demo platform and call service and receive voice.""" """Set up a TTS platform and call service and receive voice."""
# below data represents an empty wav file # 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" "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" + "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( tagged_data = ORIG_WRITE_TAGS(
"42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_demo.wav", "42f18378fd4393d18c8dd11d03fa9563c1e54491_en_-_test.wav",
demo_data, tts_data,
demo_provider, test_provider,
"AI person is in front of your door.", "AI person is in front of your door.",
"en", "en",
None, None,
) )
assert tagged_data != demo_data assert tagged_data != tts_data
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -781,10 +865,10 @@ def test_invalid_base_url(value) -> None:
@pytest.mark.parametrize( @pytest.mark.parametrize(
("engine", "language", "options", "cache", "result_engine", "result_query"), ("engine", "language", "options", "cache", "result_engine", "result_query"),
( (
(None, None, None, None, "demo", ""), (None, None, None, None, "test", ""),
(None, "de", None, None, "demo", "language=de"), (None, "de", None, None, "test", "language=de"),
(None, "de", {"voice": "henk"}, None, "demo", "language=de&voice=henk"), (None, "de", {"voice": "henk"}, None, "test", "language=de&voice=henk"),
(None, "de", None, True, "demo", "cache=true&language=de"), (None, "de", None, True, "test", "cache=true&language=de"),
), ),
) )
async def test_generate_media_source_id( async def test_generate_media_source_id(