Files
core/tests/components/alexa_devices/test_services.py
2025-07-30 14:52:31 +02:00

196 lines
5.6 KiB
Python

"""Tests for Alexa Devices services."""
from unittest.mock import AsyncMock
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.alexa_devices.const import DOMAIN
from homeassistant.components.alexa_devices.services import (
ATTR_SOUND,
ATTR_SOUND_VARIANT,
ATTR_TEXT_COMMAND,
SERVICE_SOUND_NOTIFICATION,
SERVICE_TEXT_COMMAND,
)
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import ATTR_DEVICE_ID
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import device_registry as dr
from . import setup_integration
from .const import TEST_DEVICE_ID, TEST_SERIAL_NUMBER
from tests.common import MockConfigEntry, mock_device_registry
async def test_setup_services(
hass: HomeAssistant,
mock_amazon_devices_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test setup of Alexa Devices services."""
await setup_integration(hass, mock_config_entry)
assert (services := hass.services.async_services_for_domain(DOMAIN))
assert SERVICE_TEXT_COMMAND in services
assert SERVICE_SOUND_NOTIFICATION in services
async def test_send_sound_service(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
mock_amazon_devices_client: AsyncMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test send sound service."""
await setup_integration(hass, mock_config_entry)
device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, TEST_SERIAL_NUMBER)}
)
assert device_entry
await hass.services.async_call(
DOMAIN,
SERVICE_SOUND_NOTIFICATION,
{
ATTR_SOUND: "chimes_bells",
ATTR_SOUND_VARIANT: 1,
ATTR_DEVICE_ID: device_entry.id,
},
blocking=True,
)
assert mock_amazon_devices_client.call_alexa_sound.call_count == 1
assert mock_amazon_devices_client.call_alexa_sound.call_args == snapshot
async def test_send_text_service(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
mock_amazon_devices_client: AsyncMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
) -> None:
"""Test send text service."""
await setup_integration(hass, mock_config_entry)
device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, TEST_SERIAL_NUMBER)}
)
assert device_entry
await hass.services.async_call(
DOMAIN,
SERVICE_TEXT_COMMAND,
{
ATTR_TEXT_COMMAND: "Play B.B.C. radio on TuneIn",
ATTR_DEVICE_ID: device_entry.id,
},
blocking=True,
)
assert mock_amazon_devices_client.call_alexa_text_command.call_count == 1
assert mock_amazon_devices_client.call_alexa_text_command.call_args == snapshot
@pytest.mark.parametrize(
("sound", "device_id", "translation_key", "translation_placeholders"),
[
(
"chimes_bells",
"fake_device_id",
"invalid_device_id",
{"device_id": "fake_device_id"},
),
(
"wrong_sound_name",
TEST_DEVICE_ID,
"invalid_sound_value",
{
"sound": "wrong_sound_name",
"variant": "1",
},
),
],
)
async def test_invalid_parameters(
hass: HomeAssistant,
mock_amazon_devices_client: AsyncMock,
mock_config_entry: MockConfigEntry,
sound: str,
device_id: str,
translation_key: str,
translation_placeholders: dict[str, str],
) -> None:
"""Test invalid service parameters."""
device_entry = dr.DeviceEntry(
id=TEST_DEVICE_ID, identifiers={(DOMAIN, TEST_SERIAL_NUMBER)}
)
mock_device_registry(
hass,
{device_entry.id: device_entry},
)
await setup_integration(hass, mock_config_entry)
# Call Service
with pytest.raises(ServiceValidationError) as exc_info:
await hass.services.async_call(
DOMAIN,
SERVICE_SOUND_NOTIFICATION,
{
ATTR_SOUND: sound,
ATTR_SOUND_VARIANT: 1,
ATTR_DEVICE_ID: device_id,
},
blocking=True,
)
assert exc_info.value.translation_domain == DOMAIN
assert exc_info.value.translation_key == translation_key
assert exc_info.value.translation_placeholders == translation_placeholders
async def test_config_entry_not_loaded(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
mock_amazon_devices_client: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test config entry not loaded."""
await setup_integration(hass, mock_config_entry)
device_entry = device_registry.async_get_device(
identifiers={(DOMAIN, TEST_SERIAL_NUMBER)}
)
assert device_entry
await hass.config_entries.async_unload(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
# Call Service
with pytest.raises(ServiceValidationError) as exc_info:
await hass.services.async_call(
DOMAIN,
SERVICE_SOUND_NOTIFICATION,
{
ATTR_SOUND: "chimes_bells",
ATTR_SOUND_VARIANT: 1,
ATTR_DEVICE_ID: device_entry.id,
},
blocking=True,
)
assert exc_info.value.translation_domain == DOMAIN
assert exc_info.value.translation_key == "entry_not_loaded"
assert exc_info.value.translation_placeholders == {"entry": mock_config_entry.title}