Fix webostv live TV source missing when configuring sources (#65243)

This commit is contained in:
Shay Levy 2022-01-30 23:05:30 +02:00 committed by GitHub
parent 75b37bee3d
commit 9825111c8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 113 additions and 66 deletions

View File

@ -23,6 +23,7 @@ from homeassistant.helpers import config_validation as cv
from . import async_control_connect
from .const import CONF_SOURCES, DEFAULT_NAME, DOMAIN, WEBOSTV_EXCEPTIONS
from .helpers import async_get_sources
DATA_SCHEMA = vol.Schema(
{
@ -199,20 +200,3 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
return self.async_show_form(
step_id="init", data_schema=options_schema, errors=errors
)
async def async_get_sources(host: str, key: str) -> list[str]:
"""Construct sources list."""
try:
client = await async_control_connect(host, key)
except WEBOSTV_EXCEPTIONS:
return []
return list(
dict.fromkeys( # Preserve order when filtering duplicates
[
*(app["title"] for app in client.apps.values()),
*(app["label"] for app in client.inputs.values()),
]
)
)

View File

@ -6,8 +6,8 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.device_registry import DeviceEntry
from . import WebOsClientWrapper
from .const import DATA_CONFIG_ENTRY, DOMAIN
from . import WebOsClientWrapper, async_control_connect
from .const import DATA_CONFIG_ENTRY, DOMAIN, LIVE_TV_APP_ID, WEBOSTV_EXCEPTIONS
@callback
@ -81,3 +81,29 @@ def async_get_client_wrapper_by_device_entry(
)
return wrapper
async def async_get_sources(host: str, key: str) -> list[str]:
"""Construct sources list."""
try:
client = await async_control_connect(host, key)
except WEBOSTV_EXCEPTIONS:
return []
sources = []
found_live_tv = False
for app in client.apps.values():
sources.append(app["title"])
if app["id"] == LIVE_TV_APP_ID:
found_live_tv = True
for source in client.inputs.values():
sources.append(source["label"])
if source["appId"] == LIVE_TV_APP_ID:
found_live_tv = True
if not found_live_tv:
sources.append("Live TV")
# Preserve order when filtering duplicates
return list(dict.fromkeys(sources))

View File

@ -11,27 +11,10 @@ from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST
from homeassistant.helpers import entity_registry
from homeassistant.setup import async_setup_component
from .const import CLIENT_KEY, FAKE_UUID, HOST, MOCK_CLIENT_KEYS, TV_NAME
from tests.common import MockConfigEntry
FAKE_UUID = "some-fake-uuid"
TV_NAME = "fake_webos"
ENTITY_ID = f"{MP_DOMAIN}.{TV_NAME}"
HOST = "1.2.3.4"
CLIENT_KEY = "some-secret"
MOCK_CLIENT_KEYS = {HOST: CLIENT_KEY}
MOCK_JSON = '{"1.2.3.4": "some-secret"}'
CHANNEL_1 = {
"channelNumber": "1",
"channelName": "Channel 1",
"channelId": "ch1id",
}
CHANNEL_2 = {
"channelNumber": "20",
"channelName": "Channel Name 2",
"channelId": "ch2id",
}
async def setup_webostv(hass, unique_id=FAKE_UUID):
"""Initialize webostv and media_player for tests."""

View File

@ -6,7 +6,7 @@ import pytest
from homeassistant.components.webostv.const import LIVE_TV_APP_ID
from homeassistant.helpers import entity_registry
from . import CHANNEL_1, CHANNEL_2, CLIENT_KEY, FAKE_UUID
from .const import CHANNEL_1, CHANNEL_2, CLIENT_KEY, FAKE_UUID, MOCK_APPS, MOCK_INPUTS
from tests.common import async_mock_service
@ -28,18 +28,8 @@ def client_fixture():
client.software_info = {"major_ver": "major", "minor_ver": "minor"}
client.system_info = {"modelName": "TVFAKE"}
client.client_key = CLIENT_KEY
client.apps = {
LIVE_TV_APP_ID: {
"title": "Live TV",
"id": LIVE_TV_APP_ID,
"largeIcon": "large-icon",
"icon": "icon",
},
}
client.inputs = {
"in1": {"label": "Input01", "id": "in1", "appId": "app0"},
"in2": {"label": "Input02", "id": "in2", "appId": "app1"},
}
client.apps = MOCK_APPS
client.inputs = MOCK_INPUTS
client.current_app_id = LIVE_TV_APP_ID
client.channels = [CHANNEL_1, CHANNEL_2]

View File

@ -0,0 +1,36 @@
"""Constants for LG webOS Smart TV tests."""
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
from homeassistant.components.webostv.const import LIVE_TV_APP_ID
FAKE_UUID = "some-fake-uuid"
TV_NAME = "fake_webos"
ENTITY_ID = f"{MP_DOMAIN}.{TV_NAME}"
HOST = "1.2.3.4"
CLIENT_KEY = "some-secret"
MOCK_CLIENT_KEYS = {HOST: CLIENT_KEY}
MOCK_JSON = '{"1.2.3.4": "some-secret"}'
CHANNEL_1 = {
"channelNumber": "1",
"channelName": "Channel 1",
"channelId": "ch1id",
}
CHANNEL_2 = {
"channelNumber": "20",
"channelName": "Channel Name 2",
"channelId": "ch2id",
}
MOCK_APPS = {
LIVE_TV_APP_ID: {
"title": "Live TV",
"id": LIVE_TV_APP_ID,
"largeIcon": "large-icon",
"icon": "icon",
},
}
MOCK_INPUTS = {
"in1": {"label": "Input01", "id": "in1", "appId": "app0"},
"in2": {"label": "Input02", "id": "in2", "appId": "app1"},
}

View File

@ -7,7 +7,7 @@ import pytest
from homeassistant import config_entries
from homeassistant.components import ssdp
from homeassistant.components.webostv.const import CONF_SOURCES, DOMAIN
from homeassistant.components.webostv.const import CONF_SOURCES, DOMAIN, LIVE_TV_APP_ID
from homeassistant.config_entries import SOURCE_SSDP
from homeassistant.const import (
CONF_CLIENT_SECRET,
@ -24,7 +24,8 @@ from homeassistant.data_entry_flow import (
RESULT_TYPE_FORM,
)
from . import CLIENT_KEY, FAKE_UUID, HOST, TV_NAME, setup_webostv
from . import setup_webostv
from .const import CLIENT_KEY, FAKE_UUID, HOST, MOCK_APPS, MOCK_INPUTS, TV_NAME
MOCK_YAML_CONFIG = {
CONF_HOST: HOST,
@ -149,8 +150,27 @@ async def test_form(hass, client):
assert result["title"] == TV_NAME
async def test_options_flow(hass, client):
"""Test options config flow."""
@pytest.mark.parametrize(
"apps, inputs",
[
# Live TV in apps (default)
(MOCK_APPS, MOCK_INPUTS),
# Live TV in inputs
(
{},
{
**MOCK_INPUTS,
"livetv": {"label": "Live TV", "id": "livetv", "appId": LIVE_TV_APP_ID},
},
),
# Live TV not found
({}, MOCK_INPUTS),
],
)
async def test_options_flow_live_tv_in_apps(hass, client, apps, inputs):
"""Test options config flow Live TV found in apps."""
client.apps = apps
client.inputs = inputs
entry = await setup_webostv(hass)
result = await hass.config_entries.options.async_init(entry.entry_id)
@ -161,20 +181,24 @@ async def test_options_flow(hass, client):
result2 = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={CONF_SOURCES: ["Input01", "Input02"]},
user_input={CONF_SOURCES: ["Live TV", "Input01", "Input02"]},
)
await hass.async_block_till_done()
assert result2["type"] == RESULT_TYPE_CREATE_ENTRY
assert result2["data"][CONF_SOURCES] == ["Input01", "Input02"]
assert result2["data"][CONF_SOURCES] == ["Live TV", "Input01", "Input02"]
async def test_options_flow_cannot_retrieve(hass, client):
"""Test options config flow cannot retrieve sources."""
entry = await setup_webostv(hass)
client.connect = Mock(side_effect=ConnectionRefusedError())
result3 = await hass.config_entries.options.async_init(entry.entry_id)
result = await hass.config_entries.options.async_init(entry.entry_id)
await hass.async_block_till_done()
assert result3["type"] == RESULT_TYPE_FORM
assert result3["errors"] == {"base": "cannot_retrieve"}
assert result["type"] == RESULT_TYPE_FORM
assert result["errors"] == {"base": "cannot_retrieve"}
async def test_form_cannot_connect(hass, client):

View File

@ -11,7 +11,8 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import async_get as get_dev_reg
from homeassistant.setup import async_setup_component
from . import ENTITY_ID, FAKE_UUID, setup_webostv
from . import setup_webostv
from .const import ENTITY_ID, FAKE_UUID
from tests.common import MockConfigEntry, async_get_device_automations

View File

@ -8,11 +8,11 @@ from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
from homeassistant.components.webostv import DOMAIN
from . import (
MOCK_JSON,
create_memory_sqlite_engine,
is_entity_unique_id_updated,
setup_legacy_component,
)
from .const import MOCK_JSON
async def test_missing_keys_file_abort(hass, client, caplog):

View File

@ -64,7 +64,8 @@ from homeassistant.helpers import device_registry
from homeassistant.setup import async_setup_component
from homeassistant.util import dt
from . import CHANNEL_2, ENTITY_ID, TV_NAME, setup_webostv
from . import setup_webostv
from .const import CHANNEL_2, ENTITY_ID, TV_NAME
from tests.common import async_fire_time_changed

View File

@ -9,7 +9,8 @@ from homeassistant.components.webostv import DOMAIN
from homeassistant.const import CONF_ICON, CONF_SERVICE_DATA
from homeassistant.setup import async_setup_component
from . import TV_NAME, setup_webostv
from . import setup_webostv
from .const import TV_NAME
ICON_PATH = "/some/path"
MESSAGE = "one, two, testing, testing"

View File

@ -7,7 +7,8 @@ from homeassistant.const import SERVICE_RELOAD
from homeassistant.helpers.device_registry import async_get as get_dev_reg
from homeassistant.setup import async_setup_component
from . import ENTITY_ID, FAKE_UUID, setup_webostv
from . import setup_webostv
from .const import ENTITY_ID, FAKE_UUID
from tests.common import MockEntity, MockEntityPlatform