2019-11-05 14:04:19 +00:00
|
|
|
"""Tests for samsungtv component."""
|
2022-03-03 18:06:33 +00:00
|
|
|
from copy import deepcopy
|
2022-02-17 20:47:58 +00:00
|
|
|
from datetime import datetime, timedelta
|
2019-11-03 17:32:01 +00:00
|
|
|
import logging
|
2022-03-02 19:30:33 +00:00
|
|
|
from unittest.mock import DEFAULT as DEFAULT_MOCK, AsyncMock, Mock, call, patch
|
2019-12-09 13:38:01 +00:00
|
|
|
|
2018-06-26 14:22:10 +00:00
|
|
|
import pytest
|
2019-10-25 12:32:12 +00:00
|
|
|
from samsungctl import exceptions
|
2022-03-02 19:30:33 +00:00
|
|
|
from samsungtvws.async_remote import SamsungTVWSAsyncRemote
|
2022-03-08 07:20:58 +00:00
|
|
|
from samsungtvws.command import SamsungTVSleepCommand
|
2022-03-03 18:06:33 +00:00
|
|
|
from samsungtvws.exceptions import ConnectionFailure, HttpApiError
|
2022-03-02 19:30:33 +00:00
|
|
|
from samsungtvws.remote import ChannelEmitCommand, SendRemoteKey
|
2022-03-08 10:02:00 +00:00
|
|
|
from websockets.exceptions import ConnectionClosedError, WebSocketException
|
2018-06-26 14:22:10 +00:00
|
|
|
|
2021-12-17 15:26:53 +00:00
|
|
|
from homeassistant.components.media_player import MediaPlayerDeviceClass
|
2019-07-31 19:25:30 +00:00
|
|
|
from homeassistant.components.media_player.const import (
|
2019-10-25 12:32:12 +00:00
|
|
|
ATTR_INPUT_SOURCE,
|
|
|
|
ATTR_MEDIA_CONTENT_ID,
|
|
|
|
ATTR_MEDIA_CONTENT_TYPE,
|
|
|
|
ATTR_MEDIA_VOLUME_MUTED,
|
|
|
|
DOMAIN,
|
2022-02-18 21:33:49 +00:00
|
|
|
MEDIA_TYPE_APP,
|
2019-12-09 13:38:01 +00:00
|
|
|
MEDIA_TYPE_CHANNEL,
|
|
|
|
MEDIA_TYPE_URL,
|
2019-10-25 12:32:12 +00:00
|
|
|
SERVICE_PLAY_MEDIA,
|
|
|
|
SERVICE_SELECT_SOURCE,
|
2019-07-31 19:25:30 +00:00
|
|
|
SUPPORT_TURN_ON,
|
|
|
|
)
|
2020-01-10 02:19:10 +00:00
|
|
|
from homeassistant.components.samsungtv.const import (
|
|
|
|
CONF_ON_ACTION,
|
|
|
|
DOMAIN as SAMSUNGTV_DOMAIN,
|
2021-05-22 15:41:18 +00:00
|
|
|
TIMEOUT_WEBSOCKET,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2020-01-10 02:19:10 +00:00
|
|
|
from homeassistant.components.samsungtv.media_player import SUPPORT_SAMSUNGTV
|
2019-07-31 19:25:30 +00:00
|
|
|
from homeassistant.const import (
|
2019-10-25 12:32:12 +00:00
|
|
|
ATTR_DEVICE_CLASS,
|
|
|
|
ATTR_ENTITY_ID,
|
|
|
|
ATTR_FRIENDLY_NAME,
|
|
|
|
ATTR_SUPPORTED_FEATURES,
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_HOST,
|
2020-03-21 15:50:18 +00:00
|
|
|
CONF_IP_ADDRESS,
|
2021-05-22 20:33:37 +00:00
|
|
|
CONF_MAC,
|
2020-03-21 15:50:18 +00:00
|
|
|
CONF_METHOD,
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_NAME,
|
|
|
|
CONF_PORT,
|
2021-05-22 15:41:18 +00:00
|
|
|
CONF_TIMEOUT,
|
2020-03-21 15:50:18 +00:00
|
|
|
CONF_TOKEN,
|
2019-10-25 12:32:12 +00:00
|
|
|
SERVICE_MEDIA_NEXT_TRACK,
|
|
|
|
SERVICE_MEDIA_PAUSE,
|
|
|
|
SERVICE_MEDIA_PLAY,
|
2021-05-22 15:41:18 +00:00
|
|
|
SERVICE_MEDIA_PLAY_PAUSE,
|
2019-10-25 12:32:12 +00:00
|
|
|
SERVICE_MEDIA_PREVIOUS_TRACK,
|
|
|
|
SERVICE_TURN_OFF,
|
|
|
|
SERVICE_TURN_ON,
|
|
|
|
SERVICE_VOLUME_DOWN,
|
|
|
|
SERVICE_VOLUME_MUTE,
|
|
|
|
SERVICE_VOLUME_UP,
|
2019-07-31 19:25:30 +00:00
|
|
|
STATE_OFF,
|
2019-10-25 12:32:12 +00:00
|
|
|
STATE_ON,
|
2021-05-22 15:41:18 +00:00
|
|
|
STATE_UNAVAILABLE,
|
2019-07-31 19:25:30 +00:00
|
|
|
)
|
2022-02-17 20:47:58 +00:00
|
|
|
from homeassistant.core import HomeAssistant
|
2022-03-20 23:01:58 +00:00
|
|
|
from homeassistant.exceptions import HomeAssistantError
|
2022-02-17 20:47:58 +00:00
|
|
|
from homeassistant.helpers.typing import ConfigType
|
2019-10-25 12:32:12 +00:00
|
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
import homeassistant.util.dt as dt_util
|
|
|
|
|
2022-03-08 07:20:58 +00:00
|
|
|
from .const import SAMPLE_APP_LIST, SAMPLE_DEVICE_INFO_FRAME
|
2022-02-18 21:33:49 +00:00
|
|
|
|
2020-03-21 15:50:18 +00:00
|
|
|
from tests.common import MockConfigEntry, async_fire_time_changed
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
ENTITY_ID = f"{DOMAIN}.fake"
|
|
|
|
MOCK_CONFIG = {
|
2020-03-10 10:48:09 +00:00
|
|
|
SAMSUNGTV_DOMAIN: [
|
|
|
|
{
|
2021-05-22 15:41:18 +00:00
|
|
|
CONF_HOST: "fake_host",
|
2020-03-10 10:48:09 +00:00
|
|
|
CONF_NAME: "fake",
|
|
|
|
CONF_PORT: 55000,
|
|
|
|
CONF_ON_ACTION: [{"delay": "00:00:01"}],
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
MOCK_CONFIGWS = {
|
2020-01-10 02:19:10 +00:00
|
|
|
SAMSUNGTV_DOMAIN: [
|
|
|
|
{
|
2021-05-22 15:41:18 +00:00
|
|
|
CONF_HOST: "fake_host",
|
2020-01-10 02:19:10 +00:00
|
|
|
CONF_NAME: "fake",
|
|
|
|
CONF_PORT: 8001,
|
2020-03-21 15:50:18 +00:00
|
|
|
CONF_TOKEN: "123456789",
|
2020-01-10 02:19:10 +00:00
|
|
|
CONF_ON_ACTION: [{"delay": "00:00:01"}],
|
|
|
|
}
|
|
|
|
]
|
2019-10-25 12:32:12 +00:00
|
|
|
}
|
2020-03-21 15:50:18 +00:00
|
|
|
MOCK_CALLS_WS = {
|
2021-05-22 15:41:18 +00:00
|
|
|
CONF_HOST: "fake_host",
|
|
|
|
CONF_PORT: 8001,
|
|
|
|
CONF_TOKEN: "123456789",
|
|
|
|
CONF_TIMEOUT: TIMEOUT_WEBSOCKET,
|
|
|
|
CONF_NAME: "HomeAssistant",
|
2020-03-21 15:50:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MOCK_ENTRY_WS = {
|
|
|
|
CONF_IP_ADDRESS: "test",
|
2021-05-22 15:41:18 +00:00
|
|
|
CONF_HOST: "fake_host",
|
2020-03-21 15:50:18 +00:00
|
|
|
CONF_METHOD: "websocket",
|
|
|
|
CONF_NAME: "fake",
|
|
|
|
CONF_PORT: 8001,
|
2021-05-22 15:41:18 +00:00
|
|
|
CONF_TOKEN: "123456789",
|
2020-03-21 15:50:18 +00:00
|
|
|
}
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2021-05-22 20:33:37 +00:00
|
|
|
|
|
|
|
MOCK_ENTRY_WS_WITH_MAC = {
|
|
|
|
CONF_IP_ADDRESS: "test",
|
|
|
|
CONF_HOST: "fake_host",
|
|
|
|
CONF_METHOD: "websocket",
|
|
|
|
CONF_MAC: "aa:bb:cc:dd:ee:ff",
|
|
|
|
CONF_NAME: "fake",
|
|
|
|
CONF_PORT: 8002,
|
|
|
|
CONF_TOKEN: "123456789",
|
|
|
|
}
|
|
|
|
|
2020-01-10 02:19:10 +00:00
|
|
|
ENTITY_ID_NOTURNON = f"{DOMAIN}.fake_noturnon"
|
|
|
|
MOCK_CONFIG_NOTURNON = {
|
|
|
|
SAMSUNGTV_DOMAIN: [
|
|
|
|
{CONF_HOST: "fake_noturnon", CONF_NAME: "fake_noturnon", CONF_PORT: 55000}
|
|
|
|
]
|
2019-10-25 12:32:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-01-10 02:19:10 +00:00
|
|
|
@pytest.fixture(name="delay")
|
|
|
|
def delay_fixture():
|
|
|
|
"""Patch the delay script function."""
|
2019-11-05 14:04:19 +00:00
|
|
|
with patch(
|
2020-01-10 02:19:10 +00:00
|
|
|
"homeassistant.components.samsungtv.media_player.Script.async_run"
|
|
|
|
) as delay:
|
|
|
|
yield delay
|
2018-06-26 14:22:10 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def setup_samsungtv(hass: HomeAssistant, config: ConfigType) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Set up mock Samsung TV."""
|
2020-01-10 02:19:10 +00:00
|
|
|
await async_setup_component(hass, SAMSUNGTV_DOMAIN, config)
|
2019-10-25 12:32:12 +00:00
|
|
|
await hass.async_block_till_done()
|
2018-06-26 14:22:10 +00:00
|
|
|
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_setup_with_turnon(hass: HomeAssistant) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test setup of platform."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert hass.states.get(ENTITY_ID)
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_setup_without_turnon(hass: HomeAssistant) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test setup of platform."""
|
2020-01-10 02:19:10 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG_NOTURNON)
|
|
|
|
assert hass.states.get(ENTITY_ID_NOTURNON)
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remotews")
|
|
|
|
async def test_setup_websocket(hass: HomeAssistant) -> None:
|
2020-03-21 15:50:18 +00:00
|
|
|
"""Test setup of platform."""
|
2022-03-02 19:30:33 +00:00
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote"
|
|
|
|
) as remote_class:
|
|
|
|
remote = Mock(SamsungTVWSAsyncRemote)
|
|
|
|
remote.__aenter__ = AsyncMock(return_value=remote)
|
|
|
|
remote.__aexit__ = AsyncMock()
|
2022-02-18 21:33:49 +00:00
|
|
|
remote.app_list.return_value = SAMPLE_APP_LIST
|
2022-02-16 20:28:01 +00:00
|
|
|
remote.token = "123456789"
|
2020-03-21 15:50:18 +00:00
|
|
|
remote_class.return_value = remote
|
|
|
|
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
|
|
|
|
2022-02-28 19:53:42 +00:00
|
|
|
assert remote_class.call_count == 1
|
|
|
|
assert remote_class.call_args_list == [call(**MOCK_CALLS_WS)]
|
2020-03-21 15:50:18 +00:00
|
|
|
assert hass.states.get(ENTITY_ID)
|
|
|
|
|
2021-06-24 18:15:16 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
config_entries = hass.config_entries.async_entries(SAMSUNGTV_DOMAIN)
|
|
|
|
assert len(config_entries) == 1
|
2022-03-03 18:07:08 +00:00
|
|
|
assert config_entries[0].data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
|
2021-06-24 18:15:16 +00:00
|
|
|
|
2020-03-21 15:50:18 +00:00
|
|
|
|
2022-03-03 18:07:08 +00:00
|
|
|
async def test_setup_websocket_2(hass: HomeAssistant, mock_now: datetime) -> None:
|
2020-03-21 15:50:18 +00:00
|
|
|
"""Test setup of platform from config entry."""
|
|
|
|
entity_id = f"{DOMAIN}.fake"
|
|
|
|
|
|
|
|
entry = MockConfigEntry(
|
2020-08-27 11:56:20 +00:00
|
|
|
domain=SAMSUNGTV_DOMAIN,
|
|
|
|
data=MOCK_ENTRY_WS,
|
|
|
|
unique_id=entity_id,
|
2020-03-21 15:50:18 +00:00
|
|
|
)
|
|
|
|
entry.add_to_hass(hass)
|
|
|
|
|
|
|
|
config_entries = hass.config_entries.async_entries(SAMSUNGTV_DOMAIN)
|
|
|
|
assert len(config_entries) == 1
|
|
|
|
assert entry is config_entries[0]
|
|
|
|
|
2022-03-02 19:30:33 +00:00
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.bridge.SamsungTVWSAsyncRemote"
|
|
|
|
) as remote_class:
|
|
|
|
remote = Mock(SamsungTVWSAsyncRemote)
|
|
|
|
remote.__aenter__ = AsyncMock(return_value=remote)
|
|
|
|
remote.__aexit__ = AsyncMock()
|
2022-02-18 21:33:49 +00:00
|
|
|
remote.app_list.return_value = SAMPLE_APP_LIST
|
2022-02-16 20:13:11 +00:00
|
|
|
remote.token = "987654321"
|
2021-06-24 18:15:16 +00:00
|
|
|
remote_class.return_value = remote
|
|
|
|
assert await async_setup_component(hass, SAMSUNGTV_DOMAIN, {})
|
2020-03-21 15:50:18 +00:00
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2022-03-03 18:07:08 +00:00
|
|
|
assert config_entries[0].data[CONF_MAC] == "aa:bb:ww:ii:ff:ii"
|
2021-06-24 18:15:16 +00:00
|
|
|
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2020-03-21 15:50:18 +00:00
|
|
|
state = hass.states.get(entity_id)
|
|
|
|
assert state
|
2022-03-02 19:30:33 +00:00
|
|
|
remote_class.assert_called_once_with(**MOCK_CALLS_WS)
|
2020-03-21 15:50:18 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_update_on(hass: HomeAssistant, mock_now: datetime) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Testing update tv on."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_update_off(hass: HomeAssistant, mock_now: datetime) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Testing update tv off."""
|
2020-02-03 19:34:02 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
|
2020-01-23 20:43:30 +00:00
|
|
|
with patch(
|
2020-03-10 10:48:09 +00:00
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
2020-04-30 20:29:50 +00:00
|
|
|
side_effect=[OSError("Boom"), DEFAULT_MOCK],
|
2020-02-03 19:34:02 +00:00
|
|
|
):
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2020-01-23 20:43:30 +00:00
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2020-01-23 20:43:30 +00:00
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
|
|
|
2022-03-03 18:06:33 +00:00
|
|
|
async def test_update_off_ws_no_power_state(
|
|
|
|
hass: HomeAssistant, remotews: Mock, rest_api: Mock, mock_now: datetime
|
2022-02-25 16:15:45 +00:00
|
|
|
) -> None:
|
|
|
|
"""Testing update tv off."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
2022-03-03 18:06:33 +00:00
|
|
|
# device_info should only get called once, as part of the setup
|
|
|
|
rest_api.rest_device_info.assert_called_once()
|
|
|
|
rest_api.rest_device_info.reset_mock()
|
2022-02-25 16:15:45 +00:00
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
2022-03-02 19:30:33 +00:00
|
|
|
remotews.start_listening = Mock(side_effect=WebSocketException("Boom"))
|
|
|
|
remotews.is_alive.return_value = False
|
2022-02-25 16:15:45 +00:00
|
|
|
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_OFF
|
2022-03-03 18:06:33 +00:00
|
|
|
rest_api.rest_device_info.assert_not_called()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.usefixtures("remotews")
|
|
|
|
async def test_update_off_ws_with_power_state(
|
|
|
|
hass: HomeAssistant, remotews: Mock, rest_api: Mock, mock_now: datetime
|
|
|
|
) -> None:
|
|
|
|
"""Testing update tv off."""
|
|
|
|
with patch.object(
|
|
|
|
rest_api, "rest_device_info", side_effect=HttpApiError
|
|
|
|
) as mock_device_info, patch.object(
|
|
|
|
remotews, "start_listening", side_effect=WebSocketException("Boom")
|
|
|
|
) as mock_start_listening:
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
|
|
|
|
|
|
|
mock_device_info.assert_called_once()
|
|
|
|
mock_start_listening.assert_called_once()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
|
|
# First update uses start_listening once, and initialises device_info
|
|
|
|
device_info = deepcopy(rest_api.rest_device_info.return_value)
|
|
|
|
device_info["device"]["PowerState"] = "on"
|
|
|
|
rest_api.rest_device_info.return_value = device_info
|
|
|
|
next_update = mock_now + timedelta(minutes=1)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
remotews.start_listening.assert_called_once()
|
|
|
|
rest_api.rest_device_info.assert_called_once()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
# After initial update, start_listening shouldn't be called
|
|
|
|
remotews.start_listening.reset_mock()
|
|
|
|
|
|
|
|
# Second update uses device_info(ON)
|
|
|
|
rest_api.rest_device_info.reset_mock()
|
|
|
|
next_update = mock_now + timedelta(minutes=2)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
rest_api.rest_device_info.assert_called_once()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
# Third update uses device_info (OFF)
|
|
|
|
rest_api.rest_device_info.reset_mock()
|
|
|
|
device_info["device"]["PowerState"] = "off"
|
|
|
|
next_update = mock_now + timedelta(minutes=3)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
rest_api.rest_device_info.assert_called_once()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
|
|
remotews.start_listening.assert_not_called()
|
2022-02-25 16:15:45 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_update_access_denied(hass: HomeAssistant, mock_now: datetime) -> None:
|
2020-03-10 10:48:09 +00:00
|
|
|
"""Testing update tv access denied exception."""
|
2020-02-03 19:34:02 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
|
|
|
|
with patch(
|
2020-03-10 10:48:09 +00:00
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
2020-02-03 19:34:02 +00:00
|
|
|
side_effect=exceptions.AccessDenied("Boom"),
|
|
|
|
):
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
2021-05-22 15:41:18 +00:00
|
|
|
next_update = mock_now + timedelta(minutes=10)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
2020-02-03 19:34:02 +00:00
|
|
|
|
|
|
|
assert [
|
|
|
|
flow
|
|
|
|
for flow in hass.config_entries.flow.async_progress()
|
|
|
|
if flow["context"]["source"] == "reauth"
|
|
|
|
]
|
2021-05-22 15:41:18 +00:00
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_UNAVAILABLE
|
2020-02-03 19:34:02 +00:00
|
|
|
|
|
|
|
|
2022-03-08 10:02:00 +00:00
|
|
|
async def test_update_ws_connection_failure(
|
|
|
|
hass: HomeAssistant,
|
|
|
|
mock_now: datetime,
|
|
|
|
remotews: Mock,
|
|
|
|
caplog: pytest.LogCaptureFixture,
|
|
|
|
) -> None:
|
|
|
|
"""Testing update tv connection failure exception."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
|
|
|
|
|
|
|
with patch.object(
|
|
|
|
remotews,
|
|
|
|
"start_listening",
|
|
|
|
side_effect=ConnectionFailure('{"event": "ms.voiceApp.hide"}'),
|
|
|
|
), patch.object(remotews, "is_alive", return_value=False):
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
assert (
|
|
|
|
"Unexpected ConnectionFailure trying to get remote for fake_host, please "
|
|
|
|
'report this issue: ConnectionFailure(\'{"event": "ms.voiceApp.hide"}\')'
|
|
|
|
in caplog.text
|
|
|
|
)
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
|
|
|
|
|
|
async def test_update_ws_connection_closed(
|
2022-02-17 21:04:48 +00:00
|
|
|
hass: HomeAssistant, mock_now: datetime, remotews: Mock
|
2022-02-17 20:47:58 +00:00
|
|
|
) -> None:
|
2020-03-10 10:48:09 +00:00
|
|
|
"""Testing update tv connection failure exception."""
|
2022-03-08 10:02:00 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
2020-03-10 10:48:09 +00:00
|
|
|
|
2022-03-08 10:02:00 +00:00
|
|
|
with patch.object(
|
|
|
|
remotews, "start_listening", side_effect=ConnectionClosedError(None, None)
|
|
|
|
), patch.object(remotews, "is_alive", return_value=False):
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
2020-03-10 10:48:09 +00:00
|
|
|
|
|
|
|
assert [
|
|
|
|
flow
|
|
|
|
for flow in hass.config_entries.flow.async_progress()
|
|
|
|
if flow["context"]["source"] == "reauth"
|
|
|
|
]
|
2021-05-22 15:41:18 +00:00
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_UNAVAILABLE
|
2020-03-10 10:48:09 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_update_unhandled_response(
|
|
|
|
hass: HomeAssistant, mock_now: datetime
|
|
|
|
) -> None:
|
2020-01-23 20:43:30 +00:00
|
|
|
"""Testing update tv unhandled response exception."""
|
2020-02-03 19:34:02 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
|
2020-01-23 20:43:30 +00:00
|
|
|
with patch(
|
2020-03-10 10:48:09 +00:00
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
2020-04-30 20:29:50 +00:00
|
|
|
side_effect=[exceptions.UnhandledResponse("Boom"), DEFAULT_MOCK],
|
2020-02-03 19:34:02 +00:00
|
|
|
):
|
2020-01-23 20:43:30 +00:00
|
|
|
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_connection_closed_during_update_can_recover(
|
|
|
|
hass: HomeAssistant, mock_now: datetime
|
|
|
|
) -> None:
|
Handle connection being closed in legacy samsungtv (#52137)
* Handle connection being closed in legacy samsungtv
- Mirror the websocket behavior
Fixes
```
2021-06-24 02:54:13 ERROR (MainThread) [homeassistant.helpers.entity] Update for media_player.89_guestroom fails
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 401, in async_update_ha_state
await self.async_device_update()
File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 609, in async_device_update
raise exc
File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/src/homeassistant/homeassistant/components/samsungtv/media_player.py", line 124, in update
self._state = STATE_ON if self._bridge.is_on() else STATE_OFF
File "/usr/src/homeassistant/homeassistant/components/samsungtv/bridge.py", line 113, in is_on
return self._get_remote() is not None
File "/usr/src/homeassistant/homeassistant/components/samsungtv/bridge.py", line 232, in _get_remote
self._remote = Remote(self.config.copy())
File "/usr/local/lib/python3.8/site-packages/samsungctl/remote.py", line 9, in __init__
self.remote = RemoteLegacy(config)
File "/usr/local/lib/python3.8/site-packages/samsungctl/remote_legacy.py", line 32, in __init__
self._read_response(True)
File "/usr/local/lib/python3.8/site-packages/samsungctl/remote_legacy.py", line 77, in _read_response
raise exceptions.ConnectionClosed()
samsungctl.exceptions.ConnectionClosed
```
* add coverage
* pass instead
2021-06-25 05:31:44 +00:00
|
|
|
"""Testing update tv connection closed exception can recover."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
|
|
|
side_effect=[exceptions.ConnectionClosed(), DEFAULT_MOCK],
|
|
|
|
):
|
|
|
|
|
|
|
|
next_update = mock_now + timedelta(minutes=5)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
|
|
next_update = mock_now + timedelta(minutes=10)
|
|
|
|
with patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_send_key(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for send key."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_VOLUP")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_send_key_broken_pipe(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Testing broken pipe Exception."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-04-30 20:29:50 +00:00
|
|
|
remote.control = Mock(side_effect=BrokenPipeError("Boom"))
|
2019-10-25 12:32:12 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_send_key_connection_closed_retry_succeed(
|
|
|
|
hass: HomeAssistant, remote: Mock
|
|
|
|
) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test retry on connection closed."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-04-30 20:29:50 +00:00
|
|
|
remote.control = Mock(
|
|
|
|
side_effect=[exceptions.ConnectionClosed("Boom"), DEFAULT_MOCK, DEFAULT_MOCK]
|
2019-10-25 12:32:12 +00:00
|
|
|
)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
# key because of retry two times and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 2
|
2019-10-25 12:32:12 +00:00
|
|
|
assert remote.control.call_args_list == [
|
|
|
|
call("KEY_VOLUP"),
|
|
|
|
call("KEY_VOLUP"),
|
|
|
|
]
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_send_key_unhandled_response(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Testing unhandled response exception."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-04-30 20:29:50 +00:00
|
|
|
remote.control = Mock(side_effect=exceptions.UnhandledResponse("Boom"))
|
2019-10-25 12:32:12 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
2022-02-25 16:15:45 +00:00
|
|
|
async def test_send_key_websocketexception(hass: HomeAssistant, remotews: Mock) -> None:
|
2019-11-25 09:45:50 +00:00
|
|
|
"""Testing unhandled response exception."""
|
2022-02-25 16:15:45 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
2022-03-02 19:30:33 +00:00
|
|
|
remotews.send_command = Mock(side_effect=WebSocketException("Boom"))
|
2022-02-25 16:15:45 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
|
|
|
async def test_send_key_os_error_ws(hass: HomeAssistant, remotews: Mock) -> None:
|
|
|
|
"""Testing unhandled response exception."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
2022-03-02 19:30:33 +00:00
|
|
|
remotews.send_command = Mock(side_effect=OSError("Boom"))
|
2019-11-25 09:45:50 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_send_key_os_error(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Testing broken pipe Exception."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-04-30 20:29:50 +00:00
|
|
|
remote.control = Mock(side_effect=OSError("Boom"))
|
2019-10-25 12:32:12 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
2020-01-23 20:43:30 +00:00
|
|
|
assert state.state == STATE_ON
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_name(hass: HomeAssistant) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for name property."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.attributes[ATTR_FRIENDLY_NAME] == "fake"
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_state_with_turnon(hass: HomeAssistant, delay: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for state property."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_ON
|
2020-01-10 02:19:10 +00:00
|
|
|
assert delay.call_count == 1
|
|
|
|
|
2019-10-25 12:32:12 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_state_without_turnon(hass: HomeAssistant) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for state property."""
|
2020-01-10 02:19:10 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG_NOTURNON)
|
2019-10-25 12:32:12 +00:00
|
|
|
assert await hass.services.async_call(
|
2020-01-10 02:19:10 +00:00
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID_NOTURNON}, True
|
2019-10-25 12:32:12 +00:00
|
|
|
)
|
2020-01-10 02:19:10 +00:00
|
|
|
state = hass.states.get(ENTITY_ID_NOTURNON)
|
2019-10-25 12:32:12 +00:00
|
|
|
assert state.state == STATE_ON
|
|
|
|
assert await hass.services.async_call(
|
2020-01-10 02:19:10 +00:00
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID_NOTURNON}, True
|
2019-10-25 12:32:12 +00:00
|
|
|
)
|
2021-06-10 17:24:30 +00:00
|
|
|
state = hass.states.get(ENTITY_ID_NOTURNON)
|
|
|
|
# Should be STATE_UNAVAILABLE after the timer expires
|
|
|
|
assert state.state == STATE_OFF
|
|
|
|
|
|
|
|
next_update = dt_util.utcnow() + timedelta(seconds=20)
|
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
|
|
|
side_effect=OSError,
|
|
|
|
), patch("homeassistant.util.dt.utcnow", return_value=next_update):
|
|
|
|
async_fire_time_changed(hass, next_update)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
|
2020-01-10 02:19:10 +00:00
|
|
|
state = hass.states.get(ENTITY_ID_NOTURNON)
|
2021-05-22 15:41:18 +00:00
|
|
|
# Should be STATE_UNAVAILABLE since there is no way to turn it back on
|
|
|
|
assert state.state == STATE_UNAVAILABLE
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_supported_features_with_turnon(hass: HomeAssistant) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for supported_features property."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
|
|
|
assert (
|
|
|
|
state.attributes[ATTR_SUPPORTED_FEATURES] == SUPPORT_SAMSUNGTV | SUPPORT_TURN_ON
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_supported_features_without_turnon(hass: HomeAssistant) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for supported_features property."""
|
2020-01-10 02:19:10 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG_NOTURNON)
|
|
|
|
state = hass.states.get(ENTITY_ID_NOTURNON)
|
2019-10-25 12:32:12 +00:00
|
|
|
assert state.attributes[ATTR_SUPPORTED_FEATURES] == SUPPORT_SAMSUNGTV
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_device_class(hass: HomeAssistant) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for device_class property."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
state = hass.states.get(ENTITY_ID)
|
2021-12-17 15:26:53 +00:00
|
|
|
assert state.attributes[ATTR_DEVICE_CLASS] is MediaPlayerDeviceClass.TV.value
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-03-05 00:37:27 +00:00
|
|
|
async def test_turn_off_websocket(
|
|
|
|
hass: HomeAssistant, remotews: Mock, caplog: pytest.LogCaptureFixture
|
|
|
|
) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for turn_off."""
|
2020-03-10 10:48:09 +00:00
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
2020-04-30 20:29:50 +00:00
|
|
|
side_effect=[OSError("Boom"), DEFAULT_MOCK],
|
2020-01-10 02:19:10 +00:00
|
|
|
):
|
2020-03-10 10:48:09 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
2022-03-05 00:37:27 +00:00
|
|
|
|
|
|
|
remotews.send_command.reset_mock()
|
|
|
|
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key called
|
|
|
|
assert remotews.send_command.call_count == 1
|
2022-03-08 09:10:17 +00:00
|
|
|
commands = remotews.send_command.call_args_list[0].args[0]
|
|
|
|
assert len(commands) == 1
|
|
|
|
assert isinstance(commands[0], SendRemoteKey)
|
|
|
|
assert commands[0].params["DataOfCmd"] == "KEY_POWER"
|
2022-03-05 00:37:27 +00:00
|
|
|
|
|
|
|
# commands not sent : power off in progress
|
|
|
|
remotews.send_command.reset_mock()
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
2022-03-08 06:46:34 +00:00
|
|
|
assert "TV is powering off, not sending keys: ['KEY_VOLUP']" in caplog.text
|
2022-03-05 00:37:27 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_SELECT_SOURCE,
|
|
|
|
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_INPUT_SOURCE: "Deezer"},
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
assert "TV is powering off, not sending launch_app command" in caplog.text
|
|
|
|
remotews.send_command.assert_not_called()
|
2022-02-25 16:15:45 +00:00
|
|
|
|
2020-03-10 10:48:09 +00:00
|
|
|
|
2022-03-08 07:20:58 +00:00
|
|
|
async def test_turn_off_websocket_frame(
|
|
|
|
hass: HomeAssistant, remotews: Mock, rest_api: Mock
|
|
|
|
) -> None:
|
|
|
|
"""Test for turn_off."""
|
|
|
|
rest_api.rest_device_info.return_value = SAMPLE_DEVICE_INFO_FRAME
|
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
|
|
|
side_effect=[OSError("Boom"), DEFAULT_MOCK],
|
|
|
|
):
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
|
|
|
|
|
|
|
remotews.send_command.reset_mock()
|
|
|
|
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key called
|
2022-03-08 09:10:17 +00:00
|
|
|
assert remotews.send_command.call_count == 1
|
|
|
|
commands = remotews.send_command.call_args_list[0].args[0]
|
|
|
|
assert len(commands) == 3
|
|
|
|
assert isinstance(commands[0], SendRemoteKey)
|
|
|
|
assert commands[0].params["Cmd"] == "Press"
|
|
|
|
assert commands[0].params["DataOfCmd"] == "KEY_POWER"
|
|
|
|
assert isinstance(commands[1], SamsungTVSleepCommand)
|
|
|
|
assert commands[1].delay == 3
|
|
|
|
assert isinstance(commands[2], SendRemoteKey)
|
|
|
|
assert commands[2].params["Cmd"] == "Release"
|
|
|
|
assert commands[2].params["DataOfCmd"] == "KEY_POWER"
|
2022-03-08 07:20:58 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_turn_off_legacy(hass: HomeAssistant, remote: Mock) -> None:
|
2020-03-10 10:48:09 +00:00
|
|
|
"""Test for turn_off."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG_NOTURNON)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID_NOTURNON}, True
|
|
|
|
)
|
|
|
|
# key called
|
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_POWEROFF")]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_turn_off_os_error(
|
|
|
|
hass: HomeAssistant, remote: Mock, caplog: pytest.LogCaptureFixture
|
|
|
|
) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for turn_off with OSError."""
|
2019-11-03 17:32:01 +00:00
|
|
|
caplog.set_level(logging.DEBUG)
|
2019-10-25 12:32:12 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-04-30 20:29:50 +00:00
|
|
|
remote.close = Mock(side_effect=OSError("BOOM"))
|
2019-10-25 12:32:12 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
2020-03-10 10:48:09 +00:00
|
|
|
assert "Could not establish connection" in caplog.text
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-25 16:15:45 +00:00
|
|
|
async def test_turn_off_ws_os_error(
|
|
|
|
hass: HomeAssistant, remotews: Mock, caplog: pytest.LogCaptureFixture
|
|
|
|
) -> None:
|
|
|
|
"""Test for turn_off with OSError."""
|
|
|
|
caplog.set_level(logging.DEBUG)
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
|
|
|
remotews.close = Mock(side_effect=OSError("BOOM"))
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
2022-03-07 22:31:57 +00:00
|
|
|
assert "Error closing connection" in caplog.text
|
2022-02-25 16:15:45 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_volume_up(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for volume_up."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_VOLUP")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_volume_down(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for volume_down."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_VOLUME_DOWN, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_VOLDOWN")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_mute_volume(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for mute_volume."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_VOLUME_MUTE,
|
|
|
|
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_MEDIA_VOLUME_MUTED: True},
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_MUTE")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_media_play(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for media_play."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_MEDIA_PLAY, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_PLAY")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2021-05-22 15:41:18 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_MEDIA_PLAY_PAUSE, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
|
|
|
assert remote.control.call_count == 2
|
|
|
|
assert remote.control.call_args_list == [call("KEY_PLAY"), call("KEY_PAUSE")]
|
|
|
|
assert remote.close.call_count == 2
|
|
|
|
assert remote.close.call_args_list == [call(), call()]
|
|
|
|
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_media_pause(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for media_pause."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_MEDIA_PAUSE, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_PAUSE")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2021-05-22 15:41:18 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_MEDIA_PLAY_PAUSE, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
|
|
|
assert remote.control.call_count == 2
|
|
|
|
assert remote.control.call_args_list == [call("KEY_PAUSE"), call("KEY_PLAY")]
|
|
|
|
assert remote.close.call_count == 2
|
|
|
|
assert remote.close.call_args_list == [call(), call()]
|
|
|
|
|
2019-10-25 12:32:12 +00:00
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_media_next_track(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for media_next_track."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_MEDIA_NEXT_TRACK, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_CHUP")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_media_previous_track(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test for media_previous_track."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_MEDIA_PREVIOUS_TRACK, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_CHDOWN")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remote")
|
|
|
|
async def test_turn_on_with_turnon(hass: HomeAssistant, delay: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test turn on."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
2020-01-10 02:19:10 +00:00
|
|
|
assert delay.call_count == 1
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
@pytest.mark.usefixtures("remotews")
|
|
|
|
async def test_turn_on_wol(hass: HomeAssistant) -> None:
|
2021-05-22 20:33:37 +00:00
|
|
|
"""Test turn on."""
|
|
|
|
entry = MockConfigEntry(
|
|
|
|
domain=SAMSUNGTV_DOMAIN,
|
|
|
|
data=MOCK_ENTRY_WS_WITH_MAC,
|
|
|
|
unique_id="any",
|
|
|
|
)
|
|
|
|
entry.add_to_hass(hass)
|
|
|
|
assert await async_setup_component(hass, SAMSUNGTV_DOMAIN, {})
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.media_player.send_magic_packet"
|
|
|
|
) as mock_send_magic_packet:
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
|
|
assert mock_send_magic_packet.called
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_turn_on_without_turnon(hass: HomeAssistant, remote: Mock) -> None:
|
2019-10-25 12:32:12 +00:00
|
|
|
"""Test turn on."""
|
2020-01-10 02:19:10 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG_NOTURNON)
|
2022-03-20 23:01:58 +00:00
|
|
|
with pytest.raises(HomeAssistantError):
|
|
|
|
await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_ID_NOTURNON}, True
|
|
|
|
)
|
2019-10-25 12:32:12 +00:00
|
|
|
# nothing called as not supported feature
|
|
|
|
assert remote.control.call_count == 0
|
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_play_media(hass: HomeAssistant, remote: Mock) -> None:
|
2018-06-26 14:22:10 +00:00
|
|
|
"""Test for play_media."""
|
2019-10-25 12:32:12 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2022-03-08 06:46:34 +00:00
|
|
|
with patch("homeassistant.components.samsungtv.bridge.asyncio.sleep") as sleep:
|
2019-10-25 12:32:12 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_PLAY_MEDIA,
|
|
|
|
{
|
|
|
|
ATTR_ENTITY_ID: ENTITY_ID,
|
|
|
|
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_CHANNEL,
|
|
|
|
ATTR_MEDIA_CONTENT_ID: "576",
|
|
|
|
},
|
|
|
|
True,
|
|
|
|
)
|
2022-03-08 06:46:34 +00:00
|
|
|
# keys and update called
|
|
|
|
assert remote.control.call_count == 4
|
|
|
|
assert remote.control.call_args_list == [
|
|
|
|
call("KEY_5"),
|
|
|
|
call("KEY_7"),
|
|
|
|
call("KEY_6"),
|
|
|
|
call("KEY_ENTER"),
|
|
|
|
]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
|
|
|
assert sleep.call_count == 3
|
2018-06-26 14:22:10 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_play_media_invalid_type(hass: HomeAssistant) -> None:
|
2018-06-26 14:22:10 +00:00
|
|
|
"""Test for play_media with invalid media type."""
|
2020-04-06 09:21:52 +00:00
|
|
|
with patch("homeassistant.components.samsungtv.bridge.Remote") as remote:
|
2020-01-23 20:43:30 +00:00
|
|
|
url = "https://example.com"
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-03-10 10:48:09 +00:00
|
|
|
remote.reset_mock()
|
2020-01-23 20:43:30 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_PLAY_MEDIA,
|
|
|
|
{
|
|
|
|
ATTR_ENTITY_ID: ENTITY_ID,
|
|
|
|
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_URL,
|
|
|
|
ATTR_MEDIA_CONTENT_ID: url,
|
|
|
|
},
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
# only update called
|
|
|
|
assert remote.control.call_count == 0
|
|
|
|
assert remote.close.call_count == 0
|
|
|
|
assert remote.call_count == 1
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_play_media_channel_as_string(hass: HomeAssistant) -> None:
|
2018-06-26 14:22:10 +00:00
|
|
|
"""Test for play_media with invalid channel as string."""
|
2020-04-06 09:21:52 +00:00
|
|
|
with patch("homeassistant.components.samsungtv.bridge.Remote") as remote:
|
2020-01-23 20:43:30 +00:00
|
|
|
url = "https://example.com"
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-03-10 10:48:09 +00:00
|
|
|
remote.reset_mock()
|
2020-01-23 20:43:30 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_PLAY_MEDIA,
|
|
|
|
{
|
|
|
|
ATTR_ENTITY_ID: ENTITY_ID,
|
|
|
|
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_CHANNEL,
|
|
|
|
ATTR_MEDIA_CONTENT_ID: url,
|
|
|
|
},
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
# only update called
|
|
|
|
assert remote.control.call_count == 0
|
|
|
|
assert remote.close.call_count == 0
|
|
|
|
assert remote.call_count == 1
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_play_media_channel_as_non_positive(hass: HomeAssistant) -> None:
|
2018-06-26 14:22:10 +00:00
|
|
|
"""Test for play_media with invalid channel as non positive integer."""
|
2020-04-06 09:21:52 +00:00
|
|
|
with patch("homeassistant.components.samsungtv.bridge.Remote") as remote:
|
2020-01-23 20:43:30 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-03-10 10:48:09 +00:00
|
|
|
remote.reset_mock()
|
2020-01-23 20:43:30 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_PLAY_MEDIA,
|
|
|
|
{
|
|
|
|
ATTR_ENTITY_ID: ENTITY_ID,
|
|
|
|
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_CHANNEL,
|
|
|
|
ATTR_MEDIA_CONTENT_ID: "-4",
|
|
|
|
},
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
# only update called
|
|
|
|
assert remote.control.call_count == 0
|
|
|
|
assert remote.close.call_count == 0
|
|
|
|
assert remote.call_count == 1
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_select_source(hass: HomeAssistant, remote: Mock) -> None:
|
2019-06-17 22:00:11 +00:00
|
|
|
"""Test for select_source."""
|
2019-10-25 12:32:12 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_SELECT_SOURCE,
|
|
|
|
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_INPUT_SOURCE: "HDMI"},
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
# key and update called
|
2020-01-23 20:43:30 +00:00
|
|
|
assert remote.control.call_count == 1
|
|
|
|
assert remote.control.call_args_list == [call("KEY_HDMI")]
|
|
|
|
assert remote.close.call_count == 1
|
|
|
|
assert remote.close.call_args_list == [call()]
|
2019-10-25 12:32:12 +00:00
|
|
|
|
|
|
|
|
2022-02-17 20:47:58 +00:00
|
|
|
async def test_select_source_invalid_source(hass: HomeAssistant) -> None:
|
2019-06-17 22:00:11 +00:00
|
|
|
"""Test for select_source with invalid source."""
|
2020-04-06 09:21:52 +00:00
|
|
|
with patch("homeassistant.components.samsungtv.bridge.Remote") as remote:
|
2020-01-23 20:43:30 +00:00
|
|
|
await setup_samsungtv(hass, MOCK_CONFIG)
|
2020-03-10 10:48:09 +00:00
|
|
|
remote.reset_mock()
|
2020-01-23 20:43:30 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_SELECT_SOURCE,
|
|
|
|
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_INPUT_SOURCE: "INVALID"},
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
# only update called
|
|
|
|
assert remote.control.call_count == 0
|
|
|
|
assert remote.close.call_count == 0
|
|
|
|
assert remote.call_count == 1
|
2022-02-18 21:33:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_play_media_app(hass: HomeAssistant, remotews: Mock) -> None:
|
|
|
|
"""Test for play_media."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
2022-03-02 19:30:33 +00:00
|
|
|
remotews.send_command.reset_mock()
|
2022-02-18 21:33:49 +00:00
|
|
|
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_PLAY_MEDIA,
|
|
|
|
{
|
|
|
|
ATTR_ENTITY_ID: ENTITY_ID,
|
|
|
|
ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_APP,
|
|
|
|
ATTR_MEDIA_CONTENT_ID: "3201608010191",
|
|
|
|
},
|
|
|
|
True,
|
|
|
|
)
|
2022-03-02 19:30:33 +00:00
|
|
|
assert remotews.send_command.call_count == 1
|
2022-03-08 09:10:17 +00:00
|
|
|
commands = remotews.send_command.call_args_list[0].args[0]
|
|
|
|
assert len(commands) == 1
|
|
|
|
assert isinstance(commands[0], ChannelEmitCommand)
|
|
|
|
assert commands[0].params["data"]["appId"] == "3201608010191"
|
2022-02-18 21:33:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_select_source_app(hass: HomeAssistant, remotews: Mock) -> None:
|
|
|
|
"""Test for select_source."""
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
2022-03-02 19:30:33 +00:00
|
|
|
remotews.send_command.reset_mock()
|
|
|
|
|
2022-02-18 21:33:49 +00:00
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN,
|
|
|
|
SERVICE_SELECT_SOURCE,
|
|
|
|
{ATTR_ENTITY_ID: ENTITY_ID, ATTR_INPUT_SOURCE: "Deezer"},
|
|
|
|
True,
|
|
|
|
)
|
2022-03-02 19:30:33 +00:00
|
|
|
assert remotews.send_command.call_count == 1
|
2022-03-08 09:10:17 +00:00
|
|
|
commands = remotews.send_command.call_args_list[0].args[0]
|
|
|
|
assert len(commands) == 1
|
|
|
|
assert isinstance(commands[0], ChannelEmitCommand)
|
|
|
|
assert commands[0].params["data"]["appId"] == "3201608010191"
|
2022-03-12 11:20:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_websocket_unsupported_remote_control(
|
|
|
|
hass: HomeAssistant, remotews: Mock, caplog: pytest.LogCaptureFixture
|
|
|
|
) -> None:
|
|
|
|
"""Test for turn_off."""
|
|
|
|
with patch(
|
|
|
|
"homeassistant.components.samsungtv.bridge.Remote",
|
|
|
|
side_effect=[OSError("Boom"), DEFAULT_MOCK],
|
|
|
|
):
|
|
|
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
|
|
|
|
|
|
|
remotews.send_command.reset_mock()
|
|
|
|
|
|
|
|
assert await hass.services.async_call(
|
|
|
|
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_ID}, True
|
|
|
|
)
|
|
|
|
remotews.raise_mock_ws_event_callback(
|
|
|
|
"ms.error",
|
|
|
|
{
|
|
|
|
"event": "ms.error",
|
|
|
|
"data": {"message": "unrecognized method value : ms.remote.control"},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
# key called
|
|
|
|
assert remotews.send_command.call_count == 1
|
|
|
|
commands = remotews.send_command.call_args_list[0].args[0]
|
|
|
|
assert len(commands) == 1
|
|
|
|
assert isinstance(commands[0], SendRemoteKey)
|
|
|
|
assert commands[0].params["DataOfCmd"] == "KEY_POWER"
|
|
|
|
|
|
|
|
# error logged
|
|
|
|
assert (
|
|
|
|
"Your TV seems to be unsupported by SamsungTVWSBridge and may need a PIN: "
|
|
|
|
"'unrecognized method value : ms.remote.control'" in caplog.text
|
|
|
|
)
|