From 10b083bbf59bf24e8099fc3002a8fbc6460bc2f8 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 23 Jun 2022 05:41:34 -0400 Subject: [PATCH] Sync empty entities when Google is disabled in cloud (#72806) --- homeassistant/components/cloud/client.py | 6 +++--- .../components/cloud/google_config.py | 1 + .../components/google_assistant/helpers.py | 8 ++++--- .../components/google_assistant/smart_home.py | 21 ++++++++++++++++--- tests/components/cloud/test_client.py | 21 +++++++++++++++---- 5 files changed, 44 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/cloud/client.py b/homeassistant/components/cloud/client.py index c47544f9d99..6011e9bf551 100644 --- a/homeassistant/components/cloud/client.py +++ b/homeassistant/components/cloud/client.py @@ -210,11 +210,11 @@ class CloudClient(Interface): async def async_google_message(self, payload: dict[Any, Any]) -> dict[Any, Any]: """Process cloud google message to client.""" - if not self._prefs.google_enabled: - return ga.turned_off_response(payload) - gconf = await self.get_google_config() + if not self._prefs.google_enabled: + return ga.api_disabled_response(payload, gconf.agent_user_id) + return await ga.async_handle_message( self._hass, gconf, gconf.cloud_user, payload, gc.SOURCE_CLOUD ) diff --git a/homeassistant/components/cloud/google_config.py b/homeassistant/components/cloud/google_config.py index 81f00b69b23..9bb2e405dca 100644 --- a/homeassistant/components/cloud/google_config.py +++ b/homeassistant/components/cloud/google_config.py @@ -219,6 +219,7 @@ class CloudGoogleConfig(AbstractConfig): sync_entities = True elif not self.enabled and self.is_local_sdk_active: self.async_disable_local_sdk() + sync_entities = True self._cur_entity_prefs = prefs.google_entity_configs self._cur_default_expose = prefs.google_default_expose diff --git a/homeassistant/components/google_assistant/helpers.py b/homeassistant/components/google_assistant/helpers.py index 15a8d832403..2ed91b42ec6 100644 --- a/homeassistant/components/google_assistant/helpers.py +++ b/homeassistant/components/google_assistant/helpers.py @@ -356,9 +356,6 @@ class AbstractConfig(ABC): pprint.pformat(payload), ) - if not self.enabled: - return json_response(smart_home.turned_off_response(payload)) - if (agent_user_id := self.get_local_agent_user_id(webhook_id)) is None: # No agent user linked to this webhook, means that the user has somehow unregistered # removing webhook and stopping processing of this request. @@ -370,6 +367,11 @@ class AbstractConfig(ABC): webhook.async_unregister(self.hass, webhook_id) return None + if not self.enabled: + return json_response( + smart_home.api_disabled_response(payload, agent_user_id) + ) + result = await smart_home.async_handle_message( self.hass, self, diff --git a/homeassistant/components/google_assistant/smart_home.py b/homeassistant/components/google_assistant/smart_home.py index 805c9100d9f..227b033bcaa 100644 --- a/homeassistant/components/google_assistant/smart_home.py +++ b/homeassistant/components/google_assistant/smart_home.py @@ -99,7 +99,7 @@ async def async_devices_sync(hass, data, payload): except Exception: # pylint: disable=broad-except _LOGGER.exception("Error serializing %s", entity.entity_id) - response = {"agentUserId": agent_user_id, "devices": devices} + response = create_sync_response(agent_user_id, devices) _LOGGER.debug("Syncing entities response: %s", response) @@ -300,9 +300,24 @@ async def async_devices_proxy_selected(hass, data: RequestData, payload): return {} -def turned_off_response(message): +def create_sync_response(agent_user_id: str, devices: list): + """Return an empty sync response.""" + return { + "agentUserId": agent_user_id, + "devices": devices, + } + + +def api_disabled_response(message, agent_user_id): """Return a device turned off response.""" + inputs: list = message.get("inputs") + + if inputs and inputs[0].get("intent") == "action.devices.SYNC": + payload = create_sync_response(agent_user_id, []) + else: + payload = {"errorCode": "deviceTurnedOff"} + return { "requestId": message.get("requestId"), - "payload": {"errorCode": "deviceTurnedOff"}, + "payload": payload, } diff --git a/tests/components/cloud/test_client.py b/tests/components/cloud/test_client.py index f56a1c86d4d..c125f5c252a 100644 --- a/tests/components/cloud/test_client.py +++ b/tests/components/cloud/test_client.py @@ -134,7 +134,16 @@ async def test_handler_google_actions(hass): assert device["roomHint"] == "living room" -async def test_handler_google_actions_disabled(hass, mock_cloud_fixture): +@pytest.mark.parametrize( + "intent,response_payload", + [ + ("action.devices.SYNC", {"agentUserId": "myUserName", "devices": []}), + ("action.devices.QUERY", {"errorCode": "deviceTurnedOff"}), + ], +) +async def test_handler_google_actions_disabled( + hass, mock_cloud_fixture, intent, response_payload +): """Test handler Google Actions when user has disabled it.""" mock_cloud_fixture._prefs[PREF_ENABLE_GOOGLE] = False @@ -142,13 +151,17 @@ async def test_handler_google_actions_disabled(hass, mock_cloud_fixture): assert await async_setup_component(hass, "cloud", {}) reqid = "5711642932632160983" - data = {"requestId": reqid, "inputs": [{"intent": "action.devices.SYNC"}]} + data = {"requestId": reqid, "inputs": [{"intent": intent}]} cloud = hass.data["cloud"] - resp = await cloud.client.async_google_message(data) + with patch( + "hass_nabucasa.Cloud._decode_claims", + return_value={"cognito:username": "myUserName"}, + ): + resp = await cloud.client.async_google_message(data) assert resp["requestId"] == reqid - assert resp["payload"]["errorCode"] == "deviceTurnedOff" + assert resp["payload"] == response_payload async def test_webhook_msg(hass, caplog):