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:
ollo69 2022-01-14 02:05:35 +01:00 committed by GitHub
parent 5a33610739
commit a978661545
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 157 deletions

View file

@ -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]

View file

@ -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.

View file

@ -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(

View file

@ -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