Convert august to async (#32586)
* Convert august to async Async io was added to py-august 0.24 * Fix lintpull/32626/head
parent
09512e9f8b
commit
3318e65948
|
@ -3,9 +3,9 @@ import asyncio
|
|||
import itertools
|
||||
import logging
|
||||
|
||||
from august.api import AugustApiHTTPError
|
||||
from aiohttp import ClientError
|
||||
from august.authenticator import ValidationResult
|
||||
from requests import RequestException
|
||||
from august.exceptions import AugustApiAIOHTTPError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
|
@ -66,8 +66,8 @@ async def async_request_validation(hass, config_entry, august_gateway):
|
|||
|
||||
async def async_august_configuration_validation_callback(data):
|
||||
code = data.get(VERIFICATION_CODE_KEY)
|
||||
result = await hass.async_add_executor_job(
|
||||
august_gateway.authenticator.validate_verification_code, code
|
||||
result = await august_gateway.authenticator.async_validate_verification_code(
|
||||
code
|
||||
)
|
||||
|
||||
if result == ValidationResult.INVALID_VERIFICATION_CODE:
|
||||
|
@ -81,9 +81,7 @@ async def async_request_validation(hass, config_entry, august_gateway):
|
|||
return False
|
||||
|
||||
if TWO_FA_REVALIDATE not in hass.data[DOMAIN][entry_id]:
|
||||
await hass.async_add_executor_job(
|
||||
august_gateway.authenticator.send_verification_code
|
||||
)
|
||||
await august_gateway.authenticator.async_send_verification_code()
|
||||
|
||||
entry_data = config_entry.data
|
||||
login_method = entry_data.get(CONF_LOGIN_METHOD)
|
||||
|
@ -109,7 +107,7 @@ async def async_setup_august(hass, config_entry, august_gateway):
|
|||
hass.data[DOMAIN].setdefault(entry_id, {})
|
||||
|
||||
try:
|
||||
august_gateway.authenticate()
|
||||
await august_gateway.async_authenticate()
|
||||
except RequireValidation:
|
||||
await async_request_validation(hass, config_entry, august_gateway)
|
||||
return False
|
||||
|
@ -125,10 +123,9 @@ async def async_setup_august(hass, config_entry, august_gateway):
|
|||
hass.data[DOMAIN][entry_id].pop(TWO_FA_REVALIDATE)
|
||||
)
|
||||
|
||||
hass.data[DOMAIN][entry_id][DATA_AUGUST] = await hass.async_add_executor_job(
|
||||
AugustData, hass, august_gateway
|
||||
)
|
||||
await hass.data[DOMAIN][entry_id][DATA_AUGUST].activity_stream.async_setup()
|
||||
hass.data[DOMAIN][entry_id][DATA_AUGUST] = AugustData(hass, august_gateway)
|
||||
|
||||
await hass.data[DOMAIN][entry_id][DATA_AUGUST].async_setup()
|
||||
|
||||
for component in AUGUST_COMPONENTS:
|
||||
hass.async_create_task(
|
||||
|
@ -167,7 +164,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
|||
"""Set up August from a config entry."""
|
||||
|
||||
august_gateway = AugustGateway(hass)
|
||||
august_gateway.async_setup(entry.data)
|
||||
await august_gateway.async_setup(entry.data)
|
||||
|
||||
return await async_setup_august(hass, entry, august_gateway)
|
||||
|
||||
|
@ -197,11 +194,22 @@ class AugustData(AugustSubscriberMixin):
|
|||
super().__init__(hass, MIN_TIME_BETWEEN_DETAIL_UPDATES)
|
||||
self._hass = hass
|
||||
self._august_gateway = august_gateway
|
||||
self.activity_stream = None
|
||||
self._api = august_gateway.api
|
||||
self._device_detail_by_id = {}
|
||||
self._doorbells_by_id = {}
|
||||
self._locks_by_id = {}
|
||||
self._house_ids = set()
|
||||
|
||||
locks = self._api.get_operable_locks(self._august_gateway.access_token) or []
|
||||
doorbells = self._api.get_doorbells(self._august_gateway.access_token) or []
|
||||
async def async_setup(self):
|
||||
"""Async setup of august device data and activities."""
|
||||
locks = (
|
||||
await self._api.async_get_operable_locks(self._august_gateway.access_token)
|
||||
or []
|
||||
)
|
||||
doorbells = (
|
||||
await self._api.async_get_doorbells(self._august_gateway.access_token) or []
|
||||
)
|
||||
|
||||
self._doorbells_by_id = dict((device.device_id, device) for device in doorbells)
|
||||
self._locks_by_id = dict((device.device_id, device) for device in locks)
|
||||
|
@ -209,7 +217,7 @@ class AugustData(AugustSubscriberMixin):
|
|||
device.house_id for device in itertools.chain(locks, doorbells)
|
||||
)
|
||||
|
||||
self._refresh_device_detail_by_ids(
|
||||
await self._async_refresh_device_detail_by_ids(
|
||||
[device.device_id for device in itertools.chain(locks, doorbells)]
|
||||
)
|
||||
|
||||
|
@ -221,8 +229,9 @@ class AugustData(AugustSubscriberMixin):
|
|||
self._remove_inoperative_doorbells()
|
||||
|
||||
self.activity_stream = ActivityStream(
|
||||
hass, self._api, self._august_gateway, self._house_ids
|
||||
self._hass, self._api, self._august_gateway, self._house_ids
|
||||
)
|
||||
await self.activity_stream.async_setup()
|
||||
|
||||
@property
|
||||
def doorbells(self):
|
||||
|
@ -238,25 +247,26 @@ class AugustData(AugustSubscriberMixin):
|
|||
"""Return the py-august LockDetail or DoorbellDetail object for a device."""
|
||||
return self._device_detail_by_id[device_id]
|
||||
|
||||
def _refresh(self, time):
|
||||
self._refresh_device_detail_by_ids(self._subscriptions.keys())
|
||||
async def _async_refresh(self, time):
|
||||
await self._async_refresh_device_detail_by_ids(self._subscriptions.keys())
|
||||
|
||||
def _refresh_device_detail_by_ids(self, device_ids_list):
|
||||
async def _async_refresh_device_detail_by_ids(self, device_ids_list):
|
||||
for device_id in device_ids_list:
|
||||
if device_id in self._locks_by_id:
|
||||
self._update_device_detail(
|
||||
self._locks_by_id[device_id], self._api.get_lock_detail
|
||||
await self._async_update_device_detail(
|
||||
self._locks_by_id[device_id], self._api.async_get_lock_detail
|
||||
)
|
||||
elif device_id in self._doorbells_by_id:
|
||||
self._update_device_detail(
|
||||
self._doorbells_by_id[device_id], self._api.get_doorbell_detail
|
||||
await self._async_update_device_detail(
|
||||
self._doorbells_by_id[device_id],
|
||||
self._api.async_get_doorbell_detail,
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"signal_device_id_update (from detail updates): %s", device_id,
|
||||
"async_signal_device_id_update (from detail updates): %s", device_id,
|
||||
)
|
||||
self.signal_device_id_update(device_id)
|
||||
self.async_signal_device_id_update(device_id)
|
||||
|
||||
def _update_device_detail(self, device, api_call):
|
||||
async def _async_update_device_detail(self, device, api_call):
|
||||
_LOGGER.debug(
|
||||
"Started retrieving detail for %s (%s)",
|
||||
device.device_name,
|
||||
|
@ -264,10 +274,10 @@ class AugustData(AugustSubscriberMixin):
|
|||
)
|
||||
|
||||
try:
|
||||
self._device_detail_by_id[device.device_id] = api_call(
|
||||
self._device_detail_by_id[device.device_id] = await api_call(
|
||||
self._august_gateway.access_token, device.device_id
|
||||
)
|
||||
except RequestException as ex:
|
||||
except ClientError as ex:
|
||||
_LOGGER.error(
|
||||
"Request error trying to retrieve %s details for %s. %s",
|
||||
device.device_id,
|
||||
|
@ -287,30 +297,32 @@ class AugustData(AugustSubscriberMixin):
|
|||
if self._doorbells_by_id.get(device_id):
|
||||
return self._doorbells_by_id[device_id].device_name
|
||||
|
||||
def lock(self, device_id):
|
||||
async def async_lock(self, device_id):
|
||||
"""Lock the device."""
|
||||
return self._call_api_op_requires_bridge(
|
||||
return await self._async_call_api_op_requires_bridge(
|
||||
device_id,
|
||||
self._api.lock_return_activities,
|
||||
self._api.async_lock_return_activities,
|
||||
self._august_gateway.access_token,
|
||||
device_id,
|
||||
)
|
||||
|
||||
def unlock(self, device_id):
|
||||
async def async_unlock(self, device_id):
|
||||
"""Unlock the device."""
|
||||
return self._call_api_op_requires_bridge(
|
||||
return await self._async_call_api_op_requires_bridge(
|
||||
device_id,
|
||||
self._api.unlock_return_activities,
|
||||
self._api.async_unlock_return_activities,
|
||||
self._august_gateway.access_token,
|
||||
device_id,
|
||||
)
|
||||
|
||||
def _call_api_op_requires_bridge(self, device_id, func, *args, **kwargs):
|
||||
async def _async_call_api_op_requires_bridge(
|
||||
self, device_id, func, *args, **kwargs
|
||||
):
|
||||
"""Call an API that requires the bridge to be online and will change the device state."""
|
||||
ret = None
|
||||
try:
|
||||
ret = func(*args, **kwargs)
|
||||
except AugustApiHTTPError as err:
|
||||
ret = await func(*args, **kwargs)
|
||||
except AugustApiAIOHTTPError as err:
|
||||
device_name = self._get_device_name(device_id)
|
||||
if device_name is None:
|
||||
device_name = f"DeviceID: {device_id}"
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
"""Consume the august activity stream."""
|
||||
from functools import partial
|
||||
import logging
|
||||
|
||||
from requests import RequestException
|
||||
from aiohttp import ClientError
|
||||
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
|
@ -31,7 +30,7 @@ class ActivityStream(AugustSubscriberMixin):
|
|||
|
||||
async def async_setup(self):
|
||||
"""Token refresh check and catch up the activity stream."""
|
||||
await self._refresh(utcnow)
|
||||
await self._async_refresh(utcnow)
|
||||
|
||||
def get_latest_device_activity(self, device_id, activity_types):
|
||||
"""Return latest activity that is one of the acitivty_types."""
|
||||
|
@ -53,7 +52,7 @@ class ActivityStream(AugustSubscriberMixin):
|
|||
|
||||
return latest_activity
|
||||
|
||||
async def _refresh(self, time):
|
||||
async def _async_refresh(self, time):
|
||||
"""Update the activity stream from August."""
|
||||
|
||||
# This is the only place we refresh the api token
|
||||
|
@ -72,15 +71,10 @@ class ActivityStream(AugustSubscriberMixin):
|
|||
for house_id in self._house_ids:
|
||||
_LOGGER.debug("Updating device activity for house id %s", house_id)
|
||||
try:
|
||||
activities = await self._hass.async_add_executor_job(
|
||||
partial(
|
||||
self._api.get_house_activities,
|
||||
self._august_gateway.access_token,
|
||||
house_id,
|
||||
limit=limit,
|
||||
)
|
||||
activities = await self._api.async_get_house_activities(
|
||||
self._august_gateway.access_token, house_id, limit=limit
|
||||
)
|
||||
except RequestException as ex:
|
||||
except ClientError as ex:
|
||||
_LOGGER.error(
|
||||
"Request error trying to retrieve activity for house id %s: %s",
|
||||
house_id,
|
||||
|
|
|
@ -5,6 +5,7 @@ from august.util import update_doorbell_image_from_activity
|
|||
|
||||
from homeassistant.components.camera import Camera
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
|
||||
from .const import DATA_AUGUST, DEFAULT_NAME, DEFAULT_TIMEOUT, DOMAIN
|
||||
from .entity import AugustEntityMixin
|
||||
|
@ -74,15 +75,11 @@ class AugustCamera(AugustEntityMixin, Camera):
|
|||
|
||||
if self._image_url is not self._detail.image_url:
|
||||
self._image_url = self._detail.image_url
|
||||
self._image_content = await self.hass.async_add_executor_job(
|
||||
self._camera_image
|
||||
self._image_content = await self._detail.async_get_doorbell_image(
|
||||
aiohttp_client.async_get_clientsession(self.hass), timeout=self._timeout
|
||||
)
|
||||
return self._image_content
|
||||
|
||||
def _camera_image(self):
|
||||
"""Return bytes of camera image."""
|
||||
return self._detail.get_doorbell_image(timeout=self._timeout)
|
||||
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
"""Get the unique id of the camera."""
|
||||
|
|
|
@ -42,15 +42,15 @@ async def async_validate_input(
|
|||
code = data.get(VERIFICATION_CODE_KEY)
|
||||
|
||||
if code is not None:
|
||||
result = await hass.async_add_executor_job(
|
||||
august_gateway.authenticator.validate_verification_code, code
|
||||
result = await august_gateway.authenticator.async_validate_verification_code(
|
||||
code
|
||||
)
|
||||
_LOGGER.debug("Verification code validation: %s", result)
|
||||
if result != ValidationResult.VALIDATED:
|
||||
raise RequireValidation
|
||||
|
||||
try:
|
||||
august_gateway.authenticate()
|
||||
await august_gateway.async_authenticate()
|
||||
except RequireValidation:
|
||||
_LOGGER.debug(
|
||||
"Requesting new verification code for %s via %s",
|
||||
|
@ -58,9 +58,7 @@ async def async_validate_input(
|
|||
data.get(CONF_LOGIN_METHOD),
|
||||
)
|
||||
if code is None:
|
||||
await hass.async_add_executor_job(
|
||||
august_gateway.authenticator.send_verification_code
|
||||
)
|
||||
await august_gateway.authenticator.async_send_verification_code()
|
||||
raise
|
||||
|
||||
return {
|
||||
|
@ -87,7 +85,7 @@ class AugustConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
self._august_gateway = AugustGateway(self.hass)
|
||||
errors = {}
|
||||
if user_input is not None:
|
||||
self._august_gateway.async_setup(user_input)
|
||||
await self._august_gateway.async_setup(user_input)
|
||||
|
||||
try:
|
||||
info = await async_validate_input(
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
import asyncio
|
||||
import logging
|
||||
|
||||
from august.api import Api
|
||||
from august.authenticator import AuthenticationState, Authenticator
|
||||
from requests import RequestException, Session
|
||||
from aiohttp import ClientError
|
||||
from august.api_async import ApiAsync
|
||||
from august.authenticator_async import AuthenticationState, AuthenticatorAsync
|
||||
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_TIMEOUT, CONF_USERNAME
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers import aiohttp_client
|
||||
|
||||
from .const import (
|
||||
CONF_ACCESS_TOKEN_CACHE_FILE,
|
||||
|
@ -27,7 +27,7 @@ class AugustGateway:
|
|||
|
||||
def __init__(self, hass):
|
||||
"""Init the connection."""
|
||||
self._api_http_session = Session()
|
||||
self._aiohttp_session = aiohttp_client.async_get_clientsession(hass)
|
||||
self._token_refresh_lock = asyncio.Lock()
|
||||
self._hass = hass
|
||||
self._config = None
|
||||
|
@ -66,8 +66,7 @@ class AugustGateway:
|
|||
CONF_ACCESS_TOKEN_CACHE_FILE: self._config[CONF_ACCESS_TOKEN_CACHE_FILE],
|
||||
}
|
||||
|
||||
@callback
|
||||
def async_setup(self, conf):
|
||||
async def async_setup(self, conf):
|
||||
"""Create the api and authenticator objects."""
|
||||
if conf.get(VERIFICATION_CODE_KEY):
|
||||
return
|
||||
|
@ -77,11 +76,11 @@ class AugustGateway:
|
|||
] = f".{conf[CONF_USERNAME]}{DEFAULT_AUGUST_CONFIG_FILE}"
|
||||
self._config = conf
|
||||
|
||||
self._api = Api(
|
||||
timeout=self._config.get(CONF_TIMEOUT), http_session=self._api_http_session,
|
||||
self._api = ApiAsync(
|
||||
self._aiohttp_session, timeout=self._config.get(CONF_TIMEOUT)
|
||||
)
|
||||
|
||||
self._authenticator = Authenticator(
|
||||
self._authenticator = AuthenticatorAsync(
|
||||
self._api,
|
||||
self._config[CONF_LOGIN_METHOD],
|
||||
self._config[CONF_USERNAME],
|
||||
|
@ -92,12 +91,14 @@ class AugustGateway:
|
|||
),
|
||||
)
|
||||
|
||||
def authenticate(self):
|
||||
await self._authenticator.async_setup_authentication()
|
||||
|
||||
async def async_authenticate(self):
|
||||
"""Authenticate with the details provided to setup."""
|
||||
self._authentication = None
|
||||
try:
|
||||
self._authentication = self.authenticator.authenticate()
|
||||
except RequestException as ex:
|
||||
self._authentication = await self.authenticator.async_authenticate()
|
||||
except ClientError as ex:
|
||||
_LOGGER.error("Unable to connect to August service: %s", str(ex))
|
||||
raise CannotConnect
|
||||
|
||||
|
@ -119,25 +120,12 @@ class AugustGateway:
|
|||
"""Refresh the august access token if needed."""
|
||||
if self.authenticator.should_refresh():
|
||||
async with self._token_refresh_lock:
|
||||
await self._hass.async_add_executor_job(self._refresh_access_token)
|
||||
|
||||
def _refresh_access_token(self):
|
||||
refreshed_authentication = self.authenticator.refresh_access_token(force=False)
|
||||
_LOGGER.info(
|
||||
"Refreshed august access token. The old token expired at %s, and the new token expires at %s",
|
||||
self.authentication.access_token_expires,
|
||||
refreshed_authentication.access_token_expires,
|
||||
)
|
||||
self._authentication = refreshed_authentication
|
||||
|
||||
def _close_http_session(self):
|
||||
"""Close API sessions used to connect to August."""
|
||||
if self._api_http_session:
|
||||
try:
|
||||
self._api_http_session.close()
|
||||
except RequestException:
|
||||
pass
|
||||
|
||||
def __del__(self):
|
||||
"""Close out the http session on destroy."""
|
||||
self._close_http_session()
|
||||
refreshed_authentication = await self.authenticator.async_refresh_access_token(
|
||||
force=False
|
||||
)
|
||||
_LOGGER.info(
|
||||
"Refreshed august access token. The old token expired at %s, and the new token expires at %s",
|
||||
self.authentication.access_token_expires,
|
||||
refreshed_authentication.access_token_expires,
|
||||
)
|
||||
self._authentication = refreshed_authentication
|
||||
|
|
|
@ -43,16 +43,14 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockDevice):
|
|||
|
||||
async def async_lock(self, **kwargs):
|
||||
"""Lock the device."""
|
||||
await self._call_lock_operation(self._data.lock)
|
||||
await self._call_lock_operation(self._data.async_lock)
|
||||
|
||||
async def async_unlock(self, **kwargs):
|
||||
"""Unlock the device."""
|
||||
await self._call_lock_operation(self._data.unlock)
|
||||
await self._call_lock_operation(self._data.async_unlock)
|
||||
|
||||
async def _call_lock_operation(self, lock_operation):
|
||||
activities = await self.hass.async_add_executor_job(
|
||||
lock_operation, self._device_id
|
||||
)
|
||||
activities = await lock_operation(self._device_id)
|
||||
for lock_activity in activities:
|
||||
update_lock_detail_from_activity(self._detail, lock_activity)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "August",
|
||||
"documentation": "https://www.home-assistant.io/integrations/august",
|
||||
"requirements": [
|
||||
"py-august==0.22.0"
|
||||
"py-august==0.24.0"
|
||||
],
|
||||
"dependencies": [
|
||||
"configurator"
|
||||
|
|
|
@ -21,7 +21,7 @@ class AugustSubscriberMixin:
|
|||
"""Add an callback subscriber."""
|
||||
if not self._subscriptions:
|
||||
self._unsub_interval = async_track_time_interval(
|
||||
self._hass, self._refresh, self._update_interval
|
||||
self._hass, self._async_refresh, self._update_interval
|
||||
)
|
||||
self._subscriptions.setdefault(device_id, []).append(update_callback)
|
||||
|
||||
|
@ -43,11 +43,3 @@ class AugustSubscriberMixin:
|
|||
|
||||
for update_callback in self._subscriptions[device_id]:
|
||||
update_callback()
|
||||
|
||||
def signal_device_id_update(self, device_id):
|
||||
"""Call the callbacks for a device_id."""
|
||||
if not self._subscriptions.get(device_id):
|
||||
return
|
||||
|
||||
for update_callback in self._subscriptions[device_id]:
|
||||
self._hass.loop.call_soon_threadsafe(update_callback)
|
||||
|
|
|
@ -1085,7 +1085,7 @@ pushover_complete==1.1.1
|
|||
pwmled==1.5.0
|
||||
|
||||
# homeassistant.components.august
|
||||
py-august==0.22.0
|
||||
py-august==0.24.0
|
||||
|
||||
# homeassistant.components.canary
|
||||
py-canary==0.5.0
|
||||
|
|
|
@ -394,7 +394,7 @@ pure-python-adb==0.2.2.dev0
|
|||
pushbullet.py==0.11.0
|
||||
|
||||
# homeassistant.components.august
|
||||
py-august==0.22.0
|
||||
py-august==0.24.0
|
||||
|
||||
# homeassistant.components.canary
|
||||
py-canary==0.5.0
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
import json
|
||||
import os
|
||||
import time
|
||||
from unittest.mock import MagicMock, PropertyMock
|
||||
|
||||
from asynctest import mock
|
||||
from asynctest.mock import CoroutineMock, MagicMock, PropertyMock
|
||||
from august.activity import (
|
||||
ACTIVITY_ACTIONS_DOOR_OPERATION,
|
||||
ACTIVITY_ACTIONS_DOORBELL_DING,
|
||||
|
@ -43,8 +43,10 @@ def _mock_get_config():
|
|||
}
|
||||
|
||||
|
||||
@mock.patch("homeassistant.components.august.gateway.Api")
|
||||
@mock.patch("homeassistant.components.august.gateway.Authenticator.authenticate")
|
||||
@mock.patch("homeassistant.components.august.gateway.ApiAsync")
|
||||
@mock.patch(
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_authenticate"
|
||||
)
|
||||
async def _mock_setup_august(hass, api_instance, authenticate_mock, api_mock):
|
||||
"""Set up august integration."""
|
||||
authenticate_mock.side_effect = MagicMock(
|
||||
|
@ -147,37 +149,40 @@ async def _mock_setup_august_with_api_side_effects(hass, api_call_side_effects):
|
|||
api_instance = MagicMock(name="Api")
|
||||
|
||||
if api_call_side_effects["get_lock_detail"]:
|
||||
api_instance.get_lock_detail.side_effect = api_call_side_effects[
|
||||
"get_lock_detail"
|
||||
]
|
||||
type(api_instance).async_get_lock_detail = CoroutineMock(
|
||||
side_effect=api_call_side_effects["get_lock_detail"]
|
||||
)
|
||||
|
||||
if api_call_side_effects["get_operable_locks"]:
|
||||
api_instance.get_operable_locks.side_effect = api_call_side_effects[
|
||||
"get_operable_locks"
|
||||
]
|
||||
type(api_instance).async_get_operable_locks = CoroutineMock(
|
||||
side_effect=api_call_side_effects["get_operable_locks"]
|
||||
)
|
||||
|
||||
if api_call_side_effects["get_doorbells"]:
|
||||
api_instance.get_doorbells.side_effect = api_call_side_effects["get_doorbells"]
|
||||
type(api_instance).async_get_doorbells = CoroutineMock(
|
||||
side_effect=api_call_side_effects["get_doorbells"]
|
||||
)
|
||||
|
||||
if api_call_side_effects["get_doorbell_detail"]:
|
||||
api_instance.get_doorbell_detail.side_effect = api_call_side_effects[
|
||||
"get_doorbell_detail"
|
||||
]
|
||||
type(api_instance).async_get_doorbell_detail = CoroutineMock(
|
||||
side_effect=api_call_side_effects["get_doorbell_detail"]
|
||||
)
|
||||
|
||||
if api_call_side_effects["get_house_activities"]:
|
||||
api_instance.get_house_activities.side_effect = api_call_side_effects[
|
||||
"get_house_activities"
|
||||
]
|
||||
type(api_instance).async_get_house_activities = CoroutineMock(
|
||||
side_effect=api_call_side_effects["get_house_activities"]
|
||||
)
|
||||
|
||||
if api_call_side_effects["lock_return_activities"]:
|
||||
api_instance.lock_return_activities.side_effect = api_call_side_effects[
|
||||
"lock_return_activities"
|
||||
]
|
||||
type(api_instance).async_lock_return_activities = CoroutineMock(
|
||||
side_effect=api_call_side_effects["lock_return_activities"]
|
||||
)
|
||||
|
||||
if api_call_side_effects["unlock_return_activities"]:
|
||||
api_instance.unlock_return_activities.side_effect = api_call_side_effects[
|
||||
"unlock_return_activities"
|
||||
]
|
||||
type(api_instance).async_unlock_return_activities = CoroutineMock(
|
||||
side_effect=api_call_side_effects["unlock_return_activities"]
|
||||
)
|
||||
|
||||
return await _mock_setup_august(hass, api_instance)
|
||||
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ async def test_create_doorbell(hass, aiohttp_client):
|
|||
doorbell_one = await _mock_doorbell_from_fixture(hass, "get_doorbell.json")
|
||||
|
||||
with mock.patch.object(
|
||||
doorbell_one, "get_doorbell_image", create=False, return_value="image"
|
||||
doorbell_one, "async_get_doorbell_image", create=False, return_value="image"
|
||||
):
|
||||
await _create_august_with_devices(hass, [doorbell_one])
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ async def test_form(hass):
|
|||
assert result["errors"] == {}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.august.config_flow.AugustGateway.authenticate",
|
||||
"homeassistant.components.august.config_flow.AugustGateway.async_authenticate",
|
||||
return_value=True,
|
||||
), patch(
|
||||
"homeassistant.components.august.async_setup", return_value=True
|
||||
|
@ -66,7 +66,7 @@ async def test_form_invalid_auth(hass):
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.august.config_flow.AugustGateway.authenticate",
|
||||
"homeassistant.components.august.config_flow.AugustGateway.async_authenticate",
|
||||
side_effect=InvalidAuth,
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
|
@ -89,7 +89,7 @@ async def test_form_cannot_connect(hass):
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.august.config_flow.AugustGateway.authenticate",
|
||||
"homeassistant.components.august.config_flow.AugustGateway.async_authenticate",
|
||||
side_effect=CannotConnect,
|
||||
):
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
|
@ -112,10 +112,10 @@ async def test_form_needs_validate(hass):
|
|||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.august.config_flow.AugustGateway.authenticate",
|
||||
"homeassistant.components.august.config_flow.AugustGateway.async_authenticate",
|
||||
side_effect=RequireValidation,
|
||||
), patch(
|
||||
"homeassistant.components.august.gateway.Authenticator.send_verification_code",
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_send_verification_code",
|
||||
return_value=True,
|
||||
) as mock_send_verification_code:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
|
@ -134,13 +134,13 @@ async def test_form_needs_validate(hass):
|
|||
|
||||
# Try with the WRONG verification code give us the form back again
|
||||
with patch(
|
||||
"homeassistant.components.august.config_flow.AugustGateway.authenticate",
|
||||
"homeassistant.components.august.config_flow.AugustGateway.async_authenticate",
|
||||
side_effect=RequireValidation,
|
||||
), patch(
|
||||
"homeassistant.components.august.gateway.Authenticator.validate_verification_code",
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_validate_verification_code",
|
||||
return_value=ValidationResult.INVALID_VERIFICATION_CODE,
|
||||
) as mock_validate_verification_code, patch(
|
||||
"homeassistant.components.august.gateway.Authenticator.send_verification_code",
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_send_verification_code",
|
||||
return_value=True,
|
||||
) as mock_send_verification_code, patch(
|
||||
"homeassistant.components.august.async_setup", return_value=True
|
||||
|
@ -161,13 +161,13 @@ async def test_form_needs_validate(hass):
|
|||
|
||||
# Try with the CORRECT verification code and we setup
|
||||
with patch(
|
||||
"homeassistant.components.august.config_flow.AugustGateway.authenticate",
|
||||
"homeassistant.components.august.config_flow.AugustGateway.async_authenticate",
|
||||
return_value=True,
|
||||
), patch(
|
||||
"homeassistant.components.august.gateway.Authenticator.validate_verification_code",
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_validate_verification_code",
|
||||
return_value=ValidationResult.VALIDATED,
|
||||
) as mock_validate_verification_code, patch(
|
||||
"homeassistant.components.august.gateway.Authenticator.send_verification_code",
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_send_verification_code",
|
||||
return_value=True,
|
||||
) as mock_send_verification_code, patch(
|
||||
"homeassistant.components.august.async_setup", return_value=True
|
||||
|
|
|
@ -14,10 +14,12 @@ async def test_refresh_access_token(hass):
|
|||
await _patched_refresh_access_token(hass, "new_token", 5678)
|
||||
|
||||
|
||||
@mock.patch("homeassistant.components.august.gateway.Authenticator.authenticate")
|
||||
@mock.patch("homeassistant.components.august.gateway.Authenticator.should_refresh")
|
||||
@mock.patch(
|
||||
"homeassistant.components.august.gateway.Authenticator.refresh_access_token"
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_authenticate"
|
||||
)
|
||||
@mock.patch("homeassistant.components.august.gateway.AuthenticatorAsync.should_refresh")
|
||||
@mock.patch(
|
||||
"homeassistant.components.august.gateway.AuthenticatorAsync.async_refresh_access_token"
|
||||
)
|
||||
async def _patched_refresh_access_token(
|
||||
hass,
|
||||
|
@ -32,8 +34,8 @@ async def _patched_refresh_access_token(
|
|||
)
|
||||
august_gateway = AugustGateway(hass)
|
||||
mocked_config = _mock_get_config()
|
||||
august_gateway.async_setup(mocked_config[DOMAIN])
|
||||
august_gateway.authenticate()
|
||||
await august_gateway.async_setup(mocked_config[DOMAIN])
|
||||
await august_gateway.async_authenticate()
|
||||
|
||||
should_refresh_mock.return_value = False
|
||||
await august_gateway.async_refresh_access_token_if_needed()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""The tests for the august platform."""
|
||||
from asynctest import patch
|
||||
from august.exceptions import AugustApiHTTPError
|
||||
from august.exceptions import AugustApiAIOHTTPError
|
||||
|
||||
from homeassistant import setup
|
||||
from homeassistant.components.august.const import (
|
||||
|
@ -38,7 +38,7 @@ async def test_unlock_throws_august_api_http_error(hass):
|
|||
mocked_lock_detail = await _mock_operative_august_lock_detail(hass)
|
||||
|
||||
def _unlock_return_activities_side_effect(access_token, device_id):
|
||||
raise AugustApiHTTPError("This should bubble up as its user consumable")
|
||||
raise AugustApiAIOHTTPError("This should bubble up as its user consumable")
|
||||
|
||||
await _create_august_with_devices(
|
||||
hass,
|
||||
|
@ -64,7 +64,7 @@ async def test_lock_throws_august_api_http_error(hass):
|
|||
mocked_lock_detail = await _mock_operative_august_lock_detail(hass)
|
||||
|
||||
def _lock_return_activities_side_effect(access_token, device_id):
|
||||
raise AugustApiHTTPError("This should bubble up as its user consumable")
|
||||
raise AugustApiAIOHTTPError("This should bubble up as its user consumable")
|
||||
|
||||
await _create_august_with_devices(
|
||||
hass,
|
||||
|
@ -124,7 +124,7 @@ async def test_set_up_from_yaml(hass):
|
|||
with patch(
|
||||
"homeassistant.components.august.async_setup_august", return_value=True,
|
||||
) as mock_setup_august, patch(
|
||||
"homeassistant.components.august.config_flow.AugustGateway.authenticate",
|
||||
"homeassistant.components.august.config_flow.AugustGateway.async_authenticate",
|
||||
return_value=True,
|
||||
):
|
||||
mocked_config = _mock_get_config()
|
||||
|
|
Loading…
Reference in New Issue