core/tests/components/androidtv_remote/test_remote.py

220 lines
7.3 KiB
Python
Raw Normal View History

"""Tests for the Android TV Remote remote platform."""
from collections.abc import Callable
from unittest.mock import MagicMock, call
from androidtvremote2 import ConnectionClosed
import pytest
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from tests.common import MockConfigEntry
REMOTE_ENTITY = "remote.my_android_tv"
async def test_remote_receives_push_updates(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
) -> None:
"""Test the Android TV Remote receives push updates and state is updated."""
is_on_updated_callback: Callable | None = None
current_app_updated_callback: Callable | None = None
is_available_updated_callback: Callable | None = None
def mocked_add_is_on_updated_callback(callback: Callable):
nonlocal is_on_updated_callback
is_on_updated_callback = callback
def mocked_add_current_app_updated_callback(callback: Callable):
nonlocal current_app_updated_callback
current_app_updated_callback = callback
def mocked_add_is_available_updated_callback(callback: Callable):
nonlocal is_available_updated_callback
is_available_updated_callback = callback
mock_api.add_is_on_updated_callback.side_effect = mocked_add_is_on_updated_callback
mock_api.add_current_app_updated_callback.side_effect = (
mocked_add_current_app_updated_callback
)
mock_api.add_is_available_updated_callback.side_effect = (
mocked_add_is_available_updated_callback
)
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
assert mock_config_entry.state is ConfigEntryState.LOADED
is_on_updated_callback(False)
assert hass.states.is_state(REMOTE_ENTITY, STATE_OFF)
is_on_updated_callback(True)
assert hass.states.is_state(REMOTE_ENTITY, STATE_ON)
current_app_updated_callback("activity1")
assert (
hass.states.get(REMOTE_ENTITY).attributes.get("current_activity") == "activity1"
)
is_available_updated_callback(False)
assert hass.states.is_state(REMOTE_ENTITY, STATE_UNAVAILABLE)
is_available_updated_callback(True)
assert hass.states.is_state(REMOTE_ENTITY, STATE_ON)
async def test_remote_toggles(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
) -> None:
"""Test the Android TV Remote toggles."""
is_on_updated_callback: Callable | None = None
def mocked_add_is_on_updated_callback(callback: Callable):
nonlocal is_on_updated_callback
is_on_updated_callback = callback
mock_api.add_is_on_updated_callback.side_effect = mocked_add_is_on_updated_callback
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
assert mock_config_entry.state is ConfigEntryState.LOADED
assert await hass.services.async_call(
"remote",
"turn_off",
{"entity_id": REMOTE_ENTITY},
blocking=True,
)
is_on_updated_callback(False)
mock_api.send_key_command.assert_called_with("POWER", "SHORT")
assert await hass.services.async_call(
"remote",
"turn_on",
{"entity_id": REMOTE_ENTITY},
blocking=True,
)
is_on_updated_callback(True)
mock_api.send_key_command.assert_called_with("POWER", "SHORT")
assert mock_api.send_key_command.call_count == 2
assert await hass.services.async_call(
"remote",
"turn_on",
{"entity_id": REMOTE_ENTITY, "activity": "activity1"},
blocking=True,
)
mock_api.send_key_command.send_launch_app_command("activity1")
assert mock_api.send_key_command.call_count == 2
assert mock_api.send_launch_app_command.call_count == 1
async def test_remote_send_command(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
) -> None:
"""Test remote.send_command service."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
assert mock_config_entry.state is ConfigEntryState.LOADED
assert await hass.services.async_call(
"remote",
"send_command",
{
"entity_id": REMOTE_ENTITY,
"command": "DPAD_LEFT",
"num_repeats": 2,
"delay_secs": 0.01,
},
blocking=True,
)
mock_api.send_key_command.assert_called_with("DPAD_LEFT", "SHORT")
assert mock_api.send_key_command.call_count == 2
async def test_remote_send_command_multiple(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
) -> None:
"""Test remote.send_command service with multiple commands."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
assert mock_config_entry.state is ConfigEntryState.LOADED
assert await hass.services.async_call(
"remote",
"send_command",
{
"entity_id": REMOTE_ENTITY,
"command": ["DPAD_LEFT", "DPAD_UP"],
"delay_secs": 0.01,
},
blocking=True,
)
assert mock_api.send_key_command.mock_calls == [
call("DPAD_LEFT", "SHORT"),
call("DPAD_UP", "SHORT"),
]
async def test_remote_send_command_with_hold_secs(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
) -> None:
"""Test remote.send_command service with hold_secs."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
assert mock_config_entry.state is ConfigEntryState.LOADED
assert await hass.services.async_call(
"remote",
"send_command",
{
"entity_id": REMOTE_ENTITY,
"command": "DPAD_RIGHT",
"delay_secs": 0.01,
"hold_secs": 0.01,
},
blocking=True,
)
assert mock_api.send_key_command.mock_calls == [
call("DPAD_RIGHT", "START_LONG"),
call("DPAD_RIGHT", "END_LONG"),
]
async def test_remote_connection_closed(
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_api: MagicMock
) -> None:
"""Test commands raise HomeAssistantError if ConnectionClosed."""
mock_config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(mock_config_entry.entry_id)
assert mock_config_entry.state is ConfigEntryState.LOADED
mock_api.send_key_command.side_effect = ConnectionClosed()
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
"remote",
"send_command",
{
"entity_id": REMOTE_ENTITY,
"command": "DPAD_LEFT",
"delay_secs": 0.01,
},
blocking=True,
)
assert mock_api.send_key_command.mock_calls == [call("DPAD_LEFT", "SHORT")]
mock_api.send_launch_app_command.side_effect = ConnectionClosed()
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
"remote",
"turn_on",
{"entity_id": REMOTE_ENTITY, "activity": "activity1"},
blocking=True,
)
assert mock_api.send_launch_app_command.mock_calls == [call("activity1")]