diff --git a/homeassistant/components/androidtv/__init__.py b/homeassistant/components/androidtv/__init__.py index e52e37df88e..81d4a3f0645 100644 --- a/homeassistant/components/androidtv/__init__.py +++ b/homeassistant/components/androidtv/__init__.py @@ -174,7 +174,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: 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.""" reload_opt = False old_options = hass.data[DOMAIN][entry.entry_id][ANDROID_DEV_OPT] diff --git a/homeassistant/components/androidtv/media_player.py b/homeassistant/components/androidtv/media_player.py index a2795da24c6..67da914a06c 100644 --- a/homeassistant/components/androidtv/media_player.py +++ b/homeassistant/components/androidtv/media_player.py @@ -125,37 +125,31 @@ SERVICE_UPLOAD = "upload" DEFAULT_NAME = "Android TV" # Deprecated in Home Assistant 2022.2 -PLATFORM_SCHEMA = cv.deprecated( - vol.All( - PLATFORM_SCHEMA=PLATFORM_SCHEMA.extend( - { - vol.Required(CONF_HOST): cv.string, - 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, - } +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( + { + vol.Required(CONF_HOST): cv.string, + 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, + } ) # Translate from `AndroidTV` / `FireTV` reported state to HA state. diff --git a/tests/components/androidtv/test_config_flow.py b/tests/components/androidtv/test_config_flow.py index 3da1a113887..ee0223300b5 100644 --- a/tests/components/androidtv/test_config_flow.py +++ b/tests/components/androidtv/test_config_flow.py @@ -3,6 +3,8 @@ import json from socket import gaierror from unittest.mock import patch +import pytest + from homeassistant import data_entry_flow from homeassistant.components.androidtv.config_flow import ( APPS_NEW_ID, @@ -92,7 +94,8 @@ class MockConfigDevice: 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.""" flow_result = await hass.config_entries.flow.async_init( 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 -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): """Test import config.""" @@ -179,7 +172,6 @@ async def test_import_data(hass): config_data[CONF_PLATFORM] = DOMAIN config_data[CONF_ADBKEY] = ADBKEY config_data[CONF_TURN_OFF_COMMAND] = "off" - config_data[CONF_STATE_DETECTION_RULES] = {"a": "b"} platform_data = {MP_DOMAIN: config_data} with patch( diff --git a/tests/components/androidtv/test_media_player.py b/tests/components/androidtv/test_media_player.py index f8f08fa2060..d82539471a6 100644 --- a/tests/components/androidtv/test_media_player.py +++ b/tests/components/androidtv/test_media_player.py @@ -163,7 +163,16 @@ async def test_setup_with_properties(hass): 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. "Handles device/service unavailable. Log a warning once when @@ -180,7 +189,6 @@ async def _test_reconnect(hass, caplog, config): patch_key ], patchers.PATCH_KEYGEN, patchers.PATCH_ANDROIDTV_OPEN, patchers.PATCH_SIGNER: 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.helpers.entity_component.async_update_entity(entity_id) @@ -225,10 +233,17 @@ async def _test_reconnect(hass, caplog, config): in caplog.record_tuples[2] ) - return True - -async def _test_adb_shell_returns_none(hass, config): +@pytest.mark.parametrize( + "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`. 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.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): """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 -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.""" config = copy.deepcopy(config0) config[DOMAIN].setdefault(CONF_OPTIONS, {}).update( @@ -436,18 +376,6 @@ async def _test_sources(hass, config0): assert state.attributes["source"] == "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): """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.""" patch_key, entity_id, config_entry = _setup(config) config_entry.add_to_hass(hass) @@ -772,18 +707,6 @@ async def _test_setup_fail(hass, config): state = hass.states.get(entity_id) 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): """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, ) - # patch_shell.assert_called_with(command) state = hass.states.get(entity_id) assert state is not None assert state.attributes["adb_response"] is None