Add config flow to Suez water (#104730)
* Add config flow to Suez water * fix tests * Complete coverage * Change version to 2024.7 * Fix final test * Add issue when import is successful * Move hassdata * Do unique_id * Remove import issue when entry already exists * Remove import issue when entry already existspull/105508/head
parent
e890671192
commit
a187a39f0b
|
@ -1233,7 +1233,8 @@ omit =
|
|||
homeassistant/components/stream/hls.py
|
||||
homeassistant/components/stream/worker.py
|
||||
homeassistant/components/streamlabswater/*
|
||||
homeassistant/components/suez_water/*
|
||||
homeassistant/components/suez_water/__init__.py
|
||||
homeassistant/components/suez_water/sensor.py
|
||||
homeassistant/components/supervisord/sensor.py
|
||||
homeassistant/components/supla/*
|
||||
homeassistant/components/surepetcare/__init__.py
|
||||
|
|
|
@ -1251,6 +1251,7 @@ build.json @home-assistant/supervisor
|
|||
/homeassistant/components/subaru/ @G-Two
|
||||
/tests/components/subaru/ @G-Two
|
||||
/homeassistant/components/suez_water/ @ooii
|
||||
/tests/components/suez_water/ @ooii
|
||||
/homeassistant/components/sun/ @Swamp-Ig
|
||||
/tests/components/sun/ @Swamp-Ig
|
||||
/homeassistant/components/sunweg/ @rokam
|
||||
|
|
|
@ -1 +1,48 @@
|
|||
"""France Suez Water integration."""
|
||||
"""The Suez Water integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
from pysuez import SuezClient
|
||||
from pysuez.client import PySuezError
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady
|
||||
|
||||
from .const import CONF_COUNTER_ID, DOMAIN
|
||||
|
||||
PLATFORMS: list[Platform] = [Platform.SENSOR]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Suez Water from a config entry."""
|
||||
|
||||
def get_client() -> SuezClient:
|
||||
try:
|
||||
client = SuezClient(
|
||||
entry.data[CONF_USERNAME],
|
||||
entry.data[CONF_PASSWORD],
|
||||
entry.data[CONF_COUNTER_ID],
|
||||
provider=None,
|
||||
)
|
||||
if not client.check_credentials():
|
||||
raise ConfigEntryError
|
||||
return client
|
||||
except PySuezError:
|
||||
raise ConfigEntryNotReady
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[
|
||||
entry.entry_id
|
||||
] = await hass.async_add_executor_job(get_client)
|
||||
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
|
||||
return unload_ok
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
"""Config flow for Suez Water integration."""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from pysuez import SuezClient
|
||||
from pysuez.client import PySuezError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
|
||||
from homeassistant.data_entry_flow import AbortFlow, FlowResult
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
|
||||
from .const import CONF_COUNTER_ID, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
ISSUE_PLACEHOLDER = {"url": "/config/integrations/dashboard/add?domain=suez_water"}
|
||||
STEP_USER_DATA_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_USERNAME): str,
|
||||
vol.Required(CONF_PASSWORD): str,
|
||||
vol.Required(CONF_COUNTER_ID): str,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def validate_input(data: dict[str, Any]) -> None:
|
||||
"""Validate the user input allows us to connect.
|
||||
|
||||
Data has the keys from STEP_USER_DATA_SCHEMA with values provided by the user.
|
||||
"""
|
||||
try:
|
||||
client = SuezClient(
|
||||
data[CONF_USERNAME],
|
||||
data[CONF_PASSWORD],
|
||||
data[CONF_COUNTER_ID],
|
||||
provider=None,
|
||||
)
|
||||
if not client.check_credentials():
|
||||
raise InvalidAuth
|
||||
except PySuezError:
|
||||
raise CannotConnect
|
||||
|
||||
|
||||
class SuezWaterConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for Suez Water."""
|
||||
|
||||
VERSION = 1
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
"""Handle the initial step."""
|
||||
errors: dict[str, str] = {}
|
||||
if user_input is not None:
|
||||
await self.async_set_unique_id(user_input[CONF_USERNAME])
|
||||
self._abort_if_unique_id_configured()
|
||||
try:
|
||||
await self.hass.async_add_executor_job(validate_input, user_input)
|
||||
except CannotConnect:
|
||||
errors["base"] = "cannot_connect"
|
||||
except InvalidAuth:
|
||||
errors["base"] = "invalid_auth"
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
else:
|
||||
return self.async_create_entry(
|
||||
title=user_input[CONF_USERNAME], data=user_input
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
|
||||
)
|
||||
|
||||
async def async_step_import(self, user_input: dict[str, Any]) -> FlowResult:
|
||||
"""Import the yaml config."""
|
||||
await self.async_set_unique_id(user_input[CONF_USERNAME])
|
||||
try:
|
||||
self._abort_if_unique_id_configured()
|
||||
except AbortFlow as err:
|
||||
async_create_issue(
|
||||
self.hass,
|
||||
HOMEASSISTANT_DOMAIN,
|
||||
f"deprecated_yaml_{DOMAIN}",
|
||||
breaks_in_ha_version="2024.7.0",
|
||||
is_fixable=False,
|
||||
issue_domain=DOMAIN,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_yaml",
|
||||
translation_placeholders={
|
||||
"domain": DOMAIN,
|
||||
"integration_title": "Suez Water",
|
||||
},
|
||||
)
|
||||
raise err
|
||||
try:
|
||||
await self.hass.async_add_executor_job(validate_input, user_input)
|
||||
except CannotConnect:
|
||||
async_create_issue(
|
||||
self.hass,
|
||||
DOMAIN,
|
||||
"deprecated_yaml_import_issue_cannot_connect",
|
||||
breaks_in_ha_version="2024.7.0",
|
||||
is_fixable=False,
|
||||
issue_domain=DOMAIN,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_yaml_import_issue_cannot_connect",
|
||||
translation_placeholders=ISSUE_PLACEHOLDER,
|
||||
)
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
except InvalidAuth:
|
||||
async_create_issue(
|
||||
self.hass,
|
||||
DOMAIN,
|
||||
"deprecated_yaml_import_issue_invalid_auth",
|
||||
breaks_in_ha_version="2024.7.0",
|
||||
is_fixable=False,
|
||||
issue_domain=DOMAIN,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_yaml_import_issue_invalid_auth",
|
||||
translation_placeholders=ISSUE_PLACEHOLDER,
|
||||
)
|
||||
return self.async_abort(reason="invalid_auth")
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
async_create_issue(
|
||||
self.hass,
|
||||
DOMAIN,
|
||||
"deprecated_yaml_import_issue_unknown",
|
||||
breaks_in_ha_version="2024.7.0",
|
||||
is_fixable=False,
|
||||
issue_domain=DOMAIN,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_yaml_import_issue_unknown",
|
||||
translation_placeholders=ISSUE_PLACEHOLDER,
|
||||
)
|
||||
return self.async_abort(reason="unknown")
|
||||
async_create_issue(
|
||||
self.hass,
|
||||
HOMEASSISTANT_DOMAIN,
|
||||
f"deprecated_yaml_{DOMAIN}",
|
||||
breaks_in_ha_version="2024.7.0",
|
||||
is_fixable=False,
|
||||
issue_domain=DOMAIN,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="deprecated_yaml",
|
||||
translation_placeholders={
|
||||
"domain": DOMAIN,
|
||||
"integration_title": "Suez Water",
|
||||
},
|
||||
)
|
||||
return self.async_create_entry(title=user_input[CONF_USERNAME], data=user_input)
|
||||
|
||||
|
||||
class CannotConnect(HomeAssistantError):
|
||||
"""Error to indicate we cannot connect."""
|
||||
|
||||
|
||||
class InvalidAuth(HomeAssistantError):
|
||||
"""Error to indicate there is invalid auth."""
|
|
@ -0,0 +1,5 @@
|
|||
"""Constants for the Suez Water integration."""
|
||||
|
||||
DOMAIN = "suez_water"
|
||||
|
||||
CONF_COUNTER_ID = "counter_id"
|
|
@ -2,6 +2,7 @@
|
|||
"domain": "suez_water",
|
||||
"name": "Suez Water",
|
||||
"codeowners": ["@ooii"],
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/suez_water",
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["pysuez", "regex"],
|
||||
|
|
|
@ -13,18 +13,19 @@ from homeassistant.components.sensor import (
|
|||
SensorDeviceClass,
|
||||
SensorEntity,
|
||||
)
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, UnitOfVolume
|
||||
from homeassistant.core import HomeAssistant
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
from .const import CONF_COUNTER_ID, DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(hours=12)
|
||||
|
||||
CONF_COUNTER_ID = "counter_id"
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(CONF_USERNAME): cv.string,
|
||||
|
@ -41,21 +42,23 @@ def setup_platform(
|
|||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> None:
|
||||
"""Set up the sensor platform."""
|
||||
username = config[CONF_USERNAME]
|
||||
password = config[CONF_PASSWORD]
|
||||
counter_id = config[CONF_COUNTER_ID]
|
||||
try:
|
||||
client = SuezClient(username, password, counter_id, provider=None)
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": SOURCE_IMPORT},
|
||||
data=config,
|
||||
)
|
||||
)
|
||||
|
||||
if not client.check_credentials():
|
||||
_LOGGER.warning("Wrong username and/or password")
|
||||
return
|
||||
|
||||
except PySuezError:
|
||||
_LOGGER.warning("Unable to create Suez Client")
|
||||
return
|
||||
|
||||
add_entities([SuezSensor(client)], True)
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Suez Water sensor from a config entry."""
|
||||
client = hass.data[DOMAIN][entry.entry_id]
|
||||
async_add_entities([SuezSensor(client)], True)
|
||||
|
||||
|
||||
class SuezSensor(SensorEntity):
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"counter_id": "Counter id"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
"deprecated_yaml_import_issue_invalid_auth": {
|
||||
"title": "The Suez water YAML configuration import failed",
|
||||
"description": "Configuring Suez water using YAML is being removed but there was an authentication error importing your YAML configuration.\n\nCorrect the YAML configuration and restart Home Assistant to try again or remove the Suez water YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually."
|
||||
},
|
||||
"deprecated_yaml_import_issue_cannot_connect": {
|
||||
"title": "The Suez water YAML configuration import failed",
|
||||
"description": "Configuring Suez water using YAML is being removed but there was an connection error importing your YAML configuration.\n\nEnsure connection to Suez water works and restart Home Assistant to try again or remove the Suez water YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually."
|
||||
},
|
||||
"deprecated_yaml_import_issue_unknown": {
|
||||
"title": "The Suez water YAML configuration import failed",
|
||||
"description": "Configuring Suez water using YAML is being removed but there was an unknown error when trying to import the YAML configuration.\n\nEnsure the imported configuration is correct and remove the Suez water YAML configuration from your configuration.yaml file and continue to [set up the integration]({url}) manually."
|
||||
}
|
||||
}
|
||||
}
|
|
@ -471,6 +471,7 @@ FLOWS = {
|
|||
"stookalert",
|
||||
"stookwijzer",
|
||||
"subaru",
|
||||
"suez_water",
|
||||
"sun",
|
||||
"sunweg",
|
||||
"surepetcare",
|
||||
|
|
|
@ -5537,7 +5537,7 @@
|
|||
"suez_water": {
|
||||
"name": "Suez Water",
|
||||
"integration_type": "hub",
|
||||
"config_flow": false,
|
||||
"config_flow": true,
|
||||
"iot_class": "cloud_polling"
|
||||
},
|
||||
"sun": {
|
||||
|
|
|
@ -1602,6 +1602,9 @@ pyspcwebgw==0.7.0
|
|||
# homeassistant.components.squeezebox
|
||||
pysqueezebox==0.7.1
|
||||
|
||||
# homeassistant.components.suez_water
|
||||
pysuez==0.2.0
|
||||
|
||||
# homeassistant.components.switchbee
|
||||
pyswitchbee==1.8.0
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"""Tests for the Suez Water integration."""
|
|
@ -0,0 +1,14 @@
|
|||
"""Common fixtures for the Suez Water tests."""
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_setup_entry() -> Generator[AsyncMock, None, None]:
|
||||
"""Override async_setup_entry."""
|
||||
with patch(
|
||||
"homeassistant.components.suez_water.async_setup_entry", return_value=True
|
||||
) as mock_setup_entry:
|
||||
yield mock_setup_entry
|
|
@ -0,0 +1,223 @@
|
|||
"""Test the Suez Water config flow."""
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from pysuez.client import PySuezError
|
||||
import pytest
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.suez_water.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import issue_registry as ir
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_DATA = {
|
||||
"username": "test-username",
|
||||
"password": "test-password",
|
||||
"counter_id": "test-counter",
|
||||
}
|
||||
|
||||
|
||||
async def test_form(hass: HomeAssistant, mock_setup_entry: AsyncMock) -> None:
|
||||
"""Test we get the form."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["errors"] == {}
|
||||
|
||||
with patch("homeassistant.components.suez_water.config_flow.SuezClient"):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
MOCK_DATA,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "test-username"
|
||||
assert result["result"].unique_id == "test-username"
|
||||
assert result["data"] == MOCK_DATA
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_invalid_auth(
|
||||
hass: HomeAssistant, mock_setup_entry: AsyncMock
|
||||
) -> None:
|
||||
"""Test we handle invalid auth."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient.__init__",
|
||||
return_value=None,
|
||||
), patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient.check_credentials",
|
||||
return_value=False,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
MOCK_DATA,
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["errors"] == {"base": "invalid_auth"}
|
||||
|
||||
with patch("homeassistant.components.suez_water.config_flow.SuezClient"):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
MOCK_DATA,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "test-username"
|
||||
assert result["result"].unique_id == "test-username"
|
||||
assert result["data"] == MOCK_DATA
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_form_already_configured(hass: HomeAssistant) -> None:
|
||||
"""Test we abort when entry is already configured."""
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="test-username",
|
||||
data=MOCK_DATA,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
MOCK_DATA,
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("exception", "error"), [(PySuezError, "cannot_connect"), (Exception, "unknown")]
|
||||
)
|
||||
async def test_form_error(
|
||||
hass: HomeAssistant, mock_setup_entry: AsyncMock, exception: Exception, error: str
|
||||
) -> None:
|
||||
"""Test we handle errors."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient",
|
||||
side_effect=exception,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
MOCK_DATA,
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.FORM
|
||||
assert result["errors"] == {"base": error}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient",
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
MOCK_DATA,
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "test-username"
|
||||
assert result["data"] == MOCK_DATA
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
|
||||
|
||||
async def test_import(
|
||||
hass: HomeAssistant, mock_setup_entry: AsyncMock, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test import flow."""
|
||||
with patch("homeassistant.components.suez_water.config_flow.SuezClient"):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=MOCK_DATA
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["type"] == FlowResultType.CREATE_ENTRY
|
||||
assert result["title"] == "test-username"
|
||||
assert result["result"].unique_id == "test-username"
|
||||
assert result["data"] == MOCK_DATA
|
||||
assert len(mock_setup_entry.mock_calls) == 1
|
||||
assert len(issue_registry.issues) == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("exception", "reason"), [(PySuezError, "cannot_connect"), (Exception, "unknown")]
|
||||
)
|
||||
async def test_import_error(
|
||||
hass: HomeAssistant,
|
||||
mock_setup_entry: AsyncMock,
|
||||
exception: Exception,
|
||||
reason: str,
|
||||
issue_registry: ir.IssueRegistry,
|
||||
) -> None:
|
||||
"""Test we handle errors while importing."""
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient",
|
||||
side_effect=exception,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=MOCK_DATA
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == reason
|
||||
assert len(issue_registry.issues) == 1
|
||||
|
||||
|
||||
async def test_importing_invalid_auth(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test we handle invalid auth when importing."""
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient.__init__",
|
||||
return_value=None,
|
||||
), patch(
|
||||
"homeassistant.components.suez_water.config_flow.SuezClient.check_credentials",
|
||||
return_value=False,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=MOCK_DATA
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == "invalid_auth"
|
||||
assert len(issue_registry.issues) == 1
|
||||
|
||||
|
||||
async def test_import_already_configured(
|
||||
hass: HomeAssistant, issue_registry: ir.IssueRegistry
|
||||
) -> None:
|
||||
"""Test we abort import when entry is already configured."""
|
||||
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id="test-username",
|
||||
data=MOCK_DATA,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_IMPORT}, data=MOCK_DATA
|
||||
)
|
||||
|
||||
assert result["type"] == FlowResultType.ABORT
|
||||
assert result["reason"] == "already_configured"
|
||||
assert len(issue_registry.issues) == 1
|
Loading…
Reference in New Issue