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 aiohttp
|
||||||
import async_timeout
|
import async_timeout
|
||||||
import attr
|
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.const import STATE_DISCONNECTED
|
||||||
from hass_nabucasa.voice import MAP_VOICE
|
from hass_nabucasa.voice import MAP_VOICE
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
@ -24,7 +24,6 @@ from homeassistant.const import (
|
||||||
HTTP_BAD_GATEWAY,
|
HTTP_BAD_GATEWAY,
|
||||||
HTTP_BAD_REQUEST,
|
HTTP_BAD_REQUEST,
|
||||||
HTTP_INTERNAL_SERVER_ERROR,
|
HTTP_INTERNAL_SERVER_ERROR,
|
||||||
HTTP_OK,
|
|
||||||
HTTP_UNAUTHORIZED,
|
HTTP_UNAUTHORIZED,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,30 +46,6 @@ from .const import (
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_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 = {
|
_CLOUD_ERRORS = {
|
||||||
InvalidTrustedNetworks: (
|
InvalidTrustedNetworks: (
|
||||||
HTTP_INTERNAL_SERVER_ERROR,
|
HTTP_INTERNAL_SERVER_ERROR,
|
||||||
|
@ -94,17 +69,11 @@ _CLOUD_ERRORS = {
|
||||||
async def async_setup(hass):
|
async def async_setup(hass):
|
||||||
"""Initialize the HTTP API."""
|
"""Initialize the HTTP API."""
|
||||||
async_register_command = hass.components.websocket_api.async_register_command
|
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(websocket_cloud_status)
|
||||||
async_register_command(
|
async_register_command(websocket_subscription)
|
||||||
WS_TYPE_SUBSCRIPTION, websocket_subscription, SCHEMA_WS_SUBSCRIPTION
|
|
||||||
)
|
|
||||||
async_register_command(websocket_update_prefs)
|
async_register_command(websocket_update_prefs)
|
||||||
async_register_command(
|
async_register_command(websocket_hook_create)
|
||||||
WS_TYPE_HOOK_CREATE, websocket_hook_create, SCHEMA_WS_HOOK_CREATE
|
async_register_command(websocket_hook_delete)
|
||||||
)
|
|
||||||
async_register_command(
|
|
||||||
WS_TYPE_HOOK_DELETE, websocket_hook_delete, SCHEMA_WS_HOOK_DELETE
|
|
||||||
)
|
|
||||||
async_register_command(websocket_remote_connect)
|
async_register_command(websocket_remote_connect)
|
||||||
async_register_command(websocket_remote_disconnect)
|
async_register_command(websocket_remote_disconnect)
|
||||||
|
|
||||||
|
@ -311,6 +280,7 @@ class CloudForgotPasswordView(HomeAssistantView):
|
||||||
|
|
||||||
|
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
|
@websocket_api.websocket_command({vol.Required("type"): "cloud/status"})
|
||||||
async def websocket_cloud_status(hass, connection, msg):
|
async def websocket_cloud_status(hass, connection, msg):
|
||||||
"""Handle request for account info.
|
"""Handle request for account info.
|
||||||
|
|
||||||
|
@ -344,36 +314,19 @@ def _require_cloud_login(handler):
|
||||||
|
|
||||||
@_require_cloud_login
|
@_require_cloud_login
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
|
@websocket_api.websocket_command({vol.Required("type"): "cloud/subscription"})
|
||||||
async def websocket_subscription(hass, connection, msg):
|
async def websocket_subscription(hass, connection, msg):
|
||||||
"""Handle request for account info."""
|
"""Handle request for account info."""
|
||||||
|
|
||||||
cloud = hass.data[DOMAIN]
|
cloud = hass.data[DOMAIN]
|
||||||
|
try:
|
||||||
with async_timeout.timeout(REQUEST_TIMEOUT):
|
with async_timeout.timeout(REQUEST_TIMEOUT):
|
||||||
response = await cloud.fetch_subscription_info()
|
data = await cloud_api.async_subscription_info(cloud)
|
||||||
|
except aiohttp.ClientError:
|
||||||
if response.status != HTTP_OK:
|
connection.send_error(
|
||||||
connection.send_message(
|
msg["id"], "request_failed", "Failed to request subscription"
|
||||||
websocket_api.error_message(
|
|
||||||
msg["id"], "request_failed", "Failed to request subscription"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
data = await response.json()
|
connection.send_result(msg["id"], data)
|
||||||
|
|
||||||
# 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))
|
|
||||||
|
|
||||||
|
|
||||||
@_require_cloud_login
|
@_require_cloud_login
|
||||||
|
@ -429,6 +382,12 @@ async def websocket_update_prefs(hass, connection, msg):
|
||||||
@_require_cloud_login
|
@_require_cloud_login
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@_ws_handle_cloud_errors
|
@_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):
|
async def websocket_hook_create(hass, connection, msg):
|
||||||
"""Handle request for account info."""
|
"""Handle request for account info."""
|
||||||
cloud = hass.data[DOMAIN]
|
cloud = hass.data[DOMAIN]
|
||||||
|
@ -439,6 +398,12 @@ async def websocket_hook_create(hass, connection, msg):
|
||||||
@_require_cloud_login
|
@_require_cloud_login
|
||||||
@websocket_api.async_response
|
@websocket_api.async_response
|
||||||
@_ws_handle_cloud_errors
|
@_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):
|
async def websocket_hook_delete(hass, connection, msg):
|
||||||
"""Handle request for account info."""
|
"""Handle request for account info."""
|
||||||
cloud = hass.data[DOMAIN]
|
cloud = hass.data[DOMAIN]
|
||||||
|
|
|
@ -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.47.1"],
|
"requirements": ["hass-nabucasa==0.49.0"],
|
||||||
"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,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.47.1
|
hass-nabucasa==0.49.0
|
||||||
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.47.1
|
hass-nabucasa==0.49.0
|
||||||
|
|
||||||
# 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.47.1
|
hass-nabucasa==0.49.0
|
||||||
|
|
||||||
# homeassistant.components.tasmota
|
# homeassistant.components.tasmota
|
||||||
hatasmota==0.2.20
|
hatasmota==0.2.20
|
||||||
|
|
|
@ -12,7 +12,7 @@ from . import mock_cloud, mock_cloud_prefs
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def mock_user_data():
|
def mock_user_data():
|
||||||
"""Mock os module."""
|
"""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
|
yield writer
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ def setup_api_fixture(hass, aioclient_mock):
|
||||||
@pytest.fixture(name="cloud_client")
|
@pytest.fixture(name="cloud_client")
|
||||||
def cloud_client_fixture(hass, hass_client):
|
def cloud_client_fixture(hass, hass_client):
|
||||||
"""Fixture that can fetch from the cloud 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())
|
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"}
|
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
|
hass, hass_ws_client, aioclient_mock, mock_auth, mock_cloud_login
|
||||||
):
|
):
|
||||||
"""Test querying the status and connecting because valid account."""
|
"""Test querying the status and connecting because valid account."""
|
||||||
aioclient_mock.get(SUBSCRIPTION_INFO_URL, json={"provider": "stripe"})
|
aioclient_mock.get(SUBSCRIPTION_INFO_URL, json={"provider": "stripe"})
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
|
|
||||||
with patch(
|
with patch("hass_nabucasa.auth.CognitoAuth.async_renew_access_token") as mock_renew:
|
||||||
"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"})
|
await client.send_json({"id": 5, "type": "cloud/subscription"})
|
||||||
response = await client.receive_json()
|
response = await client.receive_json()
|
||||||
|
|
||||||
assert response["result"] == {"provider": "stripe"}
|
assert response["result"] == {"provider": "stripe"}
|
||||||
assert len(mock_renew.mock_calls) == 1
|
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(
|
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."""
|
"""Test querying the status."""
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
with patch(
|
with patch(
|
||||||
"hass_nabucasa.Cloud.fetch_subscription_info",
|
"hass_nabucasa.cloud_api.async_subscription_info",
|
||||||
return_value={"return": "value"},
|
return_value={"return": "value"},
|
||||||
):
|
):
|
||||||
await client.send_json({"id": 5, "type": "cloud/subscription"})
|
await client.send_json({"id": 5, "type": "cloud/subscription"})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue