mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
more tweaks
This commit is contained in:
parent
1122217326
commit
dd2b092b70
41
tests/components/roku/snapshots/test_init.ambr
Normal file
41
tests/components/roku/snapshots/test_init.ambr
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_device_info
|
||||||
|
DeviceRegistryEntrySnapshot({
|
||||||
|
'area_id': None,
|
||||||
|
'config_entries': <ANY>,
|
||||||
|
'configuration_url': None,
|
||||||
|
'connections': set({
|
||||||
|
tuple(
|
||||||
|
'mac',
|
||||||
|
'b0:a7:37:96:4d:fa',
|
||||||
|
),
|
||||||
|
tuple(
|
||||||
|
'mac',
|
||||||
|
'b0:a7:37:96:4d:fb',
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
'disabled_by': None,
|
||||||
|
'entry_type': None,
|
||||||
|
'hw_version': '4200X',
|
||||||
|
'id': <ANY>,
|
||||||
|
'identifiers': set({
|
||||||
|
tuple(
|
||||||
|
'roku',
|
||||||
|
'1GU48T017973',
|
||||||
|
),
|
||||||
|
}),
|
||||||
|
'is_new': False,
|
||||||
|
'labels': set({
|
||||||
|
}),
|
||||||
|
'manufacturer': 'Roku',
|
||||||
|
'model': 'Roku 3',
|
||||||
|
'model_id': None,
|
||||||
|
'name': 'My Roku 3',
|
||||||
|
'name_by_user': None,
|
||||||
|
'primary_config_entry': <ANY>,
|
||||||
|
'serial_number': None,
|
||||||
|
'suggested_area': None,
|
||||||
|
'sw_version': '7.5.0',
|
||||||
|
'via_device_id': None,
|
||||||
|
})
|
||||||
|
# ---
|
@ -50,7 +50,7 @@
|
|||||||
'app_id': '12',
|
'app_id': '12',
|
||||||
'app_name': 'Netflix',
|
'app_name': 'Netflix',
|
||||||
'device_class': 'receiver',
|
'device_class': 'receiver',
|
||||||
'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=302b9654ec1a8c4fa9872fba3795edda5c07aa9c4d9a5231bf967376c91ceb1e&cache=2cab7007c60e13ef',
|
'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=fa35b32224ca3c83235d621f684a24389bf26b4acd4f2daff53ae76433427864&cache=2cab7007c60e13ef',
|
||||||
'friendly_name': 'My Roku 3',
|
'friendly_name': 'My Roku 3',
|
||||||
'media_content_type': <MediaType.APP: 'app'>,
|
'media_content_type': <MediaType.APP: 'app'>,
|
||||||
'source': 'Netflix',
|
'source': 'Netflix',
|
||||||
@ -199,7 +199,7 @@
|
|||||||
'app_id': '74519',
|
'app_id': '74519',
|
||||||
'app_name': "Pluto TV - It's Free TV",
|
'app_name': "Pluto TV - It's Free TV",
|
||||||
'device_class': 'receiver',
|
'device_class': 'receiver',
|
||||||
'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=7c360550a5a5274ff9e9e79ebc73ae1044c37851e47a0ff58cd36cab59eda988&cache=be54f0f123f7d91f',
|
'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=d91134eba0c155326d21ca70ef3c57b0e47cfb8da439b64a03016b40668ee3f7&cache=be54f0f123f7d91f',
|
||||||
'friendly_name': 'My Roku 3',
|
'friendly_name': 'My Roku 3',
|
||||||
'media_content_type': <MediaType.APP: 'app'>,
|
'media_content_type': <MediaType.APP: 'app'>,
|
||||||
'media_duration': 6496,
|
'media_duration': 6496,
|
||||||
@ -278,7 +278,7 @@
|
|||||||
'app_id': '74519',
|
'app_id': '74519',
|
||||||
'app_name': "Pluto TV - It's Free TV",
|
'app_name': "Pluto TV - It's Free TV",
|
||||||
'device_class': 'receiver',
|
'device_class': 'receiver',
|
||||||
'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=0b7d72bb6e62507f8efe49db9bbca12f4b803e52969cdd797cd8121b74f2de27&cache=be54f0f123f7d91f',
|
'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=3961658cb01e3e6f9d3194a0487e1043616ede6c9ef18c7033650e09160226ec&cache=be54f0f123f7d91f',
|
||||||
'friendly_name': 'My Roku 3',
|
'friendly_name': 'My Roku 3',
|
||||||
'media_content_type': <MediaType.APP: 'app'>,
|
'media_content_type': <MediaType.APP: 'app'>,
|
||||||
'media_duration': 6496,
|
'media_duration': 6496,
|
||||||
@ -506,7 +506,7 @@
|
|||||||
'app_id': 'tvinput.dtv',
|
'app_id': 'tvinput.dtv',
|
||||||
'app_name': 'Antenna TV',
|
'app_name': 'Antenna TV',
|
||||||
'device_class': 'tv',
|
'device_class': 'tv',
|
||||||
'entity_picture': '/api/media_player_proxy/media_player.58_onn_roku_tv?token=0304dee053f24675c326f5cda374eb4cebf7561bc8c3da18561632f5fda38ae6&cache=545b6ca11153d83a',
|
'entity_picture': '/api/media_player_proxy/media_player.58_onn_roku_tv?token=cc580699c8223d0f71d05c4de40776ae72df5981efeb24b5ee5725b19dd8b9b7&cache=545b6ca11153d83a',
|
||||||
'friendly_name': '58" Onn Roku TV',
|
'friendly_name': '58" Onn Roku TV',
|
||||||
'media_channel': 'getTV (14.3)',
|
'media_channel': 'getTV (14.3)',
|
||||||
'media_content_type': <MediaType.CHANNEL: 'channel'>,
|
'media_content_type': <MediaType.CHANNEL: 'channel'>,
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
"""Test the Roku config flow."""
|
"""Test the Roku config flow."""
|
||||||
|
|
||||||
import dataclasses
|
|
||||||
from unittest.mock import AsyncMock, MagicMock
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from rokuecp import Device as RokuDevice, RokuConnectionError
|
from rokuecp import (
|
||||||
|
Device as RokuDevice,
|
||||||
|
RokuConnectionError,
|
||||||
|
RokuConnectionTimeoutError,
|
||||||
|
)
|
||||||
|
|
||||||
from homeassistant.components.roku.const import CONF_PLAY_MEDIA_APP_ID, DOMAIN
|
from homeassistant.components.roku.const import CONF_PLAY_MEDIA_APP_ID, DOMAIN
|
||||||
from homeassistant.config_entries import (
|
from homeassistant.config_entries import (
|
||||||
@ -31,39 +34,6 @@ from tests.common import MockConfigEntry
|
|||||||
RECONFIGURE_HOST = "192.168.1.190"
|
RECONFIGURE_HOST = "192.168.1.190"
|
||||||
|
|
||||||
|
|
||||||
async def test_duplicate_error(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
mock_config_entry: MockConfigEntry,
|
|
||||||
mock_roku_config_flow: MagicMock,
|
|
||||||
) -> None:
|
|
||||||
"""Test that errors are shown when duplicates are added."""
|
|
||||||
mock_config_entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
|
||||||
assert result["reason"] == "already_configured"
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
|
||||||
assert result["reason"] == "already_configured"
|
|
||||||
|
|
||||||
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
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
|
||||||
assert result["reason"] == "already_configured"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_form(
|
async def test_form(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_roku_config_flow: MagicMock,
|
mock_roku_config_flow: MagicMock,
|
||||||
@ -73,6 +43,9 @@ async def test_form(
|
|||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
|
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
|
|
||||||
@ -80,6 +53,7 @@ async def test_form(
|
|||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id=result["flow_id"], user_input=user_input
|
flow_id=result["flow_id"], user_input=user_input
|
||||||
)
|
)
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
@ -92,77 +66,100 @@ async def test_form(
|
|||||||
assert result["result"].unique_id == "1GU48T017973"
|
assert result["result"].unique_id == "1GU48T017973"
|
||||||
|
|
||||||
|
|
||||||
async def test_form_cannot_connect(
|
@pytest.mark.parametrize(
|
||||||
hass: HomeAssistant, mock_roku_config_flow: MagicMock
|
("error", "reason"),
|
||||||
|
[
|
||||||
|
(RokuConnectionError, "cannot_connect"),
|
||||||
|
(RokuConnectionTimeoutError, "cannot_connect"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_form_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_roku_config_flow: MagicMock,
|
||||||
|
error: Exception,
|
||||||
|
reason: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we handle cannot connect roku error."""
|
"""Test we handle usrr flow on error."""
|
||||||
mock_roku_config_flow.update.side_effect = RokuConnectionError
|
mock_roku_config_flow.update.side_effect = error
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
|
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id=result["flow_id"], user_input={CONF_HOST: HOST}
|
flow_id=result["flow_id"], user_input={CONF_HOST: HOST}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["errors"] == {"base": "cannot_connect"}
|
assert result["errors"] == {"base": reason}
|
||||||
|
|
||||||
|
mock_roku_config_flow.update.side_effect = None
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_configure(
|
||||||
|
flow_id=result["flow_id"], user_input={CONF_HOST: HOST}
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
|
|
||||||
|
|
||||||
async def test_form_unknown_error(
|
async def test_form_unknown_error(
|
||||||
hass: HomeAssistant, mock_roku_config_flow: MagicMock
|
hass: HomeAssistant, mock_roku_config_flow: MagicMock
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test we handle unknown error."""
|
"""Test we handle user flow on unknown error."""
|
||||||
mock_roku_config_flow.update.side_effect = Exception
|
mock_roku_config_flow.update.side_effect = Exception
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
|
DOMAIN, context={CONF_SOURCE: SOURCE_USER}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
user_input = {CONF_HOST: HOST}
|
user_input = {CONF_HOST: HOST}
|
||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id=result["flow_id"], user_input=user_input
|
flow_id=result["flow_id"], user_input=user_input
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
await hass.async_block_till_done()
|
||||||
assert result["reason"] == "unknown"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_homekit_cannot_connect(
|
|
||||||
hass: HomeAssistant, mock_roku_config_flow: MagicMock
|
|
||||||
) -> None:
|
|
||||||
"""Test we abort homekit flow on connection error."""
|
|
||||||
mock_roku_config_flow.update.side_effect = RokuConnectionError
|
|
||||||
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
|
||||||
assert result["reason"] == "cannot_connect"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_homekit_unknown_error(
|
|
||||||
hass: HomeAssistant, mock_roku_config_flow: MagicMock
|
|
||||||
) -> None:
|
|
||||||
"""Test we abort homekit flow on unknown error."""
|
|
||||||
mock_roku_config_flow.update.side_effect = Exception
|
|
||||||
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == "unknown"
|
assert result["reason"] == "unknown"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_form_duplicate_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_roku_config_flow: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test that we handle user flow on duplicates."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("mock_device", ["rokutv-7820x"], indirect=True)
|
@pytest.mark.parametrize("mock_device", ["rokutv-7820x"], indirect=True)
|
||||||
async def test_homekit_discovery(
|
async def test_homekit_discovery(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -170,11 +167,13 @@ async def test_homekit_discovery(
|
|||||||
mock_setup_entry: None,
|
mock_setup_entry: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the homekit discovery flow."""
|
"""Test the homekit discovery flow."""
|
||||||
discovery_info = dataclasses.replace(MOCK_HOMEKIT_DISCOVERY_INFO)
|
discovery_info = MOCK_HOMEKIT_DISCOVERY_INFO
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={CONF_SOURCE: SOURCE_HOMEKIT}, data=discovery_info
|
DOMAIN, context={CONF_SOURCE: SOURCE_HOMEKIT}, data=discovery_info
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["step_id"] == "discovery_confirm"
|
assert result["step_id"] == "discovery_confirm"
|
||||||
assert result["description_placeholders"] == {CONF_NAME: NAME_ROKUTV}
|
assert result["description_placeholders"] == {CONF_NAME: NAME_ROKUTV}
|
||||||
@ -182,70 +181,80 @@ async def test_homekit_discovery(
|
|||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id=result["flow_id"], user_input={}
|
flow_id=result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
assert result["title"] == NAME_ROKUTV
|
assert result["title"] == NAME_ROKUTV
|
||||||
|
|
||||||
|
assert "result" in result
|
||||||
|
assert result["result"].unique_id == "YN00H5555555"
|
||||||
|
|
||||||
assert "data" in result
|
assert "data" in result
|
||||||
assert result["data"][CONF_HOST] == HOMEKIT_HOST
|
assert result["data"][CONF_HOST] == HOMEKIT_HOST
|
||||||
assert result["data"][CONF_NAME] == NAME_ROKUTV
|
assert result["data"][CONF_NAME] == NAME_ROKUTV
|
||||||
|
|
||||||
# test abort on existing host
|
|
||||||
discovery_info = dataclasses.replace(MOCK_HOMEKIT_DISCOVERY_INFO)
|
@pytest.mark.parametrize(
|
||||||
|
("error", "reason"),
|
||||||
|
[
|
||||||
|
(RokuConnectionError, "cannot_connect"),
|
||||||
|
(RokuConnectionTimeoutError, "cannot_connect"),
|
||||||
|
(Exception, "unknown"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_homekit_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_roku_config_flow: MagicMock,
|
||||||
|
error: Exception,
|
||||||
|
reason: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test we abort Homekit flow on error."""
|
||||||
|
mock_roku_config_flow.update.side_effect = error
|
||||||
|
|
||||||
|
discovery_info = MOCK_HOMEKIT_DISCOVERY_INFO
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={CONF_SOURCE: SOURCE_HOMEKIT}, data=discovery_info
|
DOMAIN, context={CONF_SOURCE: SOURCE_HOMEKIT}, data=discovery_info
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == reason
|
||||||
|
|
||||||
|
|
||||||
|
async def test_homekit_duplicate_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_roku_config_flow: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test that we handle Homekit flow on duplicates."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
discovery_info = MOCK_HOMEKIT_DISCOVERY_INFO
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={CONF_SOURCE: SOURCE_HOMEKIT}, data=discovery_info
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == "already_configured"
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_ssdp_cannot_connect(
|
|
||||||
hass: HomeAssistant, mock_roku_config_flow: MagicMock
|
|
||||||
) -> None:
|
|
||||||
"""Test we abort SSDP flow on connection error."""
|
|
||||||
mock_roku_config_flow.update.side_effect = RokuConnectionError
|
|
||||||
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
|
||||||
assert result["reason"] == "cannot_connect"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_ssdp_unknown_error(
|
|
||||||
hass: HomeAssistant, mock_roku_config_flow: MagicMock
|
|
||||||
) -> None:
|
|
||||||
"""Test we abort SSDP flow on unknown error."""
|
|
||||||
mock_roku_config_flow.update.side_effect = Exception
|
|
||||||
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
|
||||||
assert result["reason"] == "unknown"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_ssdp_discovery(
|
async def test_ssdp_discovery(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_roku_config_flow: MagicMock,
|
mock_roku_config_flow: MagicMock,
|
||||||
mock_setup_entry: None,
|
mock_setup_entry: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the SSDP discovery flow."""
|
"""Test the SSDP discovery flow."""
|
||||||
discovery_info = dataclasses.replace(MOCK_SSDP_DISCOVERY_INFO)
|
discovery_info = MOCK_SSDP_DISCOVERY_INFO
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={CONF_SOURCE: SOURCE_SSDP}, data=discovery_info
|
DOMAIN, context={CONF_SOURCE: SOURCE_SSDP}, data=discovery_info
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["step_id"] == "discovery_confirm"
|
assert result["step_id"] == "discovery_confirm"
|
||||||
assert result["description_placeholders"] == {CONF_NAME: UPNP_FRIENDLY_NAME}
|
assert result["description_placeholders"] == {CONF_NAME: UPNP_FRIENDLY_NAME}
|
||||||
@ -253,16 +262,69 @@ async def test_ssdp_discovery(
|
|||||||
result = await hass.config_entries.flow.async_configure(
|
result = await hass.config_entries.flow.async_configure(
|
||||||
flow_id=result["flow_id"], user_input={}
|
flow_id=result["flow_id"], user_input={}
|
||||||
)
|
)
|
||||||
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.CREATE_ENTRY
|
assert result["type"] is FlowResultType.CREATE_ENTRY
|
||||||
assert result["title"] == UPNP_FRIENDLY_NAME
|
assert result["title"] == UPNP_FRIENDLY_NAME
|
||||||
|
|
||||||
|
assert "result" in result
|
||||||
|
assert result["result"].unique_id == "1GU48T017973"
|
||||||
|
|
||||||
assert result["data"]
|
assert result["data"]
|
||||||
assert result["data"][CONF_HOST] == HOST
|
assert result["data"][CONF_HOST] == HOST
|
||||||
assert result["data"][CONF_NAME] == UPNP_FRIENDLY_NAME
|
assert result["data"][CONF_NAME] == UPNP_FRIENDLY_NAME
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("error", "reason"),
|
||||||
|
[
|
||||||
|
(RokuConnectionError, "cannot_connect"),
|
||||||
|
(RokuConnectionTimeoutError, "cannot_connect"),
|
||||||
|
(Exception, "unknown"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_ssdp_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_roku_config_flow: MagicMock,
|
||||||
|
error: Exception,
|
||||||
|
reason: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test we abort SSDP flow on error."""
|
||||||
|
mock_roku_config_flow.update.side_effect = error
|
||||||
|
|
||||||
|
discovery_info = MOCK_SSDP_DISCOVERY_INFO
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={CONF_SOURCE: SOURCE_SSDP},
|
||||||
|
data=discovery_info,
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == reason
|
||||||
|
|
||||||
|
|
||||||
|
async def test_ssdp_duplicate_error(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_config_entry: MockConfigEntry,
|
||||||
|
mock_roku_config_flow: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test that we handle SSDP flow on duplicates."""
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
discovery_info = MOCK_SSDP_DISCOVERY_INFO
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={CONF_SOURCE: SOURCE_SSDP}, data=discovery_info
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result["type"] is FlowResultType.ABORT
|
||||||
|
assert result["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow(
|
async def test_options_flow(
|
||||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -271,6 +333,8 @@ async def test_options_flow(
|
|||||||
|
|
||||||
result = await hass.config_entries.options.async_init(mock_config_entry.entry_id)
|
result = await hass.config_entries.options.async_init(mock_config_entry.entry_id)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result.get("type") is FlowResultType.FORM
|
assert result.get("type") is FlowResultType.FORM
|
||||||
assert result.get("step_id") == "init"
|
assert result.get("step_id") == "init"
|
||||||
|
|
||||||
@ -279,6 +343,8 @@ async def test_options_flow(
|
|||||||
user_input={CONF_PLAY_MEDIA_APP_ID: "782875"},
|
user_input={CONF_PLAY_MEDIA_APP_ID: "782875"},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result2.get("type") is FlowResultType.CREATE_ENTRY
|
assert result2.get("type") is FlowResultType.CREATE_ENTRY
|
||||||
assert result2.get("data") == {
|
assert result2.get("data") == {
|
||||||
CONF_PLAY_MEDIA_APP_ID: "782875",
|
CONF_PLAY_MEDIA_APP_ID: "782875",
|
||||||
@ -312,6 +378,8 @@ async def test_reconfigure_flow(
|
|||||||
"""Test reconfigure flow."""
|
"""Test reconfigure flow."""
|
||||||
result = await _start_reconfigure_flow(hass, mock_config_entry)
|
result = await _start_reconfigure_flow(hass, mock_config_entry)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == "reconfigure_successful"
|
assert result["reason"] == "reconfigure_successful"
|
||||||
|
|
||||||
@ -334,5 +402,7 @@ async def test_reconfigure_unique_id_mismatch(
|
|||||||
|
|
||||||
result = await _start_reconfigure_flow(hass, mock_config_entry)
|
result = await _start_reconfigure_flow(hass, mock_config_entry)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert result["type"] is FlowResultType.ABORT
|
assert result["type"] is FlowResultType.ABORT
|
||||||
assert result["reason"] == "wrong_device"
|
assert result["reason"] == "wrong_device"
|
||||||
|
@ -3,13 +3,30 @@
|
|||||||
from unittest.mock import AsyncMock, MagicMock, patch
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
from rokuecp import RokuConnectionError
|
from rokuecp import RokuConnectionError
|
||||||
|
from syrupy import SnapshotAssertion
|
||||||
|
|
||||||
|
from homeassistant.components.roku.const import DOMAIN
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
|
||||||
|
async def test_device_info(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
|
device_registry: dr.DeviceRegistry,
|
||||||
|
init_integration: MockConfigEntry,
|
||||||
|
) -> None:
|
||||||
|
"""Test device registry integration."""
|
||||||
|
device_entry = device_registry.async_get_device(
|
||||||
|
identifiers={(DOMAIN, init_integration.unique_id)}
|
||||||
|
)
|
||||||
|
assert device_entry is not None
|
||||||
|
assert device_entry == snapshot
|
||||||
|
|
||||||
|
|
||||||
@patch(
|
@patch(
|
||||||
"homeassistant.components.roku.coordinator.Roku._request",
|
"homeassistant.components.roku.coordinator.Roku._request",
|
||||||
side_effect=RokuConnectionError,
|
side_effect=RokuConnectionError,
|
||||||
|
@ -57,7 +57,6 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.core_config import async_process_ha_core_config
|
from homeassistant.core_config import async_process_ha_core_config
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util import dt as dt_util
|
|
||||||
|
|
||||||
from . import setup_integration
|
from . import setup_integration
|
||||||
|
|
||||||
@ -109,24 +108,19 @@ async def test_availability(
|
|||||||
error: RokuError,
|
error: RokuError,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test entity availability."""
|
"""Test entity availability."""
|
||||||
now = dt_util.utcnow()
|
|
||||||
future = now + timedelta(minutes=1)
|
|
||||||
|
|
||||||
mock_config_entry.add_to_hass(hass)
|
mock_config_entry.add_to_hass(hass)
|
||||||
freezer.move_to(now)
|
|
||||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
freezer.move_to(future)
|
freezer.tick(timedelta(minutes=1))
|
||||||
mock_roku.update.side_effect = error
|
mock_roku.update.side_effect = error
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_UNAVAILABLE
|
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
future += timedelta(minutes=1)
|
freezer.tick(timedelta(minutes=1))
|
||||||
freezer.move_to(future)
|
|
||||||
mock_roku.update.side_effect = None
|
mock_roku.update.side_effect = None
|
||||||
async_fire_time_changed(hass, future)
|
async_fire_time_changed(hass)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_IDLE
|
assert hass.states.get(MAIN_ENTITY_ID).state == STATE_IDLE
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user