mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Fix webostv live TV source missing when configuring sources (#65243)
This commit is contained in:
parent
75b37bee3d
commit
9825111c8d
@ -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()),
|
||||
]
|
||||
)
|
||||
)
|
||||
|
@ -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))
|
||||
|
@ -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."""
|
||||
|
@ -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]
|
||||
|
36
tests/components/webostv/const.py
Normal file
36
tests/components/webostv/const.py
Normal 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"},
|
||||
}
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user