mirror of
https://github.com/home-assistant/core.git
synced 2025-06-21 05:27:06 +00:00
Make elevenlabs recoverable (#134094)
* Make elevenlabs recoverable * Add tests for entry setup * Use the same fixtures for setup and config flow * Update tests/components/elevenlabs/test_setup.py Co-authored-by: Simon <80467011+sorgfresser@users.noreply.github.com> --------- Co-authored-by: Simon Sorg <simon.sorg@student.hpi.de> Co-authored-by: G Johansson <goran.johansson@shiftit.se> Co-authored-by: Simon <80467011+sorgfresser@users.noreply.github.com>
This commit is contained in:
parent
873b078bb3
commit
c23f5c9f2c
@ -6,11 +6,16 @@ from dataclasses import dataclass
|
|||||||
|
|
||||||
from elevenlabs import AsyncElevenLabs, Model
|
from elevenlabs import AsyncElevenLabs, Model
|
||||||
from elevenlabs.core import ApiError
|
from elevenlabs.core import ApiError
|
||||||
|
from httpx import ConnectError
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_API_KEY, Platform
|
from homeassistant.const import CONF_API_KEY, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryError
|
from homeassistant.exceptions import (
|
||||||
|
ConfigEntryAuthFailed,
|
||||||
|
ConfigEntryError,
|
||||||
|
ConfigEntryNotReady,
|
||||||
|
)
|
||||||
from homeassistant.helpers.httpx_client import get_async_client
|
from homeassistant.helpers.httpx_client import get_async_client
|
||||||
|
|
||||||
from .const import CONF_MODEL
|
from .const import CONF_MODEL
|
||||||
@ -48,6 +53,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ElevenLabsConfigEntry) -
|
|||||||
model_id = entry.options[CONF_MODEL]
|
model_id = entry.options[CONF_MODEL]
|
||||||
try:
|
try:
|
||||||
model = await get_model_by_id(client, model_id)
|
model = await get_model_by_id(client, model_id)
|
||||||
|
except ConnectError as err:
|
||||||
|
raise ConfigEntryNotReady("Failed to connect") from err
|
||||||
except ApiError as err:
|
except ApiError as err:
|
||||||
raise ConfigEntryAuthFailed("Auth failed") from err
|
raise ConfigEntryAuthFailed("Auth failed") from err
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, patch
|
|||||||
|
|
||||||
from elevenlabs.core import ApiError
|
from elevenlabs.core import ApiError
|
||||||
from elevenlabs.types import GetVoicesResponse
|
from elevenlabs.types import GetVoicesResponse
|
||||||
|
from httpx import ConnectError
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.elevenlabs.const import CONF_MODEL, CONF_VOICE
|
from homeassistant.components.elevenlabs.const import CONF_MODEL, CONF_VOICE
|
||||||
@ -34,21 +35,55 @@ def _client_mock():
|
|||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_async_client() -> Generator[AsyncMock]:
|
def mock_async_client() -> Generator[AsyncMock]:
|
||||||
"""Override async ElevenLabs client."""
|
"""Override async ElevenLabs client."""
|
||||||
with patch(
|
with (
|
||||||
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
patch(
|
||||||
|
"homeassistant.components.elevenlabs.AsyncElevenLabs",
|
||||||
return_value=_client_mock(),
|
return_value=_client_mock(),
|
||||||
) as mock_async_client:
|
) as mock_async_client,
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
||||||
|
new=mock_async_client,
|
||||||
|
),
|
||||||
|
):
|
||||||
yield mock_async_client
|
yield mock_async_client
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_async_client_fail() -> Generator[AsyncMock]:
|
def mock_async_client_api_error() -> Generator[AsyncMock]:
|
||||||
"""Override async ElevenLabs client."""
|
"""Override async ElevenLabs client with ApiError side effect."""
|
||||||
with patch(
|
client_mock = _client_mock()
|
||||||
|
client_mock.models.get_all.side_effect = ApiError
|
||||||
|
client_mock.voices.get_all.side_effect = ApiError
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch(
|
||||||
|
"homeassistant.components.elevenlabs.AsyncElevenLabs",
|
||||||
|
return_value=client_mock,
|
||||||
|
) as mock_async_client,
|
||||||
|
patch(
|
||||||
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
"homeassistant.components.elevenlabs.config_flow.AsyncElevenLabs",
|
||||||
return_value=_client_mock(),
|
new=mock_async_client,
|
||||||
) as mock_async_client:
|
),
|
||||||
mock_async_client.side_effect = ApiError
|
):
|
||||||
|
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.get_all.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
|
yield mock_async_client
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.elevenlabs.const import (
|
from homeassistant.components.elevenlabs.const import (
|
||||||
CONF_CONFIGURE_VOICE,
|
CONF_CONFIGURE_VOICE,
|
||||||
CONF_MODEL,
|
CONF_MODEL,
|
||||||
@ -56,7 +58,10 @@ async def test_user_step(
|
|||||||
|
|
||||||
|
|
||||||
async def test_invalid_api_key(
|
async def test_invalid_api_key(
|
||||||
hass: HomeAssistant, mock_setup_entry: AsyncMock, mock_async_client_fail: AsyncMock
|
hass: HomeAssistant,
|
||||||
|
mock_setup_entry: AsyncMock,
|
||||||
|
mock_async_client_api_error: AsyncMock,
|
||||||
|
request: pytest.FixtureRequest,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test user step with invalid api key."""
|
"""Test user step with invalid api key."""
|
||||||
|
|
||||||
@ -77,8 +82,8 @@ async def test_invalid_api_key(
|
|||||||
|
|
||||||
mock_setup_entry.assert_not_called()
|
mock_setup_entry.assert_not_called()
|
||||||
|
|
||||||
# Reset the side effect
|
# Use a working client
|
||||||
mock_async_client_fail.side_effect = None
|
request.getfixturevalue("mock_async_client")
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
result["flow_id"],
|
result["flow_id"],
|
||||||
|
36
tests/components/elevenlabs/test_setup.py
Normal file
36
tests/components/elevenlabs/test_setup.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
"""Tests for the ElevenLabs TTS entity."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_async_client: MagicMock,
|
||||||
|
mock_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test entry setup without any exceptions."""
|
||||||
|
mock_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||||
|
assert mock_entry.state == ConfigEntryState.LOADED
|
||||||
|
# Unload
|
||||||
|
await hass.config_entries.async_unload(mock_entry.entry_id)
|
||||||
|
assert mock_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_connect_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_async_client_connect_error: MagicMock,
|
||||||
|
mock_entry: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test entry setup with a connection error."""
|
||||||
|
mock_entry.add_to_hass(hass)
|
||||||
|
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||||
|
# Ensure is not ready
|
||||||
|
assert mock_entry.state == ConfigEntryState.SETUP_RETRY
|
Loading…
x
Reference in New Issue
Block a user