Add config flow to Smarty (#127540)

Co-authored-by: Sid <27780930+autinerd@users.noreply.github.com>
This commit is contained in:
Joost Lekkerkerker 2024-10-24 13:32:27 +02:00 committed by GitHub
parent 937dbdc71f
commit cd4aa8ccd6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 492 additions and 61 deletions

View File

@ -1350,6 +1350,7 @@ build.json @home-assistant/supervisor
/homeassistant/components/smarttub/ @mdz /homeassistant/components/smarttub/ @mdz
/tests/components/smarttub/ @mdz /tests/components/smarttub/ @mdz
/homeassistant/components/smarty/ @z0mbieprocess /homeassistant/components/smarty/ @z0mbieprocess
/tests/components/smarty/ @z0mbieprocess
/homeassistant/components/smhi/ @gjohansson-ST /homeassistant/components/smhi/ @gjohansson-ST
/tests/components/smhi/ @gjohansson-ST /tests/components/smhi/ @gjohansson-ST
/homeassistant/components/smlight/ @tl-sl /homeassistant/components/smlight/ @tl-sl

View File

@ -7,17 +7,17 @@ import logging
from pysmarty2 import Smarty from pysmarty2 import Smarty
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_HOST, CONF_NAME, Platform from homeassistant.const import CONF_HOST, CONF_NAME, Platform
from homeassistant.core import HomeAssistant from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
from homeassistant.helpers import discovery from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import issue_registry as ir
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import track_time_interval from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
DOMAIN = "smarty" from .const import DOMAIN, SIGNAL_UPDATE_SMARTY
DATA_SMARTY = "smarty"
SMARTY_NAME = "Smarty"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -26,48 +26,96 @@ CONFIG_SCHEMA = vol.Schema(
DOMAIN: vol.Schema( DOMAIN: vol.Schema(
{ {
vol.Required(CONF_HOST): vol.All(ipaddress.ip_address, cv.string), vol.Required(CONF_HOST): vol.All(ipaddress.ip_address, cv.string),
vol.Optional(CONF_NAME, default=SMARTY_NAME): cv.string, vol.Optional(CONF_NAME, default="Smarty"): cv.string,
} }
) )
}, },
extra=vol.ALLOW_EXTRA, extra=vol.ALLOW_EXTRA,
) )
RPM = "rpm" PLATFORMS = [Platform.BINARY_SENSOR, Platform.FAN, Platform.SENSOR]
SIGNAL_UPDATE_SMARTY = "smarty_update"
type SmartyConfigEntry = ConfigEntry[Smarty]
def setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, hass_config: ConfigType) -> bool:
"""Create a smarty system."""
if config := hass_config.get(DOMAIN):
hass.async_create_task(_async_import(hass, config))
return True
async def _async_import(hass: HomeAssistant, config: ConfigType) -> None:
"""Set up the smarty environment.""" """Set up the smarty environment."""
conf = config[DOMAIN] if not hass.config_entries.async_entries(DOMAIN):
# Start import flow
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
)
if result["type"] == FlowResultType.ABORT:
ir.async_create_issue(
hass,
DOMAIN,
f"deprecated_yaml_import_issue_{result['reason']}",
breaks_in_ha_version="2025.5.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=ir.IssueSeverity.WARNING,
translation_key=f"deprecated_yaml_import_issue_{result['reason']}",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Smarty",
},
)
return
host = conf[CONF_HOST] ir.async_create_issue(
name = conf[CONF_NAME] hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{DOMAIN}",
breaks_in_ha_version="2025.5.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=ir.IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Smarty",
},
)
_LOGGER.debug("Name: %s, host: %s", name, host)
smarty = Smarty(host=host) async def async_setup_entry(hass: HomeAssistant, entry: SmartyConfigEntry) -> bool:
"""Set up the Smarty environment from a config entry."""
hass.data[DOMAIN] = {"api": smarty, "name": name} def _setup_smarty() -> Smarty:
smarty = Smarty(host=entry.data[CONF_HOST])
smarty.update()
return smarty
# Initial update smarty = await hass.async_add_executor_job(_setup_smarty)
smarty.update()
# Load platforms entry.runtime_data = smarty
discovery.load_platform(hass, Platform.FAN, DOMAIN, {}, config)
discovery.load_platform(hass, Platform.SENSOR, DOMAIN, {}, config)
discovery.load_platform(hass, Platform.BINARY_SENSOR, DOMAIN, {}, config)
def poll_device_update(event_time): async def poll_device_update(event_time) -> None:
"""Update Smarty device.""" """Update Smarty device."""
_LOGGER.debug("Updating Smarty device") _LOGGER.debug("Updating Smarty device")
if smarty.update(): if await hass.async_add_executor_job(smarty.update):
_LOGGER.debug("Update success") _LOGGER.debug("Update success")
dispatcher_send(hass, SIGNAL_UPDATE_SMARTY) async_dispatcher_send(hass, SIGNAL_UPDATE_SMARTY)
else: else:
_LOGGER.debug("Update failed") _LOGGER.debug("Update failed")
track_time_interval(hass, poll_device_update, timedelta(seconds=30)) entry.async_on_unload(
async_track_time_interval(hass, poll_device_update, timedelta(seconds=30))
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True return True
async def async_unload_entry(hass: HomeAssistant, entry: SmartyConfigEntry) -> bool:
"""Unload a config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)

View File

@ -13,27 +13,25 @@ from homeassistant.components.binary_sensor import (
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import DOMAIN, SIGNAL_UPDATE_SMARTY from . import SIGNAL_UPDATE_SMARTY, SmartyConfigEntry
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
async def async_setup_platform( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config: ConfigType, entry: SmartyConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None: ) -> None:
"""Set up the Smarty Binary Sensor Platform.""" """Set up the Smarty Binary Sensor Platform."""
smarty: Smarty = hass.data[DOMAIN]["api"]
name: str = hass.data[DOMAIN]["name"] smarty = entry.runtime_data
sensors = [ sensors = [
AlarmSensor(name, smarty), AlarmSensor(entry.title, smarty),
WarningSensor(name, smarty), WarningSensor(entry.title, smarty),
BoostSensor(name, smarty), BoostSensor(entry.title, smarty),
] ]
async_add_entities(sensors, True) async_add_entities(sensors, True)

View File

@ -0,0 +1,62 @@
"""Config flow for Smarty integration."""
from typing import Any
from pysmarty2 import Smarty
import voluptuous as vol
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
from homeassistant.const import CONF_HOST, CONF_NAME
from .const import DOMAIN
class SmartyConfigFlow(ConfigFlow, domain=DOMAIN):
"""Smarty config flow."""
def _test_connection(self, host: str) -> str | None:
"""Test the connection to the Smarty API."""
smarty = Smarty(host=host)
try:
if smarty.update():
return None
except Exception: # noqa: BLE001
return "unknown"
else:
return "cannot_connect"
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
"""Handle a flow initialized by the user."""
errors: dict[str, str] = {}
if user_input is not None:
self._async_abort_entries_match(user_input)
error = await self.hass.async_add_executor_job(
self._test_connection, user_input[CONF_HOST]
)
if not error:
return self.async_create_entry(
title=user_input[CONF_HOST], data=user_input
)
errors["base"] = error
return self.async_show_form(
step_id="user",
data_schema=vol.Schema({vol.Required(CONF_HOST): str}),
errors=errors,
)
async def async_step_import(
self, import_config: dict[str, Any]
) -> ConfigFlowResult:
"""Handle a flow initialized by import."""
error = await self.hass.async_add_executor_job(
self._test_connection, import_config[CONF_HOST]
)
if not error:
return self.async_create_entry(
title=import_config[CONF_NAME],
data={CONF_HOST: import_config[CONF_HOST]},
)
return self.async_abort(reason=error)

View File

@ -0,0 +1,5 @@
"""Constants for the Smarty component."""
DOMAIN = "smarty"
SIGNAL_UPDATE_SMARTY = "smarty_update"

View File

@ -6,21 +6,18 @@ import logging
import math import math
from typing import Any from typing import Any
from pysmarty2 import Smarty
from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.components.fan import FanEntity, FanEntityFeature
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util.percentage import ( from homeassistant.util.percentage import (
percentage_to_ranged_value, percentage_to_ranged_value,
ranged_value_to_percentage, ranged_value_to_percentage,
) )
from homeassistant.util.scaling import int_states_in_range from homeassistant.util.scaling import int_states_in_range
from . import DOMAIN, SIGNAL_UPDATE_SMARTY from . import SIGNAL_UPDATE_SMARTY, SmartyConfigEntry
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -28,17 +25,16 @@ DEFAULT_ON_PERCENTAGE = 66
SPEED_RANGE = (1, 3) # off is not included SPEED_RANGE = (1, 3) # off is not included
async def async_setup_platform( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config: ConfigType, entry: SmartyConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None: ) -> None:
"""Set up the Smarty Fan Platform.""" """Set up the Smarty Fan Platform."""
smarty: Smarty = hass.data[DOMAIN]["api"]
name: str = hass.data[DOMAIN]["name"]
async_add_entities([SmartyFan(name, smarty)], True) smarty = entry.runtime_data
async_add_entities([SmartyFan(entry.title, smarty)], True)
class SmartyFan(FanEntity): class SmartyFan(FanEntity):

View File

@ -2,6 +2,7 @@
"domain": "smarty", "domain": "smarty",
"name": "Salda Smarty", "name": "Salda Smarty",
"codeowners": ["@z0mbieprocess"], "codeowners": ["@z0mbieprocess"],
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/smarty", "documentation": "https://www.home-assistant.io/integrations/smarty",
"integration_type": "hub", "integration_type": "hub",
"iot_class": "local_polling", "iot_class": "local_polling",

View File

@ -12,31 +12,28 @@ from homeassistant.const import UnitOfTemperature
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from . import DOMAIN, SIGNAL_UPDATE_SMARTY from . import SIGNAL_UPDATE_SMARTY, SmartyConfigEntry
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
async def async_setup_platform( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
config: ConfigType, entry: SmartyConfigEntry,
async_add_entities: AddEntitiesCallback, async_add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None: ) -> None:
"""Set up the Smarty Sensor Platform.""" """Set up the Smarty Sensor Platform."""
smarty: Smarty = hass.data[DOMAIN]["api"]
name: str = hass.data[DOMAIN]["name"]
smarty = entry.runtime_data
sensors = [ sensors = [
SupplyAirTemperatureSensor(name, smarty), SupplyAirTemperatureSensor(entry.title, smarty),
ExtractAirTemperatureSensor(name, smarty), ExtractAirTemperatureSensor(entry.title, smarty),
OutdoorAirTemperatureSensor(name, smarty), OutdoorAirTemperatureSensor(entry.title, smarty),
SupplyFanSpeedSensor(name, smarty), SupplyFanSpeedSensor(entry.title, smarty),
ExtractFanSpeedSensor(name, smarty), ExtractFanSpeedSensor(entry.title, smarty),
FilterDaysLeftSensor(name, smarty), FilterDaysLeftSensor(entry.title, smarty),
] ]
async_add_entities(sensors, True) async_add_entities(sensors, True)

View File

@ -0,0 +1,33 @@
{
"config": {
"step": {
"user": {
"data": {
"host": "[%key:common::config_flow::data::host%]"
},
"data_description": {
"host": "The hostname or IP address of the Smarty device"
}
}
},
"error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
},
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"unknown": "[%key:common::config_flow::error::unknown%]"
}
},
"issues": {
"deprecated_yaml_import_issue_unknown": {
"title": "YAML import failed with unknown error",
"description": "Configuring {integration_title} using YAML is being removed but there was an unknown error while importing your existing configuration.\nSetup will not proceed.\n\nVerify that your {integration_title} is operating correctly and restart Home Assistant to attempt the import again.\n\nAlternatively, you may remove the `{domain}` configuration from your configuration.yaml entirely, restart Home Assistant, and add the {integration_title} integration manually."
},
"deprecated_yaml_import_issue_auth_error": {
"title": "YAML import failed due to an authentication error",
"description": "Configuring {integration_title} using YAML is being removed but there was an authentication error while importing your existing configuration.\nSetup will not proceed.\n\nVerify that your {integration_title} is operating correctly and restart Home Assistant to attempt the import again.\n\nAlternatively, you may remove the `{domain}` configuration from your configuration.yaml entirely, restart Home Assistant, and add the {integration_title} integration manually."
}
}
}

View File

@ -540,6 +540,7 @@ FLOWS = {
"smart_meter_texas", "smart_meter_texas",
"smartthings", "smartthings",
"smarttub", "smarttub",
"smarty",
"smhi", "smhi",
"smlight", "smlight",
"sms", "sms",

View File

@ -5663,7 +5663,7 @@
"smarty": { "smarty": {
"name": "Salda Smarty", "name": "Salda Smarty",
"integration_type": "hub", "integration_type": "hub",
"config_flow": false, "config_flow": true,
"iot_class": "local_polling" "iot_class": "local_polling"
}, },
"smhi": { "smhi": {

View File

@ -1804,6 +1804,9 @@ pysmartapp==0.3.5
# homeassistant.components.smartthings # homeassistant.components.smartthings
pysmartthings==0.7.8 pysmartthings==0.7.8
# homeassistant.components.smarty
pysmarty2==0.10.1
# homeassistant.components.edl21 # homeassistant.components.edl21
pysml==0.0.12 pysml==0.0.12

View File

@ -0,0 +1,13 @@
"""Tests for the Smarty integration."""
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
"""Set up the component."""
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()

View File

@ -0,0 +1,46 @@
"""Smarty tests configuration."""
from collections.abc import Generator
from unittest.mock import patch
import pytest
from homeassistant.components.smarty import DOMAIN
from homeassistant.const import CONF_HOST
from tests.common import MockConfigEntry
from tests.components.smhi.common import AsyncMock
@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock]:
"""Override integration setup."""
with patch(
"homeassistant.components.smarty.async_setup_entry",
return_value=True,
) as mock_setup_entry:
yield mock_setup_entry
@pytest.fixture
def mock_smarty() -> Generator[AsyncMock]:
"""Mock a Smarty client."""
with (
patch(
"homeassistant.components.smarty.Smarty",
autospec=True,
) as mock_client,
patch(
"homeassistant.components.smarty.config_flow.Smarty",
new=mock_client,
),
):
client = mock_client.return_value
client.update.return_value = True
yield client
@pytest.fixture
def mock_config_entry() -> MockConfigEntry:
"""Return the default mocked config entry."""
return MockConfigEntry(domain=DOMAIN, data={CONF_HOST: "192.168.0.2"})

View File

@ -0,0 +1,165 @@
"""Test the smarty config flow."""
from unittest.mock import AsyncMock
from homeassistant.components.smarty.const import DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER
from homeassistant.const import CONF_HOST, CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
async def test_full_flow(
hass: HomeAssistant, mock_smarty: AsyncMock, mock_setup_entry: AsyncMock
) -> None:
"""Test the full flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "192.168.0.2"},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "192.168.0.2"
assert result["data"] == {CONF_HOST: "192.168.0.2"}
assert len(mock_setup_entry.mock_calls) == 1
async def test_cannot_connect(
hass: HomeAssistant, mock_smarty: AsyncMock, mock_setup_entry: AsyncMock
) -> None:
"""Test we handle cannot connect error."""
mock_smarty.update.return_value = False
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "192.168.0.2"},
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "cannot_connect"}
mock_smarty.update.return_value = True
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "192.168.0.2"},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
async def test_unknown_error(
hass: HomeAssistant, mock_smarty: AsyncMock, mock_setup_entry: AsyncMock
) -> None:
"""Test we handle unknown error."""
mock_smarty.update.side_effect = Exception
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "192.168.0.2"},
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": "unknown"}
mock_smarty.update.side_effect = None
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "192.168.0.2"},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
async def test_existing_entry(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test we handle existing entry."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {}
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "192.168.0.2"},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_import_flow(
hass: HomeAssistant, mock_smarty: AsyncMock, mock_setup_entry: AsyncMock
) -> None:
"""Test the import flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={CONF_HOST: "192.168.0.2", CONF_NAME: "Smarty"},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "Smarty"
assert result["data"] == {CONF_HOST: "192.168.0.2"}
assert len(mock_setup_entry.mock_calls) == 1
async def test_import_cannot_connect(
hass: HomeAssistant, mock_smarty: AsyncMock
) -> None:
"""Test we handle cannot connect error."""
mock_smarty.update.return_value = False
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={CONF_HOST: "192.168.0.2", CONF_NAME: "Smarty"},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "cannot_connect"
async def test_import_unknown_error(
hass: HomeAssistant, mock_smarty: AsyncMock
) -> None:
"""Test we handle unknown error."""
mock_smarty.update.side_effect = Exception
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={CONF_HOST: "192.168.0.2", CONF_NAME: "Smarty"},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "unknown"

View File

@ -0,0 +1,62 @@
"""Tests for the Smarty component."""
from unittest.mock import AsyncMock
from homeassistant.components.smarty import DOMAIN
from homeassistant.const import CONF_HOST, CONF_NAME
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
from homeassistant.helpers import issue_registry as ir
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry
async def test_import_flow(
hass: HomeAssistant,
mock_smarty: AsyncMock,
issue_registry: ir.IssueRegistry,
mock_setup_entry: AsyncMock,
) -> None:
"""Test import flow."""
assert await async_setup_component(
hass, DOMAIN, {DOMAIN: {CONF_HOST: "192.168.0.2", CONF_NAME: "smarty"}}
)
await hass.async_block_till_done()
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert (HOMEASSISTANT_DOMAIN, "deprecated_yaml_smarty") in issue_registry.issues
async def test_import_flow_already_exists(
hass: HomeAssistant,
mock_smarty: AsyncMock,
issue_registry: ir.IssueRegistry,
mock_setup_entry: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test import flow when entry already exists."""
mock_config_entry.add_to_hass(hass)
assert await async_setup_component(
hass, DOMAIN, {DOMAIN: {CONF_HOST: "192.168.0.2", CONF_NAME: "smarty"}}
)
await hass.async_block_till_done()
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert (HOMEASSISTANT_DOMAIN, "deprecated_yaml_smarty") in issue_registry.issues
async def test_import_flow_error(
hass: HomeAssistant,
mock_smarty: AsyncMock,
issue_registry: ir.IssueRegistry,
mock_setup_entry: AsyncMock,
) -> None:
"""Test import flow when error occurs."""
mock_smarty.update.return_value = False
assert await async_setup_component(
hass, DOMAIN, {DOMAIN: {CONF_HOST: "192.168.0.2", CONF_NAME: "smarty"}}
)
await hass.async_block_till_done()
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
assert (
DOMAIN,
"deprecated_yaml_import_issue_cannot_connect",
) in issue_registry.issues