Address late review of Minor AndroidTV config flow (#64088)
* Minor changes for AndroidTV config flow * Add mark.parametrize to media_player tests
This commit is contained in:
parent
5a33610739
commit
a978661545
4 changed files with 65 additions and 157 deletions
|
@ -174,7 +174,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
return unload_ok
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
async def update_listener(hass: HomeAssistant, entry: ConfigEntry):
|
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||||
"""Update when config_entry options update."""
|
"""Update when config_entry options update."""
|
||||||
reload_opt = False
|
reload_opt = False
|
||||||
old_options = hass.data[DOMAIN][entry.entry_id][ANDROID_DEV_OPT]
|
old_options = hass.data[DOMAIN][entry.entry_id][ANDROID_DEV_OPT]
|
||||||
|
|
|
@ -125,37 +125,31 @@ SERVICE_UPLOAD = "upload"
|
||||||
DEFAULT_NAME = "Android TV"
|
DEFAULT_NAME = "Android TV"
|
||||||
|
|
||||||
# Deprecated in Home Assistant 2022.2
|
# Deprecated in Home Assistant 2022.2
|
||||||
PLATFORM_SCHEMA = cv.deprecated(
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||||
vol.All(
|
{
|
||||||
PLATFORM_SCHEMA=PLATFORM_SCHEMA.extend(
|
vol.Required(CONF_HOST): cv.string,
|
||||||
{
|
vol.Optional(CONF_DEVICE_CLASS, default=DEFAULT_DEVICE_CLASS): vol.In(
|
||||||
vol.Required(CONF_HOST): cv.string,
|
DEVICE_CLASSES
|
||||||
vol.Optional(CONF_DEVICE_CLASS, default=DEFAULT_DEVICE_CLASS): vol.In(
|
|
||||||
DEVICE_CLASSES
|
|
||||||
),
|
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
||||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
|
||||||
vol.Optional(CONF_ADBKEY): cv.isfile,
|
|
||||||
vol.Optional(CONF_ADB_SERVER_IP): cv.string,
|
|
||||||
vol.Optional(
|
|
||||||
CONF_ADB_SERVER_PORT, default=DEFAULT_ADB_SERVER_PORT
|
|
||||||
): cv.port,
|
|
||||||
vol.Optional(CONF_GET_SOURCES, default=DEFAULT_GET_SOURCES): cv.boolean,
|
|
||||||
vol.Optional(CONF_APPS, default={}): vol.Schema(
|
|
||||||
{cv.string: vol.Any(cv.string, None)}
|
|
||||||
),
|
|
||||||
vol.Optional(CONF_TURN_ON_COMMAND): cv.string,
|
|
||||||
vol.Optional(CONF_TURN_OFF_COMMAND): cv.string,
|
|
||||||
vol.Optional(CONF_STATE_DETECTION_RULES, default={}): vol.Schema(
|
|
||||||
{cv.string: ha_state_detection_rules_validator(vol.Invalid)}
|
|
||||||
),
|
|
||||||
vol.Optional(
|
|
||||||
CONF_EXCLUDE_UNNAMED_APPS, default=DEFAULT_EXCLUDE_UNNAMED_APPS
|
|
||||||
): cv.boolean,
|
|
||||||
vol.Optional(CONF_SCREENCAP, default=DEFAULT_SCREENCAP): cv.boolean,
|
|
||||||
}
|
|
||||||
),
|
),
|
||||||
)
|
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||||
|
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||||
|
vol.Optional(CONF_ADBKEY): cv.isfile,
|
||||||
|
vol.Optional(CONF_ADB_SERVER_IP): cv.string,
|
||||||
|
vol.Optional(CONF_ADB_SERVER_PORT, default=DEFAULT_ADB_SERVER_PORT): cv.port,
|
||||||
|
vol.Optional(CONF_GET_SOURCES, default=DEFAULT_GET_SOURCES): cv.boolean,
|
||||||
|
vol.Optional(CONF_APPS, default={}): vol.Schema(
|
||||||
|
{cv.string: vol.Any(cv.string, None)}
|
||||||
|
),
|
||||||
|
vol.Optional(CONF_TURN_ON_COMMAND): cv.string,
|
||||||
|
vol.Optional(CONF_TURN_OFF_COMMAND): cv.string,
|
||||||
|
vol.Optional(CONF_STATE_DETECTION_RULES, default={}): vol.Schema(
|
||||||
|
{cv.string: ha_state_detection_rules_validator(vol.Invalid)}
|
||||||
|
),
|
||||||
|
vol.Optional(
|
||||||
|
CONF_EXCLUDE_UNNAMED_APPS, default=DEFAULT_EXCLUDE_UNNAMED_APPS
|
||||||
|
): cv.boolean,
|
||||||
|
vol.Optional(CONF_SCREENCAP, default=DEFAULT_SCREENCAP): cv.boolean,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Translate from `AndroidTV` / `FireTV` reported state to HA state.
|
# Translate from `AndroidTV` / `FireTV` reported state to HA state.
|
||||||
|
|
|
@ -3,6 +3,8 @@ import json
|
||||||
from socket import gaierror
|
from socket import gaierror
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant import data_entry_flow
|
from homeassistant import data_entry_flow
|
||||||
from homeassistant.components.androidtv.config_flow import (
|
from homeassistant.components.androidtv.config_flow import (
|
||||||
APPS_NEW_ID,
|
APPS_NEW_ID,
|
||||||
|
@ -92,7 +94,8 @@ class MockConfigDevice:
|
||||||
self.available = False
|
self.available = False
|
||||||
|
|
||||||
|
|
||||||
async def _test_user(hass, config):
|
@pytest.mark.parametrize("config", [CONFIG_PYTHON_ADB, CONFIG_ADB_SERVER])
|
||||||
|
async def test_user(hass, config):
|
||||||
"""Test user config."""
|
"""Test user config."""
|
||||||
flow_result = await hass.config_entries.flow.async_init(
|
flow_result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER, "show_advanced_options": True}
|
DOMAIN, context={"source": SOURCE_USER, "show_advanced_options": True}
|
||||||
|
@ -117,16 +120,6 @@ async def _test_user(hass, config):
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_user_python_adb(hass):
|
|
||||||
"""Test user config for Python ADB."""
|
|
||||||
await _test_user(hass, CONFIG_PYTHON_ADB)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_user_adb_server(hass):
|
|
||||||
"""Test user config for ADB server."""
|
|
||||||
await _test_user(hass, CONFIG_ADB_SERVER)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_import(hass):
|
async def test_import(hass):
|
||||||
"""Test import config."""
|
"""Test import config."""
|
||||||
|
|
||||||
|
@ -179,7 +172,6 @@ async def test_import_data(hass):
|
||||||
config_data[CONF_PLATFORM] = DOMAIN
|
config_data[CONF_PLATFORM] = DOMAIN
|
||||||
config_data[CONF_ADBKEY] = ADBKEY
|
config_data[CONF_ADBKEY] = ADBKEY
|
||||||
config_data[CONF_TURN_OFF_COMMAND] = "off"
|
config_data[CONF_TURN_OFF_COMMAND] = "off"
|
||||||
config_data[CONF_STATE_DETECTION_RULES] = {"a": "b"}
|
|
||||||
platform_data = {MP_DOMAIN: config_data}
|
platform_data = {MP_DOMAIN: config_data}
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
|
|
|
@ -163,7 +163,16 @@ async def test_setup_with_properties(hass):
|
||||||
assert state is not None
|
assert state is not None
|
||||||
|
|
||||||
|
|
||||||
async def _test_reconnect(hass, caplog, config):
|
@pytest.mark.parametrize(
|
||||||
|
"config",
|
||||||
|
[
|
||||||
|
CONFIG_ANDROIDTV_PYTHON_ADB,
|
||||||
|
CONFIG_FIRETV_PYTHON_ADB,
|
||||||
|
CONFIG_ANDROIDTV_ADB_SERVER,
|
||||||
|
CONFIG_FIRETV_ADB_SERVER,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_reconnect(hass, caplog, config):
|
||||||
"""Test that the error and reconnection attempts are logged correctly.
|
"""Test that the error and reconnection attempts are logged correctly.
|
||||||
|
|
||||||
"Handles device/service unavailable. Log a warning once when
|
"Handles device/service unavailable. Log a warning once when
|
||||||
|
@ -180,7 +189,6 @@ async def _test_reconnect(hass, caplog, config):
|
||||||
patch_key
|
patch_key
|
||||||
], patchers.PATCH_KEYGEN, patchers.PATCH_ANDROIDTV_OPEN, patchers.PATCH_SIGNER:
|
], patchers.PATCH_KEYGEN, patchers.PATCH_ANDROIDTV_OPEN, patchers.PATCH_SIGNER:
|
||||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
# assert await async_setup_component(hass, DOMAIN, config)
|
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
await hass.helpers.entity_component.async_update_entity(entity_id)
|
await hass.helpers.entity_component.async_update_entity(entity_id)
|
||||||
|
@ -225,10 +233,17 @@ async def _test_reconnect(hass, caplog, config):
|
||||||
in caplog.record_tuples[2]
|
in caplog.record_tuples[2]
|
||||||
)
|
)
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
async def _test_adb_shell_returns_none(hass, config):
|
"config",
|
||||||
|
[
|
||||||
|
CONFIG_ANDROIDTV_PYTHON_ADB,
|
||||||
|
CONFIG_FIRETV_PYTHON_ADB,
|
||||||
|
CONFIG_ANDROIDTV_ADB_SERVER,
|
||||||
|
CONFIG_FIRETV_ADB_SERVER,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_adb_shell_returns_none(hass, config):
|
||||||
"""Test the case that the ADB shell command returns `None`.
|
"""Test the case that the ADB shell command returns `None`.
|
||||||
|
|
||||||
The state should be `None` and the device should be unavailable.
|
The state should be `None` and the device should be unavailable.
|
||||||
|
@ -256,88 +271,6 @@ async def _test_adb_shell_returns_none(hass, config):
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.state == STATE_UNAVAILABLE
|
assert state.state == STATE_UNAVAILABLE
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
async def test_reconnect_androidtv_python_adb(hass, caplog):
|
|
||||||
"""Test that the error and reconnection attempts are logged correctly.
|
|
||||||
|
|
||||||
* Device type: Android TV
|
|
||||||
* ADB connection method: Python ADB implementation
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_reconnect(hass, caplog, CONFIG_ANDROIDTV_PYTHON_ADB)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_adb_shell_returns_none_androidtv_python_adb(hass):
|
|
||||||
"""Test the case that the ADB shell command returns `None`.
|
|
||||||
|
|
||||||
* Device type: Android TV
|
|
||||||
* ADB connection method: Python ADB implementation
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_adb_shell_returns_none(hass, CONFIG_ANDROIDTV_PYTHON_ADB)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_reconnect_firetv_python_adb(hass, caplog):
|
|
||||||
"""Test that the error and reconnection attempts are logged correctly.
|
|
||||||
|
|
||||||
* Device type: Fire TV
|
|
||||||
* ADB connection method: Python ADB implementation
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_reconnect(hass, caplog, CONFIG_FIRETV_PYTHON_ADB)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_adb_shell_returns_none_firetv_python_adb(hass):
|
|
||||||
"""Test the case that the ADB shell command returns `None`.
|
|
||||||
|
|
||||||
* Device type: Fire TV
|
|
||||||
* ADB connection method: Python ADB implementation
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_adb_shell_returns_none(hass, CONFIG_FIRETV_PYTHON_ADB)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_reconnect_androidtv_adb_server(hass, caplog):
|
|
||||||
"""Test that the error and reconnection attempts are logged correctly.
|
|
||||||
|
|
||||||
* Device type: Android TV
|
|
||||||
* ADB connection method: ADB server
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_reconnect(hass, caplog, CONFIG_ANDROIDTV_ADB_SERVER)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_adb_shell_returns_none_androidtv_adb_server(hass):
|
|
||||||
"""Test the case that the ADB shell command returns `None`.
|
|
||||||
|
|
||||||
* Device type: Android TV
|
|
||||||
* ADB connection method: ADB server
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_adb_shell_returns_none(hass, CONFIG_ANDROIDTV_ADB_SERVER)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_reconnect_firetv_adb_server(hass, caplog):
|
|
||||||
"""Test that the error and reconnection attempts are logged correctly.
|
|
||||||
|
|
||||||
* Device type: Fire TV
|
|
||||||
* ADB connection method: ADB server
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_reconnect(hass, caplog, CONFIG_FIRETV_ADB_SERVER)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_adb_shell_returns_none_firetv_adb_server(hass):
|
|
||||||
"""Test the case that the ADB shell command returns `None`.
|
|
||||||
|
|
||||||
* Device type: Fire TV
|
|
||||||
* ADB connection method: ADB server
|
|
||||||
|
|
||||||
"""
|
|
||||||
assert await _test_adb_shell_returns_none(hass, CONFIG_FIRETV_ADB_SERVER)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_setup_with_adbkey(hass):
|
async def test_setup_with_adbkey(hass):
|
||||||
"""Test that setup succeeds when using an ADB key."""
|
"""Test that setup succeeds when using an ADB key."""
|
||||||
|
@ -359,7 +292,14 @@ async def test_setup_with_adbkey(hass):
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
async def _test_sources(hass, config0):
|
@pytest.mark.parametrize(
|
||||||
|
"config0",
|
||||||
|
[
|
||||||
|
CONFIG_ANDROIDTV_ADB_SERVER,
|
||||||
|
CONFIG_FIRETV_ADB_SERVER,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_sources(hass, config0):
|
||||||
"""Test that sources (i.e., apps) are handled correctly for Android TV and Fire TV devices."""
|
"""Test that sources (i.e., apps) are handled correctly for Android TV and Fire TV devices."""
|
||||||
config = copy.deepcopy(config0)
|
config = copy.deepcopy(config0)
|
||||||
config[DOMAIN].setdefault(CONF_OPTIONS, {}).update(
|
config[DOMAIN].setdefault(CONF_OPTIONS, {}).update(
|
||||||
|
@ -436,18 +376,6 @@ async def _test_sources(hass, config0):
|
||||||
assert state.attributes["source"] == "com.app.test2"
|
assert state.attributes["source"] == "com.app.test2"
|
||||||
assert sorted(state.attributes["source_list"]) == ["TEST 1", "com.app.test2"]
|
assert sorted(state.attributes["source_list"]) == ["TEST 1", "com.app.test2"]
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
async def test_androidtv_sources(hass):
|
|
||||||
"""Test that sources (i.e., apps) are handled correctly for Android TV devices."""
|
|
||||||
assert await _test_sources(hass, CONFIG_ANDROIDTV_ADB_SERVER)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_firetv_sources(hass):
|
|
||||||
"""Test that sources (i.e., apps) are handled correctly for Fire TV devices."""
|
|
||||||
assert await _test_sources(hass, CONFIG_FIRETV_ADB_SERVER)
|
|
||||||
|
|
||||||
|
|
||||||
async def _test_exclude_sources(hass, config0, expected_sources):
|
async def _test_exclude_sources(hass, config0, expected_sources):
|
||||||
"""Test that sources (i.e., apps) are handled correctly when the `exclude_unnamed_apps` config parameter is provided."""
|
"""Test that sources (i.e., apps) are handled correctly when the `exclude_unnamed_apps` config parameter is provided."""
|
||||||
|
@ -756,7 +684,14 @@ async def test_firetv_select_source_stop_hidden(hass):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def _test_setup_fail(hass, config):
|
@pytest.mark.parametrize(
|
||||||
|
"config",
|
||||||
|
[
|
||||||
|
CONFIG_ANDROIDTV_PYTHON_ADB,
|
||||||
|
CONFIG_FIRETV_PYTHON_ADB,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_setup_fail(hass, config):
|
||||||
"""Test that the entity is not created when the ADB connection is not established."""
|
"""Test that the entity is not created when the ADB connection is not established."""
|
||||||
patch_key, entity_id, config_entry = _setup(config)
|
patch_key, entity_id, config_entry = _setup(config)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
@ -772,18 +707,6 @@ async def _test_setup_fail(hass, config):
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state is None
|
assert state is None
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
async def test_setup_fail_androidtv(hass):
|
|
||||||
"""Test that the Android TV entity is not created when the ADB connection is not established."""
|
|
||||||
assert await _test_setup_fail(hass, CONFIG_ANDROIDTV_PYTHON_ADB)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_setup_fail_firetv(hass):
|
|
||||||
"""Test that the Fire TV entity is not created when the ADB connection is not established."""
|
|
||||||
assert await _test_setup_fail(hass, CONFIG_FIRETV_PYTHON_ADB)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_adb_command(hass):
|
async def test_adb_command(hass):
|
||||||
"""Test sending a command via the `androidtv.adb_command` service."""
|
"""Test sending a command via the `androidtv.adb_command` service."""
|
||||||
|
@ -838,7 +761,6 @@ async def test_adb_command_unicode_decode_error(hass):
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# patch_shell.assert_called_with(command)
|
|
||||||
state = hass.states.get(entity_id)
|
state = hass.states.get(entity_id)
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.attributes["adb_response"] is None
|
assert state.attributes["adb_response"] is None
|
||||||
|
|
Loading…
Add table
Reference in a new issue