diff --git a/tests/components/roku/__init__.py b/tests/components/roku/__init__.py
index 5ae81eb7b72..c0e044a3589 100644
--- a/tests/components/roku/__init__.py
+++ b/tests/components/roku/__init__.py
@@ -1,16 +1,6 @@
"""Tests for the Roku component."""
-from http import HTTPStatus
-import re
-from socket import gaierror as SocketGIAError
-
from homeassistant.components import ssdp, zeroconf
-from homeassistant.components.roku.const import DOMAIN
from homeassistant.components.ssdp import ATTR_UPNP_FRIENDLY_NAME, ATTR_UPNP_SERIAL
-from homeassistant.const import CONF_HOST
-from homeassistant.core import HomeAssistant
-
-from tests.common import MockConfigEntry, load_fixture
-from tests.test_util.aiohttp import AiohttpClientMocker
NAME = "Roku 3"
NAME_ROKUTV = '58" Onn Roku TV'
@@ -42,174 +32,3 @@ MOCK_HOMEKIT_DISCOVERY_INFO = zeroconf.ZeroconfServiceInfo(
},
type="mock_type",
)
-
-
-def mock_connection(
- aioclient_mock: AiohttpClientMocker,
- device: str = "roku3",
- app: str = "roku",
- host: str = HOST,
- power: bool = True,
- media_state: str = "close",
- error: bool = False,
- server_error: bool = False,
-) -> None:
- """Mock the Roku connection."""
- roku_url = f"http://{host}:8060"
-
- if error:
- mock_connection_error(
- aioclient_mock=aioclient_mock, device=device, app=app, host=host
- )
- return
-
- if server_error:
- mock_connection_server_error(
- aioclient_mock=aioclient_mock, device=device, app=app, host=host
- )
- return
-
- info_fixture = f"roku/{device}-device-info.xml"
- if not power:
- info_fixture = f"roku/{device}-device-info-power-off.xml"
-
- aioclient_mock.get(
- f"{roku_url}/query/device-info",
- text=load_fixture(info_fixture),
- headers={"Content-Type": "text/xml"},
- )
-
- apps_fixture = "roku/apps.xml"
- if device == "rokutv":
- apps_fixture = "roku/apps-tv.xml"
-
- aioclient_mock.get(
- f"{roku_url}/query/apps",
- text=load_fixture(apps_fixture),
- headers={"Content-Type": "text/xml"},
- )
-
- aioclient_mock.get(
- f"{roku_url}/query/active-app",
- text=load_fixture(f"roku/active-app-{app}.xml"),
- headers={"Content-Type": "text/xml"},
- )
-
- aioclient_mock.get(
- f"{roku_url}/query/tv-active-channel",
- text=load_fixture("roku/rokutv-tv-active-channel.xml"),
- headers={"Content-Type": "text/xml"},
- )
-
- aioclient_mock.get(
- f"{roku_url}/query/tv-channels",
- text=load_fixture("roku/rokutv-tv-channels.xml"),
- headers={"Content-Type": "text/xml"},
- )
-
- aioclient_mock.get(
- f"{roku_url}/query/media-player",
- text=load_fixture(f"roku/media-player-{media_state}.xml"),
- headers={"Content-Type": "text/xml"},
- )
-
- aioclient_mock.post(
- re.compile(f"{roku_url}/keypress/.*"),
- text="OK",
- )
-
- aioclient_mock.post(
- re.compile(f"{roku_url}/launch/.*"),
- text="OK",
- )
-
- aioclient_mock.post(f"{roku_url}/search", text="OK")
-
-
-def mock_connection_error(
- aioclient_mock: AiohttpClientMocker,
- device: str = "roku3",
- app: str = "roku",
- host: str = HOST,
-) -> None:
- """Mock the Roku connection error."""
- roku_url = f"http://{host}:8060"
-
- aioclient_mock.get(f"{roku_url}/query/device-info", exc=SocketGIAError)
- aioclient_mock.get(f"{roku_url}/query/apps", exc=SocketGIAError)
- aioclient_mock.get(f"{roku_url}/query/active-app", exc=SocketGIAError)
- aioclient_mock.get(f"{roku_url}/query/tv-active-channel", exc=SocketGIAError)
- aioclient_mock.get(f"{roku_url}/query/tv-channels", exc=SocketGIAError)
-
- aioclient_mock.post(re.compile(f"{roku_url}/keypress/.*"), exc=SocketGIAError)
- aioclient_mock.post(re.compile(f"{roku_url}/launch/.*"), exc=SocketGIAError)
- aioclient_mock.post(f"{roku_url}/search", exc=SocketGIAError)
-
-
-def mock_connection_server_error(
- aioclient_mock: AiohttpClientMocker,
- device: str = "roku3",
- app: str = "roku",
- host: str = HOST,
-) -> None:
- """Mock the Roku server error."""
- roku_url = f"http://{host}:8060"
-
- aioclient_mock.get(
- f"{roku_url}/query/device-info", status=HTTPStatus.INTERNAL_SERVER_ERROR
- )
- aioclient_mock.get(
- f"{roku_url}/query/apps", status=HTTPStatus.INTERNAL_SERVER_ERROR
- )
- aioclient_mock.get(
- f"{roku_url}/query/active-app", status=HTTPStatus.INTERNAL_SERVER_ERROR
- )
- aioclient_mock.get(
- f"{roku_url}/query/tv-active-channel", status=HTTPStatus.INTERNAL_SERVER_ERROR
- )
- aioclient_mock.get(
- f"{roku_url}/query/tv-channels", status=HTTPStatus.INTERNAL_SERVER_ERROR
- )
-
- aioclient_mock.post(
- re.compile(f"{roku_url}/keypress/.*"), status=HTTPStatus.INTERNAL_SERVER_ERROR
- )
- aioclient_mock.post(
- re.compile(f"{roku_url}/launch/.*"), status=HTTPStatus.INTERNAL_SERVER_ERROR
- )
- aioclient_mock.post(f"{roku_url}/search", status=HTTPStatus.INTERNAL_SERVER_ERROR)
-
-
-async def setup_integration(
- hass: HomeAssistant,
- aioclient_mock: AiohttpClientMocker,
- device: str = "roku3",
- app: str = "roku",
- host: str = HOST,
- unique_id: str = UPNP_SERIAL,
- error: bool = False,
- power: bool = True,
- media_state: str = "close",
- server_error: bool = False,
- skip_entry_setup: bool = False,
-) -> MockConfigEntry:
- """Set up the Roku integration in Home Assistant."""
- entry = MockConfigEntry(domain=DOMAIN, unique_id=unique_id, data={CONF_HOST: host})
-
- entry.add_to_hass(hass)
-
- if not skip_entry_setup:
- mock_connection(
- aioclient_mock,
- device,
- app=app,
- host=host,
- error=error,
- power=power,
- media_state=media_state,
- server_error=server_error,
- )
- await hass.config_entries.async_setup(entry.entry_id)
- await hass.async_block_till_done()
-
- return entry
diff --git a/tests/components/roku/conftest.py b/tests/components/roku/conftest.py
new file mode 100644
index 00000000000..16261e07a89
--- /dev/null
+++ b/tests/components/roku/conftest.py
@@ -0,0 +1,86 @@
+"""Fixtures for Roku integration tests."""
+from collections.abc import Generator
+import json
+from unittest.mock import MagicMock, patch
+
+import pytest
+from rokuecp import Device as RokuDevice
+
+from homeassistant.components.roku.const import DOMAIN
+from homeassistant.const import CONF_HOST
+from homeassistant.core import HomeAssistant
+
+from tests.common import MockConfigEntry, load_fixture
+
+
+def app_icon_url(*args, **kwargs):
+ """Get the URL to the application icon."""
+ app_id = args[0]
+ return f"http://192.168.1.160:8060/query/icon/{app_id}"
+
+
+@pytest.fixture
+def mock_config_entry() -> MockConfigEntry:
+ """Return the default mocked config entry."""
+ return MockConfigEntry(
+ title="Roku",
+ domain=DOMAIN,
+ data={CONF_HOST: "192.168.1.160"},
+ unique_id="1GU48T017973",
+ )
+
+
+@pytest.fixture
+def mock_setup_entry() -> Generator[None, None, None]:
+ """Mock setting up a config entry."""
+ with patch("homeassistant.components.roku.async_setup_entry", return_value=True):
+ yield
+
+
+@pytest.fixture
+def mock_roku_config_flow(
+ request: pytest.FixtureRequest,
+) -> Generator[None, MagicMock, None]:
+ """Return a mocked Roku client."""
+ fixture: str = "roku/roku3.json"
+ if hasattr(request, "param") and request.param:
+ fixture = request.param
+
+ device = RokuDevice(json.loads(load_fixture(fixture)))
+ with patch(
+ "homeassistant.components.roku.config_flow.Roku", autospec=True
+ ) as roku_mock:
+ client = roku_mock.return_value
+ client.app_icon_url.side_effect = app_icon_url
+ client.update.return_value = device
+ yield client
+
+
+@pytest.fixture
+def mock_roku(request: pytest.FixtureRequest) -> Generator[None, MagicMock, None]:
+ """Return a mocked Roku client."""
+ fixture: str = "roku/roku3.json"
+ if hasattr(request, "param") and request.param:
+ fixture = request.param
+
+ device = RokuDevice(json.loads(load_fixture(fixture)))
+ with patch(
+ "homeassistant.components.roku.coordinator.Roku", autospec=True
+ ) as roku_mock:
+ client = roku_mock.return_value
+ client.app_icon_url.side_effect = app_icon_url
+ client.update.return_value = device
+ yield client
+
+
+@pytest.fixture
+async def init_integration(
+ hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_roku: MagicMock
+) -> MockConfigEntry:
+ """Set up the Roku integration for testing."""
+ mock_config_entry.add_to_hass(hass)
+
+ await hass.config_entries.async_setup(mock_config_entry.entry_id)
+ await hass.async_block_till_done()
+
+ return mock_config_entry
diff --git a/tests/components/roku/fixtures/active-app-netflix.xml b/tests/components/roku/fixtures/active-app-netflix.xml
deleted file mode 100644
index 4cf7a3fc506..00000000000
--- a/tests/components/roku/fixtures/active-app-netflix.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-Netflix
-
diff --git a/tests/components/roku/fixtures/active-app-pluto.xml b/tests/components/roku/fixtures/active-app-pluto.xml
deleted file mode 100644
index cb3b85dc51c..00000000000
--- a/tests/components/roku/fixtures/active-app-pluto.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Pluto TV - It's Free TV
-
diff --git a/tests/components/roku/fixtures/active-app-roku.xml b/tests/components/roku/fixtures/active-app-roku.xml
deleted file mode 100644
index 19808409518..00000000000
--- a/tests/components/roku/fixtures/active-app-roku.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Roku
-
diff --git a/tests/components/roku/fixtures/active-app-screensaver.xml b/tests/components/roku/fixtures/active-app-screensaver.xml
deleted file mode 100644
index fcbb85c426d..00000000000
--- a/tests/components/roku/fixtures/active-app-screensaver.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- Roku
- Default screensaver
-
diff --git a/tests/components/roku/fixtures/active-app-tvinput-dtv.xml b/tests/components/roku/fixtures/active-app-tvinput-dtv.xml
deleted file mode 100644
index 7dd4cdc8f40..00000000000
--- a/tests/components/roku/fixtures/active-app-tvinput-dtv.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
- Antenna TV
-
diff --git a/tests/components/roku/fixtures/apps-tv.xml b/tests/components/roku/fixtures/apps-tv.xml
deleted file mode 100644
index e5862268d90..00000000000
--- a/tests/components/roku/fixtures/apps-tv.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- Satellite TV
- Blu-ray player
- Antenna TV
- Roku Channel Store
- Netflix
- Amazon Video on Demand
- MLB.TV®
- Free FrameChannel Service
- Mediafly
- Pandora
- Pluto TV - It's Free TV
-
diff --git a/tests/components/roku/fixtures/apps.xml b/tests/components/roku/fixtures/apps.xml
deleted file mode 100644
index 477304c09e8..00000000000
--- a/tests/components/roku/fixtures/apps.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- Roku Channel Store
- Netflix
- Amazon Video on Demand
- MLB.TV®
- Free FrameChannel Service
- Mediafly
- Pandora
- Pluto TV - It's Free TV
-
diff --git a/tests/components/roku/fixtures/media-player-close.xml b/tests/components/roku/fixtures/media-player-close.xml
deleted file mode 100644
index 0f542941d8c..00000000000
--- a/tests/components/roku/fixtures/media-player-close.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
- false
-
diff --git a/tests/components/roku/fixtures/media-player-live.xml b/tests/components/roku/fixtures/media-player-live.xml
deleted file mode 100644
index 62d819f228c..00000000000
--- a/tests/components/roku/fixtures/media-player-live.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
- 73313 ms
- 95000 ms
- true
- 25106 ms
-
-
diff --git a/tests/components/roku/fixtures/media-player-pause.xml b/tests/components/roku/fixtures/media-player-pause.xml
deleted file mode 100644
index a771208ef57..00000000000
--- a/tests/components/roku/fixtures/media-player-pause.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
- 313813 ms
- 6496762 ms
- false
- 15000 ms
-
-
diff --git a/tests/components/roku/fixtures/media-player-play.xml b/tests/components/roku/fixtures/media-player-play.xml
deleted file mode 100644
index eceb3ce59a2..00000000000
--- a/tests/components/roku/fixtures/media-player-play.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
- 38813 ms
- 6496762 ms
- false
- 15000 ms
-
-
diff --git a/tests/components/roku/fixtures/roku3-app.json b/tests/components/roku/fixtures/roku3-app.json
new file mode 100644
index 00000000000..0bf9411ef5c
--- /dev/null
+++ b/tests/components/roku/fixtures/roku3-app.json
@@ -0,0 +1,93 @@
+{
+ "available": true,
+ "standby": false,
+ "info": {
+ "udn": "015e5108-9000-1046-8035-b0a737964dfb",
+ "serial-number": "1GU48T017973",
+ "device-id": "1GU48T017973",
+ "vendor-name": "Roku",
+ "model-number": "4200X",
+ "model-name": "Roku 3",
+ "model-region": "US",
+ "supports-ethernet": "true",
+ "wifi-mac": "b0:a7:37:96:4d:fb",
+ "ethernet-mac": "b0:a7:37:96:4d:fa",
+ "network-type": "ethernet",
+ "user-device-name": "My Roku 3",
+ "software-version": "7.5.0",
+ "software-build": "09021",
+ "secure-device": "true",
+ "language": "en",
+ "country": "US",
+ "locale": "en_US",
+ "time-zone": "US/Pacific",
+ "time-zone-offset": "-480",
+ "power-mode": "PowerOn",
+ "supports-suspend": "false",
+ "supports-find-remote": "false",
+ "supports-audio-guide": "false",
+ "developer-enabled": "true",
+ "keyed-developer-id": "70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558",
+ "search-enabled": "true",
+ "voice-search-enabled": "true",
+ "notifications-enabled": "true",
+ "notifications-first-use": "false",
+ "supports-private-listening": "false",
+ "headphones-connected": "false"
+ },
+ "app": {
+ "@id": "12",
+ "@type": "appl",
+ "@version": "4.1.218",
+ "#text": "Netflix"
+ },
+ "apps": [
+ {
+ "@id": "11",
+ "#text": "Roku Channel Store"
+ },
+ {
+ "@id": "12",
+ "#text": "Netflix"
+ },
+ {
+ "@id": "13",
+ "#text": "Amazon Video on Demand"
+ },
+ {
+ "@id": "14",
+ "#text": "MLB.TV®"
+ },
+ {
+ "@id": "26",
+ "#text": "Free FrameChannel Service"
+ },
+ {
+ "@id": "27",
+ "#text": "Mediafly"
+ },
+ {
+ "@id": "28",
+ "#text": "Pandora"
+ },
+ {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ }
+ ],
+ "media": {
+ "@error": "false",
+ "@state": "close",
+ "format":
+ {
+ "@audio": "eac3",
+ "@captions": "none",
+ "@drm": "none",
+ "@video": "hevc_b"
+ },
+ "is_live": "false"
+ }
+}
diff --git a/tests/components/roku/fixtures/roku3-device-info-power-off.xml b/tests/components/roku/fixtures/roku3-device-info-power-off.xml
deleted file mode 100644
index 4a89724016b..00000000000
--- a/tests/components/roku/fixtures/roku3-device-info-power-off.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- 015e5108-9000-1046-8035-b0a737964dfb
- 1GU48T017973
- 1GU48T017973
- Roku
- 4200X
- Roku 3
- US
- true
- b0:a7:37:96:4d:fb
- b0:a7:37:96:4d:fa
- ethernet
- My Roku 3
- 7.5.0
- 09021
- true
- en
- US
- en_US
- US/Pacific
- -480
- PowerOff
- false
- false
- false
- true
- 70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558
- true
- true
- true
- false
- false
- false
-
diff --git a/tests/components/roku/fixtures/roku3-device-info.xml b/tests/components/roku/fixtures/roku3-device-info.xml
deleted file mode 100644
index e41e4201518..00000000000
--- a/tests/components/roku/fixtures/roku3-device-info.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
- 015e5108-9000-1046-8035-b0a737964dfb
- 1GU48T017973
- 1GU48T017973
- Roku
- 4200X
- Roku 3
- US
- true
- b0:a7:37:96:4d:fb
- b0:a7:37:96:4d:fa
- ethernet
- My Roku 3
- 7.5.0
- 09021
- true
- en
- US
- en_US
- US/Pacific
- -480
- PowerOn
- false
- false
- false
- true
- 70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558
- true
- true
- true
- false
- false
- false
-
diff --git a/tests/components/roku/fixtures/roku3-idle.json b/tests/components/roku/fixtures/roku3-idle.json
new file mode 100644
index 00000000000..d092b16df69
--- /dev/null
+++ b/tests/components/roku/fixtures/roku3-idle.json
@@ -0,0 +1,90 @@
+{
+ "available": true,
+ "standby": true,
+ "info": {
+ "udn": "015e5108-9000-1046-8035-b0a737964dfb",
+ "serial-number": "1GU48T017973",
+ "device-id": "1GU48T017973",
+ "vendor-name": "Roku",
+ "model-number": "4200X",
+ "model-name": "Roku 3",
+ "model-region": "US",
+ "supports-ethernet": "true",
+ "wifi-mac": "b0:a7:37:96:4d:fb",
+ "ethernet-mac": "b0:a7:37:96:4d:fa",
+ "network-type": "ethernet",
+ "user-device-name": "My Roku 3",
+ "software-version": "7.5.0",
+ "software-build": "09021",
+ "secure-device": "true",
+ "language": "en",
+ "country": "US",
+ "locale": "en_US",
+ "time-zone": "US/Pacific",
+ "time-zone-offset": "-480",
+ "power-mode": "PowerOn",
+ "supports-suspend": "false",
+ "supports-find-remote": "false",
+ "supports-audio-guide": "false",
+ "developer-enabled": "true",
+ "keyed-developer-id": "70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558",
+ "search-enabled": "true",
+ "voice-search-enabled": "true",
+ "notifications-enabled": "true",
+ "notifications-first-use": "false",
+ "supports-private-listening": "false",
+ "headphones-connected": "false"
+ },
+ "app": {
+ "#text": "Roku"
+ },
+ "apps": [
+ {
+ "@id": "11",
+ "#text": "Roku Channel Store"
+ },
+ {
+ "@id": "12",
+ "#text": "Netflix"
+ },
+ {
+ "@id": "13",
+ "#text": "Amazon Video on Demand"
+ },
+ {
+ "@id": "14",
+ "#text": "MLB.TV®"
+ },
+ {
+ "@id": "26",
+ "#text": "Free FrameChannel Service"
+ },
+ {
+ "@id": "27",
+ "#text": "Mediafly"
+ },
+ {
+ "@id": "28",
+ "#text": "Pandora"
+ },
+ {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ }
+ ],
+ "media": {
+ "@error": "false",
+ "@state": "close",
+ "format":
+ {
+ "@audio": "eac3",
+ "@captions": "none",
+ "@drm": "none",
+ "@video": "hevc_b"
+ },
+ "is_live": "false"
+ }
+}
diff --git a/tests/components/roku/fixtures/roku3-media-paused.json b/tests/components/roku/fixtures/roku3-media-paused.json
new file mode 100644
index 00000000000..cf37d05528d
--- /dev/null
+++ b/tests/components/roku/fixtures/roku3-media-paused.json
@@ -0,0 +1,116 @@
+{
+ "available": true,
+ "standby": false,
+ "info": {
+ "udn": "015e5108-9000-1046-8035-b0a737964dfb",
+ "serial-number": "1GU48T017973",
+ "device-id": "1GU48T017973",
+ "vendor-name": "Roku",
+ "model-number": "4200X",
+ "model-name": "Roku 3",
+ "model-region": "US",
+ "supports-ethernet": "true",
+ "wifi-mac": "b0:a7:37:96:4d:fb",
+ "ethernet-mac": "b0:a7:37:96:4d:fa",
+ "network-type": "ethernet",
+ "user-device-name": "My Roku 3",
+ "software-version": "7.5.0",
+ "software-build": "09021",
+ "secure-device": "true",
+ "language": "en",
+ "country": "US",
+ "locale": "en_US",
+ "time-zone": "US/Pacific",
+ "time-zone-offset": "-480",
+ "power-mode": "PowerOn",
+ "supports-suspend": "false",
+ "supports-find-remote": "false",
+ "supports-audio-guide": "false",
+ "developer-enabled": "true",
+ "keyed-developer-id": "70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558",
+ "search-enabled": "true",
+ "voice-search-enabled": "true",
+ "notifications-enabled": "true",
+ "notifications-first-use": "false",
+ "supports-private-listening": "false",
+ "headphones-connected": "false"
+ },
+ "app": {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ },
+ "apps": [
+ {
+ "@id": "11",
+ "#text": "Roku Channel Store"
+ },
+ {
+ "@id": "12",
+ "#text": "Netflix"
+ },
+ {
+ "@id": "13",
+ "#text": "Amazon Video on Demand"
+ },
+ {
+ "@id": "14",
+ "#text": "MLB.TV®"
+ },
+ {
+ "@id": "26",
+ "#text": "Free FrameChannel Service"
+ },
+ {
+ "@id": "27",
+ "#text": "Mediafly"
+ },
+ {
+ "@id": "28",
+ "#text": "Pandora"
+ },
+ {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ }
+ ],
+ "media": {
+ "@error": "false",
+ "@state": "pause",
+ "plugin": {
+ "@bandwidth": "10000000 bps",
+ "@id": "74519",
+ "@name": "Pluto TV - It's Free TV"
+ },
+ "format": {
+ "@audio": "aac_adts",
+ "@captions": "webvtt",
+ "@container": "hls",
+ "@drm": "none",
+ "@video": "mpeg4_10b"
+ },
+ "buffering": {
+ "@current": "1000",
+ "@max": "1000",
+ "@target": "0"
+ },
+ "new_stream": {
+ "@speed": "128000 bps"
+ },
+ "position": "313813 ms",
+ "duration": "6496762 ms",
+ "is_live": "false",
+ "runtime": "15000 ms",
+ "stream_segment": {
+ "@bitrate": "3063648",
+ "@media_sequence": "61",
+ "@segment_type": "mux",
+ "@time": "310013"
+ }
+ }
+}
diff --git a/tests/components/roku/fixtures/roku3-media-playing.json b/tests/components/roku/fixtures/roku3-media-playing.json
new file mode 100644
index 00000000000..17f016a409f
--- /dev/null
+++ b/tests/components/roku/fixtures/roku3-media-playing.json
@@ -0,0 +1,116 @@
+{
+ "available": true,
+ "standby": false,
+ "info": {
+ "udn": "015e5108-9000-1046-8035-b0a737964dfb",
+ "serial-number": "1GU48T017973",
+ "device-id": "1GU48T017973",
+ "vendor-name": "Roku",
+ "model-number": "4200X",
+ "model-name": "Roku 3",
+ "model-region": "US",
+ "supports-ethernet": "true",
+ "wifi-mac": "b0:a7:37:96:4d:fb",
+ "ethernet-mac": "b0:a7:37:96:4d:fa",
+ "network-type": "ethernet",
+ "user-device-name": "My Roku 3",
+ "software-version": "7.5.0",
+ "software-build": "09021",
+ "secure-device": "true",
+ "language": "en",
+ "country": "US",
+ "locale": "en_US",
+ "time-zone": "US/Pacific",
+ "time-zone-offset": "-480",
+ "power-mode": "PowerOn",
+ "supports-suspend": "false",
+ "supports-find-remote": "false",
+ "supports-audio-guide": "false",
+ "developer-enabled": "true",
+ "keyed-developer-id": "70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558",
+ "search-enabled": "true",
+ "voice-search-enabled": "true",
+ "notifications-enabled": "true",
+ "notifications-first-use": "false",
+ "supports-private-listening": "false",
+ "headphones-connected": "false"
+ },
+ "app": {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ },
+ "apps": [
+ {
+ "@id": "11",
+ "#text": "Roku Channel Store"
+ },
+ {
+ "@id": "12",
+ "#text": "Netflix"
+ },
+ {
+ "@id": "13",
+ "#text": "Amazon Video on Demand"
+ },
+ {
+ "@id": "14",
+ "#text": "MLB.TV®"
+ },
+ {
+ "@id": "26",
+ "#text": "Free FrameChannel Service"
+ },
+ {
+ "@id": "27",
+ "#text": "Mediafly"
+ },
+ {
+ "@id": "28",
+ "#text": "Pandora"
+ },
+ {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ }
+ ],
+ "media": {
+ "@error": "false",
+ "@state": "play",
+ "plugin": {
+ "@bandwidth": "10000000 bps",
+ "@id": "74519",
+ "@name": "Pluto TV - It's Free TV"
+ },
+ "format": {
+ "@audio": "aac_adts",
+ "@captions": "webvtt",
+ "@container": "hls",
+ "@drm": "none",
+ "@video": "mpeg4_10b"
+ },
+ "buffering": {
+ "@current": "1000",
+ "@max": "1000",
+ "@target": "0"
+ },
+ "new_stream": {
+ "@speed": "128000 bps"
+ },
+ "position": "38813 ms",
+ "duration": "6496762 ms",
+ "is_live": "false",
+ "runtime": "15000 ms",
+ "stream_segment": {
+ "@bitrate": "2000",
+ "@media_sequence": "68",
+ "@segment_type": "captions",
+ "@time": "39013"
+ }
+ }
+}
diff --git a/tests/components/roku/fixtures/roku3-screensaver.json b/tests/components/roku/fixtures/roku3-screensaver.json
new file mode 100644
index 00000000000..c2e9d36ec38
--- /dev/null
+++ b/tests/components/roku/fixtures/roku3-screensaver.json
@@ -0,0 +1,96 @@
+{
+ "available": true,
+ "standby": false,
+ "info": {
+ "udn": "015e5108-9000-1046-8035-b0a737964dfb",
+ "serial-number": "1GU48T017973",
+ "device-id": "1GU48T017973",
+ "vendor-name": "Roku",
+ "model-number": "4200X",
+ "model-name": "Roku 3",
+ "model-region": "US",
+ "supports-ethernet": "true",
+ "wifi-mac": "b0:a7:37:96:4d:fb",
+ "ethernet-mac": "b0:a7:37:96:4d:fa",
+ "network-type": "ethernet",
+ "user-device-name": "My Roku 3",
+ "software-version": "7.5.0",
+ "software-build": "09021",
+ "secure-device": "true",
+ "language": "en",
+ "country": "US",
+ "locale": "en_US",
+ "time-zone": "US/Pacific",
+ "time-zone-offset": "-480",
+ "power-mode": "PowerOn",
+ "supports-suspend": "false",
+ "supports-find-remote": "false",
+ "supports-audio-guide": "false",
+ "developer-enabled": "true",
+ "keyed-developer-id": "70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558",
+ "search-enabled": "true",
+ "voice-search-enabled": "true",
+ "notifications-enabled": "true",
+ "notifications-first-use": "false",
+ "supports-private-listening": "false",
+ "headphones-connected": "false"
+ },
+ "app": {
+ "app": "Roku",
+ "screensaver": {
+ "@id": "55545",
+ "@type": "ssvr",
+ "@version": "2.0.1",
+ "#text": "Default screensaver"
+ }
+ },
+ "apps": [
+ {
+ "@id": "11",
+ "#text": "Roku Channel Store"
+ },
+ {
+ "@id": "12",
+ "#text": "Netflix"
+ },
+ {
+ "@id": "13",
+ "#text": "Amazon Video on Demand"
+ },
+ {
+ "@id": "14",
+ "#text": "MLB.TV®"
+ },
+ {
+ "@id": "26",
+ "#text": "Free FrameChannel Service"
+ },
+ {
+ "@id": "27",
+ "#text": "Mediafly"
+ },
+ {
+ "@id": "28",
+ "#text": "Pandora"
+ },
+ {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ }
+ ],
+ "media": {
+ "@error": "false",
+ "@state": "close",
+ "format":
+ {
+ "@audio": "eac3",
+ "@captions": "none",
+ "@drm": "none",
+ "@video": "hevc_b"
+ },
+ "is_live": "false"
+ }
+}
diff --git a/tests/components/roku/fixtures/roku3.json b/tests/components/roku/fixtures/roku3.json
new file mode 100644
index 00000000000..bf731a3b200
--- /dev/null
+++ b/tests/components/roku/fixtures/roku3.json
@@ -0,0 +1,90 @@
+{
+ "available": true,
+ "standby": false,
+ "info": {
+ "udn": "015e5108-9000-1046-8035-b0a737964dfb",
+ "serial-number": "1GU48T017973",
+ "device-id": "1GU48T017973",
+ "vendor-name": "Roku",
+ "model-number": "4200X",
+ "model-name": "Roku 3",
+ "model-region": "US",
+ "supports-ethernet": "true",
+ "wifi-mac": "b0:a7:37:96:4d:fb",
+ "ethernet-mac": "b0:a7:37:96:4d:fa",
+ "network-type": "ethernet",
+ "user-device-name": "My Roku 3",
+ "software-version": "7.5.0",
+ "software-build": "09021",
+ "secure-device": "true",
+ "language": "en",
+ "country": "US",
+ "locale": "en_US",
+ "time-zone": "US/Pacific",
+ "time-zone-offset": "-480",
+ "power-mode": "PowerOn",
+ "supports-suspend": "false",
+ "supports-find-remote": "false",
+ "supports-audio-guide": "false",
+ "developer-enabled": "true",
+ "keyed-developer-id": "70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558",
+ "search-enabled": "true",
+ "voice-search-enabled": "true",
+ "notifications-enabled": "true",
+ "notifications-first-use": "false",
+ "supports-private-listening": "false",
+ "headphones-connected": "false"
+ },
+ "app": {
+ "#text": "Roku"
+ },
+ "apps": [
+ {
+ "@id": "11",
+ "#text": "Roku Channel Store"
+ },
+ {
+ "@id": "12",
+ "#text": "Netflix"
+ },
+ {
+ "@id": "13",
+ "#text": "Amazon Video on Demand"
+ },
+ {
+ "@id": "14",
+ "#text": "MLB.TV®"
+ },
+ {
+ "@id": "26",
+ "#text": "Free FrameChannel Service"
+ },
+ {
+ "@id": "27",
+ "#text": "Mediafly"
+ },
+ {
+ "@id": "28",
+ "#text": "Pandora"
+ },
+ {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ }
+ ],
+ "media": {
+ "@error": "false",
+ "@state": "close",
+ "format":
+ {
+ "@audio": "eac3",
+ "@captions": "none",
+ "@drm": "none",
+ "@video": "hevc_b"
+ },
+ "is_live": "false"
+ }
+}
diff --git a/tests/components/roku/fixtures/rokutv-7820x.json b/tests/components/roku/fixtures/rokutv-7820x.json
new file mode 100644
index 00000000000..42181b08745
--- /dev/null
+++ b/tests/components/roku/fixtures/rokutv-7820x.json
@@ -0,0 +1,184 @@
+{
+ "available": true,
+ "standby": false,
+ "info": {
+ "udn": "015e5555-9000-5555-5555-b0a555555dfb",
+ "serial-number": "YN00H5555555",
+ "device-id": "0S596H055555",
+ "advertising-id": "055555a9-d82b-5c75-b8fe-5555550cb7ee",
+ "vendor-name": "Onn",
+ "model-name": "100005844",
+ "model-number": "7820X",
+ "model-region": "US",
+ "is-tv": "true",
+ "is-stick": "false",
+ "screen-size": "58",
+ "panel-id": "2",
+ "tuner-type": "ATSC",
+ "supports-ethernet": "true",
+ "wifi-mac": "d8:13:99:f8:b0:c6",
+ "wifi-driver": "realtek",
+ "ethernet-mac": "d4:3a:2e:07:fd:cb",
+ "network-type": "wifi",
+ "network-name": "NetworkSSID",
+ "friendly-device-name": "58\" Onn Roku TV",
+ "friendly-model-name": "Onn Roku TV",
+ "default-device-name": "Onn Roku TV - YN00H5555555",
+ "user-device-name": "58\" Onn Roku TV",
+ "user-device-location": "Living room",
+ "build-number": "AT9.20E04502A",
+ "software-version": "9.2.0",
+ "software-build": "4502",
+ "secure-device": "true",
+ "language": "en",
+ "country": "US",
+ "locale": "en_US",
+ "time-zone-auto": "true",
+ "time-zone": "US/Central",
+ "time-zone-name": "United States/Central",
+ "time-zone-tz": "America/Chicago",
+ "time-zone-offset": "-300",
+ "clock-format": "12-hour",
+ "uptime": "264789",
+ "power-mode": "PowerOn",
+ "supports-suspend": "true",
+ "supports-find-remote": "true",
+ "find-remote-is-possible": "false",
+ "supports-audio-guide": "true",
+ "supports-rva": "true",
+ "developer-enabled": "false",
+ "keyed-developer-id": [],
+ "search-enabled": "true",
+ "search-channels-enabled": "true",
+ "voice-search-enabled": "true",
+ "notifications-enabled": "true",
+ "notifications-first-use": "false",
+ "supports-private-listening": "true",
+ "supports-private-listening-dtv": "true",
+ "supports-warm-standby": "true",
+ "headphones-connected": "false",
+ "expert-pq-enabled": "0.9",
+ "supports-ecs-textedit": "true",
+ "supports-ecs-microphone": "true",
+ "supports-wake-on-wlan": "true",
+ "supports-airplay": "true",
+ "has-play-on-roku": "true",
+ "has-mobile-screensaver": "true",
+ "support-url": "https://www.onntvsupport.com/",
+ "grandcentral-version": "2.9.57",
+ "trc-version": "3.0",
+ "trc-channel-version": "2.9.42",
+ "davinci-version": "2.8.20",
+ "has-wifi-extender": "false",
+ "has-wifi-5G-support": "true",
+ "can-use-wifi-extender": "true"
+ },
+ "app": {
+ "@id": "tvinput.dtv",
+ "@type": "tvin",
+ "@version": "1.0.0",
+ "#text": "Antenna TV"
+ },
+ "apps": [
+ {
+ "@id": "tvinput.hdmi2",
+ "@type": "tvin",
+ "@version": "1.0.0",
+ "#text": "Satellite TV"
+ },
+ {
+ "@id": "tvinput.hdmi1",
+ "@type": "tvin",
+ "@version": "1.0.0",
+ "#text": "Blu-ray player"
+ },
+ {
+ "@id": "tvinput.dtv",
+ "@type": "tvin",
+ "@version": "1.0.0",
+ "#text": "Antenna TV"
+ },
+ {
+ "@id": "11",
+ "#text": "Roku Channel Store"
+ },
+ {
+ "@id": "12",
+ "#text": "Netflix"
+ },
+ {
+ "@id": "13",
+ "#text": "Amazon Video on Demand"
+ },
+ {
+ "@id": "14",
+ "#text": "MLB.TV®"
+ },
+ {
+ "@id": "26",
+ "#text": "Free FrameChannel Service"
+ },
+ {
+ "@id": "27",
+ "#text": "Mediafly"
+ },
+ {
+ "@id": "28",
+ "#text": "Pandora"
+ },
+ {
+ "@id": "74519",
+ "@subtype": "rsga",
+ "@type": "appl",
+ "@version": "5.2.0",
+ "#text": "Pluto TV - It's Free TV"
+ }
+ ],
+ "channel": {
+ "number": "14.3",
+ "name": "getTV",
+ "type": "air-digital",
+ "user-hidden": "false",
+ "active-input": "true",
+ "signal-state": "valid",
+ "signal-mode": "480i",
+ "signal-quality": "20",
+ "signal-strength": "-75",
+ "program-title": "Airwolf",
+ "program-description": "The team will travel all around the world in order to shut down a global crime ring.",
+ "program-ratings": "TV-14-D-V",
+ "program-analog-audio": "none",
+ "program-digital-audio": "stereo",
+ "program-audio-languages": "eng",
+ "program-audio-formats": "AC3",
+ "program-audio-language": "eng",
+ "program-audio-format": "AC3",
+ "program-has-cc": "true"
+ },
+ "channels": [
+ {
+ "number": "1.1",
+ "name": "WhatsOn",
+ "type": "air-digital",
+ "user-hidden": "false"
+ },
+ {
+ "number": "1.3",
+ "name": "QVC",
+ "type": "air-digital",
+ "user-hidden": "false"
+ }
+ ],
+ "media": {
+ "@error": "false",
+ "@state": "close",
+ "format":
+ {
+ "@audio": "eac3",
+ "@captions": "none",
+ "@drm": "none",
+ "@video": "hevc_b"
+ },
+ "is_live": "false"
+ }
+}
diff --git a/tests/components/roku/fixtures/rokutv-device-info-power-off.xml b/tests/components/roku/fixtures/rokutv-device-info-power-off.xml
deleted file mode 100644
index 658fc130629..00000000000
--- a/tests/components/roku/fixtures/rokutv-device-info-power-off.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
- 015e5555-9000-5555-5555-b0a555555dfb
- YN00H5555555
- 0S596H055555
- 055555a9-d82b-5c75-b8fe-5555550cb7ee
- Onn
- 100005844
- 7820X
- US
- true
- false
- 58
- 2
- ATSC
- true
- d8:13:99:f8:b0:c6
- realtek
- d4:3a:2e:07:fd:cb
- wifi
- NetworkSSID
- 58" Onn Roku TV
- Onn Roku TV
- Onn Roku TV - YN00H5555555
- 58" Onn Roku TV
- Living room
- AT9.20E04502A
- 9.2.0
- 4502
- true
- en
- US
- en_US
- true
- US/Central
- United States/Central
- America/Chicago
- -300
- 12-hour
- 264789
- PowerOn
- true
- true
- false
- true
- true
- false
-
- true
- true
- true
- true
- false
- true
- true
- true
- false
- 0.9
- true
- true
- true
- true
- true
- https://www.onntvsupport.com/
- 2.9.57
- 3.0
- 2.9.42
- 2.8.20
- false
- true
- true
-
diff --git a/tests/components/roku/fixtures/rokutv-device-info.xml b/tests/components/roku/fixtures/rokutv-device-info.xml
deleted file mode 100644
index cbb538ba4c1..00000000000
--- a/tests/components/roku/fixtures/rokutv-device-info.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
- 015e5555-9000-5555-5555-b0a555555dfb
- YN00H5555555
- 0S596H055555
- 055555a9-d82b-5c75-b8fe-5555550cb7ee
- Onn
- 100005844
- 7820X
- US
- true
- false
- 58
- 2
- ATSC
- true
- d8:13:99:f8:b0:c6
- realtek
- d4:3a:2e:07:fd:cb
- wifi
- NetworkSSID
- 58" Onn Roku TV
- Onn Roku TV
- Onn Roku TV - YN00H5555555
- 58" Onn Roku TV
- Living room
- AT9.20E04502A
- 9.2.0
- 4502
- true
- en
- US
- en_US
- true
- US/Central
- United States/Central
- America/Chicago
- -300
- 12-hour
- 264789
- PowerOn
- true
- true
- false
- true
- true
- false
-
- true
- true
- true
- true
- false
- true
- true
- true
- false
- 0.9
- true
- true
- true
- true
- true
- true
- https://www.onntvsupport.com/
- 2.9.57
- 3.0
- 2.9.42
- 2.8.20
- false
- true
- true
-
diff --git a/tests/components/roku/fixtures/rokutv-tv-active-channel.xml b/tests/components/roku/fixtures/rokutv-tv-active-channel.xml
deleted file mode 100644
index 9d6bf582726..00000000000
--- a/tests/components/roku/fixtures/rokutv-tv-active-channel.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
- 14.3
- getTV
- air-digital
- false
- true
- valid
- 480i
- 20
- -75
- Airwolf
- The team will travel all around the world in order to shut down a global crime ring.
- TV-14-D-V
- none
- stereo
- eng
- AC3
- eng
- AC3
- true
-
-
diff --git a/tests/components/roku/fixtures/rokutv-tv-channels.xml b/tests/components/roku/fixtures/rokutv-tv-channels.xml
deleted file mode 100644
index db4b816c9e2..00000000000
--- a/tests/components/roku/fixtures/rokutv-tv-channels.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- 1.1
- WhatsOn
- air-digital
- false
-
-
- 1.3
- QVC
- air-digital
- false
-
-
diff --git a/tests/components/roku/test_binary_sensor.py b/tests/components/roku/test_binary_sensor.py
index d04e2db623b..d551a548c4c 100644
--- a/tests/components/roku/test_binary_sensor.py
+++ b/tests/components/roku/test_binary_sensor.py
@@ -1,4 +1,8 @@
"""Tests for the sensors provided by the Roku integration."""
+from unittest.mock import MagicMock
+
+import pytest
+
from homeassistant.components.binary_sensor import STATE_OFF, STATE_ON
from homeassistant.components.roku.const import DOMAIN
from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, ATTR_ICON
@@ -6,17 +10,14 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.entity import EntityCategory
-from tests.components.roku import UPNP_SERIAL, setup_integration
-from tests.test_util.aiohttp import AiohttpClientMocker
+from tests.common import MockConfigEntry
+from tests.components.roku import UPNP_SERIAL
async def test_roku_binary_sensors(
- hass: HomeAssistant,
- aioclient_mock: AiohttpClientMocker,
+ hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test the Roku binary sensors."""
- await setup_integration(hass, aioclient_mock)
-
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
@@ -77,22 +78,17 @@ async def test_roku_binary_sensors(
assert device_entry.name == "My Roku 3"
assert device_entry.entry_type is None
assert device_entry.sw_version == "7.5.0"
+ assert device_entry.hw_version == "4200X"
+ assert device_entry.suggested_area is None
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
async def test_rokutv_binary_sensors(
hass: HomeAssistant,
- aioclient_mock: AiohttpClientMocker,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test the Roku binary sensors."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host="192.168.1.161",
- unique_id="YN00H5555555",
- )
-
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
@@ -167,3 +163,5 @@ async def test_rokutv_binary_sensors(
assert device_entry.name == '58" Onn Roku TV'
assert device_entry.entry_type is None
assert device_entry.sw_version == "9.2.0"
+ assert device_entry.hw_version == "7820X"
+ assert device_entry.suggested_area == "Living room"
diff --git a/tests/components/roku/test_config_flow.py b/tests/components/roku/test_config_flow.py
index 8aa015d3e01..99d0d1bb2c0 100644
--- a/tests/components/roku/test_config_flow.py
+++ b/tests/components/roku/test_config_flow.py
@@ -1,6 +1,9 @@
"""Test the Roku config flow."""
import dataclasses
-from unittest.mock import patch
+from unittest.mock import MagicMock
+
+import pytest
+from rokuecp import RokuConnectionError
from homeassistant.components.roku.const import DOMAIN
from homeassistant.config_entries import SOURCE_HOMEKIT, SOURCE_SSDP, SOURCE_USER
@@ -12,6 +15,7 @@ from homeassistant.data_entry_flow import (
RESULT_TYPE_FORM,
)
+from tests.common import MockConfigEntry
from tests.components.roku import (
HOMEKIT_HOST,
HOST,
@@ -19,20 +23,18 @@ from tests.components.roku import (
MOCK_SSDP_DISCOVERY_INFO,
NAME_ROKUTV,
UPNP_FRIENDLY_NAME,
- mock_connection,
- setup_integration,
)
-from tests.test_util.aiohttp import AiohttpClientMocker
async def test_duplicate_error(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ mock_config_entry: MockConfigEntry,
+ mock_roku_config_flow: MagicMock,
) -> None:
"""Test that errors are shown when duplicates are added."""
- await setup_integration(hass, aioclient_mock, skip_entry_setup=True)
- mock_connection(aioclient_mock)
+ mock_config_entry.add_to_hass(hass)
- user_input = {CONF_HOST: HOST}
+ user_input = {CONF_HOST: mock_config_entry.data[CONF_HOST]}
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}, data=user_input
)
@@ -40,7 +42,7 @@ async def test_duplicate_error(
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
- user_input = {CONF_HOST: HOST}
+ user_input = {CONF_HOST: mock_config_entry.data[CONF_HOST]}
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}, data=user_input
)
@@ -57,11 +59,12 @@ async def test_duplicate_error(
assert result["reason"] == "already_configured"
-async def test_form(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker) -> None:
+async def test_form(
+ hass: HomeAssistant,
+ mock_roku_config_flow: MagicMock,
+ mock_setup_entry: None,
+) -> None:
"""Test the user step."""
-
- mock_connection(aioclient_mock)
-
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
)
@@ -69,29 +72,26 @@ async def test_form(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker) ->
assert result["errors"] == {}
user_input = {CONF_HOST: HOST}
- with patch(
- "homeassistant.components.roku.async_setup_entry",
- return_value=True,
- ) as mock_setup_entry:
- result = await hass.config_entries.flow.async_configure(
- flow_id=result["flow_id"], user_input=user_input
- )
- await hass.async_block_till_done()
+ result = await hass.config_entries.flow.async_configure(
+ flow_id=result["flow_id"], user_input=user_input
+ )
+ await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
- assert result["title"] == UPNP_FRIENDLY_NAME
+ assert result["title"] == "My Roku 3"
- assert result["data"]
+ assert "data" in result
assert result["data"][CONF_HOST] == HOST
- assert len(mock_setup_entry.mock_calls) == 1
+ assert "result" in result
+ assert result["result"].unique_id == "1GU48T017973"
async def test_form_cannot_connect(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, mock_roku_config_flow: MagicMock
) -> None:
"""Test we handle cannot connect roku error."""
- mock_connection(aioclient_mock, error=True)
+ mock_roku_config_flow.update.side_effect = RokuConnectionError
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
@@ -106,40 +106,29 @@ async def test_form_cannot_connect(
async def test_form_unknown_error(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, mock_roku_config_flow: MagicMock
) -> None:
"""Test we handle unknown error."""
- mock_connection(aioclient_mock)
+ mock_roku_config_flow.update.side_effect = Exception
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
)
user_input = {CONF_HOST: HOST}
- with patch(
- "homeassistant.components.roku.config_flow.Roku._request",
- side_effect=Exception,
- ) as mock_validate_input:
- result = await hass.config_entries.flow.async_configure(
- flow_id=result["flow_id"], user_input=user_input
- )
+ result = await hass.config_entries.flow.async_configure(
+ flow_id=result["flow_id"], user_input=user_input
+ )
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "unknown"
- await hass.async_block_till_done()
- assert len(mock_validate_input.mock_calls) == 1
-
async def test_homekit_cannot_connect(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, mock_roku_config_flow: MagicMock
) -> None:
"""Test we abort homekit flow on connection error."""
- mock_connection(
- aioclient_mock,
- host=HOMEKIT_HOST,
- error=True,
- )
+ mock_roku_config_flow.update.side_effect = RokuConnectionError
discovery_info = dataclasses.replace(MOCK_HOMEKIT_DISCOVERY_INFO)
result = await hass.config_entries.flow.async_init(
@@ -153,32 +142,31 @@ async def test_homekit_cannot_connect(
async def test_homekit_unknown_error(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, mock_roku_config_flow: MagicMock
) -> None:
"""Test we abort homekit flow on unknown error."""
- mock_connection(aioclient_mock)
+ mock_roku_config_flow.update.side_effect = Exception
discovery_info = dataclasses.replace(MOCK_HOMEKIT_DISCOVERY_INFO)
- with patch(
- "homeassistant.components.roku.config_flow.Roku._request",
- side_effect=Exception,
- ):
- result = await hass.config_entries.flow.async_init(
- DOMAIN,
- context={CONF_SOURCE: SOURCE_HOMEKIT},
- data=discovery_info,
- )
+ result = await hass.config_entries.flow.async_init(
+ DOMAIN,
+ context={CONF_SOURCE: SOURCE_HOMEKIT},
+ data=discovery_info,
+ )
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "unknown"
+@pytest.mark.parametrize(
+ "mock_roku_config_flow", ["roku/rokutv-7820x.json"], indirect=True
+)
async def test_homekit_discovery(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ mock_roku_config_flow: MagicMock,
+ mock_setup_entry: None,
) -> None:
"""Test the homekit discovery flow."""
- mock_connection(aioclient_mock, device="rokutv", host=HOMEKIT_HOST)
-
discovery_info = dataclasses.replace(MOCK_HOMEKIT_DISCOVERY_INFO)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_HOMEKIT}, data=discovery_info
@@ -188,24 +176,18 @@ async def test_homekit_discovery(
assert result["step_id"] == "discovery_confirm"
assert result["description_placeholders"] == {CONF_NAME: NAME_ROKUTV}
- with patch(
- "homeassistant.components.roku.async_setup_entry",
- return_value=True,
- ) as mock_setup_entry:
- result = await hass.config_entries.flow.async_configure(
- flow_id=result["flow_id"], user_input={}
- )
- await hass.async_block_till_done()
+ result = await hass.config_entries.flow.async_configure(
+ flow_id=result["flow_id"], user_input={}
+ )
+ await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == NAME_ROKUTV
- assert result["data"]
+ assert "data" in result
assert result["data"][CONF_HOST] == HOMEKIT_HOST
assert result["data"][CONF_NAME] == NAME_ROKUTV
- assert len(mock_setup_entry.mock_calls) == 1
-
# test abort on existing host
discovery_info = dataclasses.replace(MOCK_HOMEKIT_DISCOVERY_INFO)
result = await hass.config_entries.flow.async_init(
@@ -217,10 +199,10 @@ async def test_homekit_discovery(
async def test_ssdp_cannot_connect(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, mock_roku_config_flow: MagicMock
) -> None:
"""Test we abort SSDP flow on connection error."""
- mock_connection(aioclient_mock, error=True)
+ mock_roku_config_flow.update.side_effect = RokuConnectionError
discovery_info = dataclasses.replace(MOCK_SSDP_DISCOVERY_INFO)
result = await hass.config_entries.flow.async_init(
@@ -234,32 +216,28 @@ async def test_ssdp_cannot_connect(
async def test_ssdp_unknown_error(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, mock_roku_config_flow: MagicMock
) -> None:
"""Test we abort SSDP flow on unknown error."""
- mock_connection(aioclient_mock)
+ mock_roku_config_flow.update.side_effect = Exception
discovery_info = dataclasses.replace(MOCK_SSDP_DISCOVERY_INFO)
- with patch(
- "homeassistant.components.roku.config_flow.Roku._request",
- side_effect=Exception,
- ):
- result = await hass.config_entries.flow.async_init(
- DOMAIN,
- context={CONF_SOURCE: SOURCE_SSDP},
- data=discovery_info,
- )
+ result = await hass.config_entries.flow.async_init(
+ DOMAIN,
+ context={CONF_SOURCE: SOURCE_SSDP},
+ data=discovery_info,
+ )
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "unknown"
async def test_ssdp_discovery(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ mock_roku_config_flow: MagicMock,
+ mock_setup_entry: None,
) -> None:
"""Test the SSDP discovery flow."""
- mock_connection(aioclient_mock)
-
discovery_info = dataclasses.replace(MOCK_SSDP_DISCOVERY_INFO)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={CONF_SOURCE: SOURCE_SSDP}, data=discovery_info
@@ -269,14 +247,10 @@ async def test_ssdp_discovery(
assert result["step_id"] == "discovery_confirm"
assert result["description_placeholders"] == {CONF_NAME: UPNP_FRIENDLY_NAME}
- with patch(
- "homeassistant.components.roku.async_setup_entry",
- return_value=True,
- ) as mock_setup_entry:
- result = await hass.config_entries.flow.async_configure(
- flow_id=result["flow_id"], user_input={}
- )
- await hass.async_block_till_done()
+ result = await hass.config_entries.flow.async_configure(
+ flow_id=result["flow_id"], user_input={}
+ )
+ await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == UPNP_FRIENDLY_NAME
@@ -284,5 +258,3 @@ async def test_ssdp_discovery(
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_NAME] == UPNP_FRIENDLY_NAME
-
- assert len(mock_setup_entry.mock_calls) == 1
diff --git a/tests/components/roku/test_init.py b/tests/components/roku/test_init.py
index fc624f5cb64..f8820e711a2 100644
--- a/tests/components/roku/test_init.py
+++ b/tests/components/roku/test_init.py
@@ -1,41 +1,45 @@
"""Tests for the Roku integration."""
-from unittest.mock import patch
+from unittest.mock import AsyncMock, MagicMock, patch
+
+from rokuecp import RokuConnectionError
from homeassistant.components.roku.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
-from tests.components.roku import setup_integration
-from tests.test_util.aiohttp import AiohttpClientMocker
+from tests.common import MockConfigEntry
+@patch(
+ "homeassistant.components.roku.coordinator.Roku._request",
+ side_effect=RokuConnectionError,
+)
async def test_config_entry_not_ready(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ mock_request: MagicMock, hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test the Roku configuration entry not ready."""
- entry = await setup_integration(hass, aioclient_mock, error=True)
-
- assert entry.state is ConfigEntryState.SETUP_RETRY
-
-
-async def test_unload_config_entry(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
-) -> None:
- """Test the Roku configuration entry unloading."""
- with patch(
- "homeassistant.components.roku.media_player.async_setup_entry",
- return_value=True,
- ), patch(
- "homeassistant.components.roku.remote.async_setup_entry",
- return_value=True,
- ):
- entry = await setup_integration(hass, aioclient_mock)
-
- assert hass.data[DOMAIN][entry.entry_id]
- assert entry.state is ConfigEntryState.LOADED
-
- await hass.config_entries.async_unload(entry.entry_id)
+ mock_config_entry.add_to_hass(hass)
+ await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
- assert entry.entry_id not in hass.data[DOMAIN]
- assert entry.state is ConfigEntryState.NOT_LOADED
+ assert mock_request.call_count == 1
+ assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
+
+
+async def test_load_unload_config_entry(
+ hass: HomeAssistant,
+ mock_config_entry: MockConfigEntry,
+ mock_roku: AsyncMock,
+) -> None:
+ """Test the Roku configuration entry loading/unloading."""
+ mock_config_entry.add_to_hass(hass)
+ await hass.config_entries.async_setup(mock_config_entry.entry_id)
+ await hass.async_block_till_done()
+
+ assert mock_config_entry.entry_id in hass.data[DOMAIN]
+ assert mock_config_entry.state is ConfigEntryState.LOADED
+
+ await hass.config_entries.async_unload(mock_config_entry.entry_id)
+ await hass.async_block_till_done()
+ assert mock_config_entry.entry_id not in hass.data[DOMAIN]
+ assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
diff --git a/tests/components/roku/test_media_player.py b/tests/components/roku/test_media_player.py
index 5f3e5ebe956..154bcedded5 100644
--- a/tests/components/roku/test_media_player.py
+++ b/tests/components/roku/test_media_player.py
@@ -1,7 +1,8 @@
"""Tests for the Roku Media Player platform."""
from datetime import timedelta
-from unittest.mock import patch
+from unittest.mock import MagicMock, patch
+import pytest
from rokuecp import RokuError
from homeassistant.components.media_player import MediaPlayerDeviceClass
@@ -76,25 +77,14 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.util import dt as dt_util
-from tests.common import async_fire_time_changed
-from tests.components.roku import NAME_ROKUTV, UPNP_SERIAL, setup_integration
-from tests.test_util.aiohttp import AiohttpClientMocker
+from tests.common import MockConfigEntry, async_fire_time_changed
MAIN_ENTITY_ID = f"{MP_DOMAIN}.my_roku_3"
TV_ENTITY_ID = f"{MP_DOMAIN}.58_onn_roku_tv"
-TV_HOST = "192.168.1.161"
-TV_LOCATION = "Living room"
-TV_MANUFACTURER = "Onn"
-TV_MODEL = "100005844"
-TV_SERIAL = "YN00H5555555"
-TV_SW_VERSION = "9.2.0"
-
-async def test_setup(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker) -> None:
+async def test_setup(hass: HomeAssistant, init_integration: MockConfigEntry) -> None:
"""Test setup with basic config."""
- await setup_integration(hass, aioclient_mock)
-
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
@@ -104,12 +94,12 @@ async def test_setup(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker) -
assert state
assert entry
assert entry.original_device_class is MediaPlayerDeviceClass.RECEIVER
- assert entry.unique_id == UPNP_SERIAL
+ assert entry.unique_id == "1GU48T017973"
assert entry.device_id
device_entry = device_registry.async_get(entry.device_id)
assert device_entry
- assert device_entry.identifiers == {(DOMAIN, UPNP_SERIAL)}
+ assert device_entry.identifiers == {(DOMAIN, "1GU48T017973")}
assert device_entry.connections == {
(dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fb"),
(dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fa"),
@@ -118,34 +108,30 @@ async def test_setup(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker) -
assert device_entry.model == "Roku 3"
assert device_entry.name == "My Roku 3"
assert device_entry.entry_type is None
- assert device_entry.hw_version == "4200X"
assert device_entry.sw_version == "7.5.0"
+ assert device_entry.hw_version == "4200X"
+ assert device_entry.suggested_area is None
+@pytest.mark.parametrize("mock_roku", ["roku/roku3-idle.json"], indirect=True)
async def test_idle_setup(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test setup with idle device."""
- await setup_integration(hass, aioclient_mock, power=False)
-
state = hass.states.get(MAIN_ENTITY_ID)
assert state
assert state.state == STATE_STANDBY
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
async def test_tv_setup(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test Roku TV setup."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host=TV_HOST,
- unique_id=TV_SERIAL,
- )
-
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
@@ -155,37 +141,41 @@ async def test_tv_setup(
assert state
assert entry
assert entry.original_device_class is MediaPlayerDeviceClass.TV
- assert entry.unique_id == TV_SERIAL
+ assert entry.unique_id == "YN00H5555555"
assert entry.device_id
device_entry = device_registry.async_get(entry.device_id)
assert device_entry
- assert device_entry.identifiers == {(DOMAIN, TV_SERIAL)}
+ assert device_entry.identifiers == {(DOMAIN, "YN00H5555555")}
assert device_entry.connections == {
(dr.CONNECTION_NETWORK_MAC, "d8:13:99:f8:b0:c6"),
(dr.CONNECTION_NETWORK_MAC, "d4:3a:2e:07:fd:cb"),
}
- assert device_entry.manufacturer == TV_MANUFACTURER
- assert device_entry.model == TV_MODEL
+ assert device_entry.manufacturer == "Onn"
+ assert device_entry.model == "100005844"
assert device_entry.name == '58" Onn Roku TV'
assert device_entry.entry_type is None
+ assert device_entry.sw_version == "9.2.0"
assert device_entry.hw_version == "7820X"
- assert device_entry.sw_version == TV_SW_VERSION
+ assert device_entry.suggested_area == "Living room"
async def test_availability(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ mock_roku: MagicMock,
+ mock_config_entry: MockConfigEntry,
) -> None:
"""Test entity availability."""
now = dt_util.utcnow()
future = now + timedelta(minutes=1)
+ mock_config_entry.add_to_hass(hass)
with patch("homeassistant.util.dt.utcnow", return_value=now):
- await setup_integration(hass, aioclient_mock)
+ await hass.config_entries.async_setup(mock_config_entry.entry_id)
+ await hass.async_block_till_done()
- with patch(
- "homeassistant.components.roku.coordinator.Roku.update", side_effect=RokuError
- ), patch("homeassistant.util.dt.utcnow", return_value=future):
+ with patch("homeassistant.util.dt.utcnow", return_value=future):
+ mock_roku.update.side_effect = RokuError
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_UNAVAILABLE
@@ -193,17 +183,18 @@ async def test_availability(
future += timedelta(minutes=1)
with patch("homeassistant.util.dt.utcnow", return_value=future):
+ mock_roku.update.side_effect = None
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_HOME
async def test_supported_features(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test supported features."""
- await setup_integration(hass, aioclient_mock)
-
# Features supported for Rokus
state = hass.states.get(MAIN_ENTITY_ID)
assert (
@@ -222,20 +213,15 @@ async def test_supported_features(
)
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
async def test_tv_supported_features(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test supported features for Roku TV."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host=TV_HOST,
- unique_id=TV_SERIAL,
- )
-
state = hass.states.get(TV_ENTITY_ID)
+ assert state
assert (
SUPPORT_PREVIOUS_TRACK
| SUPPORT_NEXT_TRACK
@@ -253,12 +239,11 @@ async def test_tv_supported_features(
async def test_attributes(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test attributes."""
- await setup_integration(hass, aioclient_mock)
-
state = hass.states.get(MAIN_ENTITY_ID)
+ assert state
assert state.state == STATE_HOME
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) is None
@@ -267,13 +252,15 @@ async def test_attributes(
assert state.attributes.get(ATTR_INPUT_SOURCE) == "Roku"
+@pytest.mark.parametrize("mock_roku", ["roku/roku3-app.json"], indirect=True)
async def test_attributes_app(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test attributes for app."""
- await setup_integration(hass, aioclient_mock, app="netflix")
-
state = hass.states.get(MAIN_ENTITY_ID)
+ assert state
assert state.state == STATE_ON
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MEDIA_TYPE_APP
@@ -282,13 +269,15 @@ async def test_attributes_app(
assert state.attributes.get(ATTR_INPUT_SOURCE) == "Netflix"
+@pytest.mark.parametrize("mock_roku", ["roku/roku3-media-playing.json"], indirect=True)
async def test_attributes_app_media_playing(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test attributes for app with playing media."""
- await setup_integration(hass, aioclient_mock, app="pluto", media_state="play")
-
state = hass.states.get(MAIN_ENTITY_ID)
+ assert state
assert state.state == STATE_PLAYING
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MEDIA_TYPE_APP
@@ -299,13 +288,15 @@ async def test_attributes_app_media_playing(
assert state.attributes.get(ATTR_INPUT_SOURCE) == "Pluto TV - It's Free TV"
+@pytest.mark.parametrize("mock_roku", ["roku/roku3-media-paused.json"], indirect=True)
async def test_attributes_app_media_paused(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test attributes for app with paused media."""
- await setup_integration(hass, aioclient_mock, app="pluto", media_state="pause")
-
state = hass.states.get(MAIN_ENTITY_ID)
+ assert state
assert state.state == STATE_PAUSED
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MEDIA_TYPE_APP
@@ -316,13 +307,15 @@ async def test_attributes_app_media_paused(
assert state.attributes.get(ATTR_INPUT_SOURCE) == "Pluto TV - It's Free TV"
+@pytest.mark.parametrize("mock_roku", ["roku/roku3-screensaver.json"], indirect=True)
async def test_attributes_screensaver(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test attributes for app with screensaver."""
- await setup_integration(hass, aioclient_mock, app="screensaver")
-
state = hass.states.get(MAIN_ENTITY_ID)
+ assert state
assert state.state == STATE_IDLE
assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) is None
@@ -331,20 +324,13 @@ async def test_attributes_screensaver(
assert state.attributes.get(ATTR_INPUT_SOURCE) == "Roku"
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
async def test_tv_attributes(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test attributes for Roku TV."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host=TV_HOST,
- unique_id=TV_SERIAL,
- )
-
state = hass.states.get(TV_ENTITY_ID)
+ assert state
assert state.state == STATE_ON
assert state.attributes.get(ATTR_APP_ID) == "tvinput.dtv"
@@ -355,277 +341,245 @@ async def test_tv_attributes(
assert state.attributes.get(ATTR_MEDIA_TITLE) == "Airwolf"
-async def test_tv_device_registry(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
-) -> None:
- """Test device registered for Roku TV in the device registry."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host=TV_HOST,
- unique_id=TV_SERIAL,
- )
-
- device_registry = dr.async_get(hass)
- reg_device = device_registry.async_get_device(identifiers={(DOMAIN, TV_SERIAL)})
-
- assert reg_device.model == TV_MODEL
- assert reg_device.sw_version == TV_SW_VERSION
- assert reg_device.manufacturer == TV_MANUFACTURER
- assert reg_device.suggested_area == TV_LOCATION
- assert reg_device.name == NAME_ROKUTV
-
-
async def test_services(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test the different media player services."""
- await setup_integration(hass, aioclient_mock)
+ await hass.services.async_call(
+ MP_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: MAIN_ENTITY_ID}, blocking=True
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: MAIN_ENTITY_ID}, blocking=True
- )
+ assert mock_roku.remote.call_count == 1
+ mock_roku.remote.assert_called_with("poweroff")
- remote_mock.assert_called_once_with("poweroff")
+ await hass.services.async_call(
+ MP_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: MAIN_ENTITY_ID}, blocking=True
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: MAIN_ENTITY_ID}, blocking=True
- )
+ assert mock_roku.remote.call_count == 2
+ mock_roku.remote.assert_called_with("poweron")
- remote_mock.assert_called_once_with("poweron")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_MEDIA_PAUSE,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_MEDIA_PAUSE,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
- blocking=True,
- )
+ assert mock_roku.remote.call_count == 3
+ mock_roku.remote.assert_called_with("play")
- remote_mock.assert_called_once_with("play")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_MEDIA_PLAY,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_MEDIA_PLAY,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
- blocking=True,
- )
+ assert mock_roku.remote.call_count == 4
+ mock_roku.remote.assert_called_with("play")
- remote_mock.assert_called_once_with("play")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_MEDIA_PLAY_PAUSE,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_MEDIA_PLAY_PAUSE,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
- blocking=True,
- )
+ assert mock_roku.remote.call_count == 5
+ mock_roku.remote.assert_called_with("play")
- remote_mock.assert_called_once_with("play")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_MEDIA_NEXT_TRACK,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_MEDIA_NEXT_TRACK,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
- blocking=True,
- )
+ assert mock_roku.remote.call_count == 6
+ mock_roku.remote.assert_called_with("forward")
- remote_mock.assert_called_once_with("forward")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_MEDIA_PREVIOUS_TRACK,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_MEDIA_PREVIOUS_TRACK,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
- blocking=True,
- )
+ assert mock_roku.remote.call_count == 7
+ mock_roku.remote.assert_called_with("reverse")
- remote_mock.assert_called_once_with("reverse")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_SELECT_SOURCE,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_INPUT_SOURCE: "Home"},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.launch") as launch_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_PLAY_MEDIA,
- {
- ATTR_ENTITY_ID: MAIN_ENTITY_ID,
- ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_APP,
- ATTR_MEDIA_CONTENT_ID: "11",
+ assert mock_roku.remote.call_count == 8
+ mock_roku.remote.assert_called_with("home")
+
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_PLAY_MEDIA,
+ {
+ ATTR_ENTITY_ID: MAIN_ENTITY_ID,
+ ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_APP,
+ ATTR_MEDIA_CONTENT_ID: "11",
+ },
+ blocking=True,
+ )
+
+ assert mock_roku.launch.call_count == 1
+ mock_roku.launch.assert_called_with("11", {})
+
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_PLAY_MEDIA,
+ {
+ ATTR_ENTITY_ID: MAIN_ENTITY_ID,
+ ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_APP,
+ ATTR_MEDIA_CONTENT_ID: "291097",
+ ATTR_MEDIA_EXTRA: {
+ ATTR_MEDIA_TYPE: "movie",
+ ATTR_CONTENT_ID: "8e06a8b7-d667-4e31-939d-f40a6dd78a88",
},
- blocking=True,
- )
+ },
+ blocking=True,
+ )
- launch_mock.assert_called_once_with("11", {})
+ assert mock_roku.launch.call_count == 2
+ mock_roku.launch.assert_called_with(
+ "291097",
+ {
+ "contentID": "8e06a8b7-d667-4e31-939d-f40a6dd78a88",
+ "MediaType": "movie",
+ },
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.launch") as launch_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_PLAY_MEDIA,
- {
- ATTR_ENTITY_ID: MAIN_ENTITY_ID,
- ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_APP,
- ATTR_MEDIA_CONTENT_ID: "291097",
- ATTR_MEDIA_EXTRA: {
- ATTR_MEDIA_TYPE: "movie",
- ATTR_CONTENT_ID: "8e06a8b7-d667-4e31-939d-f40a6dd78a88",
- },
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_PLAY_MEDIA,
+ {
+ ATTR_ENTITY_ID: MAIN_ENTITY_ID,
+ ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_URL,
+ ATTR_MEDIA_CONTENT_ID: "https://awesome.tld/media.mp4",
+ ATTR_MEDIA_EXTRA: {
+ ATTR_NAME: "Sent from HA",
+ ATTR_FORMAT: "mp4",
},
- blocking=True,
- )
+ },
+ blocking=True,
+ )
- launch_mock.assert_called_once_with(
- "291097",
- {
- "contentID": "8e06a8b7-d667-4e31-939d-f40a6dd78a88",
- "MediaType": "movie",
- },
- )
+ assert mock_roku.play_video.call_count == 1
+ mock_roku.play_video.assert_called_with(
+ "https://awesome.tld/media.mp4",
+ {
+ "videoName": "Sent from HA",
+ "videoFormat": "mp4",
+ },
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.play_video") as pv_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_PLAY_MEDIA,
- {
- ATTR_ENTITY_ID: MAIN_ENTITY_ID,
- ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_URL,
- ATTR_MEDIA_CONTENT_ID: "https://awesome.tld/media.mp4",
- ATTR_MEDIA_EXTRA: {
- ATTR_NAME: "Sent from HA",
- ATTR_FORMAT: "mp4",
- },
- },
- blocking=True,
- )
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_PLAY_MEDIA,
+ {
+ ATTR_ENTITY_ID: MAIN_ENTITY_ID,
+ ATTR_MEDIA_CONTENT_TYPE: FORMAT_CONTENT_TYPE[HLS_PROVIDER],
+ ATTR_MEDIA_CONTENT_ID: "https://awesome.tld/api/hls/api_token/master_playlist.m3u8",
+ },
+ blocking=True,
+ )
- pv_mock.assert_called_once_with(
- "https://awesome.tld/media.mp4",
- {
- "videoName": "Sent from HA",
- "videoFormat": "mp4",
- },
- )
+ assert mock_roku.play_video.call_count == 2
+ mock_roku.play_video.assert_called_with(
+ "https://awesome.tld/api/hls/api_token/master_playlist.m3u8",
+ {
+ "MediaType": "hls",
+ },
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.play_video") as pv_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_PLAY_MEDIA,
- {
- ATTR_ENTITY_ID: MAIN_ENTITY_ID,
- ATTR_MEDIA_CONTENT_TYPE: FORMAT_CONTENT_TYPE[HLS_PROVIDER],
- ATTR_MEDIA_CONTENT_ID: "https://awesome.tld/api/hls/api_token/master_playlist.m3u8",
- },
- blocking=True,
- )
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_SELECT_SOURCE,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_INPUT_SOURCE: "Netflix"},
+ blocking=True,
+ )
- pv_mock.assert_called_once_with(
- "https://awesome.tld/api/hls/api_token/master_playlist.m3u8",
- {
- "MediaType": "hls",
- },
- )
+ assert mock_roku.launch.call_count == 3
+ mock_roku.launch.assert_called_with("12")
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_SELECT_SOURCE,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_INPUT_SOURCE: "Home"},
- blocking=True,
- )
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_SELECT_SOURCE,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_INPUT_SOURCE: 12},
+ blocking=True,
+ )
- remote_mock.assert_called_once_with("home")
-
- with patch("homeassistant.components.roku.coordinator.Roku.launch") as launch_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_SELECT_SOURCE,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_INPUT_SOURCE: "Netflix"},
- blocking=True,
- )
-
- launch_mock.assert_called_once_with("12")
-
- with patch("homeassistant.components.roku.coordinator.Roku.launch") as launch_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_SELECT_SOURCE,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_INPUT_SOURCE: 12},
- blocking=True,
- )
-
- launch_mock.assert_called_once_with("12")
+ assert mock_roku.launch.call_count == 4
+ mock_roku.launch.assert_called_with("12")
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
async def test_tv_services(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test the media player services related to Roku TV."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host=TV_HOST,
- unique_id=TV_SERIAL,
+ await hass.services.async_call(
+ MP_DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: TV_ENTITY_ID}, blocking=True
)
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: TV_ENTITY_ID}, blocking=True
- )
+ assert mock_roku.remote.call_count == 1
+ mock_roku.remote.assert_called_with("volume_up")
- remote_mock.assert_called_once_with("volume_up")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_VOLUME_DOWN,
+ {ATTR_ENTITY_ID: TV_ENTITY_ID},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_VOLUME_DOWN,
- {ATTR_ENTITY_ID: TV_ENTITY_ID},
- blocking=True,
- )
+ assert mock_roku.remote.call_count == 2
+ mock_roku.remote.assert_called_with("volume_down")
- remote_mock.assert_called_once_with("volume_down")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_VOLUME_MUTE,
+ {ATTR_ENTITY_ID: TV_ENTITY_ID, ATTR_MEDIA_VOLUME_MUTED: True},
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_VOLUME_MUTE,
- {ATTR_ENTITY_ID: TV_ENTITY_ID, ATTR_MEDIA_VOLUME_MUTED: True},
- blocking=True,
- )
+ assert mock_roku.remote.call_count == 3
+ mock_roku.remote.assert_called_with("volume_mute")
- remote_mock.assert_called_once_with("volume_mute")
+ await hass.services.async_call(
+ MP_DOMAIN,
+ SERVICE_PLAY_MEDIA,
+ {
+ ATTR_ENTITY_ID: TV_ENTITY_ID,
+ ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_CHANNEL,
+ ATTR_MEDIA_CONTENT_ID: "55",
+ },
+ blocking=True,
+ )
- with patch("homeassistant.components.roku.coordinator.Roku.tune") as tune_mock:
- await hass.services.async_call(
- MP_DOMAIN,
- SERVICE_PLAY_MEDIA,
- {
- ATTR_ENTITY_ID: TV_ENTITY_ID,
- ATTR_MEDIA_CONTENT_TYPE: MEDIA_TYPE_CHANNEL,
- ATTR_MEDIA_CONTENT_ID: "55",
- },
- blocking=True,
- )
-
- tune_mock.assert_called_once_with("55")
+ assert mock_roku.tune.call_count == 1
+ mock_roku.tune.assert_called_with("55")
-async def test_media_browse(hass, aioclient_mock, hass_ws_client):
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
+async def test_media_browse(
+ hass,
+ init_integration,
+ mock_roku,
+ hass_ws_client,
+):
"""Test browsing media."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host=TV_HOST,
- unique_id=TV_SERIAL,
- )
-
client = await hass_ws_client(hass)
await client.send_json(
@@ -741,7 +695,13 @@ async def test_media_browse(hass, aioclient_mock, hass_ws_client):
assert not msg["success"]
-async def test_media_browse_internal(hass, aioclient_mock, hass_ws_client):
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
+async def test_media_browse_internal(
+ hass,
+ init_integration,
+ mock_roku,
+ hass_ws_client,
+):
"""Test browsing media with internal url."""
await async_process_ha_core_config(
hass,
@@ -750,15 +710,6 @@ async def test_media_browse_internal(hass, aioclient_mock, hass_ws_client):
assert hass.config.internal_url == "http://example.local:8123"
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host=TV_HOST,
- unique_id=TV_SERIAL,
- )
-
client = await hass_ws_client(hass)
with patch(
@@ -804,16 +755,15 @@ async def test_media_browse_internal(hass, aioclient_mock, hass_ws_client):
async def test_integration_services(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test integration services."""
- await setup_integration(hass, aioclient_mock)
-
- with patch("homeassistant.components.roku.coordinator.Roku.search") as search_mock:
- await hass.services.async_call(
- DOMAIN,
- SERVICE_SEARCH,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_KEYWORD: "Space Jam"},
- blocking=True,
- )
- search_mock.assert_called_once_with("Space Jam")
+ await hass.services.async_call(
+ DOMAIN,
+ SERVICE_SEARCH,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_KEYWORD: "Space Jam"},
+ blocking=True,
+ )
+ mock_roku.search.assert_called_once_with("Space Jam")
diff --git a/tests/components/roku/test_remote.py b/tests/components/roku/test_remote.py
index c0df380c1e8..f1685609563 100644
--- a/tests/components/roku/test_remote.py
+++ b/tests/components/roku/test_remote.py
@@ -1,5 +1,5 @@
"""The tests for the Roku remote platform."""
-from unittest.mock import patch
+from unittest.mock import MagicMock
from homeassistant.components.remote import (
ATTR_COMMAND,
@@ -10,26 +10,23 @@ from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_O
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
-from tests.components.roku import UPNP_SERIAL, setup_integration
-from tests.test_util.aiohttp import AiohttpClientMocker
+from tests.common import MockConfigEntry
+from tests.components.roku import UPNP_SERIAL
MAIN_ENTITY_ID = f"{REMOTE_DOMAIN}.my_roku_3"
# pylint: disable=redefined-outer-name
-async def test_setup(hass: HomeAssistant, aioclient_mock: AiohttpClientMocker) -> None:
+async def test_setup(hass: HomeAssistant, init_integration: MockConfigEntry) -> None:
"""Test setup with basic config."""
- await setup_integration(hass, aioclient_mock)
assert hass.states.get(MAIN_ENTITY_ID)
async def test_unique_id(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant, init_integration: MockConfigEntry
) -> None:
"""Test unique id."""
- await setup_integration(hass, aioclient_mock)
-
entity_registry = er.async_get(hass)
main = entity_registry.async_get(MAIN_ENTITY_ID)
@@ -37,34 +34,34 @@ async def test_unique_id(
async def test_main_services(
- hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
+ hass: HomeAssistant,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test platform services."""
- await setup_integration(hass, aioclient_mock)
+ await hass.services.async_call(
+ REMOTE_DOMAIN,
+ SERVICE_TURN_OFF,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
+ blocking=True,
+ )
+ assert mock_roku.remote.call_count == 1
+ mock_roku.remote.assert_called_with("poweroff")
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- REMOTE_DOMAIN,
- SERVICE_TURN_OFF,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
- blocking=True,
- )
- remote_mock.assert_called_once_with("poweroff")
+ await hass.services.async_call(
+ REMOTE_DOMAIN,
+ SERVICE_TURN_ON,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
+ blocking=True,
+ )
+ assert mock_roku.remote.call_count == 2
+ mock_roku.remote.assert_called_with("poweron")
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- REMOTE_DOMAIN,
- SERVICE_TURN_ON,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID},
- blocking=True,
- )
- remote_mock.assert_called_once_with("poweron")
-
- with patch("homeassistant.components.roku.coordinator.Roku.remote") as remote_mock:
- await hass.services.async_call(
- REMOTE_DOMAIN,
- SERVICE_SEND_COMMAND,
- {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_COMMAND: ["home"]},
- blocking=True,
- )
- remote_mock.assert_called_once_with("home")
+ await hass.services.async_call(
+ REMOTE_DOMAIN,
+ SERVICE_SEND_COMMAND,
+ {ATTR_ENTITY_ID: MAIN_ENTITY_ID, ATTR_COMMAND: ["home"]},
+ blocking=True,
+ )
+ assert mock_roku.remote.call_count == 3
+ mock_roku.remote.assert_called_with("home")
diff --git a/tests/components/roku/test_sensor.py b/tests/components/roku/test_sensor.py
index 670cf69a8dc..6ca27635d30 100644
--- a/tests/components/roku/test_sensor.py
+++ b/tests/components/roku/test_sensor.py
@@ -1,4 +1,8 @@
"""Tests for the sensors provided by the Roku integration."""
+from unittest.mock import MagicMock
+
+import pytest
+
from homeassistant.components.roku.const import DOMAIN
from homeassistant.const import (
ATTR_DEVICE_CLASS,
@@ -10,17 +14,15 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.entity import EntityCategory
-from tests.components.roku import UPNP_SERIAL, setup_integration
-from tests.test_util.aiohttp import AiohttpClientMocker
+from tests.common import MockConfigEntry
+from tests.components.roku import UPNP_SERIAL
async def test_roku_sensors(
hass: HomeAssistant,
- aioclient_mock: AiohttpClientMocker,
+ init_integration: MockConfigEntry,
) -> None:
"""Test the Roku sensors."""
- await setup_integration(hass, aioclient_mock)
-
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
@@ -59,22 +61,17 @@ async def test_roku_sensors(
assert device_entry.name == "My Roku 3"
assert device_entry.entry_type is None
assert device_entry.sw_version == "7.5.0"
+ assert device_entry.hw_version == "4200X"
+ assert device_entry.suggested_area is None
+@pytest.mark.parametrize("mock_roku", ["roku/rokutv-7820x.json"], indirect=True)
async def test_rokutv_sensors(
hass: HomeAssistant,
- aioclient_mock: AiohttpClientMocker,
+ init_integration: MockConfigEntry,
+ mock_roku: MagicMock,
) -> None:
"""Test the Roku TV sensors."""
- await setup_integration(
- hass,
- aioclient_mock,
- device="rokutv",
- app="tvinput-dtv",
- host="192.168.1.161",
- unique_id="YN00H5555555",
- )
-
entity_registry = er.async_get(hass)
device_registry = dr.async_get(hass)
@@ -113,3 +110,5 @@ async def test_rokutv_sensors(
assert device_entry.name == '58" Onn Roku TV'
assert device_entry.entry_type is None
assert device_entry.sw_version == "9.2.0"
+ assert device_entry.hw_version == "7820X"
+ assert device_entry.suggested_area == "Living room"