Allow custom integrations to support application_credentials platform (#71129)

This commit is contained in:
Raman Gupta 2022-05-01 19:26:22 -04:00 committed by GitHub
parent d8ee9c1922
commit ae01ec02e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 10 deletions

View file

@ -17,12 +17,15 @@ from homeassistant.components import websocket_api
from homeassistant.components.websocket_api.connection import ActiveConnection
from homeassistant.const import CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_DOMAIN, CONF_ID
from homeassistant.core import HomeAssistant, callback
from homeassistant.generated.application_credentials import APPLICATION_CREDENTIALS
from homeassistant.helpers import collection, config_entry_oauth2_flow
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.storage import Store
from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import IntegrationNotFound, async_get_integration
from homeassistant.loader import (
IntegrationNotFound,
async_get_application_credentials,
async_get_integration,
)
from homeassistant.util import slugify
__all__ = ["ClientCredential", "AuthorizationServer", "async_import_client_credential"]
@ -234,9 +237,11 @@ async def _get_platform(
@websocket_api.websocket_command(
{vol.Required("type"): "application_credentials/config"}
)
@callback
def handle_integration_list(
@websocket_api.async_response
async def handle_integration_list(
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
) -> None:
"""Handle integrations command."""
connection.send_result(msg["id"], {"domains": APPLICATION_CREDENTIALS})
connection.send_result(
msg["id"], {"domains": await async_get_application_credentials(hass)}
)

View file

@ -24,6 +24,7 @@ from awesomeversion import (
AwesomeVersionStrategy,
)
from .generated.application_credentials import APPLICATION_CREDENTIALS
from .generated.dhcp import DHCP
from .generated.mqtt import MQTT
from .generated.ssdp import SSDP
@ -210,6 +211,20 @@ async def async_get_config_flows(
return flows
async def async_get_application_credentials(hass: HomeAssistant) -> list[str]:
"""Return cached list of application credentials."""
integrations = await async_get_custom_components(hass)
return [
*APPLICATION_CREDENTIALS,
*[
integration.domain
for integration in integrations.values()
if "application_credentials" in integration.dependencies
],
]
def async_process_zeroconf_match_dict(entry: dict[str, Any]) -> dict[str, Any]:
"""Handle backwards compat with zeroconf matchers."""
entry_without_type: dict[str, Any] = entry.copy()

View file

@ -18,7 +18,7 @@ APPLICATION_CREDENTIALS = {}
def generate_and_validate(integrations: dict[str, Integration], config: Config) -> str:
"""Validate and generate config flow data."""
"""Validate and generate application_credentials data."""
match_list = []

View file

@ -98,9 +98,9 @@ class Integration:
return self.manifest.get("quality_scale")
@property
def config_flow(self) -> str:
def config_flow(self) -> bool:
"""Return if the integration has a config flow."""
return self.manifest.get("config_flow")
return self.manifest.get("config_flow", False)
@property
def requirements(self) -> list[str]:

View file

@ -615,8 +615,7 @@ async def test_websocket_integration_list(ws_client: ClientFixture):
"""Test websocket integration list command."""
client = await ws_client()
with patch(
"homeassistant.components.application_credentials.APPLICATION_CREDENTIALS",
["example1", "example2"],
"homeassistant.loader.APPLICATION_CREDENTIALS", ["example1", "example2"]
):
assert await client.cmd_result("config") == {
"domains": ["example1", "example2"]

View file

@ -327,6 +327,26 @@ def _get_test_integration(hass, name, config_flow):
)
def _get_test_integration_with_application_credentials(hass, name):
"""Return a generated test integration with application_credentials support."""
return loader.Integration(
hass,
f"homeassistant.components.{name}",
None,
{
"name": name,
"domain": name,
"config_flow": True,
"dependencies": ["application_credentials"],
"requirements": [],
"zeroconf": [f"_{name}._tcp.local."],
"homekit": {"models": [name]},
"ssdp": [{"manufacturer": name, "modelName": name}],
"mqtt": [f"{name}/discovery"],
},
)
def _get_test_integration_with_zeroconf_matcher(hass, name, config_flow):
"""Return a generated test integration with a zeroconf matcher."""
return loader.Integration(
@ -479,6 +499,23 @@ async def test_get_zeroconf(hass):
]
async def test_get_application_credentials(hass):
"""Verify that custom components with application_credentials are found."""
test_1_integration = _get_test_integration(hass, "test_1", True)
test_2_integration = _get_test_integration_with_application_credentials(
hass, "test_2"
)
with patch("homeassistant.loader.async_get_custom_components") as mock_get:
mock_get.return_value = {
"test_1": test_1_integration,
"test_2": test_2_integration,
}
application_credentials = await loader.async_get_application_credentials(hass)
assert "test_2" in application_credentials
assert "test_1" not in application_credentials
async def test_get_zeroconf_back_compat(hass):
"""Verify that custom components with zeroconf are found and legacy matchers are converted."""
test_1_integration = _get_test_integration(hass, "test_1", True)