diff --git a/homeassistant/components/garmin_connect/__init__.py b/homeassistant/components/garmin_connect/__init__.py index bc3a1f0aad0..180fcdb08a2 100644 --- a/homeassistant/components/garmin_connect/__init__.py +++ b/homeassistant/components/garmin_connect/__init__.py @@ -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) -> bool: """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) -> bool: _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, diff --git a/homeassistant/components/garmin_connect/config_flow.py b/homeassistant/components/garmin_connect/config_flow.py index 8f83a9e1071..e9966859f99 100644 --- a/homeassistant/components/garmin_connect/config_flow.py +++ b/homeassistant/components/garmin_connect/config_flow.py @@ -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) diff --git a/homeassistant/components/garmin_connect/manifest.json b/homeassistant/components/garmin_connect/manifest.json index 22e115d0e06..43b4a028290 100644 --- a/homeassistant/components/garmin_connect/manifest.json +++ b/homeassistant/components/garmin_connect/manifest.json @@ -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" -} +} \ No newline at end of file diff --git a/requirements_all.txt b/requirements_all.txt index fc4912afe04..6b047602c11 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -641,7 +641,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 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 66422b82287..46881eae733 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -347,7 +347,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 diff --git a/tests/components/garmin_connect/test_config_flow.py b/tests/components/garmin_connect/test_config_flow.py index 2ad36ffa29c..dd56fba9c1c 100644 --- a/tests/components/garmin_connect/test_config_flow.py +++ b/tests/components/garmin_connect/test_config_flow.py @@ -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"