Merge pull request #51902 from home-assistant/rc

This commit is contained in:
Franck Nijhof 2021-06-15 20:37:40 +02:00 committed by GitHub
commit f2bc69a653
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 80 additions and 76 deletions

View File

@ -3,7 +3,7 @@
"name": "Daikin AC",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/daikin",
"requirements": ["pydaikin==2.4.1"],
"requirements": ["pydaikin==2.4.2"],
"codeowners": ["@fredrike"],
"zeroconf": ["_dkapi._tcp.local."],
"quality_scale": "platinum",

View File

@ -2,7 +2,7 @@
from datetime import date
import logging
from garminconnect_aio import (
from garminconnect_ha import (
Garmin,
GarminConnectAuthenticationError,
GarminConnectConnectionError,
@ -13,7 +13,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import Throttle
from .const import DEFAULT_UPDATE_INTERVAL, DOMAIN
@ -26,14 +25,13 @@ PLATFORMS = ["sensor"]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Set up Garmin Connect from a config entry."""
websession = async_get_clientsession(hass)
username: str = entry.data[CONF_USERNAME]
password: str = entry.data[CONF_PASSWORD]
garmin_client = Garmin(websession, username, password)
api = Garmin(username, password)
try:
await garmin_client.login()
await hass.async_add_executor_job(api.login)
except (
GarminConnectAuthenticationError,
GarminConnectTooManyRequestsError,
@ -49,7 +47,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
_LOGGER.exception("Unknown error occurred during Garmin Connect login request")
return False
garmin_data = GarminConnectData(hass, garmin_client)
garmin_data = GarminConnectData(hass, api)
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = garmin_data
@ -81,14 +79,20 @@ class GarminConnectData:
today = date.today()
try:
summary = await self.client.get_user_summary(today.isoformat())
body = await self.client.get_body_composition(today.isoformat())
summary = await self.hass.async_add_executor_job(
self.client.get_user_summary, today.isoformat()
)
body = await self.hass.async_add_executor_job(
self.client.get_body_composition, today.isoformat()
)
self.data = {
**summary,
**body["totalAverage"],
}
self.data["nextAlarm"] = await self.client.get_device_alarms()
self.data["nextAlarm"] = await self.hass.async_add_executor_job(
self.client.get_device_alarms
)
except (
GarminConnectAuthenticationError,
GarminConnectTooManyRequestsError,

View File

@ -1,7 +1,7 @@
"""Config flow for Garmin Connect integration."""
import logging
from garminconnect_aio import (
from garminconnect_ha import (
Garmin,
GarminConnectAuthenticationError,
GarminConnectConnectionError,
@ -11,7 +11,6 @@ import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_ID, CONF_PASSWORD, CONF_USERNAME
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import DOMAIN
@ -38,15 +37,14 @@ class GarminConnectConfigFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
if user_input is None:
return await self._show_setup_form()
websession = async_get_clientsession(self.hass)
username = user_input[CONF_USERNAME]
password = user_input[CONF_PASSWORD]
garmin_client = Garmin(websession, username, password)
api = Garmin(username, password)
errors = {}
try:
await garmin_client.login()
await self.hass.async_add_executor_job(api.login)
except GarminConnectConnectionError:
errors["base"] = "cannot_connect"
return await self._show_setup_form(errors)

View File

@ -2,8 +2,8 @@
"domain": "garmin_connect",
"name": "Garmin Connect",
"documentation": "https://www.home-assistant.io/integrations/garmin_connect",
"requirements": ["garminconnect_aio==0.1.4"],
"requirements": ["garminconnect_ha==0.1.6"],
"codeowners": ["@cyberjunky"],
"config_flow": true,
"iot_class": "cloud_polling"
}
}

View File

@ -2,7 +2,7 @@
"domain": "ialarm",
"name": "Antifurto365 iAlarm",
"documentation": "https://www.home-assistant.io/integrations/ialarm",
"requirements": ["pyialarm==1.8.1"],
"requirements": ["pyialarm==1.9.0"],
"codeowners": ["@RyuzakiKK"],
"config_flow": true,
"iot_class": "local_polling"

View File

@ -5,7 +5,7 @@ from typing import Final
MAJOR_VERSION: Final = 2021
MINOR_VERSION: Final = 6
PATCH_VERSION: Final = "4"
PATCH_VERSION: Final = "5"
__short_version__: Final = f"{MAJOR_VERSION}.{MINOR_VERSION}"
__version__: Final = f"{__short_version__}.{PATCH_VERSION}"
REQUIRED_PYTHON_VER: Final[tuple[int, int, int]] = (3, 8, 0)

View File

@ -63,3 +63,7 @@ enum34==1000000000.0.0
typing==1000000000.0.0
uuid==1000000000.0.0
# httpcore 0.13.4 breaks several integrations
# https://github.com/home-assistant/core/issues/51778
httpcore==0.13.3

View File

@ -635,7 +635,7 @@ gTTS==2.2.2
garages-amsterdam==2.1.1
# homeassistant.components.garmin_connect
garminconnect_aio==0.1.4
garminconnect_ha==0.1.6
# homeassistant.components.geniushub
geniushub-client==0.6.30
@ -1352,7 +1352,7 @@ pycsspeechtts==1.0.4
# pycups==1.9.73
# homeassistant.components.daikin
pydaikin==2.4.1
pydaikin==2.4.2
# homeassistant.components.danfoss_air
pydanfossair==0.1.0
@ -1464,7 +1464,7 @@ pyhomematic==0.1.72
pyhomeworks==0.0.6
# homeassistant.components.ialarm
pyialarm==1.8.1
pyialarm==1.9.0
# homeassistant.components.icloud
pyicloud==0.10.2

View File

@ -341,7 +341,7 @@ gTTS==2.2.2
garages-amsterdam==2.1.1
# homeassistant.components.garmin_connect
garminconnect_aio==0.1.4
garminconnect_ha==0.1.6
# homeassistant.components.geo_json_events
# homeassistant.components.usgs_earthquakes_feed
@ -747,7 +747,7 @@ pycomfoconnect==0.4
pycoolmasternet-async==0.1.2
# homeassistant.components.daikin
pydaikin==2.4.1
pydaikin==2.4.2
# homeassistant.components.deconz
pydeconz==79
@ -808,7 +808,7 @@ pyhiveapi==0.4.2
pyhomematic==0.1.72
# homeassistant.components.ialarm
pyialarm==1.8.1
pyialarm==1.9.0
# homeassistant.components.icloud
pyicloud==0.10.2

View File

@ -83,6 +83,10 @@ enum34==1000000000.0.0
typing==1000000000.0.0
uuid==1000000000.0.0
# httpcore 0.13.4 breaks several integrations
# https://github.com/home-assistant/core/issues/51778
httpcore==0.13.3
"""
IGNORE_PRE_COMMIT_HOOK_ID = (

View File

@ -1,12 +1,11 @@
"""Test the Garmin Connect config flow."""
from unittest.mock import patch
from garminconnect_aio import (
from garminconnect_ha import (
GarminConnectAuthenticationError,
GarminConnectConnectionError,
GarminConnectTooManyRequestsError,
)
import pytest
from homeassistant import config_entries, data_entry_flow
from homeassistant.components.garmin_connect.const import DOMAIN
@ -21,37 +20,23 @@ MOCK_CONF = {
}
@pytest.fixture(name="mock_garmin_connect")
def mock_garmin():
"""Mock Garmin Connect."""
with patch(
"homeassistant.components.garmin_connect.config_flow.Garmin",
) as garmin:
garmin.return_value.login.return_value = MOCK_CONF[CONF_ID]
yield garmin.return_value
async def test_show_form(hass):
"""Test that the form is served with no input."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {}
assert result["step_id"] == config_entries.SOURCE_USER
async def test_step_user(hass):
"""Test registering an integration and finishing flow works."""
with patch(
"homeassistant.components.garmin_connect.Garmin.login",
return_value="my@email.address",
), patch(
"homeassistant.components.garmin_connect.async_setup_entry", return_value=True
):
), patch(
"homeassistant.components.garmin_connect.config_flow.Garmin",
) as garmin:
garmin.return_value.login.return_value = MOCK_CONF[CONF_ID]
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_CONF
)
@ -59,60 +44,69 @@ async def test_step_user(hass):
assert result["data"] == MOCK_CONF
async def test_connection_error(hass, mock_garmin_connect):
async def test_connection_error(hass):
"""Test for connection error."""
mock_garmin_connect.login.side_effect = GarminConnectConnectionError("errormsg")
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_CONF
)
with patch(
"homeassistant.components.garmin_connect.Garmin.login",
side_effect=GarminConnectConnectionError("errormsg"),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_CONF
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "cannot_connect"}
async def test_authentication_error(hass, mock_garmin_connect):
async def test_authentication_error(hass):
"""Test for authentication error."""
mock_garmin_connect.login.side_effect = GarminConnectAuthenticationError("errormsg")
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_CONF
)
with patch(
"homeassistant.components.garmin_connect.Garmin.login",
side_effect=GarminConnectAuthenticationError("errormsg"),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_CONF
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "invalid_auth"}
async def test_toomanyrequest_error(hass, mock_garmin_connect):
async def test_toomanyrequest_error(hass):
"""Test for toomanyrequests error."""
mock_garmin_connect.login.side_effect = GarminConnectTooManyRequestsError(
"errormsg"
)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_CONF
)
with patch(
"homeassistant.components.garmin_connect.Garmin.login",
side_effect=GarminConnectTooManyRequestsError("errormsg"),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_CONF
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "too_many_requests"}
async def test_unknown_error(hass, mock_garmin_connect):
async def test_unknown_error(hass):
"""Test for unknown error."""
mock_garmin_connect.login.side_effect = Exception
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}, data=MOCK_CONF
)
with patch(
"homeassistant.components.garmin_connect.Garmin.login",
side_effect=Exception,
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_CONF
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "unknown"}
async def test_abort_if_already_setup(hass):
"""Test abort if already setup."""
MockConfigEntry(
domain=DOMAIN, data=MOCK_CONF, unique_id=MOCK_CONF[CONF_ID]
).add_to_hass(hass)
with patch(
"homeassistant.components.garmin_connect.config_flow.Garmin", autospec=True
) as garmin:
garmin.return_value.login.return_value = MOCK_CONF[CONF_ID]
"homeassistant.components.garmin_connect.config_flow.Garmin",
):
entry = MockConfigEntry(
domain=DOMAIN, data=MOCK_CONF, unique_id=MOCK_CONF[CONF_ID]
)
entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": "user"}, data=MOCK_CONF
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"