Fix config entry has options check (#25976)

* Fix config entry has options check

* Register webhook/discovery config flows with classes

* Fix types

* Apply suggestions from code review

Co-Authored-By: Martin Hjelmare <marhje52@kth.se>
This commit is contained in:
Paulus Schoutsen 2019-08-16 16:19:19 -07:00 committed by GitHub
parent 57ef721d5d
commit 8b66c11706
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 115 additions and 87 deletions

View File

@ -54,8 +54,18 @@ class ConfigManagerEntryIndexView(HomeAssistantView):
"""List available config entries.""" """List available config entries."""
hass = request.app["hass"] hass = request.app["hass"]
return self.json( results = []
[
for entry in hass.config_entries.async_entries():
handler = config_entries.HANDLERS.get(entry.domain)
supports_options = (
# Guard in case handler is no longer registered (custom compnoent etc)
handler is not None
# pylint: disable=comparison-with-callable
and handler.async_get_options_flow
!= config_entries.ConfigFlow.async_get_options_flow
)
results.append(
{ {
"entry_id": entry.entry_id, "entry_id": entry.entry_id,
"domain": entry.domain, "domain": entry.domain,
@ -63,15 +73,12 @@ class ConfigManagerEntryIndexView(HomeAssistantView):
"source": entry.source, "source": entry.source,
"state": entry.state, "state": entry.state,
"connection_class": entry.connection_class, "connection_class": entry.connection_class,
"supports_options": hasattr( "supports_options": supports_options,
config_entries.HANDLERS.get(entry.domain),
"async_get_options_flow",
),
} }
for entry in hass.config_entries.async_entries()
]
) )
return self.json(results)
class ConfigManagerEntryResourceView(HomeAssistantView): class ConfigManagerEntryResourceView(HomeAssistantView):
"""View to interact with a config entry.""" """View to interact with a config entry."""

View File

@ -1,29 +1,11 @@
"""Helpers for data entry flows for config entries.""" """Helpers for data entry flows for config entries."""
from functools import partial from typing import Callable, Awaitable, Union
from homeassistant import config_entries from homeassistant import config_entries
from .typing import HomeAssistantType from .typing import HomeAssistantType
# mypy: allow-untyped-defs # mypy: allow-untyped-defs
DiscoveryFunctionType = Callable[[], Union[Awaitable[bool], bool]]
def register_discovery_flow(domain, title, discovery_function, connection_class):
"""Register flow for discovered integrations that not require auth."""
config_entries.HANDLERS.register(domain)(
partial(
DiscoveryFlowHandler, domain, title, discovery_function, connection_class
)
)
def register_webhook_flow(domain, title, description_placeholder, allow_multiple=False):
"""Register flow for webhook integrations."""
config_entries.HANDLERS.register(domain)(
partial(
WebhookFlowHandler, domain, title, description_placeholder, allow_multiple
)
)
class DiscoveryFlowHandler(config_entries.ConfigFlow): class DiscoveryFlowHandler(config_entries.ConfigFlow):
@ -31,7 +13,13 @@ class DiscoveryFlowHandler(config_entries.ConfigFlow):
VERSION = 1 VERSION = 1
def __init__(self, domain, title, discovery_function, connection_class): def __init__(
self,
domain: str,
title: str,
discovery_function: DiscoveryFunctionType,
connection_class: str,
) -> None:
"""Initialize the discovery config flow.""" """Initialize the discovery config flow."""
self._domain = domain self._domain = domain
self._title = title self._title = title
@ -91,12 +79,35 @@ class DiscoveryFlowHandler(config_entries.ConfigFlow):
return self.async_create_entry(title=self._title, data={}) return self.async_create_entry(title=self._title, data={})
def register_discovery_flow(
domain: str,
title: str,
discovery_function: DiscoveryFunctionType,
connection_class: str,
) -> None:
"""Register flow for discovered integrations that not require auth."""
class DiscoveryFlow(DiscoveryFlowHandler):
"""Discovery flow handler."""
def __init__(self) -> None:
super().__init__(domain, title, discovery_function, connection_class)
config_entries.HANDLERS.register(domain)(DiscoveryFlow)
class WebhookFlowHandler(config_entries.ConfigFlow): class WebhookFlowHandler(config_entries.ConfigFlow):
"""Handle a webhook config flow.""" """Handle a webhook config flow."""
VERSION = 1 VERSION = 1
def __init__(self, domain, title, description_placeholder, allow_multiple): def __init__(
self,
domain: str,
title: str,
description_placeholder: dict,
allow_multiple: bool,
) -> None:
"""Initialize the discovery config flow.""" """Initialize the discovery config flow."""
self._domain = domain self._domain = domain
self._title = title self._title = title
@ -131,6 +142,20 @@ class WebhookFlowHandler(config_entries.ConfigFlow):
) )
def register_webhook_flow(
domain: str, title: str, description_placeholder: dict, allow_multiple: bool = False
) -> None:
"""Register flow for webhook integrations."""
class WebhookFlow(WebhookFlowHandler):
"""Webhook flow handler."""
def __init__(self) -> None:
super().__init__(domain, title, description_placeholder, allow_multiple)
config_entries.HANDLERS.register(domain)(WebhookFlow)
async def webhook_async_remove_entry( async def webhook_async_remove_entry(
hass: HomeAssistantType, entry: config_entries.ConfigEntry hass: HomeAssistantType, entry: config_entries.ConfigEntry
) -> None: ) -> None:

View File

@ -37,6 +37,10 @@ def client(hass, hass_client):
yield hass.loop.run_until_complete(hass_client()) yield hass.loop.run_until_complete(hass_client())
async def test_get_entries(hass, client):
"""Test get entries."""
with patch.dict(HANDLERS, clear=True):
@HANDLERS.register("comp1") @HANDLERS.register("comp1")
class Comp1ConfigFlow: class Comp1ConfigFlow:
"""Config flow with options flow.""" """Config flow with options flow."""
@ -47,18 +51,10 @@ class Comp1ConfigFlow:
"""Get options flow.""" """Get options flow."""
pass pass
hass.helpers.config_entry_flow.register_discovery_flow(
"comp2", "Comp 2", lambda: None, core_ce.CONN_CLASS_ASSUMED
)
@HANDLERS.register("comp2")
class Comp2ConfigFlow:
"""Config flow without options flow."""
def __init__(self):
"""Init."""
pass
async def test_get_entries(hass, client):
"""Test get entries."""
MockConfigEntry( MockConfigEntry(
domain="comp1", domain="comp1",
title="Test 1", title="Test 1",