Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions homeassistant/components/vesync/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
import logging

from pyvesync import VeSync
from pyvesync.utils.errors import VeSyncLoginError
from pyvesync.utils.errors import (
VeSyncAPIResponseError,
VeSyncLoginError,
VeSyncServerError,
)

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import config_validation as cv, entity_registry as er
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.device_registry import DeviceEntry
Expand Down Expand Up @@ -59,7 +63,17 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
try:
await manager.login()
except VeSyncLoginError as err:
raise ConfigEntryAuthFailed from err
raise ConfigEntryAuthFailed(
translation_domain=DOMAIN, translation_key="invalid_auth"
) from err
except VeSyncServerError as err:
raise ConfigEntryNotReady(
translation_domain=DOMAIN, translation_key="server_error"
) from err
except VeSyncAPIResponseError as err:
raise ConfigEntryNotReady(
translation_domain=DOMAIN, translation_key="api_response_error"
) from err

hass.data[DOMAIN] = {}
hass.data[DOMAIN][VS_MANAGER] = manager
Expand Down
4 changes: 3 additions & 1 deletion homeassistant/components/vesync/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
},
"error": {
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]"
"api_response_error": "API response error",
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
"server_error": "Server error occurred"
},
"step": {
"reauth_confirm": {
Expand Down
26 changes: 20 additions & 6 deletions tests/components/vesync/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

from unittest.mock import AsyncMock, patch

import pytest
from pyvesync import VeSync
from pyvesync.utils.errors import VeSyncLoginError
from pyvesync.utils.errors import (
VeSyncAPIResponseError,
VeSyncLoginError,
VeSyncServerError,
)

from homeassistant.components.vesync import (
async_remove_config_entry_device,
Expand All @@ -18,21 +23,30 @@
from tests.common import MockConfigEntry


async def test_async_setup_entry__not_login(
@pytest.mark.parametrize(
("exception", "expected_state"),
[
(VeSyncLoginError("Mock login failed"), ConfigEntryState.SETUP_ERROR),
(VeSyncAPIResponseError("Mock login failed"), ConfigEntryState.SETUP_RETRY),
(VeSyncServerError("Mock login failed"), ConfigEntryState.SETUP_RETRY),
],
)
async def test_async_setup_entry_login_errors(
hass: HomeAssistant,
config_entry: ConfigEntry,
manager: VeSync,
exception: Exception,
expected_state: ConfigEntryState,
) -> None:
"""Test setup does not create config entry when not logged in."""
manager.login = AsyncMock(side_effect=VeSyncLoginError("Mock login failed"))
"""Test setup handles different login errors appropriately."""
manager.login = AsyncMock(side_effect=exception)

assert not await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()

assert manager.login.call_count == 1
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert config_entry.state is ConfigEntryState.SETUP_ERROR
assert not hass.data.get(DOMAIN)
assert config_entry.state is expected_state


async def test_async_setup_entry__no_devices(
Expand Down
Loading