Bump hass-nabucasa 49 (#55823)
This commit is contained in:
parent
c6888e4faf
commit
93083513b4
7 changed files with 36 additions and 112 deletions
|
@ -6,7 +6,7 @@ import logging
|
|||
import aiohttp
|
||||
import async_timeout
|
||||
import attr
|
||||
from hass_nabucasa import Cloud, auth, thingtalk
|
||||
from hass_nabucasa import Cloud, auth, cloud_api, thingtalk
|
||||
from hass_nabucasa.const import STATE_DISCONNECTED
|
||||
from hass_nabucasa.voice import MAP_VOICE
|
||||
import voluptuous as vol
|
||||
|
@ -24,7 +24,6 @@ from homeassistant.const import (
|
|||
HTTP_BAD_GATEWAY,
|
||||
HTTP_BAD_REQUEST,
|
||||
HTTP_INTERNAL_SERVER_ERROR,
|
||||
HTTP_OK,
|
||||
HTTP_UNAUTHORIZED,
|
||||
)
|
||||
|
||||
|
@ -47,30 +46,6 @@ from .const import (
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
WS_TYPE_STATUS = "cloud/status"
|
||||
SCHEMA_WS_STATUS = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
|
||||
{vol.Required("type"): WS_TYPE_STATUS}
|
||||
)
|
||||
|
||||
|
||||
WS_TYPE_SUBSCRIPTION = "cloud/subscription"
|
||||
SCHEMA_WS_SUBSCRIPTION = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
|
||||
{vol.Required("type"): WS_TYPE_SUBSCRIPTION}
|
||||
)
|
||||
|
||||
|
||||
WS_TYPE_HOOK_CREATE = "cloud/cloudhook/create"
|
||||
SCHEMA_WS_HOOK_CREATE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
|
||||
{vol.Required("type"): WS_TYPE_HOOK_CREATE, vol.Required("webhook_id"): str}
|
||||
)
|
||||
|
||||
|
||||
WS_TYPE_HOOK_DELETE = "cloud/cloudhook/delete"
|
||||
SCHEMA_WS_HOOK_DELETE = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend(
|
||||
{vol.Required("type"): WS_TYPE_HOOK_DELETE, vol.Required("webhook_id"): str}
|
||||
)
|
||||
|
||||
|
||||
_CLOUD_ERRORS = {
|
||||
InvalidTrustedNetworks: (
|
||||
HTTP_INTERNAL_SERVER_ERROR,
|
||||
|
@ -94,17 +69,11 @@ _CLOUD_ERRORS = {
|
|||
async def async_setup(hass):
|
||||
"""Initialize the HTTP API."""
|
||||
async_register_command = hass.components.websocket_api.async_register_command
|
||||
async_register_command(WS_TYPE_STATUS, websocket_cloud_status, SCHEMA_WS_STATUS)
|
||||
async_register_command(
|
||||
WS_TYPE_SUBSCRIPTION, websocket_subscription, SCHEMA_WS_SUBSCRIPTION
|
||||
)
|
||||
async_register_command(websocket_cloud_status)
|
||||
async_register_command(websocket_subscription)
|
||||
async_register_command(websocket_update_prefs)
|
||||
async_register_command(
|
||||
WS_TYPE_HOOK_CREATE, websocket_hook_create, SCHEMA_WS_HOOK_CREATE
|
||||
)
|
||||
async_register_command(
|
||||
WS_TYPE_HOOK_DELETE, websocket_hook_delete, SCHEMA_WS_HOOK_DELETE
|
||||
)
|
||||
async_register_command(websocket_hook_create)
|
||||
async_register_command(websocket_hook_delete)
|
||||
async_register_command(websocket_remote_connect)
|
||||
async_register_command(websocket_remote_disconnect)
|
||||
|
||||
|
@ -311,6 +280,7 @@ class CloudForgotPasswordView(HomeAssistantView):
|
|||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "cloud/status"})
|
||||
async def websocket_cloud_status(hass, connection, msg):
|
||||
"""Handle request for account info.
|
||||
|
||||
|
@ -344,36 +314,19 @@ def _require_cloud_login(handler):
|
|||
|
||||
@_require_cloud_login
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command({vol.Required("type"): "cloud/subscription"})
|
||||
async def websocket_subscription(hass, connection, msg):
|
||||
"""Handle request for account info."""
|
||||
|
||||
cloud = hass.data[DOMAIN]
|
||||
|
||||
with async_timeout.timeout(REQUEST_TIMEOUT):
|
||||
response = await cloud.fetch_subscription_info()
|
||||
|
||||
if response.status != HTTP_OK:
|
||||
connection.send_message(
|
||||
websocket_api.error_message(
|
||||
msg["id"], "request_failed", "Failed to request subscription"
|
||||
)
|
||||
try:
|
||||
with async_timeout.timeout(REQUEST_TIMEOUT):
|
||||
data = await cloud_api.async_subscription_info(cloud)
|
||||
except aiohttp.ClientError:
|
||||
connection.send_error(
|
||||
msg["id"], "request_failed", "Failed to request subscription"
|
||||
)
|
||||
|
||||
data = await response.json()
|
||||
|
||||
# Check if a user is subscribed but local info is outdated
|
||||
# In that case, let's refresh and reconnect
|
||||
if data.get("provider") and not cloud.is_connected:
|
||||
_LOGGER.debug("Found disconnected account with valid subscriotion, connecting")
|
||||
await cloud.auth.async_renew_access_token()
|
||||
|
||||
# Cancel reconnect in progress
|
||||
if cloud.iot.state != STATE_DISCONNECTED:
|
||||
await cloud.iot.disconnect()
|
||||
|
||||
hass.async_create_task(cloud.iot.connect())
|
||||
|
||||
connection.send_message(websocket_api.result_message(msg["id"], data))
|
||||
else:
|
||||
connection.send_result(msg["id"], data)
|
||||
|
||||
|
||||
@_require_cloud_login
|
||||
|
@ -429,6 +382,12 @@ async def websocket_update_prefs(hass, connection, msg):
|
|||
@_require_cloud_login
|
||||
@websocket_api.async_response
|
||||
@_ws_handle_cloud_errors
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "cloud/cloudhook/create",
|
||||
vol.Required("webhook_id"): str,
|
||||
}
|
||||
)
|
||||
async def websocket_hook_create(hass, connection, msg):
|
||||
"""Handle request for account info."""
|
||||
cloud = hass.data[DOMAIN]
|
||||
|
@ -439,6 +398,12 @@ async def websocket_hook_create(hass, connection, msg):
|
|||
@_require_cloud_login
|
||||
@websocket_api.async_response
|
||||
@_ws_handle_cloud_errors
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "cloud/cloudhook/delete",
|
||||
vol.Required("webhook_id"): str,
|
||||
}
|
||||
)
|
||||
async def websocket_hook_delete(hass, connection, msg):
|
||||
"""Handle request for account info."""
|
||||
cloud = hass.data[DOMAIN]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"domain": "cloud",
|
||||
"name": "Home Assistant Cloud",
|
||||
"documentation": "https://www.home-assistant.io/integrations/cloud",
|
||||
"requirements": ["hass-nabucasa==0.47.1"],
|
||||
"requirements": ["hass-nabucasa==0.49.0"],
|
||||
"dependencies": ["http", "webhook"],
|
||||
"after_dependencies": ["google_assistant", "alexa"],
|
||||
"codeowners": ["@home-assistant/cloud"],
|
||||
|
|
|
@ -15,7 +15,7 @@ ciso8601==2.1.3
|
|||
cryptography==3.3.2
|
||||
defusedxml==0.7.1
|
||||
emoji==1.2.0
|
||||
hass-nabucasa==0.47.1
|
||||
hass-nabucasa==0.49.0
|
||||
home-assistant-frontend==20210830.0
|
||||
httpx==0.19.0
|
||||
ifaddr==0.1.7
|
||||
|
|
|
@ -760,7 +760,7 @@ habitipy==0.2.0
|
|||
hangups==0.4.14
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.47.1
|
||||
hass-nabucasa==0.49.0
|
||||
|
||||
# homeassistant.components.splunk
|
||||
hass_splunk==0.1.1
|
||||
|
|
|
@ -441,7 +441,7 @@ habitipy==0.2.0
|
|||
hangups==0.4.14
|
||||
|
||||
# homeassistant.components.cloud
|
||||
hass-nabucasa==0.47.1
|
||||
hass-nabucasa==0.49.0
|
||||
|
||||
# homeassistant.components.tasmota
|
||||
hatasmota==0.2.20
|
||||
|
|
|
@ -12,7 +12,7 @@ from . import mock_cloud, mock_cloud_prefs
|
|||
@pytest.fixture(autouse=True)
|
||||
def mock_user_data():
|
||||
"""Mock os module."""
|
||||
with patch("hass_nabucasa.Cloud.write_user_info") as writer:
|
||||
with patch("hass_nabucasa.Cloud._write_user_info") as writer:
|
||||
yield writer
|
||||
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ def setup_api_fixture(hass, aioclient_mock):
|
|||
@pytest.fixture(name="cloud_client")
|
||||
def cloud_client_fixture(hass, hass_client):
|
||||
"""Fixture that can fetch from the cloud client."""
|
||||
with patch("hass_nabucasa.Cloud.write_user_info"):
|
||||
with patch("hass_nabucasa.Cloud._write_user_info"):
|
||||
yield hass.loop.run_until_complete(hass_client())
|
||||
|
||||
|
||||
|
@ -394,59 +394,18 @@ async def test_websocket_status_not_logged_in(hass, hass_ws_client):
|
|||
assert response["result"] == {"logged_in": False, "cloud": "disconnected"}
|
||||
|
||||
|
||||
async def test_websocket_subscription_reconnect(
|
||||
async def test_websocket_subscription_info(
|
||||
hass, hass_ws_client, aioclient_mock, mock_auth, mock_cloud_login
|
||||
):
|
||||
"""Test querying the status and connecting because valid account."""
|
||||
aioclient_mock.get(SUBSCRIPTION_INFO_URL, json={"provider": "stripe"})
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
with patch(
|
||||
"hass_nabucasa.auth.CognitoAuth.async_renew_access_token"
|
||||
) as mock_renew, patch("hass_nabucasa.iot.CloudIoT.connect") as mock_connect:
|
||||
with patch("hass_nabucasa.auth.CognitoAuth.async_renew_access_token") as mock_renew:
|
||||
await client.send_json({"id": 5, "type": "cloud/subscription"})
|
||||
response = await client.receive_json()
|
||||
|
||||
assert response["result"] == {"provider": "stripe"}
|
||||
assert len(mock_renew.mock_calls) == 1
|
||||
assert len(mock_connect.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_websocket_subscription_no_reconnect_if_connected(
|
||||
hass, hass_ws_client, aioclient_mock, mock_auth, mock_cloud_login
|
||||
):
|
||||
"""Test querying the status and not reconnecting because still expired."""
|
||||
aioclient_mock.get(SUBSCRIPTION_INFO_URL, json={"provider": "stripe"})
|
||||
hass.data[DOMAIN].iot.state = STATE_CONNECTED
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
with patch(
|
||||
"hass_nabucasa.auth.CognitoAuth.async_renew_access_token"
|
||||
) as mock_renew, patch("hass_nabucasa.iot.CloudIoT.connect") as mock_connect:
|
||||
await client.send_json({"id": 5, "type": "cloud/subscription"})
|
||||
response = await client.receive_json()
|
||||
|
||||
assert response["result"] == {"provider": "stripe"}
|
||||
assert len(mock_renew.mock_calls) == 0
|
||||
assert len(mock_connect.mock_calls) == 0
|
||||
|
||||
|
||||
async def test_websocket_subscription_no_reconnect_if_expired(
|
||||
hass, hass_ws_client, aioclient_mock, mock_auth, mock_cloud_login
|
||||
):
|
||||
"""Test querying the status and not reconnecting because still expired."""
|
||||
aioclient_mock.get(SUBSCRIPTION_INFO_URL, json={"provider": "stripe"})
|
||||
client = await hass_ws_client(hass)
|
||||
|
||||
with patch(
|
||||
"hass_nabucasa.auth.CognitoAuth.async_renew_access_token"
|
||||
) as mock_renew, patch("hass_nabucasa.iot.CloudIoT.connect") as mock_connect:
|
||||
await client.send_json({"id": 5, "type": "cloud/subscription"})
|
||||
response = await client.receive_json()
|
||||
|
||||
assert response["result"] == {"provider": "stripe"}
|
||||
assert len(mock_renew.mock_calls) == 1
|
||||
assert len(mock_connect.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_websocket_subscription_fail(
|
||||
|
@ -466,7 +425,7 @@ async def test_websocket_subscription_not_logged_in(hass, hass_ws_client):
|
|||
"""Test querying the status."""
|
||||
client = await hass_ws_client(hass)
|
||||
with patch(
|
||||
"hass_nabucasa.Cloud.fetch_subscription_info",
|
||||
"hass_nabucasa.cloud_api.async_subscription_info",
|
||||
return_value={"return": "value"},
|
||||
):
|
||||
await client.send_json({"id": 5, "type": "cloud/subscription"})
|
||||
|
|
Loading…
Add table
Reference in a new issue