diff --git a/homeassistant/components/cloud/__init__.py b/homeassistant/components/cloud/__init__.py index cd8e5101e73..80c02571d24 100644 --- a/homeassistant/components/cloud/__init__.py +++ b/homeassistant/components/cloud/__init__.py @@ -55,6 +55,7 @@ from .const import ( CONF_SERVICEHANDLERS_SERVER, CONF_THINGTALK_SERVER, CONF_USER_POOL_ID, + DATA_CLOUD, DATA_PLATFORMS_SETUP, DOMAIN, MODE_DEV, @@ -155,14 +156,14 @@ def async_is_logged_in(hass: HomeAssistant) -> bool: Note: This returns True even if not currently connected to the cloud. """ - return DOMAIN in hass.data and hass.data[DOMAIN].is_logged_in + return DATA_CLOUD in hass.data and hass.data[DATA_CLOUD].is_logged_in @bind_hass @callback def async_is_connected(hass: HomeAssistant) -> bool: """Test if connected to the cloud.""" - return DOMAIN in hass.data and hass.data[DOMAIN].iot.connected + return DATA_CLOUD in hass.data and hass.data[DATA_CLOUD].iot.connected @callback @@ -178,7 +179,7 @@ def async_listen_connection_change( @callback def async_active_subscription(hass: HomeAssistant) -> bool: """Test if user has an active subscription.""" - return async_is_logged_in(hass) and not hass.data[DOMAIN].subscription_expired + return async_is_logged_in(hass) and not hass.data[DATA_CLOUD].subscription_expired async def async_get_or_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str: @@ -189,7 +190,7 @@ async def async_get_or_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> if not async_is_logged_in(hass): raise CloudNotAvailable - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] cloudhooks = cloud.client.cloudhooks if hook := cloudhooks.get(webhook_id): return cast(str, hook["cloudhook_url"]) @@ -206,7 +207,7 @@ async def async_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str: if not async_is_logged_in(hass): raise CloudNotAvailable - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] hook = await cloud.cloudhooks.async_create(webhook_id, True) cloudhook_url: str = hook["cloudhook_url"] return cloudhook_url @@ -215,10 +216,10 @@ async def async_create_cloudhook(hass: HomeAssistant, webhook_id: str) -> str: @bind_hass async def async_delete_cloudhook(hass: HomeAssistant, webhook_id: str) -> None: """Delete a cloudhook.""" - if DOMAIN not in hass.data: + if DATA_CLOUD not in hass.data: raise CloudNotAvailable - await hass.data[DOMAIN].cloudhooks.async_delete(webhook_id) + await hass.data[DATA_CLOUD].cloudhooks.async_delete(webhook_id) @bind_hass @@ -228,10 +229,10 @@ def async_remote_ui_url(hass: HomeAssistant) -> str: if not async_is_logged_in(hass): raise CloudNotAvailable - if not hass.data[DOMAIN].client.prefs.remote_enabled: + if not hass.data[DATA_CLOUD].client.prefs.remote_enabled: raise CloudNotAvailable - if not (remote_domain := hass.data[DOMAIN].client.prefs.remote_domain): + if not (remote_domain := hass.data[DATA_CLOUD].client.prefs.remote_domain): raise CloudNotAvailable return f"https://{remote_domain}" @@ -256,7 +257,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # Initialize Cloud websession = async_get_clientsession(hass) client = CloudClient(hass, prefs, websession, alexa_conf, google_conf) - cloud = hass.data[DOMAIN] = Cloud(client, **kwargs) + cloud = hass.data[DATA_CLOUD] = Cloud(client, **kwargs) async def _shutdown(event: Event) -> None: """Shutdown event.""" @@ -373,9 +374,7 @@ def _remote_handle_prefs_updated(cloud: Cloud[CloudClient]) -> None: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) - stt_tts_entities_added: asyncio.Event = hass.data[DATA_PLATFORMS_SETUP][ - "stt_tts_entities_added" - ] + stt_tts_entities_added = hass.data[DATA_PLATFORMS_SETUP]["stt_tts_entities_added"] stt_tts_entities_added.set() return True diff --git a/homeassistant/components/cloud/account_link.py b/homeassistant/components/cloud/account_link.py index 784de14e6ad..b67c1afad71 100644 --- a/homeassistant/components/cloud/account_link.py +++ b/homeassistant/components/cloud/account_link.py @@ -14,7 +14,7 @@ from homeassistant.const import __version__ as HA_VERSION from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_entry_oauth2_flow, event -from .const import DOMAIN +from .const import DATA_CLOUD, DOMAIN DATA_SERVICES = "cloud_account_link_services" CACHE_TIMEOUT = 3600 @@ -68,7 +68,9 @@ async def _get_services(hass: HomeAssistant) -> list[dict[str, Any]]: return services # noqa: RET504 try: - services = await account_link.async_fetch_available_services(hass.data[DOMAIN]) + services = await account_link.async_fetch_available_services( + hass.data[DATA_CLOUD] + ) except (aiohttp.ClientError, TimeoutError): return [] @@ -105,7 +107,7 @@ class CloudOAuth2Implementation(config_entry_oauth2_flow.AbstractOAuth2Implement async def async_generate_authorize_url(self, flow_id: str) -> str: """Generate a url for the user to authorize.""" helper = account_link.AuthorizeAccountHelper( - self.hass.data[DOMAIN], self.service + self.hass.data[DATA_CLOUD], self.service ) authorize_url = await helper.async_get_authorize_url() @@ -138,6 +140,6 @@ class CloudOAuth2Implementation(config_entry_oauth2_flow.AbstractOAuth2Implement async def _async_refresh_token(self, token: dict) -> dict: """Refresh a token.""" new_token = await account_link.async_fetch_access_token( - self.hass.data[DOMAIN], self.service, token["refresh_token"] + self.hass.data[DATA_CLOUD], self.service, token["refresh_token"] ) return {**token, **new_token} diff --git a/homeassistant/components/cloud/assist_pipeline.py b/homeassistant/components/cloud/assist_pipeline.py index e9d66bdcc1f..f3a591d6eda 100644 --- a/homeassistant/components/cloud/assist_pipeline.py +++ b/homeassistant/components/cloud/assist_pipeline.py @@ -27,7 +27,7 @@ async def async_create_cloud_pipeline(hass: HomeAssistant) -> str | None: """Create a cloud assist pipeline.""" # Wait for stt and tts platforms to set up and entities to be added # before creating the pipeline. - platforms_setup: dict[str, asyncio.Event] = hass.data[DATA_PLATFORMS_SETUP] + platforms_setup = hass.data[DATA_PLATFORMS_SETUP] await asyncio.gather(*(event.wait() for event in platforms_setup.values())) # Make sure the pipeline store is loaded, needed because assist_pipeline # is an after dependency of cloud @@ -91,7 +91,7 @@ async def async_migrate_cloud_pipeline_engine( else: raise ValueError(f"Invalid platform {platform}") - platforms_setup: dict[str, asyncio.Event] = hass.data[DATA_PLATFORMS_SETUP] + platforms_setup = hass.data[DATA_PLATFORMS_SETUP] await platforms_setup[wait_for_platform].wait() # Make sure the pipeline store is loaded, needed because assist_pipeline diff --git a/homeassistant/components/cloud/binary_sensor.py b/homeassistant/components/cloud/binary_sensor.py index 0693a8285ce..75cbd3c9f3d 100644 --- a/homeassistant/components/cloud/binary_sensor.py +++ b/homeassistant/components/cloud/binary_sensor.py @@ -18,7 +18,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback from .client import CloudClient -from .const import DISPATCHER_REMOTE_UPDATE, DOMAIN +from .const import DATA_CLOUD, DISPATCHER_REMOTE_UPDATE WAIT_UNTIL_CHANGE = 3 @@ -29,7 +29,7 @@ async def async_setup_entry( async_add_entities: AddEntitiesCallback, ) -> None: """Set up the Home Assistant Cloud binary sensors.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] async_add_entities([CloudRemoteBinary(cloud)]) diff --git a/homeassistant/components/cloud/const.py b/homeassistant/components/cloud/const.py index 2c58dd57340..5e9fb2e9dc7 100644 --- a/homeassistant/components/cloud/const.py +++ b/homeassistant/components/cloud/const.py @@ -2,12 +2,22 @@ from __future__ import annotations -from typing import Any +import asyncio +from typing import TYPE_CHECKING, Any +from homeassistant.util.hass_dict import HassKey from homeassistant.util.signal_type import SignalType +if TYPE_CHECKING: + from hass_nabucasa import Cloud + + from .client import CloudClient + DOMAIN = "cloud" -DATA_PLATFORMS_SETUP = "cloud_platforms_setup" +DATA_CLOUD: HassKey[Cloud[CloudClient]] = HassKey(DOMAIN) +DATA_PLATFORMS_SETUP: HassKey[dict[str, asyncio.Event]] = HassKey( + "cloud_platforms_setup" +) REQUEST_TIMEOUT = 10 PREF_ENABLE_ALEXA = "alexa_enabled" diff --git a/homeassistant/components/cloud/http_api.py b/homeassistant/components/cloud/http_api.py index bd2860b19df..b1931515745 100644 --- a/homeassistant/components/cloud/http_api.py +++ b/homeassistant/components/cloud/http_api.py @@ -38,7 +38,7 @@ from .alexa_config import entity_supported as entity_supported_by_alexa from .assist_pipeline import async_create_cloud_pipeline from .client import CloudClient from .const import ( - DOMAIN, + DATA_CLOUD, PREF_ALEXA_REPORT_STATE, PREF_DISABLE_2FA, PREF_ENABLE_ALEXA, @@ -196,7 +196,7 @@ class GoogleActionsSyncView(HomeAssistantView): async def post(self, request: web.Request) -> web.Response: """Trigger a Google Actions sync.""" hass = request.app[KEY_HASS] - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] gconf = await cloud.client.get_google_config() status = await gconf.async_sync_entities(gconf.agent_user_id) return self.json({}, status_code=status) @@ -216,7 +216,7 @@ class CloudLoginView(HomeAssistantView): async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: """Handle login request.""" hass = request.app[KEY_HASS] - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] await cloud.login(data["email"], data["password"]) if "assist_pipeline" in hass.config.components: @@ -237,7 +237,7 @@ class CloudLogoutView(HomeAssistantView): async def post(self, request: web.Request) -> web.Response: """Handle logout request.""" hass = request.app[KEY_HASS] - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] async with asyncio.timeout(REQUEST_TIMEOUT): await cloud.logout() @@ -264,7 +264,7 @@ class CloudRegisterView(HomeAssistantView): async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: """Handle registration request.""" hass = request.app[KEY_HASS] - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] client_metadata = None @@ -301,7 +301,7 @@ class CloudResendConfirmView(HomeAssistantView): async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: """Handle resending confirm email code request.""" hass = request.app[KEY_HASS] - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] async with asyncio.timeout(REQUEST_TIMEOUT): await cloud.auth.async_resend_email_confirm(data["email"]) @@ -321,7 +321,7 @@ class CloudForgotPasswordView(HomeAssistantView): async def post(self, request: web.Request, data: dict[str, Any]) -> web.Response: """Handle forgot password request.""" hass = request.app[KEY_HASS] - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] async with asyncio.timeout(REQUEST_TIMEOUT): await cloud.auth.async_forgot_password(data["email"]) @@ -341,7 +341,7 @@ async def websocket_cloud_remove_data( Async friendly. """ - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] if cloud.is_logged_in: connection.send_message( websocket_api.error_message( @@ -367,7 +367,7 @@ async def websocket_cloud_status( Async friendly. """ - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] connection.send_message( websocket_api.result_message(msg["id"], await _account_data(hass, cloud)) ) @@ -391,7 +391,7 @@ def _require_cloud_login( msg: dict[str, Any], ) -> None: """Require to be logged into the cloud.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] if not cloud.is_logged_in: connection.send_message( websocket_api.error_message( @@ -414,7 +414,7 @@ async def websocket_subscription( msg: dict[str, Any], ) -> None: """Handle request for account info.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] if (data := await async_subscription_info(cloud)) is None: connection.send_error( msg["id"], "request_failed", "Failed to request subscription" @@ -457,7 +457,7 @@ async def websocket_update_prefs( msg: dict[str, Any], ) -> None: """Handle request for account info.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] changes = dict(msg) changes.pop("id") @@ -508,7 +508,7 @@ async def websocket_hook_create( msg: dict[str, Any], ) -> None: """Handle request for account info.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] hook = await cloud.cloudhooks.async_create(msg["webhook_id"], False) connection.send_message(websocket_api.result_message(msg["id"], hook)) @@ -528,7 +528,7 @@ async def websocket_hook_delete( msg: dict[str, Any], ) -> None: """Handle request for account info.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] await cloud.cloudhooks.async_delete(msg["webhook_id"]) connection.send_message(websocket_api.result_message(msg["id"])) @@ -597,7 +597,7 @@ async def websocket_remote_connect( msg: dict[str, Any], ) -> None: """Handle request for connect remote.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] await cloud.client.prefs.async_update(remote_enabled=True) connection.send_result(msg["id"], await _account_data(hass, cloud)) @@ -613,7 +613,7 @@ async def websocket_remote_disconnect( msg: dict[str, Any], ) -> None: """Handle request for disconnect remote.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] await cloud.client.prefs.async_update(remote_enabled=False) connection.send_result(msg["id"], await _account_data(hass, cloud)) @@ -634,7 +634,7 @@ async def google_assistant_get( msg: dict[str, Any], ) -> None: """Get data for a single google assistant entity.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] gconf = await cloud.client.get_google_config() entity_id: str = msg["entity_id"] state = hass.states.get(entity_id) @@ -682,7 +682,7 @@ async def google_assistant_list( msg: dict[str, Any], ) -> None: """List all google assistant entities.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] gconf = await cloud.client.get_google_config() entities = google_helpers.async_get_entities(hass, gconf) @@ -774,7 +774,7 @@ async def alexa_list( msg: dict[str, Any], ) -> None: """List all alexa entities.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] alexa_config = await cloud.client.get_alexa_config() entities = alexa_entities.async_get_entities(hass, alexa_config) @@ -800,7 +800,7 @@ async def alexa_sync( msg: dict[str, Any], ) -> None: """Sync with Alexa.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] alexa_config = await cloud.client.get_alexa_config() async with asyncio.timeout(10): @@ -830,7 +830,7 @@ async def thingtalk_convert( msg: dict[str, Any], ) -> None: """Convert a query.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] async with asyncio.timeout(10): try: diff --git a/homeassistant/components/cloud/repairs.py b/homeassistant/components/cloud/repairs.py index 9042a010589..fe418fb5340 100644 --- a/homeassistant/components/cloud/repairs.py +++ b/homeassistant/components/cloud/repairs.py @@ -5,7 +5,6 @@ from __future__ import annotations import asyncio from typing import Any -from hass_nabucasa import Cloud import voluptuous as vol from homeassistant.components.repairs import ( @@ -17,8 +16,7 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers import issue_registry as ir -from .client import CloudClient -from .const import DOMAIN +from .const import DATA_CLOUD, DOMAIN from .subscription import async_migrate_paypal_agreement, async_subscription_info BACKOFF_TIME = 5 @@ -73,7 +71,7 @@ class LegacySubscriptionRepairFlow(RepairsFlow): async def async_step_change_plan(self, _: None = None) -> FlowResult: """Wait for the user to authorize the app installation.""" - cloud: Cloud[CloudClient] = self.hass.data[DOMAIN] + cloud = self.hass.data[DATA_CLOUD] async def _async_wait_for_plan_change() -> None: flow_manager = repairs_flow_manager(self.hass) diff --git a/homeassistant/components/cloud/stt.py b/homeassistant/components/cloud/stt.py index c68e9f245ee..b2154448d3a 100644 --- a/homeassistant/components/cloud/stt.py +++ b/homeassistant/components/cloud/stt.py @@ -2,7 +2,6 @@ from __future__ import annotations -import asyncio from collections.abc import AsyncIterable import logging @@ -28,7 +27,7 @@ from homeassistant.setup import async_when_setup from .assist_pipeline import async_migrate_cloud_pipeline_engine from .client import CloudClient -from .const import DATA_PLATFORMS_SETUP, DOMAIN, STT_ENTITY_UNIQUE_ID +from .const import DATA_CLOUD, DATA_PLATFORMS_SETUP, STT_ENTITY_UNIQUE_ID _LOGGER = logging.getLogger(__name__) @@ -39,9 +38,9 @@ async def async_setup_entry( async_add_entities: AddEntitiesCallback, ) -> None: """Set up Home Assistant Cloud speech platform via config entry.""" - stt_platform_loaded: asyncio.Event = hass.data[DATA_PLATFORMS_SETUP][Platform.STT] + stt_platform_loaded = hass.data[DATA_PLATFORMS_SETUP][Platform.STT] stt_platform_loaded.set() - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] async_add_entities([CloudProviderEntity(cloud)]) diff --git a/homeassistant/components/cloud/system_health.py b/homeassistant/components/cloud/system_health.py index 866626f4c79..0e65aa93eaf 100644 --- a/homeassistant/components/cloud/system_health.py +++ b/homeassistant/components/cloud/system_health.py @@ -2,13 +2,10 @@ from typing import Any -from hass_nabucasa import Cloud - from homeassistant.components import system_health from homeassistant.core import HomeAssistant, callback -from .client import CloudClient -from .const import DOMAIN +from .const import DATA_CLOUD @callback @@ -21,7 +18,7 @@ def async_register( async def system_health_info(hass: HomeAssistant) -> dict[str, Any]: """Get info for the info page.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] client = cloud.client data: dict[str, Any] = { diff --git a/homeassistant/components/cloud/tts.py b/homeassistant/components/cloud/tts.py index 53cec74d133..8cf18c08314 100644 --- a/homeassistant/components/cloud/tts.py +++ b/homeassistant/components/cloud/tts.py @@ -2,7 +2,6 @@ from __future__ import annotations -import asyncio import logging from typing import Any @@ -31,7 +30,7 @@ from homeassistant.setup import async_when_setup from .assist_pipeline import async_migrate_cloud_pipeline_engine from .client import CloudClient -from .const import DATA_PLATFORMS_SETUP, DOMAIN, TTS_ENTITY_UNIQUE_ID +from .const import DATA_CLOUD, DATA_PLATFORMS_SETUP, DOMAIN, TTS_ENTITY_UNIQUE_ID from .prefs import CloudPreferences ATTR_GENDER = "gender" @@ -97,7 +96,7 @@ async def async_get_engine( discovery_info: DiscoveryInfoType | None = None, ) -> CloudProvider: """Set up Cloud speech component.""" - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] cloud_provider = CloudProvider(cloud) if discovery_info is not None: discovery_info["platform_loaded"].set() @@ -110,9 +109,9 @@ async def async_setup_entry( async_add_entities: AddEntitiesCallback, ) -> None: """Set up Home Assistant Cloud text-to-speech platform.""" - tts_platform_loaded: asyncio.Event = hass.data[DATA_PLATFORMS_SETUP][Platform.TTS] + tts_platform_loaded = hass.data[DATA_PLATFORMS_SETUP][Platform.TTS] tts_platform_loaded.set() - cloud: Cloud[CloudClient] = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] async_add_entities([CloudTTSEntity(cloud)]) diff --git a/tests/components/cloud/__init__.py b/tests/components/cloud/__init__.py index d527cbbeec2..82280336a8c 100644 --- a/tests/components/cloud/__init__.py +++ b/tests/components/cloud/__init__.py @@ -2,10 +2,9 @@ from unittest.mock import AsyncMock, patch -from hass_nabucasa import Cloud - from homeassistant.components import cloud from homeassistant.components.cloud import const, prefs as cloud_prefs +from homeassistant.components.cloud.const import DATA_CLOUD from homeassistant.setup import async_setup_component PIPELINE_DATA = { @@ -64,7 +63,7 @@ async def mock_cloud(hass, config=None): assert await async_setup_component(hass, "homeassistant", {}) assert await async_setup_component(hass, cloud.DOMAIN, {"cloud": config or {}}) - cloud_inst: Cloud = hass.data["cloud"] + cloud_inst = hass.data[DATA_CLOUD] with patch("hass_nabucasa.Cloud.run_executor", AsyncMock(return_value=None)): await cloud_inst.initialize() @@ -79,5 +78,5 @@ def mock_cloud_prefs(hass, prefs): const.PREF_GOOGLE_SETTINGS_VERSION: cloud_prefs.GOOGLE_SETTINGS_VERSION, } prefs_to_set.update(prefs) - hass.data[cloud.DOMAIN].client._prefs._prefs = prefs_to_set - return hass.data[cloud.DOMAIN].client._prefs + hass.data[DATA_CLOUD].client._prefs._prefs = prefs_to_set + return hass.data[DATA_CLOUD].client._prefs diff --git a/tests/components/cloud/conftest.py b/tests/components/cloud/conftest.py index ebd9ea6663e..3058718551e 100644 --- a/tests/components/cloud/conftest.py +++ b/tests/components/cloud/conftest.py @@ -17,7 +17,8 @@ import jwt import pytest from typing_extensions import AsyncGenerator -from homeassistant.components.cloud import CloudClient, const, prefs +from homeassistant.components.cloud import CloudClient, prefs +from homeassistant.components.cloud.const import DATA_CLOUD from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component from homeassistant.util.dt import utcnow @@ -223,7 +224,7 @@ async def mock_cloud_setup(hass): @pytest.fixture def mock_cloud_login(hass, mock_cloud_setup): """Mock cloud is logged in.""" - hass.data[const.DOMAIN].id_token = jwt.encode( + hass.data[DATA_CLOUD].id_token = jwt.encode( { "email": "hello@home-assistant.io", "custom:sub-exp": "2300-01-03", @@ -231,7 +232,7 @@ def mock_cloud_login(hass, mock_cloud_setup): }, "test", ) - with patch.object(hass.data[const.DOMAIN].auth, "async_check_token"): + with patch.object(hass.data[DATA_CLOUD].auth, "async_check_token"): yield @@ -248,7 +249,7 @@ def mock_auth_fixture(): @pytest.fixture def mock_expired_cloud_login(hass, mock_cloud_setup): """Mock cloud is logged in.""" - hass.data[const.DOMAIN].id_token = jwt.encode( + hass.data[DATA_CLOUD].id_token = jwt.encode( { "email": "hello@home-assistant.io", "custom:sub-exp": "2018-01-01", diff --git a/tests/components/cloud/test_account_link.py b/tests/components/cloud/test_account_link.py index 3f108961bc5..7a85531904a 100644 --- a/tests/components/cloud/test_account_link.py +++ b/tests/components/cloud/test_account_link.py @@ -9,6 +9,7 @@ import pytest from homeassistant import config_entries from homeassistant.components.cloud import account_link +from homeassistant.components.cloud.const import DATA_CLOUD from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType from homeassistant.helpers import config_entry_oauth2_flow @@ -133,7 +134,7 @@ async def test_setup_provide_implementation(hass: HomeAssistant) -> None: async def test_get_services_cached(hass: HomeAssistant) -> None: """Test that we cache services.""" - hass.data["cloud"] = None + hass.data[DATA_CLOUD] = None services = 1 @@ -165,7 +166,7 @@ async def test_get_services_cached(hass: HomeAssistant) -> None: async def test_get_services_error(hass: HomeAssistant) -> None: """Test that we cache services.""" - hass.data["cloud"] = None + hass.data[DATA_CLOUD] = None with ( patch.object(account_link, "CACHE_TIMEOUT", 0), @@ -181,7 +182,7 @@ async def test_get_services_error(hass: HomeAssistant) -> None: @pytest.mark.usefixtures("current_request_with_host") async def test_implementation(hass: HomeAssistant, flow_handler) -> None: """Test Cloud OAuth2 implementation.""" - hass.data["cloud"] = None + hass.data[DATA_CLOUD] = None impl = account_link.CloudOAuth2Implementation(hass, "test") assert impl.name == "Home Assistant Cloud" diff --git a/tests/components/cloud/test_alexa_config.py b/tests/components/cloud/test_alexa_config.py index f37ee114220..e4ad425d4d4 100644 --- a/tests/components/cloud/test_alexa_config.py +++ b/tests/components/cloud/test_alexa_config.py @@ -8,6 +8,7 @@ import pytest from homeassistant.components.alexa import errors from homeassistant.components.cloud import ALEXA_SCHEMA, alexa_config from homeassistant.components.cloud.const import ( + DATA_CLOUD, PREF_ALEXA_DEFAULT_EXPOSE, PREF_ALEXA_ENTITY_CONFIGS, PREF_SHOULD_EXPOSE, @@ -425,7 +426,7 @@ async def test_alexa_entity_registry_sync( expose_new(hass, True) await alexa_config.CloudAlexaConfig( - hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ).async_initialize() with patch_sync_helper() as (to_update, to_remove): @@ -506,11 +507,11 @@ def test_enabled_requires_valid_sub( ) -> None: """Test that alexa config enabled requires a valid Cloud sub.""" assert cloud_prefs.alexa_enabled - assert hass.data["cloud"].is_logged_in - assert hass.data["cloud"].subscription_expired + assert hass.data[DATA_CLOUD].is_logged_in + assert hass.data[DATA_CLOUD].subscription_expired config = alexa_config.CloudAlexaConfig( - hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, ALEXA_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ) assert not config.enabled diff --git a/tests/components/cloud/test_client.py b/tests/components/cloud/test_client.py index 3126d56e3fb..62af4e88857 100644 --- a/tests/components/cloud/test_client.py +++ b/tests/components/cloud/test_client.py @@ -15,6 +15,7 @@ from homeassistant.components.cloud.client import ( CloudClient, ) from homeassistant.components.cloud.const import ( + DATA_CLOUD, PREF_ALEXA_REPORT_STATE, PREF_ENABLE_ALEXA, PREF_ENABLE_GOOGLE, @@ -63,7 +64,7 @@ async def test_handler_alexa(hass: HomeAssistant) -> None: ) mock_cloud_prefs(hass, {PREF_ALEXA_REPORT_STATE: False}) - cloud = hass.data["cloud"] + cloud = hass.data[DATA_CLOUD] resp = await cloud.client.async_alexa_message( test_alexa.get_new_request("Alexa.Discovery", "Discover") @@ -83,7 +84,7 @@ async def test_handler_alexa(hass: HomeAssistant) -> None: async def test_handler_alexa_disabled(hass: HomeAssistant, mock_cloud_fixture) -> None: """Test handler Alexa when user has disabled it.""" mock_cloud_fixture._prefs[PREF_ENABLE_ALEXA] = False - cloud = hass.data["cloud"] + cloud = hass.data[DATA_CLOUD] resp = await cloud.client.async_alexa_message( test_alexa.get_new_request("Alexa.Discovery", "Discover") @@ -117,7 +118,7 @@ async def test_handler_google_actions(hass: HomeAssistant) -> None: ) mock_cloud_prefs(hass, {}) - cloud = hass.data["cloud"] + cloud = hass.data[DATA_CLOUD] reqid = "5711642932632160983" data = {"requestId": reqid, "inputs": [{"intent": "action.devices.SYNC"}]} @@ -164,7 +165,7 @@ async def test_handler_google_actions_disabled( reqid = "5711642932632160983" data = {"requestId": reqid, "inputs": [{"intent": intent}]} - cloud = hass.data["cloud"] + cloud = hass.data[DATA_CLOUD] with patch( "hass_nabucasa.Cloud._decode_claims", return_value={"cognito:username": "myUserName"}, @@ -182,7 +183,7 @@ async def test_webhook_msg( with patch("hass_nabucasa.Cloud.initialize"): setup = await async_setup_component(hass, "cloud", {"cloud": {}}) assert setup - cloud = hass.data["cloud"] + cloud = hass.data[DATA_CLOUD] await cloud.client.prefs.async_initialize() await cloud.client.prefs.async_update( @@ -269,7 +270,7 @@ async def test_google_config_expose_entity( "light", "test", "unique", suggested_object_id="kitchen" ) - cloud_client = hass.data[DOMAIN].client + cloud_client = hass.data[DATA_CLOUD].client state = State(entity_entry.entity_id, "on") gconf = await cloud_client.get_google_config() @@ -293,7 +294,7 @@ async def test_google_config_should_2fa( "light", "test", "unique", suggested_object_id="kitchen" ) - cloud_client = hass.data[DOMAIN].client + cloud_client = hass.data[DATA_CLOUD].client gconf = await cloud_client.get_google_config() state = State(entity_entry.entity_id, "on") @@ -350,7 +351,7 @@ async def test_system_msg(hass: HomeAssistant) -> None: with patch("hass_nabucasa.Cloud.initialize"): setup = await async_setup_component(hass, "cloud", {"cloud": {}}) assert setup - cloud = hass.data["cloud"] + cloud = hass.data[DATA_CLOUD] assert cloud.client.relayer_region is None @@ -373,7 +374,7 @@ async def test_cloud_connection_info(hass: HomeAssistant) -> None: hexmock.return_value = "12345678901234567890" setup = await async_setup_component(hass, "cloud", {"cloud": {}}) assert setup - cloud = hass.data["cloud"] + cloud = hass.data[DATA_CLOUD] response = await cloud.client.async_cloud_connection_info({}) diff --git a/tests/components/cloud/test_google_config.py b/tests/components/cloud/test_google_config.py index 89882d92037..40d3f6ef2c5 100644 --- a/tests/components/cloud/test_google_config.py +++ b/tests/components/cloud/test_google_config.py @@ -8,6 +8,7 @@ import pytest from homeassistant.components.cloud import GACTIONS_SCHEMA from homeassistant.components.cloud.const import ( + DATA_CLOUD, PREF_DISABLE_2FA, PREF_GOOGLE_DEFAULT_EXPOSE, PREF_GOOGLE_ENTITY_CONFIGS, @@ -196,7 +197,7 @@ async def test_google_entity_registry_sync( expose_new(hass, True) config = CloudGoogleConfig( - hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ) await config.async_initialize() await config.async_connect_agent_user("mock-user-id") @@ -264,7 +265,7 @@ async def test_google_device_registry_sync( ) -> None: """Test Google config responds to device registry.""" config = CloudGoogleConfig( - hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ) # Enable exposing new entities to Google @@ -333,7 +334,7 @@ async def test_sync_google_when_started( ) -> None: """Test Google config syncs on init.""" config = CloudGoogleConfig( - hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ) with patch.object(config, "async_sync_entities_all") as mock_sync: await config.async_initialize() @@ -346,7 +347,7 @@ async def test_sync_google_on_home_assistant_start( ) -> None: """Test Google config syncs when home assistant started.""" config = CloudGoogleConfig( - hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ) hass.set_state(CoreState.not_running) with patch.object(config, "async_sync_entities_all") as mock_sync: @@ -441,11 +442,11 @@ def test_enabled_requires_valid_sub( ) -> None: """Test that google config enabled requires a valid Cloud sub.""" assert cloud_prefs.google_enabled - assert hass.data["cloud"].is_logged_in - assert hass.data["cloud"].subscription_expired + assert hass.data[DATA_CLOUD].is_logged_in + assert hass.data[DATA_CLOUD].subscription_expired config = CloudGoogleConfig( - hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ) assert not config.enabled @@ -494,7 +495,7 @@ async def test_google_handle_logout( await cloud_prefs.get_cloud_user() with patch.object( - hass.data["cloud"].auth, + hass.data[DATA_CLOUD].auth, "async_check_token", side_effect=AssertionError("Should not be called"), ): @@ -857,7 +858,7 @@ async def test_google_config_get_agent_user_id( ) -> None: """Test overridden get_agent_user_id_from_webhook method.""" config = CloudGoogleConfig( - hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data["cloud"] + hass, GACTIONS_SCHEMA({}), "mock-user-id", cloud_prefs, hass.data[DATA_CLOUD] ) assert ( config.get_agent_user_id_from_webhook(cloud_prefs.google_local_webhook_id) diff --git a/tests/components/cloud/test_init.py b/tests/components/cloud/test_init.py index 9cc1324ebc1..db8253b0329 100644 --- a/tests/components/cloud/test_init.py +++ b/tests/components/cloud/test_init.py @@ -4,7 +4,6 @@ from collections.abc import Callable, Coroutine from typing import Any from unittest.mock import MagicMock, patch -from hass_nabucasa import Cloud import pytest from homeassistant.components import cloud @@ -13,7 +12,7 @@ from homeassistant.components.cloud import ( CloudNotConnected, async_get_or_create_cloudhook, ) -from homeassistant.components.cloud.const import DOMAIN, PREF_CLOUDHOOKS +from homeassistant.components.cloud.const import DATA_CLOUD, DOMAIN, PREF_CLOUDHOOKS from homeassistant.components.cloud.prefs import STORAGE_KEY from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import Context, HomeAssistant @@ -47,7 +46,7 @@ async def test_constructor_loads_info_from_config(hass: HomeAssistant) -> None: ) assert result - cl = hass.data["cloud"] + cl = hass.data[DATA_CLOUD] assert cl.mode == cloud.MODE_DEV assert cl.cognito_client_id == "test-cognito_client_id" assert cl.user_pool_id == "test-user_pool_id" @@ -65,7 +64,7 @@ async def test_remote_services( hass: HomeAssistant, mock_cloud_fixture, hass_read_only_user: MockUser ) -> None: """Setup cloud component and test services.""" - cloud = hass.data[DOMAIN] + cloud = hass.data[DATA_CLOUD] assert hass.services.has_service(DOMAIN, "remote_connect") assert hass.services.has_service(DOMAIN, "remote_disconnect") @@ -145,7 +144,7 @@ async def test_setup_existing_cloud_user( async def test_on_connect(hass: HomeAssistant, mock_cloud_fixture) -> None: """Test cloud on connect triggers.""" - cl: Cloud[cloud.client.CloudClient] = hass.data["cloud"] + cl = hass.data[DATA_CLOUD] assert len(cl.iot._on_connect) == 3 @@ -202,7 +201,7 @@ async def test_on_connect(hass: HomeAssistant, mock_cloud_fixture) -> None: async def test_remote_ui_url(hass: HomeAssistant, mock_cloud_fixture) -> None: """Test getting remote ui url.""" - cl = hass.data["cloud"] + cl = hass.data[DATA_CLOUD] # Not logged in with pytest.raises(cloud.CloudNotAvailable):