Merge system options into pref properties (#51347)
* Make system options future proof * Update tests * Add types
This commit is contained in:
parent
9e3ee73b8b
commit
ee2c950716
27 changed files with 188 additions and 245 deletions
|
@ -1,4 +1,6 @@
|
||||||
"""Http views to control the config manager."""
|
"""Http views to control the config manager."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import aiohttp.web_exceptions
|
import aiohttp.web_exceptions
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
@ -7,7 +9,7 @@ from homeassistant.auth.permissions.const import CAT_CONFIG_ENTRIES, POLICY_EDIT
|
||||||
from homeassistant.components import websocket_api
|
from homeassistant.components import websocket_api
|
||||||
from homeassistant.components.http import HomeAssistantView
|
from homeassistant.components.http import HomeAssistantView
|
||||||
from homeassistant.const import HTTP_FORBIDDEN, HTTP_NOT_FOUND
|
from homeassistant.const import HTTP_FORBIDDEN, HTTP_NOT_FOUND
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import Unauthorized
|
from homeassistant.exceptions import Unauthorized
|
||||||
from homeassistant.helpers.data_entry_flow import (
|
from homeassistant.helpers.data_entry_flow import (
|
||||||
FlowManagerIndexView,
|
FlowManagerIndexView,
|
||||||
|
@ -31,7 +33,6 @@ async def async_setup(hass):
|
||||||
hass.components.websocket_api.async_register_command(config_entry_disable)
|
hass.components.websocket_api.async_register_command(config_entry_disable)
|
||||||
hass.components.websocket_api.async_register_command(config_entry_update)
|
hass.components.websocket_api.async_register_command(config_entry_update)
|
||||||
hass.components.websocket_api.async_register_command(config_entries_progress)
|
hass.components.websocket_api.async_register_command(config_entries_progress)
|
||||||
hass.components.websocket_api.async_register_command(system_options_update)
|
|
||||||
hass.components.websocket_api.async_register_command(ignore_config_flow)
|
hass.components.websocket_api.async_register_command(ignore_config_flow)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -230,14 +231,21 @@ def config_entries_progress(hass, connection, msg):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def send_entry_not_found(connection, msg_id):
|
def send_entry_not_found(
|
||||||
|
connection: websocket_api.ActiveConnection, msg_id: int
|
||||||
|
) -> None:
|
||||||
"""Send Config entry not found error."""
|
"""Send Config entry not found error."""
|
||||||
connection.send_error(
|
connection.send_error(
|
||||||
msg_id, websocket_api.const.ERR_NOT_FOUND, "Config entry not found"
|
msg_id, websocket_api.const.ERR_NOT_FOUND, "Config entry not found"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_entry(hass, connection, entry_id, msg_id):
|
def get_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
connection: websocket_api.ActiveConnection,
|
||||||
|
entry_id: str,
|
||||||
|
msg_id: int,
|
||||||
|
) -> config_entries.ConfigEntry | None:
|
||||||
"""Get entry, send error message if it doesn't exist."""
|
"""Get entry, send error message if it doesn't exist."""
|
||||||
entry = hass.config_entries.async_get_entry(entry_id)
|
entry = hass.config_entries.async_get_entry(entry_id)
|
||||||
if entry is None:
|
if entry is None:
|
||||||
|
@ -249,49 +257,13 @@ def get_entry(hass, connection, entry_id, msg_id):
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@websocket_api.websocket_command(
|
@websocket_api.websocket_command(
|
||||||
{
|
{
|
||||||
"type": "config_entries/system_options/update",
|
"type": "config_entries/update",
|
||||||
"entry_id": str,
|
"entry_id": str,
|
||||||
vol.Optional("disable_new_entities"): bool,
|
vol.Optional("title"): str,
|
||||||
vol.Optional("disable_polling"): bool,
|
vol.Optional("pref_disable_new_entities"): bool,
|
||||||
|
vol.Optional("pref_disable_polling"): bool,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
async def system_options_update(hass, connection, msg):
|
|
||||||
"""Update config entry system options."""
|
|
||||||
changes = dict(msg)
|
|
||||||
changes.pop("id")
|
|
||||||
changes.pop("type")
|
|
||||||
changes.pop("entry_id")
|
|
||||||
|
|
||||||
entry = get_entry(hass, connection, msg["entry_id"], msg["id"])
|
|
||||||
if entry is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
old_disable_polling = entry.system_options.disable_polling
|
|
||||||
|
|
||||||
hass.config_entries.async_update_entry(entry, system_options=changes)
|
|
||||||
|
|
||||||
result = {
|
|
||||||
"system_options": entry.system_options.as_dict(),
|
|
||||||
"require_restart": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
old_disable_polling != entry.system_options.disable_polling
|
|
||||||
and entry.state is config_entries.ConfigEntryState.LOADED
|
|
||||||
):
|
|
||||||
if not await hass.config_entries.async_reload(entry.entry_id):
|
|
||||||
result["require_restart"] = (
|
|
||||||
entry.state is config_entries.ConfigEntryState.FAILED_UNLOAD
|
|
||||||
)
|
|
||||||
|
|
||||||
connection.send_result(msg["id"], result)
|
|
||||||
|
|
||||||
|
|
||||||
@websocket_api.require_admin
|
|
||||||
@websocket_api.async_response
|
|
||||||
@websocket_api.websocket_command(
|
|
||||||
{"type": "config_entries/update", "entry_id": str, vol.Optional("title"): str}
|
|
||||||
)
|
|
||||||
async def config_entry_update(hass, connection, msg):
|
async def config_entry_update(hass, connection, msg):
|
||||||
"""Update config entry."""
|
"""Update config entry."""
|
||||||
changes = dict(msg)
|
changes = dict(msg)
|
||||||
|
@ -303,8 +275,25 @@ async def config_entry_update(hass, connection, msg):
|
||||||
if entry is None:
|
if entry is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
old_disable_polling = entry.pref_disable_polling
|
||||||
|
|
||||||
hass.config_entries.async_update_entry(entry, **changes)
|
hass.config_entries.async_update_entry(entry, **changes)
|
||||||
connection.send_result(msg["id"], entry_json(entry))
|
|
||||||
|
result = {
|
||||||
|
"config_entry": entry_json(entry),
|
||||||
|
"require_restart": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
old_disable_polling != entry.pref_disable_polling
|
||||||
|
and entry.state is config_entries.ConfigEntryState.LOADED
|
||||||
|
):
|
||||||
|
if not await hass.config_entries.async_reload(entry.entry_id):
|
||||||
|
result["require_restart"] = (
|
||||||
|
entry.state is config_entries.ConfigEntryState.FAILED_UNLOAD
|
||||||
|
)
|
||||||
|
|
||||||
|
connection.send_result(msg["id"], result)
|
||||||
|
|
||||||
|
|
||||||
@websocket_api.require_admin
|
@websocket_api.require_admin
|
||||||
|
@ -391,7 +380,8 @@ def entry_json(entry: config_entries.ConfigEntry) -> dict:
|
||||||
"state": entry.state.value,
|
"state": entry.state.value,
|
||||||
"supports_options": supports_options,
|
"supports_options": supports_options,
|
||||||
"supports_unload": entry.supports_unload,
|
"supports_unload": entry.supports_unload,
|
||||||
"system_options": entry.system_options.as_dict(),
|
"pref_disable_new_entities": entry.pref_disable_new_entities,
|
||||||
|
"pref_disable_polling": entry.pref_disable_polling,
|
||||||
"disabled_by": entry.disabled_by,
|
"disabled_by": entry.disabled_by,
|
||||||
"reason": entry.reason,
|
"reason": entry.reason,
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,6 @@ from types import MappingProxyType, MethodType
|
||||||
from typing import Any, Callable, Optional, cast
|
from typing import Any, Callable, Optional, cast
|
||||||
import weakref
|
import weakref
|
||||||
|
|
||||||
import attr
|
|
||||||
|
|
||||||
from homeassistant import data_entry_flow, loader
|
from homeassistant import data_entry_flow, loader
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP
|
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_HOMEASSISTANT_STOP
|
||||||
from homeassistant.core import CALLBACK_TYPE, CoreState, HomeAssistant, callback
|
from homeassistant.core import CALLBACK_TYPE, CoreState, HomeAssistant, callback
|
||||||
|
@ -152,7 +150,8 @@ class ConfigEntry:
|
||||||
"options",
|
"options",
|
||||||
"unique_id",
|
"unique_id",
|
||||||
"supports_unload",
|
"supports_unload",
|
||||||
"system_options",
|
"pref_disable_new_entities",
|
||||||
|
"pref_disable_polling",
|
||||||
"source",
|
"source",
|
||||||
"state",
|
"state",
|
||||||
"disabled_by",
|
"disabled_by",
|
||||||
|
@ -170,7 +169,8 @@ class ConfigEntry:
|
||||||
title: str,
|
title: str,
|
||||||
data: Mapping[str, Any],
|
data: Mapping[str, Any],
|
||||||
source: str,
|
source: str,
|
||||||
system_options: dict,
|
pref_disable_new_entities: bool | None = None,
|
||||||
|
pref_disable_polling: bool | None = None,
|
||||||
options: Mapping[str, Any] | None = None,
|
options: Mapping[str, Any] | None = None,
|
||||||
unique_id: str | None = None,
|
unique_id: str | None = None,
|
||||||
entry_id: str | None = None,
|
entry_id: str | None = None,
|
||||||
|
@ -197,7 +197,15 @@ class ConfigEntry:
|
||||||
self.options = MappingProxyType(options or {})
|
self.options = MappingProxyType(options or {})
|
||||||
|
|
||||||
# Entry system options
|
# Entry system options
|
||||||
self.system_options = SystemOptions(**system_options)
|
if pref_disable_new_entities is None:
|
||||||
|
pref_disable_new_entities = False
|
||||||
|
|
||||||
|
self.pref_disable_new_entities = pref_disable_new_entities
|
||||||
|
|
||||||
|
if pref_disable_polling is None:
|
||||||
|
pref_disable_polling = False
|
||||||
|
|
||||||
|
self.pref_disable_polling = pref_disable_polling
|
||||||
|
|
||||||
# Source of the configuration (user, discovery, cloud)
|
# Source of the configuration (user, discovery, cloud)
|
||||||
self.source = source
|
self.source = source
|
||||||
|
@ -535,7 +543,8 @@ class ConfigEntry:
|
||||||
"title": self.title,
|
"title": self.title,
|
||||||
"data": dict(self.data),
|
"data": dict(self.data),
|
||||||
"options": dict(self.options),
|
"options": dict(self.options),
|
||||||
"system_options": self.system_options.as_dict(),
|
"pref_disable_new_entities": self.pref_disable_new_entities,
|
||||||
|
"pref_disable_polling": self.pref_disable_polling,
|
||||||
"source": self.source,
|
"source": self.source,
|
||||||
"unique_id": self.unique_id,
|
"unique_id": self.unique_id,
|
||||||
"disabled_by": self.disabled_by,
|
"disabled_by": self.disabled_by,
|
||||||
|
@ -652,7 +661,6 @@ class ConfigEntriesFlowManager(data_entry_flow.FlowManager):
|
||||||
title=result["title"],
|
title=result["title"],
|
||||||
data=result["data"],
|
data=result["data"],
|
||||||
options=result["options"],
|
options=result["options"],
|
||||||
system_options={},
|
|
||||||
source=flow.context["source"],
|
source=flow.context["source"],
|
||||||
unique_id=flow.unique_id,
|
unique_id=flow.unique_id,
|
||||||
)
|
)
|
||||||
|
@ -845,8 +853,18 @@ class ConfigEntries:
|
||||||
self._entries = {}
|
self._entries = {}
|
||||||
return
|
return
|
||||||
|
|
||||||
self._entries = {
|
entries = {}
|
||||||
entry["entry_id"]: ConfigEntry(
|
|
||||||
|
for entry in config["entries"]:
|
||||||
|
pref_disable_new_entities = entry.get("pref_disable_new_entities")
|
||||||
|
|
||||||
|
# Between 0.98 and 2021.6 we stored 'disable_new_entities' in a system options dictionary
|
||||||
|
if pref_disable_new_entities is None and "system_options" in entry:
|
||||||
|
pref_disable_new_entities = entry.get("system_options", {}).get(
|
||||||
|
"disable_new_entities"
|
||||||
|
)
|
||||||
|
|
||||||
|
entries[entry["entry_id"]] = ConfigEntry(
|
||||||
version=entry["version"],
|
version=entry["version"],
|
||||||
domain=entry["domain"],
|
domain=entry["domain"],
|
||||||
entry_id=entry["entry_id"],
|
entry_id=entry["entry_id"],
|
||||||
|
@ -855,15 +873,16 @@ class ConfigEntries:
|
||||||
title=entry["title"],
|
title=entry["title"],
|
||||||
# New in 0.89
|
# New in 0.89
|
||||||
options=entry.get("options"),
|
options=entry.get("options"),
|
||||||
# New in 0.98
|
|
||||||
system_options=entry.get("system_options", {}),
|
|
||||||
# New in 0.104
|
# New in 0.104
|
||||||
unique_id=entry.get("unique_id"),
|
unique_id=entry.get("unique_id"),
|
||||||
# New in 2021.3
|
# New in 2021.3
|
||||||
disabled_by=entry.get("disabled_by"),
|
disabled_by=entry.get("disabled_by"),
|
||||||
|
# New in 2021.6
|
||||||
|
pref_disable_new_entities=pref_disable_new_entities,
|
||||||
|
pref_disable_polling=entry.get("pref_disable_polling"),
|
||||||
)
|
)
|
||||||
for entry in config["entries"]
|
|
||||||
}
|
self._entries = entries
|
||||||
|
|
||||||
async def async_setup(self, entry_id: str) -> bool:
|
async def async_setup(self, entry_id: str) -> bool:
|
||||||
"""Set up a config entry.
|
"""Set up a config entry.
|
||||||
|
@ -962,11 +981,12 @@ class ConfigEntries:
|
||||||
self,
|
self,
|
||||||
entry: ConfigEntry,
|
entry: ConfigEntry,
|
||||||
*,
|
*,
|
||||||
unique_id: str | dict | None | UndefinedType = UNDEFINED,
|
unique_id: str | None | UndefinedType = UNDEFINED,
|
||||||
title: str | dict | UndefinedType = UNDEFINED,
|
title: str | UndefinedType = UNDEFINED,
|
||||||
data: dict | UndefinedType = UNDEFINED,
|
data: dict | UndefinedType = UNDEFINED,
|
||||||
options: Mapping[str, Any] | UndefinedType = UNDEFINED,
|
options: Mapping[str, Any] | UndefinedType = UNDEFINED,
|
||||||
system_options: dict | UndefinedType = UNDEFINED,
|
pref_disable_new_entities: bool | UndefinedType = UNDEFINED,
|
||||||
|
pref_disable_polling: bool | UndefinedType = UNDEFINED,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Update a config entry.
|
"""Update a config entry.
|
||||||
|
|
||||||
|
@ -978,13 +998,17 @@ class ConfigEntries:
|
||||||
"""
|
"""
|
||||||
changed = False
|
changed = False
|
||||||
|
|
||||||
if unique_id is not UNDEFINED and entry.unique_id != unique_id:
|
for attr, value in (
|
||||||
changed = True
|
("unique_id", unique_id),
|
||||||
entry.unique_id = cast(Optional[str], unique_id)
|
("title", title),
|
||||||
|
("pref_disable_new_entities", pref_disable_new_entities),
|
||||||
|
("pref_disable_polling", pref_disable_polling),
|
||||||
|
):
|
||||||
|
if value == UNDEFINED or getattr(entry, attr) == value:
|
||||||
|
continue
|
||||||
|
|
||||||
if title is not UNDEFINED and entry.title != title:
|
setattr(entry, attr, value)
|
||||||
changed = True
|
changed = True
|
||||||
entry.title = cast(str, title)
|
|
||||||
|
|
||||||
if data is not UNDEFINED and entry.data != data: # type: ignore
|
if data is not UNDEFINED and entry.data != data: # type: ignore
|
||||||
changed = True
|
changed = True
|
||||||
|
@ -994,11 +1018,6 @@ class ConfigEntries:
|
||||||
changed = True
|
changed = True
|
||||||
entry.options = MappingProxyType(options)
|
entry.options = MappingProxyType(options)
|
||||||
|
|
||||||
if system_options is not UNDEFINED:
|
|
||||||
old_system_options = entry.system_options.as_dict()
|
|
||||||
entry.system_options.update(**system_options)
|
|
||||||
changed = entry.system_options.as_dict() != old_system_options
|
|
||||||
|
|
||||||
if not changed:
|
if not changed:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1401,34 +1420,6 @@ class OptionsFlow(data_entry_flow.FlowHandler):
|
||||||
handler: str
|
handler: str
|
||||||
|
|
||||||
|
|
||||||
@attr.s(slots=True)
|
|
||||||
class SystemOptions:
|
|
||||||
"""Config entry system options."""
|
|
||||||
|
|
||||||
disable_new_entities: bool = attr.ib(default=False)
|
|
||||||
disable_polling: bool = attr.ib(default=False)
|
|
||||||
|
|
||||||
def update(
|
|
||||||
self,
|
|
||||||
*,
|
|
||||||
disable_new_entities: bool | UndefinedType = UNDEFINED,
|
|
||||||
disable_polling: bool | UndefinedType = UNDEFINED,
|
|
||||||
) -> None:
|
|
||||||
"""Update properties."""
|
|
||||||
if disable_new_entities is not UNDEFINED:
|
|
||||||
self.disable_new_entities = disable_new_entities
|
|
||||||
|
|
||||||
if disable_polling is not UNDEFINED:
|
|
||||||
self.disable_polling = disable_polling
|
|
||||||
|
|
||||||
def as_dict(self) -> dict[str, Any]:
|
|
||||||
"""Return dictionary version of this config entries system options."""
|
|
||||||
return {
|
|
||||||
"disable_new_entities": self.disable_new_entities,
|
|
||||||
"disable_polling": self.disable_polling,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class EntityRegistryDisabledHandler:
|
class EntityRegistryDisabledHandler:
|
||||||
"""Handler to handle when entities related to config entries updating disabled_by."""
|
"""Handler to handle when entities related to config entries updating disabled_by."""
|
||||||
|
|
||||||
|
|
|
@ -397,7 +397,7 @@ class EntityPlatform:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(self.config_entry and self.config_entry.system_options.disable_polling)
|
(self.config_entry and self.config_entry.pref_disable_polling)
|
||||||
or self._async_unsub_polling is not None
|
or self._async_unsub_polling is not None
|
||||||
or not any(entity.should_poll for entity in self.entities.values())
|
or not any(entity.should_poll for entity in self.entities.values())
|
||||||
):
|
):
|
||||||
|
|
|
@ -286,7 +286,7 @@ class EntityRegistry:
|
||||||
if (
|
if (
|
||||||
disabled_by is None
|
disabled_by is None
|
||||||
and config_entry
|
and config_entry
|
||||||
and config_entry.system_options.disable_new_entities
|
and config_entry.pref_disable_new_entities
|
||||||
):
|
):
|
||||||
disabled_by = DISABLED_INTEGRATION
|
disabled_by = DISABLED_INTEGRATION
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ class DataUpdateCoordinator(Generic[T]):
|
||||||
if self.update_interval is None:
|
if self.update_interval is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self.config_entry and self.config_entry.system_options.disable_polling:
|
if self.config_entry and self.config_entry.pref_disable_polling:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._unsub_refresh:
|
if self._unsub_refresh:
|
||||||
|
|
|
@ -732,7 +732,8 @@ class MockConfigEntry(config_entries.ConfigEntry):
|
||||||
title="Mock Title",
|
title="Mock Title",
|
||||||
state=None,
|
state=None,
|
||||||
options={},
|
options={},
|
||||||
system_options={},
|
pref_disable_new_entities=None,
|
||||||
|
pref_disable_polling=None,
|
||||||
unique_id=None,
|
unique_id=None,
|
||||||
disabled_by=None,
|
disabled_by=None,
|
||||||
reason=None,
|
reason=None,
|
||||||
|
@ -742,7 +743,8 @@ class MockConfigEntry(config_entries.ConfigEntry):
|
||||||
"entry_id": entry_id or uuid_util.random_uuid_hex(),
|
"entry_id": entry_id or uuid_util.random_uuid_hex(),
|
||||||
"domain": domain,
|
"domain": domain,
|
||||||
"data": data or {},
|
"data": data or {},
|
||||||
"system_options": system_options,
|
"pref_disable_new_entities": pref_disable_new_entities,
|
||||||
|
"pref_disable_polling": pref_disable_polling,
|
||||||
"options": options,
|
"options": options,
|
||||||
"version": version,
|
"version": version,
|
||||||
"title": title,
|
"title": title,
|
||||||
|
|
|
@ -29,7 +29,6 @@ FIXTURE_CONFIG_ENTRY = {
|
||||||
CONF_REGION: FIXTURE_USER_INPUT[CONF_REGION],
|
CONF_REGION: FIXTURE_USER_INPUT[CONF_REGION],
|
||||||
},
|
},
|
||||||
"options": {CONF_READ_ONLY: False, CONF_USE_LOCATION: False},
|
"options": {CONF_READ_ONLY: False, CONF_USE_LOCATION: False},
|
||||||
"system_options": {"disable_new_entities": False},
|
|
||||||
"source": config_entries.SOURCE_USER,
|
"source": config_entries.SOURCE_USER,
|
||||||
"unique_id": f"{FIXTURE_USER_INPUT[CONF_REGION]}-{FIXTURE_USER_INPUT[CONF_REGION]}",
|
"unique_id": f"{FIXTURE_USER_INPUT[CONF_REGION]}-{FIXTURE_USER_INPUT[CONF_REGION]}",
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,10 +87,8 @@ async def test_get_entries(hass, client):
|
||||||
"state": core_ce.ConfigEntryState.NOT_LOADED.value,
|
"state": core_ce.ConfigEntryState.NOT_LOADED.value,
|
||||||
"supports_options": True,
|
"supports_options": True,
|
||||||
"supports_unload": True,
|
"supports_unload": True,
|
||||||
"system_options": {
|
"pref_disable_new_entities": False,
|
||||||
"disable_new_entities": False,
|
"pref_disable_polling": False,
|
||||||
"disable_polling": False,
|
|
||||||
},
|
|
||||||
"disabled_by": None,
|
"disabled_by": None,
|
||||||
"reason": None,
|
"reason": None,
|
||||||
},
|
},
|
||||||
|
@ -101,10 +99,8 @@ async def test_get_entries(hass, client):
|
||||||
"state": core_ce.ConfigEntryState.SETUP_ERROR.value,
|
"state": core_ce.ConfigEntryState.SETUP_ERROR.value,
|
||||||
"supports_options": False,
|
"supports_options": False,
|
||||||
"supports_unload": False,
|
"supports_unload": False,
|
||||||
"system_options": {
|
"pref_disable_new_entities": False,
|
||||||
"disable_new_entities": False,
|
"pref_disable_polling": False,
|
||||||
"disable_polling": False,
|
|
||||||
},
|
|
||||||
"disabled_by": None,
|
"disabled_by": None,
|
||||||
"reason": "Unsupported API",
|
"reason": "Unsupported API",
|
||||||
},
|
},
|
||||||
|
@ -115,10 +111,8 @@ async def test_get_entries(hass, client):
|
||||||
"state": core_ce.ConfigEntryState.NOT_LOADED.value,
|
"state": core_ce.ConfigEntryState.NOT_LOADED.value,
|
||||||
"supports_options": False,
|
"supports_options": False,
|
||||||
"supports_unload": False,
|
"supports_unload": False,
|
||||||
"system_options": {
|
"pref_disable_new_entities": False,
|
||||||
"disable_new_entities": False,
|
"pref_disable_polling": False,
|
||||||
"disable_polling": False,
|
|
||||||
},
|
|
||||||
"disabled_by": core_ce.DISABLED_USER,
|
"disabled_by": core_ce.DISABLED_USER,
|
||||||
"reason": None,
|
"reason": None,
|
||||||
},
|
},
|
||||||
|
@ -340,10 +334,8 @@ async def test_create_account(hass, client, enable_custom_integrations):
|
||||||
"state": core_ce.ConfigEntryState.LOADED.value,
|
"state": core_ce.ConfigEntryState.LOADED.value,
|
||||||
"supports_options": False,
|
"supports_options": False,
|
||||||
"supports_unload": False,
|
"supports_unload": False,
|
||||||
"system_options": {
|
"pref_disable_new_entities": False,
|
||||||
"disable_new_entities": False,
|
"pref_disable_polling": False,
|
||||||
"disable_polling": False,
|
|
||||||
},
|
|
||||||
"title": "Test Entry",
|
"title": "Test Entry",
|
||||||
"reason": None,
|
"reason": None,
|
||||||
},
|
},
|
||||||
|
@ -415,10 +407,8 @@ async def test_two_step_flow(hass, client, enable_custom_integrations):
|
||||||
"state": core_ce.ConfigEntryState.LOADED.value,
|
"state": core_ce.ConfigEntryState.LOADED.value,
|
||||||
"supports_options": False,
|
"supports_options": False,
|
||||||
"supports_unload": False,
|
"supports_unload": False,
|
||||||
"system_options": {
|
"pref_disable_new_entities": False,
|
||||||
"disable_new_entities": False,
|
"pref_disable_polling": False,
|
||||||
"disable_polling": False,
|
|
||||||
},
|
|
||||||
"title": "user-title",
|
"title": "user-title",
|
||||||
"reason": None,
|
"reason": None,
|
||||||
},
|
},
|
||||||
|
@ -698,7 +688,7 @@ async def test_two_step_options_flow(hass, client):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_update_system_options(hass, hass_ws_client):
|
async def test_update_prefrences(hass, hass_ws_client):
|
||||||
"""Test that we can update system options."""
|
"""Test that we can update system options."""
|
||||||
assert await async_setup_component(hass, "config", {})
|
assert await async_setup_component(hass, "config", {})
|
||||||
ws_client = await hass_ws_client(hass)
|
ws_client = await hass_ws_client(hass)
|
||||||
|
@ -706,64 +696,45 @@ async def test_update_system_options(hass, hass_ws_client):
|
||||||
entry = MockConfigEntry(domain="demo", state=core_ce.ConfigEntryState.LOADED)
|
entry = MockConfigEntry(domain="demo", state=core_ce.ConfigEntryState.LOADED)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
assert entry.system_options.disable_new_entities is False
|
assert entry.pref_disable_new_entities is False
|
||||||
assert entry.system_options.disable_polling is False
|
assert entry.pref_disable_polling is False
|
||||||
|
|
||||||
await ws_client.send_json(
|
|
||||||
{
|
|
||||||
"id": 5,
|
|
||||||
"type": "config_entries/system_options/update",
|
|
||||||
"entry_id": entry.entry_id,
|
|
||||||
"disable_new_entities": True,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
response = await ws_client.receive_json()
|
|
||||||
|
|
||||||
assert response["success"]
|
|
||||||
assert response["result"] == {
|
|
||||||
"require_restart": False,
|
|
||||||
"system_options": {"disable_new_entities": True, "disable_polling": False},
|
|
||||||
}
|
|
||||||
assert entry.system_options.disable_new_entities is True
|
|
||||||
assert entry.system_options.disable_polling is False
|
|
||||||
|
|
||||||
await ws_client.send_json(
|
await ws_client.send_json(
|
||||||
{
|
{
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"type": "config_entries/system_options/update",
|
"type": "config_entries/update",
|
||||||
"entry_id": entry.entry_id,
|
"entry_id": entry.entry_id,
|
||||||
"disable_new_entities": False,
|
"pref_disable_new_entities": True,
|
||||||
"disable_polling": True,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
response = await ws_client.receive_json()
|
response = await ws_client.receive_json()
|
||||||
|
|
||||||
assert response["success"]
|
assert response["success"]
|
||||||
assert response["result"] == {
|
assert response["result"]["require_restart"] is False
|
||||||
"require_restart": True,
|
assert response["result"]["config_entry"]["pref_disable_new_entities"] is True
|
||||||
"system_options": {"disable_new_entities": False, "disable_polling": True},
|
assert response["result"]["config_entry"]["pref_disable_polling"] is False
|
||||||
}
|
|
||||||
assert entry.system_options.disable_new_entities is False
|
|
||||||
assert entry.system_options.disable_polling is True
|
|
||||||
|
|
||||||
|
assert entry.pref_disable_new_entities is True
|
||||||
async def test_update_system_options_nonexisting(hass, hass_ws_client):
|
assert entry.pref_disable_polling is False
|
||||||
"""Test that we can update entry."""
|
|
||||||
assert await async_setup_component(hass, "config", {})
|
|
||||||
ws_client = await hass_ws_client(hass)
|
|
||||||
|
|
||||||
await ws_client.send_json(
|
await ws_client.send_json(
|
||||||
{
|
{
|
||||||
"id": 5,
|
"id": 7,
|
||||||
"type": "config_entries/system_options/update",
|
"type": "config_entries/update",
|
||||||
"entry_id": "non_existing",
|
"entry_id": entry.entry_id,
|
||||||
"disable_new_entities": True,
|
"pref_disable_new_entities": False,
|
||||||
|
"pref_disable_polling": True,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
response = await ws_client.receive_json()
|
response = await ws_client.receive_json()
|
||||||
|
|
||||||
assert not response["success"]
|
assert response["success"]
|
||||||
assert response["error"]["code"] == "not_found"
|
assert response["result"]["require_restart"] is True
|
||||||
|
assert response["result"]["config_entry"]["pref_disable_new_entities"] is False
|
||||||
|
assert response["result"]["config_entry"]["pref_disable_polling"] is True
|
||||||
|
|
||||||
|
assert entry.pref_disable_new_entities is False
|
||||||
|
assert entry.pref_disable_polling is True
|
||||||
|
|
||||||
|
|
||||||
async def test_update_entry(hass, hass_ws_client):
|
async def test_update_entry(hass, hass_ws_client):
|
||||||
|
@ -785,7 +756,7 @@ async def test_update_entry(hass, hass_ws_client):
|
||||||
response = await ws_client.receive_json()
|
response = await ws_client.receive_json()
|
||||||
|
|
||||||
assert response["success"]
|
assert response["success"]
|
||||||
assert response["result"]["title"] == "Updated Title"
|
assert response["result"]["config_entry"]["title"] == "Updated Title"
|
||||||
assert entry.title == "Updated Title"
|
assert entry.title == "Updated Title"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@ def config_entry_fixture():
|
||||||
title="",
|
title="",
|
||||||
data=data,
|
data=data,
|
||||||
options={},
|
options={},
|
||||||
system_options={},
|
|
||||||
source=SOURCE_USER,
|
source=SOURCE_USER,
|
||||||
entry_id=1,
|
entry_id=1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -282,7 +282,6 @@ def config_entry_fixture():
|
||||||
title="",
|
title="",
|
||||||
data=data,
|
data=data,
|
||||||
options={CONF_TTS_PAUSE_TIME: 0},
|
options={CONF_TTS_PAUSE_TIME: 0},
|
||||||
system_options={},
|
|
||||||
source=SOURCE_USER,
|
source=SOURCE_USER,
|
||||||
entry_id=1,
|
entry_id=1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,7 +35,6 @@ def mock_config_entry():
|
||||||
},
|
},
|
||||||
source="test",
|
source="test",
|
||||||
options={},
|
options={},
|
||||||
system_options={"disable_new_entities": False},
|
|
||||||
unique_id=DOMAIN,
|
unique_id=DOMAIN,
|
||||||
entry_id="home_plus_control_entry_id",
|
entry_id="home_plus_control_entry_id",
|
||||||
)
|
)
|
||||||
|
|
|
@ -95,7 +95,6 @@ async def test_storage_is_removed_on_config_entry_removal(hass, utcnow):
|
||||||
"TestData",
|
"TestData",
|
||||||
pairing_data,
|
pairing_data,
|
||||||
"test",
|
"test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert hkid in hass.data[ENTITY_MAP].storage_data
|
assert hkid in hass.data[ENTITY_MAP].storage_data
|
||||||
|
|
|
@ -62,7 +62,6 @@ def hmip_config_entry_fixture() -> config_entries.ConfigEntry:
|
||||||
unique_id=HAPID,
|
unique_id=HAPID,
|
||||||
data=entry_data,
|
data=entry_data,
|
||||||
source=SOURCE_IMPORT,
|
source=SOURCE_IMPORT,
|
||||||
system_options={"disable_new_entities": False},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return config_entry
|
return config_entry
|
||||||
|
|
|
@ -127,7 +127,6 @@ async def setup_bridge_for_sensors(hass, mock_bridge, hostname=None):
|
||||||
domain=hue.DOMAIN,
|
domain=hue.DOMAIN,
|
||||||
title="Mock Title",
|
title="Mock Title",
|
||||||
data={"host": hostname},
|
data={"host": hostname},
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
mock_bridge.config_entry = config_entry
|
mock_bridge.config_entry = config_entry
|
||||||
hass.data[hue.DOMAIN] = {config_entry.entry_id: mock_bridge}
|
hass.data[hue.DOMAIN] = {config_entry.entry_id: mock_bridge}
|
||||||
|
|
|
@ -181,7 +181,6 @@ async def test_hue_activate_scene(hass, mock_api):
|
||||||
"Mock Title",
|
"Mock Title",
|
||||||
{"host": "mock-host", "username": "mock-username"},
|
{"host": "mock-host", "username": "mock-username"},
|
||||||
"test",
|
"test",
|
||||||
system_options={},
|
|
||||||
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
||||||
)
|
)
|
||||||
hue_bridge = bridge.HueBridge(hass, config_entry)
|
hue_bridge = bridge.HueBridge(hass, config_entry)
|
||||||
|
@ -215,7 +214,6 @@ async def test_hue_activate_scene_transition(hass, mock_api):
|
||||||
"Mock Title",
|
"Mock Title",
|
||||||
{"host": "mock-host", "username": "mock-username"},
|
{"host": "mock-host", "username": "mock-username"},
|
||||||
"test",
|
"test",
|
||||||
system_options={},
|
|
||||||
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
||||||
)
|
)
|
||||||
hue_bridge = bridge.HueBridge(hass, config_entry)
|
hue_bridge = bridge.HueBridge(hass, config_entry)
|
||||||
|
@ -249,7 +247,6 @@ async def test_hue_activate_scene_group_not_found(hass, mock_api):
|
||||||
"Mock Title",
|
"Mock Title",
|
||||||
{"host": "mock-host", "username": "mock-username"},
|
{"host": "mock-host", "username": "mock-username"},
|
||||||
"test",
|
"test",
|
||||||
system_options={},
|
|
||||||
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
||||||
)
|
)
|
||||||
hue_bridge = bridge.HueBridge(hass, config_entry)
|
hue_bridge = bridge.HueBridge(hass, config_entry)
|
||||||
|
@ -278,7 +275,6 @@ async def test_hue_activate_scene_scene_not_found(hass, mock_api):
|
||||||
"Mock Title",
|
"Mock Title",
|
||||||
{"host": "mock-host", "username": "mock-username"},
|
{"host": "mock-host", "username": "mock-username"},
|
||||||
"test",
|
"test",
|
||||||
system_options={},
|
|
||||||
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
options={CONF_ALLOW_HUE_GROUPS: True, CONF_ALLOW_UNREACHABLE: False},
|
||||||
)
|
)
|
||||||
hue_bridge = bridge.HueBridge(hass, config_entry)
|
hue_bridge = bridge.HueBridge(hass, config_entry)
|
||||||
|
|
|
@ -179,7 +179,6 @@ async def setup_bridge(hass, mock_bridge):
|
||||||
"Mock Title",
|
"Mock Title",
|
||||||
{"host": "mock-host"},
|
{"host": "mock-host"},
|
||||||
"test",
|
"test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
mock_bridge.config_entry = config_entry
|
mock_bridge.config_entry = config_entry
|
||||||
hass.data[hue.DOMAIN] = {config_entry.entry_id: mock_bridge}
|
hass.data[hue.DOMAIN] = {config_entry.entry_id: mock_bridge}
|
||||||
|
|
|
@ -41,7 +41,6 @@ async def test_setup_entry(hass: HomeAssistant):
|
||||||
CONF_PASSWORD: "password",
|
CONF_PASSWORD: "password",
|
||||||
},
|
},
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
@ -81,7 +80,6 @@ async def test_setup_entry_error(hass: HomeAssistant):
|
||||||
CONF_PASSWORD: "password",
|
CONF_PASSWORD: "password",
|
||||||
},
|
},
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
@ -122,7 +120,6 @@ async def test_unload_entry(hass: HomeAssistant):
|
||||||
CONF_PASSWORD: "password",
|
CONF_PASSWORD: "password",
|
||||||
},
|
},
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ async def test_setup_entry(hass: HomeAssistant):
|
||||||
CONF_PASSWORD: "password",
|
CONF_PASSWORD: "password",
|
||||||
},
|
},
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
@ -90,7 +89,6 @@ async def test_setup_entry_absent_measurement(hass: HomeAssistant):
|
||||||
CONF_PASSWORD: "password",
|
CONF_PASSWORD: "password",
|
||||||
},
|
},
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
config_entry.add_to_hass(hass)
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,6 @@ async def test_options_flow(hass):
|
||||||
title="Wartenau",
|
title="Wartenau",
|
||||||
data=FIXTURE_CONFIG_ENTRY,
|
data=FIXTURE_CONFIG_ENTRY,
|
||||||
source=SOURCE_USER,
|
source=SOURCE_USER,
|
||||||
system_options={"disable_new_entities": False},
|
|
||||||
options=FIXTURE_OPTIONS,
|
options=FIXTURE_OPTIONS,
|
||||||
unique_id="1234",
|
unique_id="1234",
|
||||||
)
|
)
|
||||||
|
@ -306,7 +305,6 @@ async def test_options_flow_invalid_auth(hass):
|
||||||
title="Wartenau",
|
title="Wartenau",
|
||||||
data=FIXTURE_CONFIG_ENTRY,
|
data=FIXTURE_CONFIG_ENTRY,
|
||||||
source=SOURCE_USER,
|
source=SOURCE_USER,
|
||||||
system_options={"disable_new_entities": False},
|
|
||||||
options=FIXTURE_OPTIONS,
|
options=FIXTURE_OPTIONS,
|
||||||
unique_id="1234",
|
unique_id="1234",
|
||||||
)
|
)
|
||||||
|
@ -346,7 +344,6 @@ async def test_options_flow_cannot_connect(hass):
|
||||||
title="Wartenau",
|
title="Wartenau",
|
||||||
data=FIXTURE_CONFIG_ENTRY,
|
data=FIXTURE_CONFIG_ENTRY,
|
||||||
source=SOURCE_USER,
|
source=SOURCE_USER,
|
||||||
system_options={"disable_new_entities": False},
|
|
||||||
options=FIXTURE_OPTIONS,
|
options=FIXTURE_OPTIONS,
|
||||||
unique_id="1234",
|
unique_id="1234",
|
||||||
)
|
)
|
||||||
|
|
|
@ -61,7 +61,6 @@ async def setup_platform(hass, platform: str, *, devices=None, scenes=None):
|
||||||
"Test",
|
"Test",
|
||||||
{CONF_INSTALLED_APP_ID: str(uuid4())},
|
{CONF_INSTALLED_APP_ID: str(uuid4())},
|
||||||
SOURCE_USER,
|
SOURCE_USER,
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
broker = DeviceBroker(
|
broker = DeviceBroker(
|
||||||
hass, config_entry, Mock(), Mock(), devices or [], scenes or []
|
hass, config_entry, Mock(), Mock(), devices or [], scenes or []
|
||||||
|
|
|
@ -943,7 +943,6 @@ async def test_restoring_client(hass, aioclient_mock):
|
||||||
title="Mock Title",
|
title="Mock Title",
|
||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
options={},
|
options={},
|
||||||
entry_id=1,
|
entry_id=1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -793,7 +793,6 @@ async def test_restore_client_succeed(hass, aioclient_mock):
|
||||||
title="Mock Title",
|
title="Mock Title",
|
||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
options={},
|
options={},
|
||||||
entry_id=1,
|
entry_id=1,
|
||||||
)
|
)
|
||||||
|
@ -884,7 +883,6 @@ async def test_restore_client_no_old_state(hass, aioclient_mock):
|
||||||
title="Mock Title",
|
title="Mock Title",
|
||||||
data=ENTRY_CONFIG,
|
data=ENTRY_CONFIG,
|
||||||
source="test",
|
source="test",
|
||||||
system_options={},
|
|
||||||
options={},
|
options={},
|
||||||
entry_id=1,
|
entry_id=1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -286,7 +286,6 @@ async def setup_ozw(hass, mock_openzwave):
|
||||||
"Mock Title",
|
"Mock Title",
|
||||||
{"usb_path": "mock-path", "network_key": "mock-key"},
|
{"usb_path": "mock-path", "network_key": "mock-key"},
|
||||||
"test",
|
"test",
|
||||||
system_options={},
|
|
||||||
)
|
)
|
||||||
await hass.config_entries.async_forward_entry_setup(config_entry, "lock")
|
await hass.config_entries.async_forward_entry_setup(config_entry, "lock")
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
|
@ -60,9 +60,7 @@ async def test_polling_only_updates_entities_it_should_poll(hass):
|
||||||
async def test_polling_disabled_by_config_entry(hass):
|
async def test_polling_disabled_by_config_entry(hass):
|
||||||
"""Test the polling of only updated entities."""
|
"""Test the polling of only updated entities."""
|
||||||
entity_platform = MockEntityPlatform(hass)
|
entity_platform = MockEntityPlatform(hass)
|
||||||
entity_platform.config_entry = MockConfigEntry(
|
entity_platform.config_entry = MockConfigEntry(pref_disable_polling=True)
|
||||||
system_options={"disable_polling": True}
|
|
||||||
)
|
|
||||||
|
|
||||||
poll_ent = MockEntity(should_poll=True)
|
poll_ent = MockEntity(should_poll=True)
|
||||||
|
|
||||||
|
|
|
@ -513,12 +513,12 @@ async def test_disabled_by(registry):
|
||||||
assert entry2.disabled_by is None
|
assert entry2.disabled_by is None
|
||||||
|
|
||||||
|
|
||||||
async def test_disabled_by_system_options(registry):
|
async def test_disabled_by_config_entry_pref(registry):
|
||||||
"""Test system options setting disabled_by."""
|
"""Test config entry preference setting disabled_by."""
|
||||||
mock_config = MockConfigEntry(
|
mock_config = MockConfigEntry(
|
||||||
domain="light",
|
domain="light",
|
||||||
entry_id="mock-id-1",
|
entry_id="mock-id-1",
|
||||||
system_options={"disable_new_entities": True},
|
pref_disable_new_entities=True,
|
||||||
)
|
)
|
||||||
entry = registry.async_get_or_create(
|
entry = registry.async_get_or_create(
|
||||||
"light", "hue", "AAAA", config_entry=mock_config
|
"light", "hue", "AAAA", config_entry=mock_config
|
||||||
|
|
|
@ -376,7 +376,7 @@ async def test_async_config_entry_first_refresh_success(crd, caplog):
|
||||||
|
|
||||||
async def test_not_schedule_refresh_if_system_option_disable_polling(hass):
|
async def test_not_schedule_refresh_if_system_option_disable_polling(hass):
|
||||||
"""Test we do not schedule a refresh if disable polling in config entry."""
|
"""Test we do not schedule a refresh if disable polling in config entry."""
|
||||||
entry = MockConfigEntry(system_options={"disable_polling": True})
|
entry = MockConfigEntry(pref_disable_polling=True)
|
||||||
config_entries.current_entry.set(entry)
|
config_entries.current_entry.set(entry)
|
||||||
crd = get_crd(hass, DEFAULT_UPDATE_INTERVAL)
|
crd = get_crd(hass, DEFAULT_UPDATE_INTERVAL)
|
||||||
crd.async_add_listener(lambda: None)
|
crd.async_add_listener(lambda: None)
|
||||||
|
|
|
@ -575,6 +575,13 @@ async def test_saving_and_loading(hass):
|
||||||
)
|
)
|
||||||
|
|
||||||
assert len(hass.config_entries.async_entries()) == 2
|
assert len(hass.config_entries.async_entries()) == 2
|
||||||
|
entry_1 = hass.config_entries.async_entries()[0]
|
||||||
|
|
||||||
|
hass.config_entries.async_update_entry(
|
||||||
|
entry_1,
|
||||||
|
pref_disable_polling=True,
|
||||||
|
pref_disable_new_entities=True,
|
||||||
|
)
|
||||||
|
|
||||||
# To trigger the call_later
|
# To trigger the call_later
|
||||||
async_fire_time_changed(hass, dt.utcnow() + timedelta(seconds=1))
|
async_fire_time_changed(hass, dt.utcnow() + timedelta(seconds=1))
|
||||||
|
@ -597,6 +604,8 @@ async def test_saving_and_loading(hass):
|
||||||
assert orig.data == loaded.data
|
assert orig.data == loaded.data
|
||||||
assert orig.source == loaded.source
|
assert orig.source == loaded.source
|
||||||
assert orig.unique_id == loaded.unique_id
|
assert orig.unique_id == loaded.unique_id
|
||||||
|
assert orig.pref_disable_new_entities == loaded.pref_disable_new_entities
|
||||||
|
assert orig.pref_disable_polling == loaded.pref_disable_polling
|
||||||
|
|
||||||
|
|
||||||
async def test_forward_entry_sets_up_component(hass):
|
async def test_forward_entry_sets_up_component(hass):
|
||||||
|
@ -814,14 +823,19 @@ async def test_updating_entry_system_options(manager):
|
||||||
domain="test",
|
domain="test",
|
||||||
data={"first": True},
|
data={"first": True},
|
||||||
state=config_entries.ConfigEntryState.SETUP_ERROR,
|
state=config_entries.ConfigEntryState.SETUP_ERROR,
|
||||||
system_options={"disable_new_entities": True},
|
pref_disable_new_entities=True,
|
||||||
)
|
)
|
||||||
entry.add_to_manager(manager)
|
entry.add_to_manager(manager)
|
||||||
|
|
||||||
assert entry.system_options.disable_new_entities
|
assert entry.pref_disable_new_entities is True
|
||||||
|
assert entry.pref_disable_polling is False
|
||||||
|
|
||||||
entry.system_options.update(disable_new_entities=False)
|
manager.async_update_entry(
|
||||||
assert not entry.system_options.disable_new_entities
|
entry, pref_disable_new_entities=False, pref_disable_polling=True
|
||||||
|
)
|
||||||
|
|
||||||
|
assert entry.pref_disable_new_entities is False
|
||||||
|
assert entry.pref_disable_polling is True
|
||||||
|
|
||||||
|
|
||||||
async def test_update_entry_options_and_trigger_listener(hass, manager):
|
async def test_update_entry_options_and_trigger_listener(hass, manager):
|
||||||
|
@ -2558,48 +2572,18 @@ async def test_updating_entry_with_and_without_changes(manager):
|
||||||
entry.add_to_manager(manager)
|
entry.add_to_manager(manager)
|
||||||
|
|
||||||
assert manager.async_update_entry(entry) is False
|
assert manager.async_update_entry(entry) is False
|
||||||
assert manager.async_update_entry(entry, data={"second": True}) is True
|
|
||||||
assert manager.async_update_entry(entry, data={"second": True}) is False
|
for change in (
|
||||||
assert (
|
{"data": {"second": True, "third": 456}},
|
||||||
manager.async_update_entry(entry, data={"second": True, "third": 456}) is True
|
{"data": {"second": True}},
|
||||||
)
|
{"options": {"hello": True}},
|
||||||
assert (
|
{"pref_disable_new_entities": True},
|
||||||
manager.async_update_entry(entry, data={"second": True, "third": 456}) is False
|
{"pref_disable_polling": True},
|
||||||
)
|
{"title": "sometitle"},
|
||||||
assert manager.async_update_entry(entry, options={"second": True}) is True
|
{"unique_id": "abcd1234"},
|
||||||
assert manager.async_update_entry(entry, options={"second": True}) is False
|
):
|
||||||
assert (
|
assert manager.async_update_entry(entry, **change) is True
|
||||||
manager.async_update_entry(entry, options={"second": True, "third": "123"})
|
assert manager.async_update_entry(entry, **change) is False
|
||||||
is True
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
manager.async_update_entry(entry, options={"second": True, "third": "123"})
|
|
||||||
is False
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
manager.async_update_entry(entry, system_options={"disable_new_entities": True})
|
|
||||||
is True
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
manager.async_update_entry(entry, system_options={"disable_new_entities": True})
|
|
||||||
is False
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
manager.async_update_entry(
|
|
||||||
entry, system_options={"disable_new_entities": False}
|
|
||||||
)
|
|
||||||
is True
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
manager.async_update_entry(
|
|
||||||
entry, system_options={"disable_new_entities": False}
|
|
||||||
)
|
|
||||||
is False
|
|
||||||
)
|
|
||||||
assert manager.async_update_entry(entry, title="thetitle") is False
|
|
||||||
assert manager.async_update_entry(entry, title="newtitle") is True
|
|
||||||
assert manager.async_update_entry(entry, unique_id="abc123") is False
|
|
||||||
assert manager.async_update_entry(entry, unique_id="abc1234") is True
|
|
||||||
|
|
||||||
|
|
||||||
async def test_entry_reload_calls_on_unload_listeners(hass, manager):
|
async def test_entry_reload_calls_on_unload_listeners(hass, manager):
|
||||||
|
@ -2864,3 +2848,35 @@ async def test__async_abort_entries_match(hass, manager, matchers, reason):
|
||||||
|
|
||||||
assert result["type"] == RESULT_TYPE_ABORT
|
assert result["type"] == RESULT_TYPE_ABORT
|
||||||
assert result["reason"] == reason
|
assert result["reason"] == reason
|
||||||
|
|
||||||
|
|
||||||
|
async def test_loading_old_data(hass, hass_storage):
|
||||||
|
"""Test automatically migrating old data."""
|
||||||
|
hass_storage[config_entries.STORAGE_KEY] = {
|
||||||
|
"version": 1,
|
||||||
|
"data": {
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"version": 5,
|
||||||
|
"domain": "my_domain",
|
||||||
|
"entry_id": "mock-id",
|
||||||
|
"data": {"my": "data"},
|
||||||
|
"source": "user",
|
||||||
|
"title": "Mock title",
|
||||||
|
"system_options": {"disable_new_entities": True},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
manager = config_entries.ConfigEntries(hass, {})
|
||||||
|
await manager.async_initialize()
|
||||||
|
|
||||||
|
entries = manager.async_entries()
|
||||||
|
assert len(entries) == 1
|
||||||
|
entry = entries[0]
|
||||||
|
assert entry.version == 5
|
||||||
|
assert entry.domain == "my_domain"
|
||||||
|
assert entry.entry_id == "mock-id"
|
||||||
|
assert entry.title == "Mock title"
|
||||||
|
assert entry.data == {"my": "data"}
|
||||||
|
assert entry.pref_disable_new_entities is True
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue