Bump cloud to 0.47.1 (#55312)
* Bump cloud to 0.47.0 * Bump reqs * Bump to 0.47.1 * Do not load hass_nabucasa during http startup * fix some tests * Fix test Co-authored-by: Ludeeus <ludeeus@ludeeus.dev>
This commit is contained in:
parent
c68e87c40e
commit
27e29b714c
14 changed files with 66 additions and 31 deletions
|
@ -228,7 +228,7 @@ async def async_setup(hass, config):
|
||||||
|
|
||||||
cloud.iot.register_on_connect(_on_connect)
|
cloud.iot.register_on_connect(_on_connect)
|
||||||
|
|
||||||
await cloud.start()
|
await cloud.initialize()
|
||||||
await http_api.async_setup(hass)
|
await http_api.async_setup(hass)
|
||||||
|
|
||||||
account_link.async_setup(hass)
|
account_link.async_setup(hass)
|
||||||
|
|
|
@ -108,8 +108,8 @@ class CloudClient(Interface):
|
||||||
|
|
||||||
return self._google_config
|
return self._google_config
|
||||||
|
|
||||||
async def logged_in(self) -> None:
|
async def cloud_started(self) -> None:
|
||||||
"""When user logs in."""
|
"""When cloud is started."""
|
||||||
is_new_user = await self.prefs.async_set_username(self.cloud.username)
|
is_new_user = await self.prefs.async_set_username(self.cloud.username)
|
||||||
|
|
||||||
async def enable_alexa(_):
|
async def enable_alexa(_):
|
||||||
|
@ -150,7 +150,10 @@ class CloudClient(Interface):
|
||||||
if tasks:
|
if tasks:
|
||||||
await asyncio.gather(*(task(None) for task in tasks))
|
await asyncio.gather(*(task(None) for task in tasks))
|
||||||
|
|
||||||
async def cleanups(self) -> None:
|
async def cloud_stopped(self) -> None:
|
||||||
|
"""When the cloud is stopped."""
|
||||||
|
|
||||||
|
async def logout_cleanups(self) -> None:
|
||||||
"""Cleanup some stuff after logout."""
|
"""Cleanup some stuff after logout."""
|
||||||
await self.prefs.async_set_username(None)
|
await self.prefs.async_set_username(None)
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ class CloudGoogleConfig(AbstractConfig):
|
||||||
@property
|
@property
|
||||||
def should_report_state(self):
|
def should_report_state(self):
|
||||||
"""Return if states should be proactively reported."""
|
"""Return if states should be proactively reported."""
|
||||||
return self._cloud.is_logged_in and self._prefs.google_report_state
|
return self.enabled and self._prefs.google_report_state
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def local_sdk_webhook_id(self):
|
def local_sdk_webhook_id(self):
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"domain": "cloud",
|
"domain": "cloud",
|
||||||
"name": "Home Assistant Cloud",
|
"name": "Home Assistant Cloud",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
||||||
"requirements": ["hass-nabucasa==0.46.0"],
|
"requirements": ["hass-nabucasa==0.47.1"],
|
||||||
"dependencies": ["http", "webhook"],
|
"dependencies": ["http", "webhook"],
|
||||||
"after_dependencies": ["google_assistant", "alexa"],
|
"after_dependencies": ["google_assistant", "alexa"],
|
||||||
"codeowners": ["@home-assistant/cloud"],
|
"codeowners": ["@home-assistant/cloud"],
|
||||||
|
|
|
@ -15,10 +15,10 @@ from homeassistant.const import (
|
||||||
ATTR_SUPPORTED_FEATURES,
|
ATTR_SUPPORTED_FEATURES,
|
||||||
CLOUD_NEVER_EXPOSED_ENTITIES,
|
CLOUD_NEVER_EXPOSED_ENTITIES,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
EVENT_HOMEASSISTANT_STARTED,
|
|
||||||
STATE_UNAVAILABLE,
|
STATE_UNAVAILABLE,
|
||||||
)
|
)
|
||||||
from homeassistant.core import Context, CoreState, HomeAssistant, State, callback
|
from homeassistant.core import Context, HomeAssistant, State, callback
|
||||||
|
from homeassistant.helpers import start
|
||||||
from homeassistant.helpers.area_registry import AreaEntry
|
from homeassistant.helpers.area_registry import AreaEntry
|
||||||
from homeassistant.helpers.device_registry import DeviceEntry
|
from homeassistant.helpers.device_registry import DeviceEntry
|
||||||
from homeassistant.helpers.entity_registry import RegistryEntry
|
from homeassistant.helpers.entity_registry import RegistryEntry
|
||||||
|
@ -105,15 +105,14 @@ class AbstractConfig(ABC):
|
||||||
self._store = GoogleConfigStore(self.hass)
|
self._store = GoogleConfigStore(self.hass)
|
||||||
await self._store.async_load()
|
await self._store.async_load()
|
||||||
|
|
||||||
if self.hass.state == CoreState.running:
|
if not self.enabled:
|
||||||
await self.async_sync_entities_all()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
async def sync_google(_):
|
async def sync_google(_):
|
||||||
"""Sync entities to Google."""
|
"""Sync entities to Google."""
|
||||||
await self.async_sync_entities_all()
|
await self.async_sync_entities_all()
|
||||||
|
|
||||||
self.hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STARTED, sync_google)
|
start.async_at_start(self.hass, sync_google)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enabled(self):
|
def enabled(self):
|
||||||
|
|
|
@ -4,6 +4,8 @@ from __future__ import annotations
|
||||||
from collections.abc import Awaitable, Callable
|
from collections.abc import Awaitable, Callable
|
||||||
from ipaddress import ip_address
|
from ipaddress import ip_address
|
||||||
import logging
|
import logging
|
||||||
|
from types import ModuleType
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
from aiohttp.hdrs import X_FORWARDED_FOR, X_FORWARDED_HOST, X_FORWARDED_PROTO
|
from aiohttp.hdrs import X_FORWARDED_FOR, X_FORWARDED_HOST, X_FORWARDED_PROTO
|
||||||
from aiohttp.web import Application, HTTPBadRequest, Request, StreamResponse, middleware
|
from aiohttp.web import Application, HTTPBadRequest, Request, StreamResponse, middleware
|
||||||
|
@ -63,23 +65,30 @@ def async_setup_forwarded(
|
||||||
an HTTP 400 status code is thrown.
|
an HTTP 400 status code is thrown.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
remote: Literal[False] | None | ModuleType = None
|
||||||
from hass_nabucasa import remote # pylint: disable=import-outside-toplevel
|
|
||||||
|
|
||||||
# venv users might have already loaded it before it got upgraded so guard for this
|
|
||||||
# This can only happen when people upgrade from before 2021.8.5.
|
|
||||||
if not hasattr(remote, "is_cloud_request"):
|
|
||||||
remote = None
|
|
||||||
except ImportError:
|
|
||||||
remote = None
|
|
||||||
|
|
||||||
@middleware
|
@middleware
|
||||||
async def forwarded_middleware(
|
async def forwarded_middleware(
|
||||||
request: Request, handler: Callable[[Request], Awaitable[StreamResponse]]
|
request: Request, handler: Callable[[Request], Awaitable[StreamResponse]]
|
||||||
) -> StreamResponse:
|
) -> StreamResponse:
|
||||||
"""Process forwarded data by a reverse proxy."""
|
"""Process forwarded data by a reverse proxy."""
|
||||||
|
nonlocal remote
|
||||||
|
|
||||||
|
if remote is None:
|
||||||
|
# Initialize remote method
|
||||||
|
try:
|
||||||
|
from hass_nabucasa import ( # pylint: disable=import-outside-toplevel
|
||||||
|
remote,
|
||||||
|
)
|
||||||
|
|
||||||
|
# venv users might have an old version installed if they don't have cloud around anymore
|
||||||
|
if not hasattr(remote, "is_cloud_request"):
|
||||||
|
remote = False
|
||||||
|
except ImportError:
|
||||||
|
remote = False
|
||||||
|
|
||||||
# Skip requests from Remote UI
|
# Skip requests from Remote UI
|
||||||
if remote is not None and remote.is_cloud_request.get():
|
if remote and remote.is_cloud_request.get(): # type: ignore
|
||||||
return await handler(request)
|
return await handler(request)
|
||||||
|
|
||||||
# Handle X-Forwarded-For
|
# Handle X-Forwarded-For
|
||||||
|
|
|
@ -15,7 +15,7 @@ ciso8601==2.1.3
|
||||||
cryptography==3.3.2
|
cryptography==3.3.2
|
||||||
defusedxml==0.7.1
|
defusedxml==0.7.1
|
||||||
emoji==1.2.0
|
emoji==1.2.0
|
||||||
hass-nabucasa==0.46.0
|
hass-nabucasa==0.47.1
|
||||||
home-assistant-frontend==20210830.0
|
home-assistant-frontend==20210830.0
|
||||||
httpx==0.19.0
|
httpx==0.19.0
|
||||||
ifaddr==0.1.7
|
ifaddr==0.1.7
|
||||||
|
|
|
@ -760,7 +760,7 @@ habitipy==0.2.0
|
||||||
hangups==0.4.14
|
hangups==0.4.14
|
||||||
|
|
||||||
# homeassistant.components.cloud
|
# homeassistant.components.cloud
|
||||||
hass-nabucasa==0.46.0
|
hass-nabucasa==0.47.1
|
||||||
|
|
||||||
# homeassistant.components.splunk
|
# homeassistant.components.splunk
|
||||||
hass_splunk==0.1.1
|
hass_splunk==0.1.1
|
||||||
|
|
|
@ -441,7 +441,7 @@ habitipy==0.2.0
|
||||||
hangups==0.4.14
|
hangups==0.4.14
|
||||||
|
|
||||||
# homeassistant.components.cloud
|
# homeassistant.components.cloud
|
||||||
hass-nabucasa==0.46.0
|
hass-nabucasa==0.47.1
|
||||||
|
|
||||||
# homeassistant.components.tasmota
|
# homeassistant.components.tasmota
|
||||||
hatasmota==0.2.20
|
hatasmota==0.2.20
|
||||||
|
|
|
@ -12,7 +12,7 @@ async def mock_cloud(hass, config=None):
|
||||||
assert await async_setup_component(hass, cloud.DOMAIN, {"cloud": config or {}})
|
assert await async_setup_component(hass, cloud.DOMAIN, {"cloud": config or {}})
|
||||||
cloud_inst = hass.data["cloud"]
|
cloud_inst = hass.data["cloud"]
|
||||||
with patch("hass_nabucasa.Cloud.run_executor", AsyncMock(return_value=None)):
|
with patch("hass_nabucasa.Cloud.run_executor", AsyncMock(return_value=None)):
|
||||||
await cloud_inst.start()
|
await cloud_inst.initialize()
|
||||||
|
|
||||||
|
|
||||||
def mock_cloud_prefs(hass, prefs={}):
|
def mock_cloud_prefs(hass, prefs={}):
|
||||||
|
|
|
@ -48,6 +48,8 @@ def mock_cloud_login(hass, mock_cloud_setup):
|
||||||
},
|
},
|
||||||
"test",
|
"test",
|
||||||
)
|
)
|
||||||
|
with patch.object(hass.data[const.DOMAIN].auth, "async_check_token"):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
|
|
|
@ -134,7 +134,7 @@ async def test_handler_google_actions_disabled(hass, mock_cloud_fixture):
|
||||||
"""Test handler Google Actions when user has disabled it."""
|
"""Test handler Google Actions when user has disabled it."""
|
||||||
mock_cloud_fixture._prefs[PREF_ENABLE_GOOGLE] = False
|
mock_cloud_fixture._prefs[PREF_ENABLE_GOOGLE] = False
|
||||||
|
|
||||||
with patch("hass_nabucasa.Cloud.start"):
|
with patch("hass_nabucasa.Cloud.initialize"):
|
||||||
assert await async_setup_component(hass, "cloud", {})
|
assert await async_setup_component(hass, "cloud", {})
|
||||||
|
|
||||||
reqid = "5711642932632160983"
|
reqid = "5711642932632160983"
|
||||||
|
@ -149,7 +149,7 @@ async def test_handler_google_actions_disabled(hass, mock_cloud_fixture):
|
||||||
|
|
||||||
async def test_webhook_msg(hass, caplog):
|
async def test_webhook_msg(hass, caplog):
|
||||||
"""Test webhook msg."""
|
"""Test webhook msg."""
|
||||||
with patch("hass_nabucasa.Cloud.start"):
|
with patch("hass_nabucasa.Cloud.initialize"):
|
||||||
setup = await async_setup_component(hass, "cloud", {"cloud": {}})
|
setup = await async_setup_component(hass, "cloud", {"cloud": {}})
|
||||||
assert setup
|
assert setup
|
||||||
cloud = hass.data["cloud"]
|
cloud = hass.data["cloud"]
|
||||||
|
@ -261,7 +261,7 @@ async def test_set_username(hass):
|
||||||
)
|
)
|
||||||
client = CloudClient(hass, prefs, None, {}, {})
|
client = CloudClient(hass, prefs, None, {}, {})
|
||||||
client.cloud = MagicMock(is_logged_in=True, username="mock-username")
|
client.cloud = MagicMock(is_logged_in=True, username="mock-username")
|
||||||
await client.logged_in()
|
await client.cloud_started()
|
||||||
|
|
||||||
assert len(prefs.async_set_username.mock_calls) == 1
|
assert len(prefs.async_set_username.mock_calls) == 1
|
||||||
assert prefs.async_set_username.mock_calls[0][1][0] == "mock-username"
|
assert prefs.async_set_username.mock_calls[0][1][0] == "mock-username"
|
||||||
|
@ -279,7 +279,7 @@ async def test_login_recovers_bad_internet(hass, caplog):
|
||||||
client._alexa_config = Mock(
|
client._alexa_config = Mock(
|
||||||
async_enable_proactive_mode=Mock(side_effect=aiohttp.ClientError)
|
async_enable_proactive_mode=Mock(side_effect=aiohttp.ClientError)
|
||||||
)
|
)
|
||||||
await client.logged_in()
|
await client.cloud_started()
|
||||||
assert len(client._alexa_config.async_enable_proactive_mode.mock_calls) == 1
|
assert len(client._alexa_config.async_enable_proactive_mode.mock_calls) == 1
|
||||||
assert "Unable to activate Alexa Report State" in caplog.text
|
assert "Unable to activate Alexa Report State" in caplog.text
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ async def test_google_update_report_state(mock_conf, hass, cloud_prefs):
|
||||||
await mock_conf.async_initialize()
|
await mock_conf.async_initialize()
|
||||||
await mock_conf.async_connect_agent_user("mock-user-id")
|
await mock_conf.async_connect_agent_user("mock-user-id")
|
||||||
|
|
||||||
|
mock_conf._cloud.subscription_expired = False
|
||||||
|
|
||||||
with patch.object(mock_conf, "async_sync_entities") as mock_sync, patch(
|
with patch.object(mock_conf, "async_sync_entities") as mock_sync, patch(
|
||||||
"homeassistant.components.google_assistant.report_state.async_enable_report_state"
|
"homeassistant.components.google_assistant.report_state.async_enable_report_state"
|
||||||
) as mock_report_state:
|
) as mock_report_state:
|
||||||
|
@ -41,6 +43,25 @@ async def test_google_update_report_state(mock_conf, hass, cloud_prefs):
|
||||||
assert len(mock_report_state.mock_calls) == 1
|
assert len(mock_report_state.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_google_update_report_state_subscription_expired(
|
||||||
|
mock_conf, hass, cloud_prefs
|
||||||
|
):
|
||||||
|
"""Test Google config not reporting state when subscription has expired."""
|
||||||
|
await mock_conf.async_initialize()
|
||||||
|
await mock_conf.async_connect_agent_user("mock-user-id")
|
||||||
|
|
||||||
|
assert mock_conf._cloud.subscription_expired
|
||||||
|
|
||||||
|
with patch.object(mock_conf, "async_sync_entities") as mock_sync, patch(
|
||||||
|
"homeassistant.components.google_assistant.report_state.async_enable_report_state"
|
||||||
|
) as mock_report_state:
|
||||||
|
await cloud_prefs.async_update(google_report_state=True)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert len(mock_sync.mock_calls) == 0
|
||||||
|
assert len(mock_report_state.mock_calls) == 0
|
||||||
|
|
||||||
|
|
||||||
async def test_sync_entities(mock_conf, hass, cloud_prefs):
|
async def test_sync_entities(mock_conf, hass, cloud_prefs):
|
||||||
"""Test sync devices."""
|
"""Test sync devices."""
|
||||||
await mock_conf.async_initialize()
|
await mock_conf.async_initialize()
|
||||||
|
@ -172,6 +193,7 @@ async def test_sync_google_when_started(hass, mock_cloud_login, cloud_prefs):
|
||||||
with patch.object(config, "async_sync_entities_all") as mock_sync:
|
with patch.object(config, "async_sync_entities_all") as mock_sync:
|
||||||
await config.async_initialize()
|
await config.async_initialize()
|
||||||
await config.async_connect_agent_user("mock-user-id")
|
await config.async_connect_agent_user("mock-user-id")
|
||||||
|
await hass.async_block_till_done()
|
||||||
assert len(mock_sync.mock_calls) == 1
|
assert len(mock_sync.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
async def test_constructor_loads_info_from_config(hass):
|
async def test_constructor_loads_info_from_config(hass):
|
||||||
"""Test non-dev mode loads info from SERVERS constant."""
|
"""Test non-dev mode loads info from SERVERS constant."""
|
||||||
with patch("hass_nabucasa.Cloud.start"):
|
with patch("hass_nabucasa.Cloud.initialize"):
|
||||||
result = await async_setup_component(
|
result = await async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
"cloud",
|
"cloud",
|
||||||
|
@ -109,7 +109,7 @@ async def test_setup_existing_cloud_user(hass, hass_storage):
|
||||||
"""Test setup with API push default data."""
|
"""Test setup with API push default data."""
|
||||||
user = await hass.auth.async_create_system_user("Cloud test")
|
user = await hass.auth.async_create_system_user("Cloud test")
|
||||||
hass_storage[STORAGE_KEY] = {"version": 1, "data": {"cloud_user": user.id}}
|
hass_storage[STORAGE_KEY] = {"version": 1, "data": {"cloud_user": user.id}}
|
||||||
with patch("hass_nabucasa.Cloud.start"):
|
with patch("hass_nabucasa.Cloud.initialize"):
|
||||||
result = await async_setup_component(
|
result = await async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
"cloud",
|
"cloud",
|
||||||
|
|
Loading…
Add table
Reference in a new issue