mirror of
https://github.com/home-assistant/core.git
synced 2025-12-20 10:59:24 +00:00
237 lines
6.6 KiB
Python
237 lines
6.6 KiB
Python
"""Common fixtures for the ElevenLabs text-to-speech tests."""
|
|
|
|
from collections.abc import Generator
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
from elevenlabs.core import ApiError
|
|
from elevenlabs.types import GetVoicesResponse
|
|
from httpx import ConnectError
|
|
import pytest
|
|
|
|
from homeassistant.components.elevenlabs.const import (
|
|
CONF_MODEL,
|
|
CONF_STT_AUTO_LANGUAGE,
|
|
CONF_STT_MODEL,
|
|
CONF_VOICE,
|
|
DEFAULT_SIMILARITY,
|
|
DOMAIN,
|
|
)
|
|
from homeassistant.const import CONF_API_KEY
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from .const import MOCK_MODELS, MOCK_VOICES
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_setup_entry() -> Generator[AsyncMock]:
|
|
"""Override async_setup_entry."""
|
|
with patch(
|
|
"homeassistant.components.elevenlabs.async_setup_entry", return_value=True
|
|
) as mock_setup_entry:
|
|
yield mock_setup_entry
|
|
|
|
|
|
def _client_mock():
|
|
client_mock = AsyncMock()
|
|
client_mock.voices.get_all.return_value = GetVoicesResponse(voices=MOCK_VOICES)
|
|
client_mock.models.list.return_value = MOCK_MODELS
|
|
|
|
return client_mock
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_async_client() -> Generator[AsyncMock]:
|
|
"""Override async ElevenLabs client."""
|
|
with (
|
|
patch(
|
|
"homeassistant.components.elevenlabs.AsyncElevenLabs",
|
|
return_value=_client_mock(),
|
|
) as mock_async_client,
|
|
patch(
|
|
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
|
new=mock_async_client,
|
|
),
|
|
patch(
|
|
"homeassistant.components.elevenlabs.tts.AsyncElevenLabs",
|
|
new=mock_async_client,
|
|
),
|
|
):
|
|
yield mock_async_client
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_async_client_api_error() -> Generator[AsyncMock]:
|
|
"""Override async ElevenLabs client with ApiError side effect."""
|
|
client_mock = _client_mock()
|
|
api_error = ApiError()
|
|
api_error.body = {
|
|
"detail": {"status": "invalid_api_key", "message": "API key is invalid"}
|
|
}
|
|
client_mock.models.list.side_effect = api_error
|
|
client_mock.voices.get_all.side_effect = api_error
|
|
|
|
with (
|
|
patch(
|
|
"homeassistant.components.elevenlabs.AsyncElevenLabs",
|
|
return_value=client_mock,
|
|
) as mock_async_client,
|
|
patch(
|
|
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
|
new=mock_async_client,
|
|
),
|
|
):
|
|
yield mock_async_client
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_async_client_voices_error() -> Generator[AsyncMock]:
|
|
"""Override async ElevenLabs client with ApiError side effect."""
|
|
client_mock = _client_mock()
|
|
api_error = ApiError()
|
|
api_error.body = {
|
|
"detail": {
|
|
"status": "voices_unauthorized",
|
|
"message": "API is unauthorized for voices",
|
|
}
|
|
}
|
|
client_mock.voices.get_all.side_effect = api_error
|
|
|
|
with patch(
|
|
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
|
return_value=client_mock,
|
|
) as mock_async_client:
|
|
yield mock_async_client
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_async_client_models_error() -> Generator[AsyncMock]:
|
|
"""Override async ElevenLabs client with ApiError side effect."""
|
|
client_mock = _client_mock()
|
|
api_error = ApiError()
|
|
api_error.body = {
|
|
"detail": {
|
|
"status": "models_unauthorized",
|
|
"message": "API is unauthorized for models",
|
|
}
|
|
}
|
|
client_mock.models.list.side_effect = api_error
|
|
|
|
with patch(
|
|
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
|
return_value=client_mock,
|
|
) as mock_async_client:
|
|
yield mock_async_client
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_async_client_connect_error() -> Generator[AsyncMock]:
|
|
"""Override async ElevenLabs client."""
|
|
client_mock = _client_mock()
|
|
client_mock.models.list.side_effect = ConnectError("Unknown")
|
|
client_mock.voices.get_all.side_effect = ConnectError("Unknown")
|
|
with (
|
|
patch(
|
|
"homeassistant.components.elevenlabs.AsyncElevenLabs",
|
|
return_value=client_mock,
|
|
) as mock_async_client,
|
|
patch(
|
|
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
|
new=mock_async_client,
|
|
),
|
|
):
|
|
yield mock_async_client
|
|
|
|
|
|
async def mock_config_entry_setup(
|
|
hass: HomeAssistant, config_data: dict[str, Any], config_options: dict[str, Any]
|
|
) -> None:
|
|
"""Mock config entry setup."""
|
|
default_config_data = {
|
|
CONF_API_KEY: "api_key",
|
|
}
|
|
default_config_options = {
|
|
CONF_VOICE: "voice1",
|
|
CONF_MODEL: "model1",
|
|
CONF_STT_MODEL: "stt_model1",
|
|
CONF_STT_AUTO_LANGUAGE: False,
|
|
}
|
|
config_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data=default_config_data | config_data,
|
|
options=default_config_options | config_options,
|
|
)
|
|
config_entry.add_to_hass(hass)
|
|
client_mock = AsyncMock()
|
|
client_mock.voices.get_all.return_value = GetVoicesResponse(voices=MOCK_VOICES)
|
|
client_mock.models.list.return_value = MOCK_MODELS
|
|
stt_mock = AsyncMock()
|
|
stt_mock.convert.return_value = AsyncMock(
|
|
text="hello world", language_code="en", language_probability=0.95
|
|
)
|
|
client_mock.speech_to_text = stt_mock
|
|
with patch(
|
|
"homeassistant.components.elevenlabs.AsyncElevenLabs", return_value=client_mock
|
|
):
|
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
|
|
|
|
|
@pytest.fixture(name="setup")
|
|
async def setup_fixture(
|
|
hass: HomeAssistant,
|
|
config_data: dict[str, Any],
|
|
config_options: dict[str, Any],
|
|
mock_async_client: AsyncMock,
|
|
) -> AsyncMock:
|
|
"""Set up the test environment."""
|
|
|
|
await mock_config_entry_setup(hass, config_data, config_options)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
return mock_async_client
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_entry() -> MockConfigEntry:
|
|
"""Mock a config entry."""
|
|
entry = MockConfigEntry(
|
|
domain="elevenlabs",
|
|
data={
|
|
CONF_API_KEY: "api_key",
|
|
},
|
|
options={
|
|
CONF_MODEL: "model1",
|
|
CONF_VOICE: "voice1",
|
|
CONF_STT_MODEL: "stt_model1",
|
|
CONF_STT_AUTO_LANGUAGE: False,
|
|
},
|
|
)
|
|
entry.models = {
|
|
"model1": "model1",
|
|
}
|
|
|
|
entry.voices = {"voice1": "voice1"}
|
|
entry.stt_models = {"stt_model1": "stt_model1"}
|
|
return entry
|
|
|
|
|
|
@pytest.fixture(name="config_data")
|
|
def config_data_fixture() -> dict[str, Any]:
|
|
"""Return config data."""
|
|
return {}
|
|
|
|
|
|
@pytest.fixture(name="config_options")
|
|
def config_options_fixture() -> dict[str, Any]:
|
|
"""Return config options."""
|
|
return {}
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_similarity():
|
|
"""Mock similarity."""
|
|
return DEFAULT_SIMILARITY / 2
|