1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 04:50:05 +00:00

Refactor handling of exposed entities for cloud Alexa and Google (#89877)

* Refactor handling of exposed entities for cloud Alexa

* Tweak WS API

* Validate assistant parameter

* Address some review comments

* Refactor handling of exposed entities for cloud Google

* Raise when attempting to expose an unknown entity

* Add tests

* Adjust cloud tests

* Allow getting expose new entities flag

* Test Alexa migration

* Test Google migration

* Add WS command cloud/google_assistant/entities/get

* Fix return value

* Update typing

* Address review comments

* Rename async_get_exposed_entities to async_get_assistant_settings
This commit is contained in:
Erik Montnemery
2023-04-06 19:09:45 +02:00
committed by GitHub
parent 0d84106947
commit 44c89a6b6c
17 changed files with 1607 additions and 305 deletions

View File

@@ -15,6 +15,7 @@ from homeassistant.components.alexa.entities import LightCapabilities
from homeassistant.components.cloud.const import DOMAIN
from homeassistant.components.google_assistant.helpers import GoogleEntity
from homeassistant.core import HomeAssistant, State
from homeassistant.helpers import entity_registry as er
from homeassistant.util.location import LocationInfo
from . import mock_cloud, mock_cloud_prefs
@@ -399,11 +400,9 @@ async def test_websocket_status(
"alexa_enabled": True,
"cloudhooks": {},
"google_enabled": True,
"google_entity_configs": {},
"google_secure_devices_pin": None,
"google_default_expose": None,
"alexa_default_expose": None,
"alexa_entity_configs": {},
"alexa_report_state": True,
"google_report_state": True,
"remote_enabled": False,
@@ -520,8 +519,6 @@ async def test_websocket_update_preferences(
"alexa_enabled": False,
"google_enabled": False,
"google_secure_devices_pin": "1234",
"google_default_expose": ["light", "switch"],
"alexa_default_expose": ["sensor", "media_player"],
"tts_default_voice": ["en-GB", "male"],
}
)
@@ -531,8 +528,6 @@ async def test_websocket_update_preferences(
assert not setup_api.google_enabled
assert not setup_api.alexa_enabled
assert setup_api.google_secure_devices_pin == "1234"
assert setup_api.google_default_expose == ["light", "switch"]
assert setup_api.alexa_default_expose == ["sensor", "media_player"]
assert setup_api.tts_default_voice == ("en-GB", "male")
@@ -683,7 +678,11 @@ async def test_enabling_remote(
async def test_list_google_entities(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup_api, mock_cloud_login
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
hass_ws_client: WebSocketGenerator,
setup_api,
mock_cloud_login,
) -> None:
"""Test that we can list Google entities."""
client = await hass_ws_client(hass)
@@ -699,9 +698,25 @@ async def test_list_google_entities(
"homeassistant.components.google_assistant.helpers.async_get_entities",
return_value=[entity, entity2],
):
await client.send_json({"id": 5, "type": "cloud/google_assistant/entities"})
await client.send_json_auto_id({"type": "cloud/google_assistant/entities"})
response = await client.receive_json()
assert response["success"]
assert len(response["result"]) == 0
# Add the entities to the entity registry
entity_registry.async_get_or_create(
"light", "test", "unique", suggested_object_id="kitchen"
)
entity_registry.async_get_or_create(
"cover", "test", "unique", suggested_object_id="garage"
)
with patch(
"homeassistant.components.google_assistant.helpers.async_get_entities",
return_value=[entity, entity2],
):
await client.send_json_auto_id({"type": "cloud/google_assistant/entities"})
response = await client.receive_json()
assert response["success"]
assert len(response["result"]) == 2
assert response["result"][0] == {
@@ -716,49 +731,118 @@ async def test_list_google_entities(
}
async def test_get_google_entity(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
hass_ws_client: WebSocketGenerator,
setup_api,
mock_cloud_login,
) -> None:
"""Test that we can get a Google entity."""
client = await hass_ws_client(hass)
# Test getting an unknown entity
await client.send_json_auto_id(
{"type": "cloud/google_assistant/entities/get", "entity_id": "light.kitchen"}
)
response = await client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_found",
"message": "light.kitchen unknown or not in the entity registry",
}
# Test getting a blocked entity
entity_registry.async_get_or_create(
"group", "test", "unique", suggested_object_id="all_locks"
)
hass.states.async_set("group.all_locks", "bla")
await client.send_json_auto_id(
{"type": "cloud/google_assistant/entities/get", "entity_id": "group.all_locks"}
)
response = await client.receive_json()
assert not response["success"]
assert response["error"] == {
"code": "not_supported",
"message": "group.all_locks not supported by Google assistant",
}
entity_registry.async_get_or_create(
"light", "test", "unique", suggested_object_id="kitchen"
)
entity_registry.async_get_or_create(
"cover", "test", "unique", suggested_object_id="garage"
)
hass.states.async_set("light.kitchen", "on")
hass.states.async_set("cover.garage", "open", {"device_class": "garage"})
await client.send_json_auto_id(
{"type": "cloud/google_assistant/entities/get", "entity_id": "light.kitchen"}
)
response = await client.receive_json()
assert response["success"]
assert response["result"] == {
"entity_id": "light.kitchen",
"might_2fa": False,
"traits": ["action.devices.traits.OnOff"],
}
await client.send_json_auto_id(
{"type": "cloud/google_assistant/entities/get", "entity_id": "cover.garage"}
)
response = await client.receive_json()
assert response["success"]
assert response["result"] == {
"entity_id": "cover.garage",
"might_2fa": True,
"traits": ["action.devices.traits.OpenClose"],
}
async def test_update_google_entity(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup_api, mock_cloud_login
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
hass_ws_client: WebSocketGenerator,
setup_api,
mock_cloud_login,
) -> None:
"""Test that we can update config of a Google entity."""
entry = entity_registry.async_get_or_create(
"light", "test", "unique", suggested_object_id="kitchen"
)
client = await hass_ws_client(hass)
await client.send_json(
await client.send_json_auto_id(
{
"id": 5,
"type": "cloud/google_assistant/entities/update",
"entity_id": "light.kitchen",
"should_expose": False,
"disable_2fa": False,
}
)
response = await client.receive_json()
assert response["success"]
prefs = hass.data[DOMAIN].client.prefs
assert prefs.google_entity_configs["light.kitchen"] == {
"should_expose": False,
"disable_2fa": False,
}
await client.send_json(
await client.send_json_auto_id(
{
"id": 6,
"type": "cloud/google_assistant/entities/update",
"entity_id": "light.kitchen",
"should_expose": None,
"type": "homeassistant/expose_entity",
"assistants": ["cloud.google_assistant"],
"entity_ids": [entry.entity_id],
"should_expose": False,
}
)
response = await client.receive_json()
assert response["success"]
prefs = hass.data[DOMAIN].client.prefs
assert prefs.google_entity_configs["light.kitchen"] == {
"should_expose": None,
"disable_2fa": False,
}
assert entity_registry.async_get(entry.entity_id).options[
"cloud.google_assistant"
] == {"disable_2fa": False, "should_expose": False}
async def test_list_alexa_entities(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup_api, mock_cloud_login
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
hass_ws_client: WebSocketGenerator,
setup_api,
mock_cloud_login,
) -> None:
"""Test that we can list Alexa entities."""
client = await hass_ws_client(hass)
@@ -769,9 +853,22 @@ async def test_list_alexa_entities(
"homeassistant.components.alexa.entities.async_get_entities",
return_value=[entity],
):
await client.send_json({"id": 5, "type": "cloud/alexa/entities"})
await client.send_json_auto_id({"id": 5, "type": "cloud/alexa/entities"})
response = await client.receive_json()
assert response["success"]
assert len(response["result"]) == 0
# Add the entity to the entity registry
entity_registry.async_get_or_create(
"light", "test", "unique", suggested_object_id="kitchen"
)
with patch(
"homeassistant.components.alexa.entities.async_get_entities",
return_value=[entity],
):
await client.send_json_auto_id({"type": "cloud/alexa/entities"})
response = await client.receive_json()
assert response["success"]
assert len(response["result"]) == 1
assert response["result"][0] == {
@@ -782,37 +879,31 @@ async def test_list_alexa_entities(
async def test_update_alexa_entity(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, setup_api, mock_cloud_login
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
hass_ws_client: WebSocketGenerator,
setup_api,
mock_cloud_login,
) -> None:
"""Test that we can update config of an Alexa entity."""
entry = entity_registry.async_get_or_create(
"light", "test", "unique", suggested_object_id="kitchen"
)
client = await hass_ws_client(hass)
await client.send_json(
await client.send_json_auto_id(
{
"id": 5,
"type": "cloud/alexa/entities/update",
"entity_id": "light.kitchen",
"type": "homeassistant/expose_entity",
"assistants": ["cloud.alexa"],
"entity_ids": [entry.entity_id],
"should_expose": False,
}
)
response = await client.receive_json()
assert response["success"]
prefs = hass.data[DOMAIN].client.prefs
assert prefs.alexa_entity_configs["light.kitchen"] == {"should_expose": False}
await client.send_json(
{
"id": 6,
"type": "cloud/alexa/entities/update",
"entity_id": "light.kitchen",
"should_expose": None,
}
)
response = await client.receive_json()
assert response["success"]
prefs = hass.data[DOMAIN].client.prefs
assert prefs.alexa_entity_configs["light.kitchen"] == {"should_expose": None}
assert entity_registry.async_get(entry.entity_id).options["cloud.alexa"] == {
"should_expose": False
}
async def test_sync_alexa_entities_timeout(