mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 01:07:10 +00:00
Remove webostv deprecated YAML import (#69043)
* webostv: remove deprecated YAML import * Remove unused CUSTOMIZE_SCHEMA and WEBOSTV_CONFIG_FILE
This commit is contained in:
parent
68d563c630
commit
4a921ac67f
@ -1,33 +1,24 @@
|
|||||||
"""Support for LG webOS Smart TV."""
|
"""Support for LG webOS Smart TV."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
from pickle import loads
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from aiowebostv import WebOsClient, WebOsTvPairError
|
from aiowebostv import WebOsClient, WebOsTvPairError
|
||||||
import sqlalchemy as db
|
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components import notify as hass_notify
|
from homeassistant.components import notify as hass_notify
|
||||||
from homeassistant.components.automation import AutomationActionType
|
from homeassistant.components.automation import AutomationActionType
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_COMMAND,
|
ATTR_COMMAND,
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
CONF_CLIENT_SECRET,
|
CONF_CLIENT_SECRET,
|
||||||
CONF_CUSTOMIZE,
|
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_ICON,
|
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
CONF_UNIQUE_ID,
|
|
||||||
EVENT_HOMEASSISTANT_STOP,
|
EVENT_HOMEASSISTANT_STOP,
|
||||||
Platform,
|
|
||||||
)
|
)
|
||||||
from homeassistant.core import (
|
from homeassistant.core import (
|
||||||
Context,
|
Context,
|
||||||
@ -37,7 +28,7 @@ from homeassistant.core import (
|
|||||||
ServiceCall,
|
ServiceCall,
|
||||||
callback,
|
callback,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers import config_validation as cv, discovery, entity_registry
|
from homeassistant.helpers import config_validation as cv, discovery
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
@ -46,46 +37,17 @@ from .const import (
|
|||||||
ATTR_CONFIG_ENTRY_ID,
|
ATTR_CONFIG_ENTRY_ID,
|
||||||
ATTR_PAYLOAD,
|
ATTR_PAYLOAD,
|
||||||
ATTR_SOUND_OUTPUT,
|
ATTR_SOUND_OUTPUT,
|
||||||
CONF_ON_ACTION,
|
|
||||||
CONF_SOURCES,
|
|
||||||
DATA_CONFIG_ENTRY,
|
DATA_CONFIG_ENTRY,
|
||||||
DATA_HASS_CONFIG,
|
DATA_HASS_CONFIG,
|
||||||
DEFAULT_NAME,
|
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
PLATFORMS,
|
PLATFORMS,
|
||||||
SERVICE_BUTTON,
|
SERVICE_BUTTON,
|
||||||
SERVICE_COMMAND,
|
SERVICE_COMMAND,
|
||||||
SERVICE_SELECT_SOUND_OUTPUT,
|
SERVICE_SELECT_SOUND_OUTPUT,
|
||||||
WEBOSTV_CONFIG_FILE,
|
|
||||||
WEBOSTV_EXCEPTIONS,
|
WEBOSTV_EXCEPTIONS,
|
||||||
)
|
)
|
||||||
|
|
||||||
CUSTOMIZE_SCHEMA = vol.Schema(
|
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
|
||||||
{vol.Optional(CONF_SOURCES, default=[]): vol.All(cv.ensure_list, [cv.string])}
|
|
||||||
)
|
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema(
|
|
||||||
vol.All(
|
|
||||||
cv.deprecated(DOMAIN),
|
|
||||||
{
|
|
||||||
DOMAIN: vol.All(
|
|
||||||
cv.ensure_list,
|
|
||||||
[
|
|
||||||
vol.Schema(
|
|
||||||
{
|
|
||||||
vol.Optional(CONF_CUSTOMIZE, default={}): CUSTOMIZE_SCHEMA,
|
|
||||||
vol.Required(CONF_HOST): cv.string,
|
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
||||||
vol.Optional(CONF_ON_ACTION): cv.SCRIPT_SCHEMA,
|
|
||||||
vol.Optional(CONF_ICON): cv.string,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
},
|
|
||||||
),
|
|
||||||
extra=vol.ALLOW_EXTRA,
|
|
||||||
)
|
|
||||||
|
|
||||||
CALL_SCHEMA = vol.Schema({vol.Required(ATTR_ENTITY_ID): cv.comp_entity_ids})
|
CALL_SCHEMA = vol.Schema({vol.Required(ATTR_ENTITY_ID): cv.comp_entity_ids})
|
||||||
|
|
||||||
@ -109,113 +71,12 @@ SERVICE_TO_METHOD = {
|
|||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def read_client_keys(config_file: str) -> dict[str, str]:
|
|
||||||
"""Read legacy client keys from file."""
|
|
||||||
if not os.path.isfile(config_file):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
# Try to parse the file as being JSON
|
|
||||||
with open(config_file, encoding="utf8") as json_file:
|
|
||||||
try:
|
|
||||||
client_keys = json.load(json_file)
|
|
||||||
if isinstance(client_keys, dict):
|
|
||||||
return client_keys
|
|
||||||
return {}
|
|
||||||
except (json.JSONDecodeError, UnicodeDecodeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# If the file is not JSON, read it as Sqlite DB
|
|
||||||
engine = db.create_engine(f"sqlite:///{config_file}")
|
|
||||||
table = db.Table("unnamed", db.MetaData(), autoload=True, autoload_with=engine)
|
|
||||||
results = engine.connect().execute(db.select([table])).fetchall()
|
|
||||||
db_client_keys = {k: loads(v) for k, v in results}
|
|
||||||
return db_client_keys
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
"""Set up the LG WebOS TV platform."""
|
"""Set up the LG WebOS TV platform."""
|
||||||
hass.data.setdefault(DOMAIN, {})
|
hass.data.setdefault(DOMAIN, {})
|
||||||
hass.data[DOMAIN].setdefault(DATA_CONFIG_ENTRY, {})
|
hass.data[DOMAIN].setdefault(DATA_CONFIG_ENTRY, {})
|
||||||
hass.data[DOMAIN][DATA_HASS_CONFIG] = config
|
hass.data[DOMAIN][DATA_HASS_CONFIG] = config
|
||||||
|
|
||||||
if DOMAIN not in config:
|
|
||||||
return True
|
|
||||||
|
|
||||||
config_file = hass.config.path(WEBOSTV_CONFIG_FILE)
|
|
||||||
if not (
|
|
||||||
client_keys := await hass.async_add_executor_job(read_client_keys, config_file)
|
|
||||||
):
|
|
||||||
_LOGGER.debug("No pairing keys, Not importing webOS Smart TV YAML config")
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def async_migrate_task(
|
|
||||||
entity_id: str, conf: dict[str, str], key: str
|
|
||||||
) -> None:
|
|
||||||
_LOGGER.debug("Migrating webOS Smart TV entity %s unique_id", entity_id)
|
|
||||||
client = WebOsClient(conf[CONF_HOST], key)
|
|
||||||
tries = 0
|
|
||||||
while not client.is_connected():
|
|
||||||
try:
|
|
||||||
await client.connect()
|
|
||||||
except WEBOSTV_EXCEPTIONS:
|
|
||||||
if tries == 0:
|
|
||||||
_LOGGER.warning(
|
|
||||||
"Please make sure webOS TV %s is turned on to complete "
|
|
||||||
"the migration of configuration.yaml to the UI",
|
|
||||||
entity_id,
|
|
||||||
)
|
|
||||||
wait_time = 2 ** min(tries, 4) * 5
|
|
||||||
tries += 1
|
|
||||||
await asyncio.sleep(wait_time)
|
|
||||||
except WebOsTvPairError:
|
|
||||||
return
|
|
||||||
|
|
||||||
ent_reg = entity_registry.async_get(hass)
|
|
||||||
if not (
|
|
||||||
new_entity_id := ent_reg.async_get_entity_id(
|
|
||||||
Platform.MEDIA_PLAYER, DOMAIN, key
|
|
||||||
)
|
|
||||||
):
|
|
||||||
_LOGGER.debug(
|
|
||||||
"Not updating webOSTV Smart TV entity %s unique_id, entity missing",
|
|
||||||
entity_id,
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
uuid = client.hello_info["deviceUUID"]
|
|
||||||
ent_reg.async_update_entity(new_entity_id, new_unique_id=uuid)
|
|
||||||
await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={"source": SOURCE_IMPORT},
|
|
||||||
data={
|
|
||||||
**conf,
|
|
||||||
CONF_CLIENT_SECRET: key,
|
|
||||||
CONF_UNIQUE_ID: uuid,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
ent_reg = entity_registry.async_get(hass)
|
|
||||||
|
|
||||||
tasks = []
|
|
||||||
for conf in config[DOMAIN]:
|
|
||||||
host = conf[CONF_HOST]
|
|
||||||
if (key := client_keys.get(host)) is None:
|
|
||||||
_LOGGER.debug(
|
|
||||||
"Not importing webOS Smart TV host %s without pairing key", host
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if entity_id := ent_reg.async_get_entity_id(Platform.MEDIA_PLAYER, DOMAIN, key):
|
|
||||||
tasks.append(asyncio.create_task(async_migrate_task(entity_id, conf, key)))
|
|
||||||
|
|
||||||
async def async_tasks_cancel(_event: Event) -> None:
|
|
||||||
"""Cancel config flow import tasks."""
|
|
||||||
for task in tasks:
|
|
||||||
if not task.done():
|
|
||||||
task.cancel()
|
|
||||||
|
|
||||||
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, async_tasks_cancel)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,13 +10,7 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant import config_entries, data_entry_flow
|
from homeassistant import config_entries, data_entry_flow
|
||||||
from homeassistant.components import ssdp
|
from homeassistant.components import ssdp
|
||||||
from homeassistant.const import (
|
from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST, CONF_NAME
|
||||||
CONF_CLIENT_SECRET,
|
|
||||||
CONF_CUSTOMIZE,
|
|
||||||
CONF_HOST,
|
|
||||||
CONF_NAME,
|
|
||||||
CONF_UNIQUE_ID,
|
|
||||||
)
|
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.data_entry_flow import FlowResult
|
from homeassistant.data_entry_flow import FlowResult
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
@ -55,28 +49,6 @@ class FlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
"""Get the options flow for this handler."""
|
"""Get the options flow for this handler."""
|
||||||
return OptionsFlowHandler(config_entry)
|
return OptionsFlowHandler(config_entry)
|
||||||
|
|
||||||
async def async_step_import(self, import_info: dict[str, Any]) -> FlowResult:
|
|
||||||
"""Set the config entry up from yaml."""
|
|
||||||
self._host = import_info[CONF_HOST]
|
|
||||||
self._name = import_info.get(CONF_NAME) or import_info[CONF_HOST]
|
|
||||||
await self.async_set_unique_id(
|
|
||||||
import_info[CONF_UNIQUE_ID], raise_on_progress=False
|
|
||||||
)
|
|
||||||
data = {
|
|
||||||
CONF_HOST: self._host,
|
|
||||||
CONF_CLIENT_SECRET: import_info[CONF_CLIENT_SECRET],
|
|
||||||
}
|
|
||||||
self._abort_if_unique_id_configured()
|
|
||||||
|
|
||||||
options: dict[str, list[str]] | None = None
|
|
||||||
if sources := import_info.get(CONF_CUSTOMIZE, {}).get(CONF_SOURCES):
|
|
||||||
if not isinstance(sources, list):
|
|
||||||
sources = [s.strip() for s in sources.split(",")]
|
|
||||||
options = {CONF_SOURCES: sources}
|
|
||||||
|
|
||||||
_LOGGER.debug("WebOS Smart TV host %s imported from YAML config", self._host)
|
|
||||||
return self.async_create_entry(title=self._name, data=data, options=options)
|
|
||||||
|
|
||||||
async def async_step_user(
|
async def async_step_user(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
|
@ -33,5 +33,3 @@ WEBOSTV_EXCEPTIONS = (
|
|||||||
asyncio.TimeoutError,
|
asyncio.TimeoutError,
|
||||||
asyncio.CancelledError,
|
asyncio.CancelledError,
|
||||||
)
|
)
|
||||||
|
|
||||||
WEBOSTV_CONFIG_FILE = "webostv.conf"
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "LG webOS Smart TV",
|
"name": "LG webOS Smart TV",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/webostv",
|
"documentation": "https://www.home-assistant.io/integrations/webostv",
|
||||||
"requirements": ["aiowebostv==0.2.0", "sqlalchemy==1.4.32"],
|
"requirements": ["aiowebostv==0.2.0"],
|
||||||
"codeowners": ["@bendavid", "@thecode"],
|
"codeowners": ["@bendavid", "@thecode"],
|
||||||
"ssdp": [{ "st": "urn:lge-com:service:webos-second-screen:1" }],
|
"ssdp": [{ "st": "urn:lge-com:service:webos-second-screen:1" }],
|
||||||
"quality_scale": "platinum",
|
"quality_scale": "platinum",
|
||||||
|
@ -2194,7 +2194,6 @@ spotipy==2.19.0
|
|||||||
|
|
||||||
# homeassistant.components.recorder
|
# homeassistant.components.recorder
|
||||||
# homeassistant.components.sql
|
# homeassistant.components.sql
|
||||||
# homeassistant.components.webostv
|
|
||||||
sqlalchemy==1.4.32
|
sqlalchemy==1.4.32
|
||||||
|
|
||||||
# homeassistant.components.srp_energy
|
# homeassistant.components.srp_energy
|
||||||
|
@ -1419,7 +1419,6 @@ spotipy==2.19.0
|
|||||||
|
|
||||||
# homeassistant.components.recorder
|
# homeassistant.components.recorder
|
||||||
# homeassistant.components.sql
|
# homeassistant.components.sql
|
||||||
# homeassistant.components.webostv
|
|
||||||
sqlalchemy==1.4.32
|
sqlalchemy==1.4.32
|
||||||
|
|
||||||
# homeassistant.components.srp_energy
|
# homeassistant.components.srp_energy
|
||||||
|
@ -1,17 +1,10 @@
|
|||||||
"""Tests for the WebOS TV integration."""
|
"""Tests for the WebOS TV integration."""
|
||||||
from pickle import dumps
|
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
import sqlalchemy as db
|
|
||||||
from sqlalchemy import create_engine
|
|
||||||
|
|
||||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
|
||||||
from homeassistant.components.webostv.const import DOMAIN
|
from homeassistant.components.webostv.const import DOMAIN
|
||||||
from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST
|
from homeassistant.const import CONF_CLIENT_SECRET, CONF_HOST
|
||||||
from homeassistant.helpers import entity_registry
|
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from .const import CLIENT_KEY, FAKE_UUID, HOST, MOCK_CLIENT_KEYS, TV_NAME
|
from .const import CLIENT_KEY, FAKE_UUID, HOST, TV_NAME
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
@ -29,53 +22,11 @@ async def setup_webostv(hass, unique_id=FAKE_UUID):
|
|||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
with patch(
|
await async_setup_component(
|
||||||
"homeassistant.components.webostv.read_client_keys",
|
|
||||||
return_value=MOCK_CLIENT_KEYS,
|
|
||||||
):
|
|
||||||
await async_setup_component(
|
|
||||||
hass,
|
|
||||||
DOMAIN,
|
|
||||||
{DOMAIN: {CONF_HOST: HOST}},
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
return entry
|
|
||||||
|
|
||||||
|
|
||||||
async def setup_legacy_component(hass, create_entity=True):
|
|
||||||
"""Initialize webostv component with legacy entity."""
|
|
||||||
if create_entity:
|
|
||||||
ent_reg = entity_registry.async_get(hass)
|
|
||||||
assert ent_reg.async_get_or_create(MP_DOMAIN, DOMAIN, CLIENT_KEY)
|
|
||||||
|
|
||||||
assert await async_setup_component(
|
|
||||||
hass,
|
hass,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
{DOMAIN: {CONF_HOST: HOST}},
|
{DOMAIN: {CONF_HOST: HOST}},
|
||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return entry
|
||||||
def create_memory_sqlite_engine(url):
|
|
||||||
"""Create fake db keys file in memory."""
|
|
||||||
mem_eng = create_engine("sqlite:///:memory:")
|
|
||||||
table = db.Table(
|
|
||||||
"unnamed",
|
|
||||||
db.MetaData(),
|
|
||||||
db.Column("key", db.String),
|
|
||||||
db.Column("value", db.String),
|
|
||||||
)
|
|
||||||
table.create(mem_eng)
|
|
||||||
query = db.insert(table).values(key=HOST, value=dumps(CLIENT_KEY))
|
|
||||||
connection = mem_eng.connect()
|
|
||||||
connection.execute(query)
|
|
||||||
return mem_eng
|
|
||||||
|
|
||||||
|
|
||||||
def is_entity_unique_id_updated(hass):
|
|
||||||
"""Check if entity has new unique_id from UUID."""
|
|
||||||
ent_reg = entity_registry.async_get(hass)
|
|
||||||
return ent_reg.async_get_entity_id(
|
|
||||||
MP_DOMAIN, DOMAIN, FAKE_UUID
|
|
||||||
) and not ent_reg.async_get_entity_id(MP_DOMAIN, DOMAIN, CLIENT_KEY)
|
|
||||||
|
@ -11,7 +11,6 @@ from homeassistant.components.webostv.const import CONF_SOURCES, DOMAIN, LIVE_TV
|
|||||||
from homeassistant.config_entries import SOURCE_SSDP
|
from homeassistant.config_entries import SOURCE_SSDP
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONF_CLIENT_SECRET,
|
CONF_CLIENT_SECRET,
|
||||||
CONF_CUSTOMIZE,
|
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_ICON,
|
CONF_ICON,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
@ -46,66 +45,6 @@ MOCK_DISCOVERY_INFO = ssdp.SsdpServiceInfo(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_import(hass, client):
|
|
||||||
"""Test we can import yaml config."""
|
|
||||||
assert client
|
|
||||||
|
|
||||||
with patch("homeassistant.components.webostv.async_setup_entry", return_value=True):
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={CONF_SOURCE: config_entries.SOURCE_IMPORT},
|
|
||||||
data=MOCK_YAML_CONFIG,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
||||||
assert result["title"] == TV_NAME
|
|
||||||
assert result["data"][CONF_HOST] == MOCK_YAML_CONFIG[CONF_HOST]
|
|
||||||
assert result["data"][CONF_CLIENT_SECRET] == MOCK_YAML_CONFIG[CONF_CLIENT_SECRET]
|
|
||||||
assert result["result"].unique_id == MOCK_YAML_CONFIG[CONF_UNIQUE_ID]
|
|
||||||
|
|
||||||
with patch("homeassistant.components.webostv.async_setup_entry", return_value=True):
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={CONF_SOURCE: config_entries.SOURCE_IMPORT},
|
|
||||||
data=MOCK_YAML_CONFIG,
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
|
||||||
assert result["reason"] == "already_configured"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"sources",
|
|
||||||
[
|
|
||||||
["Live TV", "Input01", "Input02"],
|
|
||||||
"Live TV, Input01 , Input02",
|
|
||||||
"Live TV,Input01 ,Input02",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
async def test_import_sources(hass, client, sources):
|
|
||||||
"""Test import yaml config with sources list/csv."""
|
|
||||||
assert client
|
|
||||||
|
|
||||||
with patch("homeassistant.components.webostv.async_setup_entry", return_value=True):
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={CONF_SOURCE: config_entries.SOURCE_IMPORT},
|
|
||||||
data={
|
|
||||||
**MOCK_YAML_CONFIG,
|
|
||||||
CONF_CUSTOMIZE: {
|
|
||||||
CONF_SOURCES: sources,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
|
|
||||||
assert result["title"] == TV_NAME
|
|
||||||
assert result["data"][CONF_HOST] == MOCK_YAML_CONFIG[CONF_HOST]
|
|
||||||
assert result["data"][CONF_CLIENT_SECRET] == MOCK_YAML_CONFIG[CONF_CLIENT_SECRET]
|
|
||||||
assert result["options"][CONF_SOURCES] == ["Live TV", "Input01", "Input02"]
|
|
||||||
assert result["result"].unique_id == MOCK_YAML_CONFIG[CONF_UNIQUE_ID]
|
|
||||||
|
|
||||||
|
|
||||||
async def test_form(hass, client):
|
async def test_form(hass, client):
|
||||||
"""Test we get the form."""
|
"""Test we get the form."""
|
||||||
assert client
|
assert client
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
"""The tests for the WebOS TV platform."""
|
|
||||||
|
|
||||||
from unittest.mock import Mock, mock_open, patch
|
|
||||||
|
|
||||||
from aiowebostv import WebOsTvPairError
|
|
||||||
|
|
||||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
|
||||||
from homeassistant.components.webostv import DOMAIN
|
|
||||||
|
|
||||||
from . import (
|
|
||||||
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):
|
|
||||||
"""Test abort import when no pairing keys file."""
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=False)
|
|
||||||
):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert "No pairing keys, Not importing" in caplog.text
|
|
||||||
assert not is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_empty_json_abort(hass, client, caplog):
|
|
||||||
"""Test abort import when keys file is empty."""
|
|
||||||
m_open = mock_open(read_data="[]")
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert "No pairing keys, Not importing" in caplog.text
|
|
||||||
assert not is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_valid_json_migrate_not_needed(hass, client, caplog):
|
|
||||||
"""Test import from valid json entity already migrated or removed."""
|
|
||||||
m_open = mock_open(read_data=MOCK_JSON)
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True):
|
|
||||||
await setup_legacy_component(hass, False)
|
|
||||||
|
|
||||||
assert "Migrating webOS Smart TV entity" not in caplog.text
|
|
||||||
assert not is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_valid_json_missing_host_key(hass, client, caplog):
|
|
||||||
"""Test import from valid json missing host key."""
|
|
||||||
m_open = mock_open(read_data='{"1.2.3.5": "other-key"}')
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert "Not importing webOS Smart TV host" in caplog.text
|
|
||||||
assert not is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_not_connected_import(hass, client, caplog, monkeypatch):
|
|
||||||
"""Test import while device is not connected."""
|
|
||||||
m_open = mock_open(read_data=MOCK_JSON)
|
|
||||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=False))
|
|
||||||
monkeypatch.setattr(client, "connect", Mock(side_effect=OSError))
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert f"Please make sure webOS TV {MP_DOMAIN}.{DOMAIN}" in caplog.text
|
|
||||||
assert not is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_pair_error_import_abort(hass, client, caplog, monkeypatch):
|
|
||||||
"""Test abort import if device is not paired."""
|
|
||||||
m_open = mock_open(read_data=MOCK_JSON)
|
|
||||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=False))
|
|
||||||
monkeypatch.setattr(client, "connect", Mock(side_effect=WebOsTvPairError))
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert f"Please make sure webOS TV {MP_DOMAIN}.{DOMAIN}" not in caplog.text
|
|
||||||
assert not is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_entity_removed_import_abort(hass, client_entity_removed, caplog):
|
|
||||||
"""Test abort import if entity removed by user during import."""
|
|
||||||
m_open = mock_open(read_data=MOCK_JSON)
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert "Not updating webOSTV Smart TV entity" in caplog.text
|
|
||||||
assert not is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_json_import(hass, client, caplog, monkeypatch):
|
|
||||||
"""Test import from json keys file."""
|
|
||||||
m_open = mock_open(read_data=MOCK_JSON)
|
|
||||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=True))
|
|
||||||
monkeypatch.setattr(client, "connect", Mock(return_value=True))
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert "imported from YAML config" in caplog.text
|
|
||||||
assert is_entity_unique_id_updated(hass)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_sqlite_import(hass, client, caplog, monkeypatch):
|
|
||||||
"""Test import from sqlite keys file."""
|
|
||||||
m_open = mock_open(read_data="will raise JSONDecodeError")
|
|
||||||
monkeypatch.setattr(client, "is_connected", Mock(return_value=True))
|
|
||||||
monkeypatch.setattr(client, "connect", Mock(return_value=True))
|
|
||||||
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.webostv.os.path.isfile", Mock(return_value=True)
|
|
||||||
), patch("homeassistant.components.webostv.open", m_open, create=True), patch(
|
|
||||||
"homeassistant.components.webostv.db.create_engine",
|
|
||||||
side_effect=create_memory_sqlite_engine,
|
|
||||||
):
|
|
||||||
await setup_legacy_component(hass)
|
|
||||||
|
|
||||||
assert "imported from YAML config" in caplog.text
|
|
||||||
assert is_entity_unique_id_updated(hass)
|
|
Loading…
x
Reference in New Issue
Block a user