mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Cleanup LG webOS TV name (#135028)
This commit is contained in:
parent
7a2a6cf7d8
commit
43ec63eabc
@ -16,7 +16,7 @@ from homeassistant.config_entries import (
|
||||
ConfigFlowResult,
|
||||
OptionsFlow,
|
||||
)
|
||||
from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST, CONF_NAME
|
||||
from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
|
||||
@ -27,7 +27,6 @@ from .helpers import async_get_sources
|
||||
DATA_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
},
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
@ -57,7 +56,6 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
errors: dict[str, str] = {}
|
||||
if user_input is not None:
|
||||
self._host = user_input[CONF_HOST]
|
||||
self._name = user_input[CONF_NAME]
|
||||
return await self.async_step_pairing()
|
||||
|
||||
return self.async_show_form(
|
||||
@ -86,6 +84,9 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
self._abort_if_unique_id_configured({CONF_HOST: self._host})
|
||||
data = {CONF_HOST: self._host, CONF_CLIENT_SECRET: client.client_key}
|
||||
|
||||
if not self._name:
|
||||
self._name = f"{DEFAULT_NAME} {client.system_info["modelName"]}"
|
||||
return self.async_create_entry(title=self._name, data=data)
|
||||
|
||||
return self.async_show_form(step_id="pairing", errors=errors)
|
||||
@ -98,7 +99,9 @@ class FlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
host = urlparse(discovery_info.ssdp_location).hostname
|
||||
assert host
|
||||
self._host = host
|
||||
self._name = discovery_info.upnp.get(ssdp.ATTR_UPNP_FRIENDLY_NAME, DEFAULT_NAME)
|
||||
self._name = discovery_info.upnp.get(
|
||||
ssdp.ATTR_UPNP_FRIENDLY_NAME, DEFAULT_NAME
|
||||
).replace("[LG]", "LG")
|
||||
|
||||
uuid = discovery_info.upnp[ssdp.ATTR_UPNP_UDN]
|
||||
assert uuid
|
||||
|
@ -11,7 +11,7 @@ DOMAIN = "webostv"
|
||||
PLATFORMS = [Platform.MEDIA_PLAYER]
|
||||
DATA_CONFIG_ENTRY = "config_entry"
|
||||
DATA_HASS_CONFIG = "hass_config"
|
||||
DEFAULT_NAME = "LG webOS Smart TV"
|
||||
DEFAULT_NAME = "LG webOS TV"
|
||||
|
||||
ATTR_BUTTON = "button"
|
||||
ATTR_CONFIG_ENTRY_ID = "entry_id"
|
||||
|
@ -8,10 +8,12 @@ rules:
|
||||
common-modules:
|
||||
status: exempt
|
||||
comment: The integration does not use common patterns.
|
||||
config-flow-test-coverage: todo
|
||||
config-flow-test-coverage:
|
||||
status: todo
|
||||
comment: remove duplicated config flow start in tests, make sure tests ends with CREATE_ENTRY or ABORT, use hass.config_entries.async_setup instead of async_setup_component, snapshot in diagnostics (and other tests when possible), test_client_disconnected validate no error in log
|
||||
config-flow:
|
||||
status: todo
|
||||
comment: remove duplicated config flow start in tests, make sure tests ends with CREATE_ENTRY or ABORT, remove name parameter, use hass.config_entries.async_setup instead of async_setup_component, snapshot in diagnostics (and other tests when possible), test_client_disconnected validate no error in log, make reauth flow more graceful
|
||||
comment: make reauth flow more graceful
|
||||
dependency-transparency: done
|
||||
docs-actions:
|
||||
status: todo
|
||||
|
@ -1,12 +1,11 @@
|
||||
{
|
||||
"config": {
|
||||
"flow_title": "LG webOS Smart TV",
|
||||
"flow_title": "{name}",
|
||||
"step": {
|
||||
"user": {
|
||||
"description": "Turn on TV, fill the following fields and select **Submit**",
|
||||
"description": "Turn on the TV, fill the host field and select **Submit**",
|
||||
"data": {
|
||||
"host": "[%key:common::config_flow::data::host%]",
|
||||
"name": "[%key:common::config_flow::data::name%]"
|
||||
"host": "[%key:common::config_flow::data::host%]"
|
||||
},
|
||||
"data_description": {
|
||||
"host": "Hostname or IP address of your webOS TV."
|
||||
|
@ -7,7 +7,15 @@ import pytest
|
||||
|
||||
from homeassistant.components.webostv.const import LIVE_TV_APP_ID
|
||||
|
||||
from .const import CHANNEL_1, CHANNEL_2, CLIENT_KEY, FAKE_UUID, MOCK_APPS, MOCK_INPUTS
|
||||
from .const import (
|
||||
CHANNEL_1,
|
||||
CHANNEL_2,
|
||||
CLIENT_KEY,
|
||||
FAKE_UUID,
|
||||
MOCK_APPS,
|
||||
MOCK_INPUTS,
|
||||
TV_MODEL,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -28,7 +36,7 @@ def client_fixture():
|
||||
client = mock_client_class.return_value
|
||||
client.hello_info = {"deviceUUID": FAKE_UUID}
|
||||
client.software_info = {"major_ver": "major", "minor_ver": "minor"}
|
||||
client.system_info = {"modelName": "TVFAKE"}
|
||||
client.system_info = {"modelName": TV_MODEL}
|
||||
client.client_key = CLIENT_KEY
|
||||
client.apps = MOCK_APPS
|
||||
client.inputs = MOCK_INPUTS
|
||||
|
@ -2,10 +2,12 @@
|
||||
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
from homeassistant.components.webostv.const import LIVE_TV_APP_ID
|
||||
from homeassistant.util import slugify
|
||||
|
||||
FAKE_UUID = "some-fake-uuid"
|
||||
TV_NAME = "fake_webos"
|
||||
ENTITY_ID = f"{MP_DOMAIN}.{TV_NAME}"
|
||||
TV_MODEL = "MODEL"
|
||||
TV_NAME = f"LG webOS TV {TV_MODEL}"
|
||||
ENTITY_ID = f"{MP_DOMAIN}.{slugify(TV_NAME)}"
|
||||
HOST = "1.2.3.4"
|
||||
CLIENT_KEY = "some-secret"
|
||||
|
||||
|
@ -10,26 +10,31 @@ from homeassistant import config_entries
|
||||
from homeassistant.components import ssdp
|
||||
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, CONF_HOST, CONF_NAME, CONF_SOURCE
|
||||
from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST, CONF_SOURCE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
|
||||
from . import setup_webostv
|
||||
from .const import CLIENT_KEY, FAKE_UUID, HOST, MOCK_APPS, MOCK_INPUTS, TV_NAME
|
||||
from .const import (
|
||||
CLIENT_KEY,
|
||||
FAKE_UUID,
|
||||
HOST,
|
||||
MOCK_APPS,
|
||||
MOCK_INPUTS,
|
||||
TV_MODEL,
|
||||
TV_NAME,
|
||||
)
|
||||
|
||||
pytestmark = pytest.mark.usefixtures("mock_setup_entry")
|
||||
|
||||
MOCK_USER_CONFIG = {
|
||||
CONF_HOST: HOST,
|
||||
CONF_NAME: TV_NAME,
|
||||
}
|
||||
MOCK_USER_CONFIG = {CONF_HOST: HOST}
|
||||
|
||||
MOCK_DISCOVERY_INFO = ssdp.SsdpServiceInfo(
|
||||
ssdp_usn="mock_usn",
|
||||
ssdp_st="mock_st",
|
||||
ssdp_location=f"http://{HOST}",
|
||||
upnp={
|
||||
ssdp.ATTR_UPNP_FRIENDLY_NAME: "LG Webostv",
|
||||
ssdp.ATTR_UPNP_FRIENDLY_NAME: f"[LG] webOS TV {TV_MODEL}",
|
||||
ssdp.ATTR_UPNP_UDN: f"uuid:{FAKE_UUID}",
|
||||
},
|
||||
)
|
||||
@ -194,6 +199,14 @@ async def test_form_ssdp(hass: HomeAssistant, client) -> None:
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "pairing"
|
||||
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], user_input={}
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result2["type"] is FlowResultType.CREATE_ENTRY
|
||||
assert result2["title"] == TV_NAME
|
||||
|
||||
|
||||
async def test_ssdp_in_progress(hass: HomeAssistant, client) -> None:
|
||||
"""Test abort if ssdp paring is already in progress."""
|
||||
@ -253,10 +266,7 @@ async def test_form_abort_uuid_configured(hass: HomeAssistant, client) -> None:
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
user_config = {
|
||||
CONF_HOST: "new_host",
|
||||
CONF_NAME: TV_NAME,
|
||||
}
|
||||
user_config = {CONF_HOST: "new_host"}
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
|
@ -36,7 +36,7 @@ async def test_diagnostics(
|
||||
"in1": {"appId": "app0", "id": "in1", "label": "Input01"},
|
||||
"in2": {"appId": "app1", "id": "in2", "label": "Input02"},
|
||||
},
|
||||
"system_info": {"modelName": "TVFAKE"},
|
||||
"system_info": {"modelName": "MODEL"},
|
||||
"software_info": {"major_ver": "major", "minor_ver": "minor"},
|
||||
"hello_info": {"deviceUUID": "**REDACTED**"},
|
||||
"sound_output": "speaker",
|
||||
@ -47,7 +47,7 @@ async def test_diagnostics(
|
||||
"version": 1,
|
||||
"minor_version": 1,
|
||||
"domain": "webostv",
|
||||
"title": "fake_webos",
|
||||
"title": "LG webOS TV MODEL",
|
||||
"data": {
|
||||
"client_secret": "**REDACTED**",
|
||||
"host": "**REDACTED**",
|
||||
|
@ -67,7 +67,7 @@ from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from . import setup_webostv
|
||||
from .const import CHANNEL_2, ENTITY_ID, TV_NAME
|
||||
from .const import CHANNEL_2, ENTITY_ID, TV_MODEL, TV_NAME
|
||||
|
||||
from tests.common import async_fire_time_changed, mock_restore_cache
|
||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||
@ -340,7 +340,7 @@ async def test_entity_attributes(
|
||||
assert device.manufacturer == "LG"
|
||||
assert device.name == TV_NAME
|
||||
assert device.sw_version == "major.minor"
|
||||
assert device.model == "TVFAKE"
|
||||
assert device.model == TV_MODEL
|
||||
|
||||
# Sound output when off
|
||||
monkeypatch.setattr(client, "sound_output", None)
|
||||
|
@ -14,22 +14,24 @@ from homeassistant.components.webostv import DOMAIN
|
||||
from homeassistant.const import ATTR_ICON
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import slugify
|
||||
|
||||
from . import setup_webostv
|
||||
from .const import TV_NAME
|
||||
|
||||
ICON_PATH = "/some/path"
|
||||
MESSAGE = "one, two, testing, testing"
|
||||
SERVICE_NAME = slugify(TV_NAME)
|
||||
|
||||
|
||||
async def test_notify(hass: HomeAssistant, client) -> None:
|
||||
"""Test sending a message."""
|
||||
await setup_webostv(hass)
|
||||
assert hass.services.has_service(NOTIFY_DOMAIN, TV_NAME)
|
||||
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
|
||||
|
||||
await hass.services.async_call(
|
||||
NOTIFY_DOMAIN,
|
||||
TV_NAME,
|
||||
SERVICE_NAME,
|
||||
{
|
||||
ATTR_MESSAGE: MESSAGE,
|
||||
ATTR_DATA: {
|
||||
@ -44,7 +46,7 @@ async def test_notify(hass: HomeAssistant, client) -> None:
|
||||
|
||||
await hass.services.async_call(
|
||||
NOTIFY_DOMAIN,
|
||||
TV_NAME,
|
||||
SERVICE_NAME,
|
||||
{
|
||||
ATTR_MESSAGE: MESSAGE,
|
||||
ATTR_DATA: {
|
||||
@ -59,7 +61,7 @@ async def test_notify(hass: HomeAssistant, client) -> None:
|
||||
|
||||
await hass.services.async_call(
|
||||
NOTIFY_DOMAIN,
|
||||
TV_NAME,
|
||||
SERVICE_NAME,
|
||||
{
|
||||
ATTR_MESSAGE: "only message, no data",
|
||||
},
|
||||
@ -77,12 +79,12 @@ async def test_notify_not_connected(
|
||||
) -> None:
|
||||
"""Test sending a message when client is not connected."""
|
||||
await setup_webostv(hass)
|
||||
assert hass.services.has_service(NOTIFY_DOMAIN, TV_NAME)
|
||||
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
|
||||
|
||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=False))
|
||||
await hass.services.async_call(
|
||||
NOTIFY_DOMAIN,
|
||||
TV_NAME,
|
||||
SERVICE_NAME,
|
||||
{
|
||||
ATTR_MESSAGE: MESSAGE,
|
||||
ATTR_DATA: {
|
||||
@ -104,12 +106,12 @@ async def test_icon_not_found(
|
||||
) -> None:
|
||||
"""Test notify icon not found error."""
|
||||
await setup_webostv(hass)
|
||||
assert hass.services.has_service(NOTIFY_DOMAIN, TV_NAME)
|
||||
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
|
||||
|
||||
monkeypatch.setattr(client, "send_message", Mock(side_effect=FileNotFoundError))
|
||||
await hass.services.async_call(
|
||||
NOTIFY_DOMAIN,
|
||||
TV_NAME,
|
||||
SERVICE_NAME,
|
||||
{
|
||||
ATTR_MESSAGE: MESSAGE,
|
||||
ATTR_DATA: {
|
||||
@ -141,13 +143,13 @@ async def test_connection_errors(
|
||||
) -> None:
|
||||
"""Test connection errors scenarios."""
|
||||
await setup_webostv(hass)
|
||||
assert hass.services.has_service("notify", TV_NAME)
|
||||
assert hass.services.has_service("notify", SERVICE_NAME)
|
||||
|
||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=False))
|
||||
monkeypatch.setattr(client, "connect", Mock(side_effect=side_effect))
|
||||
await hass.services.async_call(
|
||||
NOTIFY_DOMAIN,
|
||||
TV_NAME,
|
||||
SERVICE_NAME,
|
||||
{
|
||||
ATTR_MESSAGE: MESSAGE,
|
||||
ATTR_DATA: {
|
||||
@ -175,4 +177,4 @@ async def test_no_discovery_info(
|
||||
await hass.async_block_till_done()
|
||||
assert NOTIFY_DOMAIN in hass.config.components
|
||||
assert f"Failed to initialize notification service {DOMAIN}" in caplog.text
|
||||
assert not hass.services.has_service("notify", TV_NAME)
|
||||
assert not hass.services.has_service("notify", SERVICE_NAME)
|
||||
|
Loading…
x
Reference in New Issue
Block a user