diff --git a/homeassistant/components/rympro/__init__.py b/homeassistant/components/rympro/__init__.py index 69251608d09e..57564aeab24b 100644 --- a/homeassistant/components/rympro/__init__.py +++ b/homeassistant/components/rympro/__init__.py @@ -2,7 +2,7 @@ import logging -from pyrympro import CannotConnectError, RymPro, UnauthorizedError +from pyrympro import CannotConnectError, OperationError, RymPro, UnauthorizedError from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, CONF_TOKEN, Platform from homeassistant.core import HomeAssistant @@ -22,13 +22,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: RymProConfigEntry) -> bo rympro.set_token(data[CONF_TOKEN]) try: await rympro.account_info() - except CannotConnectError as error: + except (CannotConnectError, OperationError) as error: raise ConfigEntryNotReady from error except UnauthorizedError: try: token = await rympro.login(data[CONF_EMAIL], data[CONF_PASSWORD], "ha") except UnauthorizedError as error: raise ConfigEntryAuthFailed from error + except CannotConnectError as error: + raise ConfigEntryNotReady from error hass.config_entries.async_update_entry( entry, data={**data, CONF_TOKEN: token}, diff --git a/tests/components/rympro/test_init.py b/tests/components/rympro/test_init.py new file mode 100644 index 000000000000..d966f9cf7e30 --- /dev/null +++ b/tests/components/rympro/test_init.py @@ -0,0 +1,69 @@ +"""Test the Read Your Meter Pro integration setup.""" + +from unittest.mock import patch + +from pyrympro import CannotConnectError, OperationError, UnauthorizedError +import pytest + +from homeassistant.components.rympro.const import DOMAIN +from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import CONF_EMAIL, CONF_PASSWORD, CONF_TOKEN, CONF_UNIQUE_ID +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry + +TEST_DATA = { + CONF_EMAIL: "test-email", + CONF_PASSWORD: "test-password", + CONF_TOKEN: "test-token", + CONF_UNIQUE_ID: "test-account-number", +} + + +@pytest.fixture +def config_entry(hass: HomeAssistant) -> MockConfigEntry: + """Create a mock config entry.""" + config_entry = MockConfigEntry( + domain=DOMAIN, + data=TEST_DATA, + unique_id=TEST_DATA[CONF_UNIQUE_ID], + ) + config_entry.add_to_hass(hass) + return config_entry + + +@pytest.mark.parametrize("exception", [CannotConnectError, OperationError]) +async def test_account_info_error_retries_setup( + hass: HomeAssistant, + config_entry: MockConfigEntry, + exception: type[Exception], +) -> None: + """Test that a transient account_info error schedules a setup retry.""" + with patch( + "homeassistant.components.rympro.RymPro.account_info", + side_effect=exception, + ): + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.SETUP_RETRY + + +async def test_relogin_cannot_connect_error_retries_setup( + hass: HomeAssistant, config_entry: MockConfigEntry +) -> None: + """Test that a connection error while re-authenticating retries setup.""" + with ( + patch( + "homeassistant.components.rympro.RymPro.account_info", + side_effect=UnauthorizedError, + ), + patch( + "homeassistant.components.rympro.RymPro.login", + side_effect=CannotConnectError, + ), + ): + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.SETUP_RETRY