mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Use async rest api in SamsungTV (#67369)
Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
parent
508ed257d4
commit
1556868d56
@ -2,13 +2,14 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
from asyncio.exceptions import TimeoutError as AsyncioTimeoutError
|
||||||
import contextlib
|
import contextlib
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from requests.exceptions import Timeout as RequestsTimeout
|
|
||||||
from samsungctl import Remote
|
from samsungctl import Remote
|
||||||
from samsungctl.exceptions import AccessDenied, ConnectionClosed, UnhandledResponse
|
from samsungctl.exceptions import AccessDenied, ConnectionClosed, UnhandledResponse
|
||||||
from samsungtvws import SamsungTVWS
|
from samsungtvws import SamsungTVWS
|
||||||
|
from samsungtvws.async_rest import SamsungTVAsyncRest
|
||||||
from samsungtvws.exceptions import ConnectionFailure, HttpApiError
|
from samsungtvws.exceptions import ConnectionFailure, HttpApiError
|
||||||
from websocket import WebSocketException
|
from websocket import WebSocketException
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ from homeassistant.const import (
|
|||||||
CONF_TIMEOUT,
|
CONF_TIMEOUT,
|
||||||
)
|
)
|
||||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
|
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.device_registry import format_mac
|
from homeassistant.helpers.device_registry import format_mac
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -294,6 +296,7 @@ class SamsungTVWSBridge(SamsungTVBridge):
|
|||||||
"""Initialize Bridge."""
|
"""Initialize Bridge."""
|
||||||
super().__init__(hass, method, host, port)
|
super().__init__(hass, method, host, port)
|
||||||
self.token = token
|
self.token = token
|
||||||
|
self._rest_api: SamsungTVAsyncRest | None = None
|
||||||
self._app_list: dict[str, str] | None = None
|
self._app_list: dict[str, str] | None = None
|
||||||
self._remote: SamsungTVWS | None = None
|
self._remote: SamsungTVWS | None = None
|
||||||
|
|
||||||
@ -375,14 +378,21 @@ class SamsungTVWSBridge(SamsungTVBridge):
|
|||||||
|
|
||||||
async def async_device_info(self) -> dict[str, Any] | None:
|
async def async_device_info(self) -> dict[str, Any] | None:
|
||||||
"""Try to gather infos of this TV."""
|
"""Try to gather infos of this TV."""
|
||||||
return await self.hass.async_add_executor_job(self._device_info)
|
if not self.port:
|
||||||
|
return None
|
||||||
|
|
||||||
def _device_info(self) -> dict[str, Any] | None:
|
if self._rest_api is None:
|
||||||
"""Try to gather infos of this TV."""
|
self._rest_api = SamsungTVAsyncRest(
|
||||||
if remote := self._get_remote(avoid_open=True):
|
host=self.host,
|
||||||
with contextlib.suppress(HttpApiError, RequestsTimeout):
|
session=async_get_clientsession(self.hass),
|
||||||
device_info: dict[str, Any] = remote.rest_device_info()
|
port=self.port,
|
||||||
return device_info
|
timeout=TIMEOUT_WEBSOCKET,
|
||||||
|
)
|
||||||
|
|
||||||
|
with contextlib.suppress(HttpApiError, AsyncioTimeoutError):
|
||||||
|
device_info: dict[str, Any] = await self._rest_api.rest_device_info()
|
||||||
|
LOGGER.debug("Device info on %s is: %s", self.host, device_info)
|
||||||
|
return device_info
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -416,7 +426,7 @@ class SamsungTVWSBridge(SamsungTVBridge):
|
|||||||
# Different reasons, e.g. hostname not resolveable
|
# Different reasons, e.g. hostname not resolveable
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _get_remote(self, avoid_open: bool = False) -> SamsungTVWS:
|
def _get_remote(self) -> SamsungTVWS:
|
||||||
"""Create or return a remote control instance."""
|
"""Create or return a remote control instance."""
|
||||||
if self._remote is None:
|
if self._remote is None:
|
||||||
# We need to create a new instance to reconnect.
|
# We need to create a new instance to reconnect.
|
||||||
@ -431,8 +441,7 @@ class SamsungTVWSBridge(SamsungTVBridge):
|
|||||||
timeout=TIMEOUT_WEBSOCKET,
|
timeout=TIMEOUT_WEBSOCKET,
|
||||||
name=VALUE_CONF_NAME,
|
name=VALUE_CONF_NAME,
|
||||||
)
|
)
|
||||||
if not avoid_open:
|
self._remote.open()
|
||||||
self._remote.open()
|
|
||||||
# This is only happening when the auth was switched to DENY
|
# This is only happening when the auth was switched to DENY
|
||||||
# A removed auth will lead to socket timeout because waiting for auth popup is just an open socket
|
# A removed auth will lead to socket timeout because waiting for auth popup is just an open socket
|
||||||
except ConnectionFailure as err:
|
except ConnectionFailure as err:
|
||||||
|
@ -32,16 +32,14 @@ def remote_fixture() -> Mock:
|
|||||||
yield remote
|
yield remote
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="remotews")
|
@pytest.fixture(name="rest_api", autouse=True)
|
||||||
def remotews_fixture() -> Mock:
|
def rest_api_fixture() -> Mock:
|
||||||
"""Patch the samsungtvws SamsungTVWS."""
|
"""Patch the samsungtvws SamsungTVAsyncRest."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.samsungtv.bridge.SamsungTVWS"
|
"homeassistant.components.samsungtv.bridge.SamsungTVAsyncRest",
|
||||||
) as remotews_class:
|
autospec=True,
|
||||||
remotews = Mock(SamsungTVWS)
|
) as rest_api_class:
|
||||||
remotews.__enter__ = Mock(return_value=remotews)
|
rest_api_class.return_value.rest_device_info.return_value = {
|
||||||
remotews.__exit__ = Mock()
|
|
||||||
remotews.rest_device_info.return_value = {
|
|
||||||
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
||||||
"device": {
|
"device": {
|
||||||
"modelName": "82GXARRS",
|
"modelName": "82GXARRS",
|
||||||
@ -51,51 +49,24 @@ def remotews_fixture() -> Mock:
|
|||||||
"networkType": "wireless",
|
"networkType": "wireless",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
yield rest_api_class.return_value
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="remotews")
|
||||||
|
def remotews_fixture() -> Mock:
|
||||||
|
"""Patch the samsungtvws SamsungTVWS."""
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.samsungtv.bridge.SamsungTVWS"
|
||||||
|
) as remotews_class:
|
||||||
|
remotews = Mock(SamsungTVWS)
|
||||||
|
remotews.__enter__ = Mock(return_value=remotews)
|
||||||
|
remotews.__exit__ = Mock()
|
||||||
remotews.app_list.return_value = SAMPLE_APP_LIST
|
remotews.app_list.return_value = SAMPLE_APP_LIST
|
||||||
remotews.token = "FAKE_TOKEN"
|
remotews.token = "FAKE_TOKEN"
|
||||||
remotews_class.return_value = remotews
|
remotews_class.return_value = remotews
|
||||||
yield remotews
|
yield remotews
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="remotews_no_device_info")
|
|
||||||
def remotews_no_device_info_fixture() -> Mock:
|
|
||||||
"""Patch the samsungtvws SamsungTVWS."""
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.samsungtv.bridge.SamsungTVWS"
|
|
||||||
) as remotews_class:
|
|
||||||
remotews = Mock(SamsungTVWS)
|
|
||||||
remotews.__enter__ = Mock(return_value=remotews)
|
|
||||||
remotews.__exit__ = Mock()
|
|
||||||
remotews.rest_device_info.return_value = None
|
|
||||||
remotews.token = "FAKE_TOKEN"
|
|
||||||
remotews_class.return_value = remotews
|
|
||||||
yield remotews
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="remotews_soundbar")
|
|
||||||
def remotews_soundbar_fixture() -> Mock:
|
|
||||||
"""Patch the samsungtvws SamsungTVWS."""
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.samsungtv.bridge.SamsungTVWS"
|
|
||||||
) as remotews_class:
|
|
||||||
remotews = Mock(SamsungTVWS)
|
|
||||||
remotews.__enter__ = Mock(return_value=remotews)
|
|
||||||
remotews.__exit__ = Mock()
|
|
||||||
remotews.rest_device_info.return_value = {
|
|
||||||
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
|
||||||
"device": {
|
|
||||||
"modelName": "82GXARRS",
|
|
||||||
"wifiMac": "aa:bb:cc:dd:ee:ff",
|
|
||||||
"mac": "aa:bb:cc:dd:ee:ff",
|
|
||||||
"name": "[TV] Living Room",
|
|
||||||
"type": "Samsung SoundBar",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
remotews.token = "FAKE_TOKEN"
|
|
||||||
remotews_class.return_value = remotews
|
|
||||||
yield remotews
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="delay")
|
@pytest.fixture(name="delay")
|
||||||
def delay_fixture() -> Mock:
|
def delay_fixture() -> Mock:
|
||||||
"""Patch the delay script function."""
|
"""Patch the delay script function."""
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Tests for Samsung TV config flow."""
|
"""Tests for Samsung TV config flow."""
|
||||||
import socket
|
import socket
|
||||||
from unittest.mock import Mock, call, patch
|
from unittest.mock import ANY, AsyncMock, Mock, call, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from samsungctl.exceptions import AccessDenied, UnhandledResponse
|
from samsungctl.exceptions import AccessDenied, UnhandledResponse
|
||||||
@ -178,10 +178,9 @@ AUTODETECT_WEBSOCKET_SSL = {
|
|||||||
}
|
}
|
||||||
DEVICEINFO_WEBSOCKET_SSL = {
|
DEVICEINFO_WEBSOCKET_SSL = {
|
||||||
"host": "fake_host",
|
"host": "fake_host",
|
||||||
"name": "HomeAssistant",
|
"session": ANY,
|
||||||
"port": 8002,
|
"port": 8002,
|
||||||
"timeout": TIMEOUT_WEBSOCKET,
|
"timeout": TIMEOUT_WEBSOCKET,
|
||||||
"token": "123456789",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -456,8 +455,11 @@ async def test_ssdp_websocket_success_populates_mac_address(
|
|||||||
assert result["result"].unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de"
|
assert result["result"].unique_id == "0d1cef00-00dc-1000-9c80-4844f7b172de"
|
||||||
|
|
||||||
|
|
||||||
async def test_ssdp_websocket_not_supported(hass: HomeAssistant) -> None:
|
async def test_ssdp_websocket_not_supported(
|
||||||
|
hass: HomeAssistant, rest_api: Mock
|
||||||
|
) -> None:
|
||||||
"""Test starting a flow from discovery for not supported device."""
|
"""Test starting a flow from discovery for not supported device."""
|
||||||
|
rest_api.rest_device_info.return_value = None
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.samsungtv.bridge.Remote",
|
"homeassistant.components.samsungtv.bridge.Remote",
|
||||||
side_effect=OSError("Boom"),
|
side_effect=OSError("Boom"),
|
||||||
@ -630,9 +632,10 @@ async def test_import_legacy(hass: HomeAssistant, no_mac_address: Mock) -> None:
|
|||||||
assert entries[0].data[CONF_PORT] == LEGACY_PORT
|
assert entries[0].data[CONF_PORT] == LEGACY_PORT
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("remote", "remotews_no_device_info", "no_mac_address")
|
@pytest.mark.usefixtures("remote", "remotews", "no_mac_address")
|
||||||
async def test_import_legacy_without_name(hass: HomeAssistant) -> None:
|
async def test_import_legacy_without_name(hass: HomeAssistant, rest_api: Mock) -> None:
|
||||||
"""Test importing from yaml without a name."""
|
"""Test importing from yaml without a name."""
|
||||||
|
rest_api.rest_device_info.return_value = None
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": config_entries.SOURCE_IMPORT},
|
context={"source": config_entries.SOURCE_IMPORT},
|
||||||
@ -762,9 +765,19 @@ async def test_zeroconf(hass: HomeAssistant) -> None:
|
|||||||
assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
|
assert result["result"].unique_id == "be9554b9-c9fb-41f4-8920-22da015376a4"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("remotews_soundbar")
|
@pytest.mark.usefixtures("remotews")
|
||||||
async def test_zeroconf_ignores_soundbar(hass: HomeAssistant) -> None:
|
async def test_zeroconf_ignores_soundbar(hass: HomeAssistant, rest_api: Mock) -> None:
|
||||||
"""Test starting a flow from zeroconf where the device is actually a soundbar."""
|
"""Test starting a flow from zeroconf where the device is actually a soundbar."""
|
||||||
|
rest_api.rest_device_info.return_value = {
|
||||||
|
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
||||||
|
"device": {
|
||||||
|
"modelName": "82GXARRS",
|
||||||
|
"wifiMac": "aa:bb:cc:dd:ee:ff",
|
||||||
|
"mac": "aa:bb:cc:dd:ee:ff",
|
||||||
|
"name": "[TV] Living Room",
|
||||||
|
"type": "Samsung SoundBar",
|
||||||
|
},
|
||||||
|
}
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": config_entries.SOURCE_ZEROCONF},
|
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||||
@ -775,9 +788,10 @@ async def test_zeroconf_ignores_soundbar(hass: HomeAssistant) -> None:
|
|||||||
assert result["reason"] == "not_supported"
|
assert result["reason"] == "not_supported"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("remote", "remotews_no_device_info")
|
@pytest.mark.usefixtures("remote", "remotews")
|
||||||
async def test_zeroconf_no_device_info(hass: HomeAssistant) -> None:
|
async def test_zeroconf_no_device_info(hass: HomeAssistant, rest_api: Mock) -> None:
|
||||||
"""Test starting a flow from zeroconf where device_info returns None."""
|
"""Test starting a flow from zeroconf where device_info returns None."""
|
||||||
|
rest_api.rest_device_info.return_value = None
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
context={"source": config_entries.SOURCE_ZEROCONF},
|
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||||
@ -815,23 +829,29 @@ async def test_autodetect_websocket(hass: HomeAssistant) -> None:
|
|||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.samsungtv.bridge.Remote",
|
"homeassistant.components.samsungtv.bridge.Remote",
|
||||||
side_effect=OSError("Boom"),
|
side_effect=OSError("Boom"),
|
||||||
), patch("homeassistant.components.samsungtv.bridge.SamsungTVWS") as remotews:
|
), patch(
|
||||||
|
"homeassistant.components.samsungtv.bridge.SamsungTVWS"
|
||||||
|
) as remotews, patch(
|
||||||
|
"homeassistant.components.samsungtv.bridge.SamsungTVAsyncRest",
|
||||||
|
) as rest_api_class:
|
||||||
remote = Mock(SamsungTVWS)
|
remote = Mock(SamsungTVWS)
|
||||||
remote.__enter__ = Mock(return_value=remote)
|
remote.__enter__ = Mock(return_value=remote)
|
||||||
remote.__exit__ = Mock(return_value=False)
|
remote.__exit__ = Mock(return_value=False)
|
||||||
remote.app_list.return_value = SAMPLE_APP_LIST
|
remote.app_list.return_value = SAMPLE_APP_LIST
|
||||||
remote.rest_device_info.return_value = {
|
rest_api_class.return_value.rest_device_info = AsyncMock(
|
||||||
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
return_value={
|
||||||
"device": {
|
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
||||||
"modelName": "82GXARRS",
|
"device": {
|
||||||
"networkType": "wireless",
|
"modelName": "82GXARRS",
|
||||||
"wifiMac": "aa:bb:cc:dd:ee:ff",
|
"networkType": "wireless",
|
||||||
"udn": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
"wifiMac": "aa:bb:cc:dd:ee:ff",
|
||||||
"mac": "aa:bb:cc:dd:ee:ff",
|
"udn": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
||||||
"name": "[TV] Living Room",
|
"mac": "aa:bb:cc:dd:ee:ff",
|
||||||
"type": "Samsung SmartTV",
|
"name": "[TV] Living Room",
|
||||||
},
|
"type": "Samsung SmartTV",
|
||||||
}
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
remote.token = "123456789"
|
remote.token = "123456789"
|
||||||
remotews.return_value = remote
|
remotews.return_value = remote
|
||||||
|
|
||||||
@ -841,11 +861,8 @@ async def test_autodetect_websocket(hass: HomeAssistant) -> None:
|
|||||||
assert result["type"] == "create_entry"
|
assert result["type"] == "create_entry"
|
||||||
assert result["data"][CONF_METHOD] == "websocket"
|
assert result["data"][CONF_METHOD] == "websocket"
|
||||||
assert result["data"][CONF_TOKEN] == "123456789"
|
assert result["data"][CONF_TOKEN] == "123456789"
|
||||||
assert remotews.call_count == 2
|
remotews.assert_called_once_with(**AUTODETECT_WEBSOCKET_SSL)
|
||||||
assert remotews.call_args_list == [
|
rest_api_class.assert_called_once_with(**DEVICEINFO_WEBSOCKET_SSL)
|
||||||
call(**AUTODETECT_WEBSOCKET_SSL),
|
|
||||||
call(**DEVICEINFO_WEBSOCKET_SSL),
|
|
||||||
]
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
entries = hass.config_entries.async_entries(DOMAIN)
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
@ -861,22 +878,27 @@ async def test_websocket_no_mac(hass: HomeAssistant) -> None:
|
|||||||
), patch(
|
), patch(
|
||||||
"homeassistant.components.samsungtv.bridge.SamsungTVWS"
|
"homeassistant.components.samsungtv.bridge.SamsungTVWS"
|
||||||
) as remotews, patch(
|
) as remotews, patch(
|
||||||
|
"homeassistant.components.samsungtv.bridge.SamsungTVAsyncRest",
|
||||||
|
) as rest_api_class, patch(
|
||||||
"getmac.get_mac_address", return_value="gg:hh:ii:ll:mm:nn"
|
"getmac.get_mac_address", return_value="gg:hh:ii:ll:mm:nn"
|
||||||
):
|
):
|
||||||
remote = Mock(SamsungTVWS)
|
remote = Mock(SamsungTVWS)
|
||||||
remote.__enter__ = Mock(return_value=remote)
|
remote.__enter__ = Mock(return_value=remote)
|
||||||
remote.__exit__ = Mock(return_value=False)
|
remote.__exit__ = Mock(return_value=False)
|
||||||
remote.app_list.return_value = SAMPLE_APP_LIST
|
remote.app_list.return_value = SAMPLE_APP_LIST
|
||||||
remote.rest_device_info.return_value = {
|
rest_api_class.return_value.rest_device_info = AsyncMock(
|
||||||
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
return_value={
|
||||||
"device": {
|
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
||||||
"modelName": "82GXARRS",
|
"device": {
|
||||||
"networkType": "lan",
|
"modelName": "82GXARRS",
|
||||||
"udn": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
"networkType": "lan",
|
||||||
"name": "[TV] Living Room",
|
"udn": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
||||||
"type": "Samsung SmartTV",
|
"name": "[TV] Living Room",
|
||||||
},
|
"type": "Samsung SmartTV",
|
||||||
}
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
remote.token = "123456789"
|
remote.token = "123456789"
|
||||||
remotews.return_value = remote
|
remotews.return_value = remote
|
||||||
|
|
||||||
@ -887,11 +909,8 @@ async def test_websocket_no_mac(hass: HomeAssistant) -> None:
|
|||||||
assert result["data"][CONF_METHOD] == "websocket"
|
assert result["data"][CONF_METHOD] == "websocket"
|
||||||
assert result["data"][CONF_TOKEN] == "123456789"
|
assert result["data"][CONF_TOKEN] == "123456789"
|
||||||
assert result["data"][CONF_MAC] == "gg:hh:ii:ll:mm:nn"
|
assert result["data"][CONF_MAC] == "gg:hh:ii:ll:mm:nn"
|
||||||
assert remotews.call_count == 2
|
remotews.assert_called_once_with(**AUTODETECT_WEBSOCKET_SSL)
|
||||||
assert remotews.call_args_list == [
|
rest_api_class.assert_called_once_with(**DEVICEINFO_WEBSOCKET_SSL)
|
||||||
call(**AUTODETECT_WEBSOCKET_SSL),
|
|
||||||
call(**DEVICEINFO_WEBSOCKET_SSL),
|
|
||||||
]
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
entries = hass.config_entries.async_entries(DOMAIN)
|
entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
@ -1166,18 +1185,16 @@ async def test_update_legacy_missing_mac_from_dhcp(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
@pytest.mark.usefixtures("remote")
|
@pytest.mark.usefixtures("remote")
|
||||||
async def test_update_legacy_missing_mac_from_dhcp_no_unique_id(
|
async def test_update_legacy_missing_mac_from_dhcp_no_unique_id(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, rest_api: Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test missing mac added when there is no unique id."""
|
"""Test missing mac added when there is no unique id."""
|
||||||
|
rest_api.rest_device_info.side_effect = HttpApiError
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
data=MOCK_LEGACY_ENTRY,
|
data=MOCK_LEGACY_ENTRY,
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.samsungtv.bridge.SamsungTVWS.rest_device_info",
|
|
||||||
side_effect=HttpApiError,
|
|
||||||
), patch(
|
|
||||||
"homeassistant.components.samsungtv.bridge.Remote.__enter__",
|
"homeassistant.components.samsungtv.bridge.Remote.__enter__",
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
|
@ -159,31 +159,20 @@ async def test_setup_without_turnon(hass: HomeAssistant) -> None:
|
|||||||
@pytest.mark.usefixtures("remotews")
|
@pytest.mark.usefixtures("remotews")
|
||||||
async def test_setup_websocket(hass: HomeAssistant) -> None:
|
async def test_setup_websocket(hass: HomeAssistant) -> None:
|
||||||
"""Test setup of platform."""
|
"""Test setup of platform."""
|
||||||
|
|
||||||
with patch("homeassistant.components.samsungtv.bridge.SamsungTVWS") as remote_class:
|
with patch("homeassistant.components.samsungtv.bridge.SamsungTVWS") as remote_class:
|
||||||
remote = Mock(SamsungTVWS)
|
remote = Mock(SamsungTVWS)
|
||||||
remote.__enter__ = Mock(return_value=remote)
|
remote.__enter__ = Mock(return_value=remote)
|
||||||
remote.__exit__ = Mock()
|
remote.__exit__ = Mock()
|
||||||
remote.app_list.return_value = SAMPLE_APP_LIST
|
remote.app_list.return_value = SAMPLE_APP_LIST
|
||||||
remote.rest_device_info.return_value = {
|
|
||||||
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
|
||||||
"device": {
|
|
||||||
"modelName": "82GXARRS",
|
|
||||||
"wifiMac": "aa:bb:cc:dd:ee:ff",
|
|
||||||
"name": "[TV] Living Room",
|
|
||||||
"type": "Samsung SmartTV",
|
|
||||||
"networkType": "wireless",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
remote.token = "123456789"
|
remote.token = "123456789"
|
||||||
remote_class.return_value = remote
|
remote_class.return_value = remote
|
||||||
|
|
||||||
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
await setup_samsungtv(hass, MOCK_CONFIGWS)
|
||||||
|
|
||||||
assert remote_class.call_count == 2
|
assert remote_class.call_count == 1
|
||||||
assert remote_class.call_args_list == [
|
assert remote_class.call_args_list == [call(**MOCK_CALLS_WS)]
|
||||||
call(**MOCK_CALLS_WS),
|
|
||||||
call(**MOCK_CALLS_WS),
|
|
||||||
]
|
|
||||||
assert hass.states.get(ENTITY_ID)
|
assert hass.states.get(ENTITY_ID)
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
@ -193,7 +182,9 @@ async def test_setup_websocket(hass: HomeAssistant) -> None:
|
|||||||
assert config_entries[0].data[CONF_MAC] == "aa:bb:cc:dd:ee:ff"
|
assert config_entries[0].data[CONF_MAC] == "aa:bb:cc:dd:ee:ff"
|
||||||
|
|
||||||
|
|
||||||
async def test_setup_websocket_2(hass: HomeAssistant, mock_now: datetime) -> None:
|
async def test_setup_websocket_2(
|
||||||
|
hass: HomeAssistant, mock_now: datetime, rest_api: Mock
|
||||||
|
) -> None:
|
||||||
"""Test setup of platform from config entry."""
|
"""Test setup of platform from config entry."""
|
||||||
entity_id = f"{DOMAIN}.fake"
|
entity_id = f"{DOMAIN}.fake"
|
||||||
|
|
||||||
@ -208,21 +199,21 @@ async def test_setup_websocket_2(hass: HomeAssistant, mock_now: datetime) -> Non
|
|||||||
assert len(config_entries) == 1
|
assert len(config_entries) == 1
|
||||||
assert entry is config_entries[0]
|
assert entry is config_entries[0]
|
||||||
|
|
||||||
|
rest_api.rest_device_info.return_value = {
|
||||||
|
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
||||||
|
"device": {
|
||||||
|
"modelName": "82GXARRS",
|
||||||
|
"wifiMac": "aa:bb:cc:dd:ee:ff",
|
||||||
|
"name": "[TV] Living Room",
|
||||||
|
"type": "Samsung SmartTV",
|
||||||
|
"networkType": "wireless",
|
||||||
|
},
|
||||||
|
}
|
||||||
with patch("homeassistant.components.samsungtv.bridge.SamsungTVWS") as remote_class:
|
with patch("homeassistant.components.samsungtv.bridge.SamsungTVWS") as remote_class:
|
||||||
remote = Mock(SamsungTVWS)
|
remote = Mock(SamsungTVWS)
|
||||||
remote.__enter__ = Mock(return_value=remote)
|
remote.__enter__ = Mock(return_value=remote)
|
||||||
remote.__exit__ = Mock()
|
remote.__exit__ = Mock()
|
||||||
remote.app_list.return_value = SAMPLE_APP_LIST
|
remote.app_list.return_value = SAMPLE_APP_LIST
|
||||||
remote.rest_device_info.return_value = {
|
|
||||||
"id": "uuid:be9554b9-c9fb-41f4-8920-22da015376a4",
|
|
||||||
"device": {
|
|
||||||
"modelName": "82GXARRS",
|
|
||||||
"wifiMac": "aa:bb:cc:dd:ee:ff",
|
|
||||||
"name": "[TV] Living Room",
|
|
||||||
"type": "Samsung SmartTV",
|
|
||||||
"networkType": "wireless",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
remote.token = "987654321"
|
remote.token = "987654321"
|
||||||
remote_class.return_value = remote
|
remote_class.return_value = remote
|
||||||
assert await async_setup_component(hass, SAMSUNGTV_DOMAIN, {})
|
assert await async_setup_component(hass, SAMSUNGTV_DOMAIN, {})
|
||||||
@ -237,7 +228,7 @@ async def test_setup_websocket_2(hass: HomeAssistant, mock_now: datetime) -> Non
|
|||||||
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state
|
assert state
|
||||||
assert remote_class.call_count == 3
|
assert remote_class.call_count == 2
|
||||||
assert remote_class.call_args_list[0] == call(**MOCK_CALLS_WS)
|
assert remote_class.call_args_list[0] == call(**MOCK_CALLS_WS)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user