mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 18:57:06 +00:00
Refactor roku tests (#64498)
This commit is contained in:
parent
9d39a38c16
commit
9639968a96
@ -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
|
||||
|
86
tests/components/roku/conftest.py
Normal file
86
tests/components/roku/conftest.py
Normal file
@ -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
|
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<active-app>
|
||||
<app id="12" type="appl" version="4.1.218">Netflix</app>
|
||||
</active-app>
|
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<active-app>
|
||||
<app id="74519" subtype="rsga" type="appl" version="5.2.0">Pluto TV - It's Free TV</app>
|
||||
</active-app>
|
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<active-app>
|
||||
<app>Roku</app>
|
||||
</active-app>
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<active-app>
|
||||
<app>Roku</app>
|
||||
<screensaver id="55545" type="ssvr" version="2.0.1">Default screensaver</screensaver>
|
||||
</active-app>
|
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<active-app>
|
||||
<app id="tvinput.dtv" type="tvin" version="1.0.0">Antenna TV</app>
|
||||
</active-app>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<apps>
|
||||
<app id="tvinput.hdmi2" type="tvin" version="1.0.0">Satellite TV</app>
|
||||
<app id="tvinput.hdmi1" type="tvin" version="1.0.0">Blu-ray player</app>
|
||||
<app id="tvinput.dtv" type="tvin" version="1.0.0">Antenna TV</app>
|
||||
<app id="11">Roku Channel Store</app>
|
||||
<app id="12">Netflix</app>
|
||||
<app id="13">Amazon Video on Demand</app>
|
||||
<app id="14">MLB.TV®</app>
|
||||
<app id="26">Free FrameChannel Service</app>
|
||||
<app id="27">Mediafly</app>
|
||||
<app id="28">Pandora</app>
|
||||
<app id="74519" subtype="rsga" type="appl" version="5.2.0">Pluto TV - It's Free TV</app>
|
||||
</apps>
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<apps>
|
||||
<app id="11">Roku Channel Store</app>
|
||||
<app id="12">Netflix</app>
|
||||
<app id="13">Amazon Video on Demand</app>
|
||||
<app id="14">MLB.TV®</app>
|
||||
<app id="26">Free FrameChannel Service</app>
|
||||
<app id="27">Mediafly</app>
|
||||
<app id="28">Pandora</app>
|
||||
<app id="74519" subtype="rsga" type="appl" version="5.2.0">Pluto TV - It's Free TV</app>
|
||||
</apps>
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<player error="false" state="close">
|
||||
<format audio="eac3" captions="none" drm="none" video="hevc_b"/>
|
||||
<is_live>false</is_live>
|
||||
</player>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<player 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>73313 ms</position>
|
||||
<duration>95000 ms</duration>
|
||||
<is_live>true</is_live>
|
||||
<runtime>25106 ms</runtime>
|
||||
<stream_segment bitrate="3063648" media_sequence="49" segment_type="mux" time="70013"/>
|
||||
</player>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<player 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</position>
|
||||
<duration>6496762 ms</duration>
|
||||
<is_live>false</is_live>
|
||||
<runtime>15000 ms</runtime>
|
||||
<stream_segment bitrate="3063648" media_sequence="61" segment_type="mux" time="310013"/>
|
||||
</player>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<player 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</position>
|
||||
<duration>6496762 ms</duration>
|
||||
<is_live>false</is_live>
|
||||
<runtime>15000 ms</runtime>
|
||||
<stream_segment bitrate="2000" media_sequence="68" segment_type="captions" time="39013"/>
|
||||
</player>
|
93
tests/components/roku/fixtures/roku3-app.json
Normal file
93
tests/components/roku/fixtures/roku3-app.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<device-info>
|
||||
<udn>015e5108-9000-1046-8035-b0a737964dfb</udn>
|
||||
<serial-number>1GU48T017973</serial-number>
|
||||
<device-id>1GU48T017973</device-id>
|
||||
<vendor-name>Roku</vendor-name>
|
||||
<model-number>4200X</model-number>
|
||||
<model-name>Roku 3</model-name>
|
||||
<model-region>US</model-region>
|
||||
<supports-ethernet>true</supports-ethernet>
|
||||
<wifi-mac>b0:a7:37:96:4d:fb</wifi-mac>
|
||||
<ethernet-mac>b0:a7:37:96:4d:fa</ethernet-mac>
|
||||
<network-type>ethernet</network-type>
|
||||
<user-device-name>My Roku 3</user-device-name>
|
||||
<software-version>7.5.0</software-version>
|
||||
<software-build>09021</software-build>
|
||||
<secure-device>true</secure-device>
|
||||
<language>en</language>
|
||||
<country>US</country>
|
||||
<locale>en_US</locale>
|
||||
<time-zone>US/Pacific</time-zone>
|
||||
<time-zone-offset>-480</time-zone-offset>
|
||||
<power-mode>PowerOff</power-mode>
|
||||
<supports-suspend>false</supports-suspend>
|
||||
<supports-find-remote>false</supports-find-remote>
|
||||
<supports-audio-guide>false</supports-audio-guide>
|
||||
<developer-enabled>true</developer-enabled>
|
||||
<keyed-developer-id>70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558</keyed-developer-id>
|
||||
<search-enabled>true</search-enabled>
|
||||
<voice-search-enabled>true</voice-search-enabled>
|
||||
<notifications-enabled>true</notifications-enabled>
|
||||
<notifications-first-use>false</notifications-first-use>
|
||||
<supports-private-listening>false</supports-private-listening>
|
||||
<headphones-connected>false</headphones-connected>
|
||||
</device-info>
|
@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<device-info>
|
||||
<udn>015e5108-9000-1046-8035-b0a737964dfb</udn>
|
||||
<serial-number>1GU48T017973</serial-number>
|
||||
<device-id>1GU48T017973</device-id>
|
||||
<vendor-name>Roku</vendor-name>
|
||||
<model-number>4200X</model-number>
|
||||
<model-name>Roku 3</model-name>
|
||||
<model-region>US</model-region>
|
||||
<supports-ethernet>true</supports-ethernet>
|
||||
<wifi-mac>b0:a7:37:96:4d:fb</wifi-mac>
|
||||
<ethernet-mac>b0:a7:37:96:4d:fa</ethernet-mac>
|
||||
<network-type>ethernet</network-type>
|
||||
<user-device-name>My Roku 3</user-device-name>
|
||||
<software-version>7.5.0</software-version>
|
||||
<software-build>09021</software-build>
|
||||
<secure-device>true</secure-device>
|
||||
<language>en</language>
|
||||
<country>US</country>
|
||||
<locale>en_US</locale>
|
||||
<time-zone>US/Pacific</time-zone>
|
||||
<time-zone-offset>-480</time-zone-offset>
|
||||
<power-mode>PowerOn</power-mode>
|
||||
<supports-suspend>false</supports-suspend>
|
||||
<supports-find-remote>false</supports-find-remote>
|
||||
<supports-audio-guide>false</supports-audio-guide>
|
||||
<developer-enabled>true</developer-enabled>
|
||||
<keyed-developer-id>70f6ed9c90cf60718a26f3a7c3e5af1c3ec29558</keyed-developer-id>
|
||||
<search-enabled>true</search-enabled>
|
||||
<voice-search-enabled>true</voice-search-enabled>
|
||||
<notifications-enabled>true</notifications-enabled>
|
||||
<notifications-first-use>false</notifications-first-use>
|
||||
<supports-private-listening>false</supports-private-listening>
|
||||
<headphones-connected>false</headphones-connected>
|
||||
</device-info>
|
90
tests/components/roku/fixtures/roku3-idle.json
Normal file
90
tests/components/roku/fixtures/roku3-idle.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
116
tests/components/roku/fixtures/roku3-media-paused.json
Normal file
116
tests/components/roku/fixtures/roku3-media-paused.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
116
tests/components/roku/fixtures/roku3-media-playing.json
Normal file
116
tests/components/roku/fixtures/roku3-media-playing.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
96
tests/components/roku/fixtures/roku3-screensaver.json
Normal file
96
tests/components/roku/fixtures/roku3-screensaver.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
90
tests/components/roku/fixtures/roku3.json
Normal file
90
tests/components/roku/fixtures/roku3.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
184
tests/components/roku/fixtures/rokutv-7820x.json
Normal file
184
tests/components/roku/fixtures/rokutv-7820x.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<device-info>
|
||||
<udn>015e5555-9000-5555-5555-b0a555555dfb</udn>
|
||||
<serial-number>YN00H5555555</serial-number>
|
||||
<device-id>0S596H055555</device-id>
|
||||
<advertising-id>055555a9-d82b-5c75-b8fe-5555550cb7ee</advertising-id>
|
||||
<vendor-name>Onn</vendor-name>
|
||||
<model-name>100005844</model-name>
|
||||
<model-number>7820X</model-number>
|
||||
<model-region>US</model-region>
|
||||
<is-tv>true</is-tv>
|
||||
<is-stick>false</is-stick>
|
||||
<screen-size>58</screen-size>
|
||||
<panel-id>2</panel-id>
|
||||
<tuner-type>ATSC</tuner-type>
|
||||
<supports-ethernet>true</supports-ethernet>
|
||||
<wifi-mac>d8:13:99:f8:b0:c6</wifi-mac>
|
||||
<wifi-driver>realtek</wifi-driver>
|
||||
<ethernet-mac>d4:3a:2e:07:fd:cb</ethernet-mac>
|
||||
<network-type>wifi</network-type>
|
||||
<network-name>NetworkSSID</network-name>
|
||||
<friendly-device-name>58" Onn Roku TV</friendly-device-name>
|
||||
<friendly-model-name>Onn Roku TV</friendly-model-name>
|
||||
<default-device-name>Onn Roku TV - YN00H5555555</default-device-name>
|
||||
<user-device-name>58" Onn Roku TV</user-device-name>
|
||||
<user-device-location>Living room</user-device-location>
|
||||
<build-number>AT9.20E04502A</build-number>
|
||||
<software-version>9.2.0</software-version>
|
||||
<software-build>4502</software-build>
|
||||
<secure-device>true</secure-device>
|
||||
<language>en</language>
|
||||
<country>US</country>
|
||||
<locale>en_US</locale>
|
||||
<time-zone-auto>true</time-zone-auto>
|
||||
<time-zone>US/Central</time-zone>
|
||||
<time-zone-name>United States/Central</time-zone-name>
|
||||
<time-zone-tz>America/Chicago</time-zone-tz>
|
||||
<time-zone-offset>-300</time-zone-offset>
|
||||
<clock-format>12-hour</clock-format>
|
||||
<uptime>264789</uptime>
|
||||
<power-mode>PowerOn</power-mode>
|
||||
<supports-suspend>true</supports-suspend>
|
||||
<supports-find-remote>true</supports-find-remote>
|
||||
<find-remote-is-possible>false</find-remote-is-possible>
|
||||
<supports-audio-guide>true</supports-audio-guide>
|
||||
<supports-rva>true</supports-rva>
|
||||
<developer-enabled>false</developer-enabled>
|
||||
<keyed-developer-id/>
|
||||
<search-enabled>true</search-enabled>
|
||||
<search-channels-enabled>true</search-channels-enabled>
|
||||
<voice-search-enabled>true</voice-search-enabled>
|
||||
<notifications-enabled>true</notifications-enabled>
|
||||
<notifications-first-use>false</notifications-first-use>
|
||||
<supports-private-listening>true</supports-private-listening>
|
||||
<supports-private-listening-dtv>true</supports-private-listening-dtv>
|
||||
<supports-warm-standby>true</supports-warm-standby>
|
||||
<headphones-connected>false</headphones-connected>
|
||||
<expert-pq-enabled>0.9</expert-pq-enabled>
|
||||
<supports-ecs-textedit>true</supports-ecs-textedit>
|
||||
<supports-ecs-microphone>true</supports-ecs-microphone>
|
||||
<supports-wake-on-wlan>true</supports-wake-on-wlan>
|
||||
<has-play-on-roku>true</has-play-on-roku>
|
||||
<has-mobile-screensaver>true</has-mobile-screensaver>
|
||||
<support-url>https://www.onntvsupport.com/</support-url>
|
||||
<grandcentral-version>2.9.57</grandcentral-version>
|
||||
<trc-version>3.0</trc-version>
|
||||
<trc-channel-version>2.9.42</trc-channel-version>
|
||||
<davinci-version>2.8.20</davinci-version>
|
||||
<has-wifi-extender>false</has-wifi-extender>
|
||||
<has-wifi-5G-support>true</has-wifi-5G-support>
|
||||
<can-use-wifi-extender>true</can-use-wifi-extender>
|
||||
</device-info>
|
@ -1,73 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<device-info>
|
||||
<udn>015e5555-9000-5555-5555-b0a555555dfb</udn>
|
||||
<serial-number>YN00H5555555</serial-number>
|
||||
<device-id>0S596H055555</device-id>
|
||||
<advertising-id>055555a9-d82b-5c75-b8fe-5555550cb7ee</advertising-id>
|
||||
<vendor-name>Onn</vendor-name>
|
||||
<model-name>100005844</model-name>
|
||||
<model-number>7820X</model-number>
|
||||
<model-region>US</model-region>
|
||||
<is-tv>true</is-tv>
|
||||
<is-stick>false</is-stick>
|
||||
<screen-size>58</screen-size>
|
||||
<panel-id>2</panel-id>
|
||||
<tuner-type>ATSC</tuner-type>
|
||||
<supports-ethernet>true</supports-ethernet>
|
||||
<wifi-mac>d8:13:99:f8:b0:c6</wifi-mac>
|
||||
<wifi-driver>realtek</wifi-driver>
|
||||
<ethernet-mac>d4:3a:2e:07:fd:cb</ethernet-mac>
|
||||
<network-type>wifi</network-type>
|
||||
<network-name>NetworkSSID</network-name>
|
||||
<friendly-device-name>58" Onn Roku TV</friendly-device-name>
|
||||
<friendly-model-name>Onn Roku TV</friendly-model-name>
|
||||
<default-device-name>Onn Roku TV - YN00H5555555</default-device-name>
|
||||
<user-device-name>58" Onn Roku TV</user-device-name>
|
||||
<user-device-location>Living room</user-device-location>
|
||||
<build-number>AT9.20E04502A</build-number>
|
||||
<software-version>9.2.0</software-version>
|
||||
<software-build>4502</software-build>
|
||||
<secure-device>true</secure-device>
|
||||
<language>en</language>
|
||||
<country>US</country>
|
||||
<locale>en_US</locale>
|
||||
<time-zone-auto>true</time-zone-auto>
|
||||
<time-zone>US/Central</time-zone>
|
||||
<time-zone-name>United States/Central</time-zone-name>
|
||||
<time-zone-tz>America/Chicago</time-zone-tz>
|
||||
<time-zone-offset>-300</time-zone-offset>
|
||||
<clock-format>12-hour</clock-format>
|
||||
<uptime>264789</uptime>
|
||||
<power-mode>PowerOn</power-mode>
|
||||
<supports-suspend>true</supports-suspend>
|
||||
<supports-find-remote>true</supports-find-remote>
|
||||
<find-remote-is-possible>false</find-remote-is-possible>
|
||||
<supports-audio-guide>true</supports-audio-guide>
|
||||
<supports-rva>true</supports-rva>
|
||||
<developer-enabled>false</developer-enabled>
|
||||
<keyed-developer-id/>
|
||||
<search-enabled>true</search-enabled>
|
||||
<search-channels-enabled>true</search-channels-enabled>
|
||||
<voice-search-enabled>true</voice-search-enabled>
|
||||
<notifications-enabled>true</notifications-enabled>
|
||||
<notifications-first-use>false</notifications-first-use>
|
||||
<supports-private-listening>true</supports-private-listening>
|
||||
<supports-private-listening-dtv>true</supports-private-listening-dtv>
|
||||
<supports-warm-standby>true</supports-warm-standby>
|
||||
<headphones-connected>false</headphones-connected>
|
||||
<expert-pq-enabled>0.9</expert-pq-enabled>
|
||||
<supports-ecs-textedit>true</supports-ecs-textedit>
|
||||
<supports-ecs-microphone>true</supports-ecs-microphone>
|
||||
<supports-wake-on-wlan>true</supports-wake-on-wlan>
|
||||
<supports-airplay>true</supports-airplay>
|
||||
<has-play-on-roku>true</has-play-on-roku>
|
||||
<has-mobile-screensaver>true</has-mobile-screensaver>
|
||||
<support-url>https://www.onntvsupport.com/</support-url>
|
||||
<grandcentral-version>2.9.57</grandcentral-version>
|
||||
<trc-version>3.0</trc-version>
|
||||
<trc-channel-version>2.9.42</trc-channel-version>
|
||||
<davinci-version>2.8.20</davinci-version>
|
||||
<has-wifi-extender>false</has-wifi-extender>
|
||||
<has-wifi-5G-support>true</has-wifi-5G-support>
|
||||
<can-use-wifi-extender>true</can-use-wifi-extender>
|
||||
</device-info>
|
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<tv-channel>
|
||||
<channel>
|
||||
<number>14.3</number>
|
||||
<name>getTV</name>
|
||||
<type>air-digital</type>
|
||||
<user-hidden>false</user-hidden>
|
||||
<active-input>true</active-input>
|
||||
<signal-state>valid</signal-state>
|
||||
<signal-mode>480i</signal-mode>
|
||||
<signal-quality>20</signal-quality>
|
||||
<signal-strength>-75</signal-strength>
|
||||
<program-title>Airwolf</program-title>
|
||||
<program-description>The team will travel all around the world in order to shut down a global crime ring.</program-description>
|
||||
<program-ratings>TV-14-D-V</program-ratings>
|
||||
<program-analog-audio>none</program-analog-audio>
|
||||
<program-digital-audio>stereo</program-digital-audio>
|
||||
<program-audio-languages>eng</program-audio-languages>
|
||||
<program-audio-formats>AC3</program-audio-formats>
|
||||
<program-audio-language>eng</program-audio-language>
|
||||
<program-audio-format>AC3</program-audio-format>
|
||||
<program-has-cc>true</program-has-cc>
|
||||
</channel>
|
||||
</tv-channel>
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<tv-channels>
|
||||
<channel>
|
||||
<number>1.1</number>
|
||||
<name>WhatsOn</name>
|
||||
<type>air-digital</type>
|
||||
<user-hidden>false</user-hidden>
|
||||
</channel>
|
||||
<channel>
|
||||
<number>1.3</number>
|
||||
<name>QVC</name>
|
||||
<type>air-digital</type>
|
||||
<user-hidden>false</user-hidden>
|
||||
</channel>
|
||||
</tv-channels>
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user