diff --git a/homeassistant/components/bring/__init__.py b/homeassistant/components/bring/__init__.py index 80b7a843cc0..0ee8e3b3155 100644 --- a/homeassistant/components/bring/__init__.py +++ b/homeassistant/components/bring/__init__.py @@ -4,20 +4,13 @@ from __future__ import annotations import logging -from bring_api import ( - Bring, - BringAuthException, - BringParseException, - BringRequestException, -) +from bring_api import Bring from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, Platform from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession -from .const import DOMAIN from .coordinator import BringDataUpdateCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR, Platform.TODO] @@ -30,30 +23,8 @@ type BringConfigEntry = ConfigEntry[BringDataUpdateCoordinator] async def async_setup_entry(hass: HomeAssistant, entry: BringConfigEntry) -> bool: """Set up Bring! from a config entry.""" - email = entry.data[CONF_EMAIL] - password = entry.data[CONF_PASSWORD] - session = async_get_clientsession(hass) - bring = Bring(session, email, password) - - try: - await bring.login() - except BringRequestException as e: - raise ConfigEntryNotReady( - translation_domain=DOMAIN, - translation_key="setup_request_exception", - ) from e - except BringParseException as e: - raise ConfigEntryNotReady( - translation_domain=DOMAIN, - translation_key="setup_parse_exception", - ) from e - except BringAuthException as e: - raise ConfigEntryAuthFailed( - translation_domain=DOMAIN, - translation_key="setup_authentication_exception", - translation_placeholders={CONF_EMAIL: email}, - ) from e + bring = Bring(session, entry.data[CONF_EMAIL], entry.data[CONF_PASSWORD]) coordinator = BringDataUpdateCoordinator(hass, bring) await coordinator.async_config_entry_first_refresh() diff --git a/homeassistant/components/bring/coordinator.py b/homeassistant/components/bring/coordinator.py index a8d0a4ec322..d02237e84eb 100644 --- a/homeassistant/components/bring/coordinator.py +++ b/homeassistant/components/bring/coordinator.py @@ -16,7 +16,7 @@ from bring_api.types import BringItemsResponse, BringList, BringUserSettingsResp from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryAuthFailed +from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from .const import DOMAIN @@ -51,7 +51,7 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]): raise UpdateFailed("Unable to connect and retrieve data from bring") from e except BringParseException as e: raise UpdateFailed("Unable to parse response from bring") from e - except BringAuthException as e: + except BringAuthException: # try to recover by refreshing access token, otherwise # initiate reauth flow try: @@ -64,9 +64,7 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]): translation_key="setup_authentication_exception", translation_placeholders={CONF_EMAIL: self.bring.mail}, ) from exc - raise UpdateFailed( - "Authentication failed but re-authentication was successful, trying again later" - ) from e + return self.data list_dict: dict[str, BringData] = {} for lst in lists_response["lists"]: @@ -88,13 +86,22 @@ class BringDataUpdateCoordinator(DataUpdateCoordinator[dict[str, BringData]]): async def _async_setup(self) -> None: """Set up coordinator.""" - await self.async_refresh_user_settings() - - async def async_refresh_user_settings(self) -> None: - """Refresh user settings.""" try: + await self.bring.login() self.user_settings = await self.bring.get_all_user_settings() - except (BringAuthException, BringRequestException, BringParseException) as e: - raise UpdateFailed( - "Unable to connect and retrieve user settings from bring" + except BringRequestException as e: + raise ConfigEntryNotReady( + translation_domain=DOMAIN, + translation_key="setup_request_exception", + ) from e + except BringParseException as e: + raise ConfigEntryNotReady( + translation_domain=DOMAIN, + translation_key="setup_parse_exception", + ) from e + except BringAuthException as e: + raise ConfigEntryAuthFailed( + translation_domain=DOMAIN, + translation_key="setup_authentication_exception", + translation_placeholders={CONF_EMAIL: self.bring.mail}, ) from e diff --git a/tests/components/bring/conftest.py b/tests/components/bring/conftest.py index 62aa38d4e92..7d1b787ff0b 100644 --- a/tests/components/bring/conftest.py +++ b/tests/components/bring/conftest.py @@ -8,7 +8,7 @@ import uuid from bring_api.types import BringAuthResponse import pytest -from homeassistant.components.bring import DOMAIN +from homeassistant.components.bring.const import DOMAIN from homeassistant.const import CONF_EMAIL, CONF_PASSWORD from tests.common import MockConfigEntry, load_json_object_fixture @@ -43,6 +43,7 @@ def mock_bring_client() -> Generator[AsyncMock]: ): client = mock_client.return_value client.uuid = UUID + client.mail = EMAIL client.login.return_value = cast(BringAuthResponse, {"name": "Bring"}) client.load_lists.return_value = load_json_object_fixture("lists.json", DOMAIN) client.get_list.return_value = load_json_object_fixture("items.json", DOMAIN) diff --git a/tests/components/bring/test_init.py b/tests/components/bring/test_init.py index 659a4768600..8c215e024d5 100644 --- a/tests/components/bring/test_init.py +++ b/tests/components/bring/test_init.py @@ -3,15 +3,11 @@ from datetime import timedelta from unittest.mock import AsyncMock +from bring_api import BringAuthException, BringParseException, BringRequestException from freezegun.api import FrozenDateTimeFactory import pytest -from homeassistant.components.bring import ( - BringAuthException, - BringParseException, - BringRequestException, - async_setup_entry, -) +from homeassistant.components.bring import async_setup_entry from homeassistant.components.bring.const import DOMAIN from homeassistant.config_entries import ConfigEntryDisabler, ConfigEntryState from homeassistant.core import HomeAssistant @@ -120,13 +116,20 @@ async def test_config_entry_not_ready( @pytest.mark.parametrize( - "exception", [None, BringAuthException, BringRequestException, BringParseException] + ("exception", "state"), + [ + (None, ConfigEntryState.LOADED), + (BringAuthException, ConfigEntryState.SETUP_ERROR), + (BringRequestException, ConfigEntryState.SETUP_RETRY), + (BringParseException, ConfigEntryState.SETUP_RETRY), + ], ) async def test_config_entry_not_ready_auth_error( hass: HomeAssistant, bring_config_entry: MockConfigEntry, mock_bring_client: AsyncMock, exception: Exception | None, + state: ConfigEntryState, ) -> None: """Test config entry not ready from authentication error.""" @@ -137,7 +140,7 @@ async def test_config_entry_not_ready_auth_error( await hass.config_entries.async_setup(bring_config_entry.entry_id) await hass.async_block_till_done() - assert bring_config_entry.state is ConfigEntryState.SETUP_RETRY + assert bring_config_entry.state is state @pytest.mark.usefixtures("mock_bring_client") diff --git a/tests/components/bring/test_util.py b/tests/components/bring/test_util.py index 0d9ed0c5345..88379530362 100644 --- a/tests/components/bring/test_util.py +++ b/tests/components/bring/test_util.py @@ -5,7 +5,7 @@ from typing import cast from bring_api import BringUserSettingsResponse import pytest -from homeassistant.components.bring import DOMAIN +from homeassistant.components.bring.const import DOMAIN from homeassistant.components.bring.coordinator import BringData from homeassistant.components.bring.util import list_language, sum_attributes