diff --git a/homeassistant/components/verisure/__init__.py b/homeassistant/components/verisure/__init__.py index f61208309fc..8abb3e59a9f 100644 --- a/homeassistant/components/verisure/__init__.py +++ b/homeassistant/components/verisure/__init__.py @@ -3,9 +3,6 @@ from __future__ import annotations from contextlib import suppress import os -from typing import Any - -import voluptuous as vol from homeassistant.components.alarm_control_panel import ( DOMAIN as ALARM_CONTROL_PANEL_DOMAIN, @@ -15,27 +12,14 @@ from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN from homeassistant.components.lock import DOMAIN as LOCK_DOMAIN from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN -from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry -from homeassistant.const import ( - CONF_EMAIL, - CONF_PASSWORD, - CONF_USERNAME, - EVENT_HOMEASSISTANT_STOP, -) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed import homeassistant.helpers.config_validation as cv from homeassistant.helpers.storage import STORAGE_DIR -from .const import ( - CONF_CODE_DIGITS, - CONF_DEFAULT_LOCK_CODE, - CONF_GIID, - CONF_LOCK_CODE_DIGITS, - CONF_LOCK_DEFAULT_CODE, - DEFAULT_LOCK_CODE_DIGITS, - DOMAIN, -) +from .const import DOMAIN from .coordinator import VerisureDataUpdateCoordinator PLATFORMS = [ @@ -47,80 +31,11 @@ PLATFORMS = [ SWITCH_DOMAIN, ] -CONFIG_SCHEMA = vol.Schema( - vol.All( - cv.deprecated(DOMAIN), - { - DOMAIN: vol.Schema( - { - vol.Required(CONF_PASSWORD): cv.string, - vol.Required(CONF_USERNAME): cv.string, - vol.Optional(CONF_CODE_DIGITS): cv.positive_int, - vol.Optional(CONF_GIID): cv.string, - vol.Optional(CONF_DEFAULT_LOCK_CODE): cv.string, - }, - extra=vol.ALLOW_EXTRA, - ) - }, - ), - extra=vol.ALLOW_EXTRA, -) - - -async def async_setup(hass: HomeAssistant, config: dict[str, Any]) -> bool: - """Set up the Verisure integration.""" - if DOMAIN in config: - hass.async_create_task( - hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_IMPORT}, - data={ - CONF_EMAIL: config[DOMAIN][CONF_USERNAME], - CONF_PASSWORD: config[DOMAIN][CONF_PASSWORD], - CONF_GIID: config[DOMAIN].get(CONF_GIID), - CONF_LOCK_CODE_DIGITS: config[DOMAIN].get(CONF_CODE_DIGITS), - CONF_LOCK_DEFAULT_CODE: config[DOMAIN].get(CONF_LOCK_DEFAULT_CODE), - }, - ) - ) - - return True +CONFIG_SCHEMA = cv.deprecated(DOMAIN) async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Verisure from a config entry.""" - # Migrate old YAML settings (hidden in the config entry), - # to config entry options. Can be removed after YAML support is gone. - if CONF_LOCK_CODE_DIGITS in entry.data or CONF_DEFAULT_LOCK_CODE in entry.data: - options = entry.options.copy() - - if ( - CONF_LOCK_CODE_DIGITS in entry.data - and CONF_LOCK_CODE_DIGITS not in entry.options - and entry.data[CONF_LOCK_CODE_DIGITS] != DEFAULT_LOCK_CODE_DIGITS - ): - options.update( - { - CONF_LOCK_CODE_DIGITS: entry.data[CONF_LOCK_CODE_DIGITS], - } - ) - - if ( - CONF_DEFAULT_LOCK_CODE in entry.data - and CONF_DEFAULT_LOCK_CODE not in entry.options - ): - options.update( - { - CONF_DEFAULT_LOCK_CODE: entry.data[CONF_DEFAULT_LOCK_CODE], - } - ) - - data = entry.data.copy() - data.pop(CONF_LOCK_CODE_DIGITS, None) - data.pop(CONF_DEFAULT_LOCK_CODE, None) - hass.config_entries.async_update_entry(entry, data=data, options=options) - - # Continue as normal... coordinator = VerisureDataUpdateCoordinator(hass, entry=entry) if not await coordinator.async_login(): diff --git a/homeassistant/components/verisure/config_flow.py b/homeassistant/components/verisure/config_flow.py index 34238d0763d..6c2822896e6 100644 --- a/homeassistant/components/verisure/config_flow.py +++ b/homeassistant/components/verisure/config_flow.py @@ -36,14 +36,6 @@ class VerisureConfigFlowHandler(ConfigFlow, domain=DOMAIN): installations: dict[str, str] password: str - # These can be removed after YAML import has been removed. - giid: str | None = None - settings: dict[str, int | str] - - def __init__(self): - """Initialize.""" - self.settings = {} - @staticmethod @callback def async_get_options_flow(config_entry: ConfigEntry) -> VerisureOptionsFlowHandler: @@ -95,8 +87,6 @@ class VerisureConfigFlowHandler(ConfigFlow, domain=DOMAIN): """Select Verisure installation to add.""" if len(self.installations) == 1: user_input = {CONF_GIID: list(self.installations)[0]} - elif self.giid and self.giid in self.installations: - user_input = {CONF_GIID: self.giid} if user_input is None: return self.async_show_form( @@ -115,7 +105,6 @@ class VerisureConfigFlowHandler(ConfigFlow, domain=DOMAIN): CONF_EMAIL: self.email, CONF_PASSWORD: self.password, CONF_GIID: user_input[CONF_GIID], - **self.settings, }, ) @@ -168,26 +157,6 @@ class VerisureConfigFlowHandler(ConfigFlow, domain=DOMAIN): errors=errors, ) - async def async_step_import(self, user_input: dict[str, Any]) -> FlowResult: - """Import Verisure YAML configuration.""" - if user_input[CONF_GIID]: - self.giid = user_input[CONF_GIID] - await self.async_set_unique_id(self.giid) - self._abort_if_unique_id_configured() - else: - # The old YAML configuration could handle 1 single Verisure instance. - # Therefore, if we don't know the GIID, we can use the discovery - # without a unique ID logic, to prevent re-import/discovery. - await self._async_handle_discovery_without_unique_id() - - # Settings, later to be converted to config entry options - if user_input[CONF_LOCK_CODE_DIGITS]: - self.settings[CONF_LOCK_CODE_DIGITS] = user_input[CONF_LOCK_CODE_DIGITS] - if user_input[CONF_LOCK_DEFAULT_CODE]: - self.settings[CONF_LOCK_DEFAULT_CODE] = user_input[CONF_LOCK_DEFAULT_CODE] - - return await self.async_step_user(user_input) - class VerisureOptionsFlowHandler(OptionsFlow): """Handle Verisure options.""" diff --git a/homeassistant/components/verisure/const.py b/homeassistant/components/verisure/const.py index 030c5a58075..e8720baa1d5 100644 --- a/homeassistant/components/verisure/const.py +++ b/homeassistant/components/verisure/const.py @@ -44,7 +44,3 @@ ALARM_STATE_TO_HA = { "ARMED_AWAY": STATE_ALARM_ARMED_AWAY, "PENDING": STATE_ALARM_PENDING, } - -# Legacy; to remove after YAML removal -CONF_CODE_DIGITS = "code_digits" -CONF_DEFAULT_LOCK_CODE = "default_lock_code" diff --git a/tests/components/verisure/test_config_flow.py b/tests/components/verisure/test_config_flow.py index b9af9450132..f850487fe26 100644 --- a/tests/components/verisure/test_config_flow.py +++ b/tests/components/verisure/test_config_flow.py @@ -44,8 +44,6 @@ async def test_full_user_flow_single_installation(hass: HomeAssistant) -> None: with patch( "homeassistant.components.verisure.config_flow.Verisure", ) as mock_verisure, patch( - "homeassistant.components.verisure.async_setup", return_value=True - ) as mock_setup, patch( "homeassistant.components.verisure.async_setup_entry", return_value=True, ) as mock_setup_entry: @@ -72,7 +70,6 @@ async def test_full_user_flow_single_installation(hass: HomeAssistant) -> None: } assert len(mock_verisure.mock_calls) == 2 - assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 @@ -107,8 +104,6 @@ async def test_full_user_flow_multiple_installations(hass: HomeAssistant) -> Non assert result2["errors"] is None with patch( - "homeassistant.components.verisure.async_setup", return_value=True - ) as mock_setup, patch( "homeassistant.components.verisure.async_setup_entry", return_value=True, ) as mock_setup_entry: @@ -126,7 +121,6 @@ async def test_full_user_flow_multiple_installations(hass: HomeAssistant) -> Non } assert len(mock_verisure.mock_calls) == 2 - assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 @@ -220,8 +214,6 @@ async def test_reauth_flow(hass: HomeAssistant) -> None: "homeassistant.components.verisure.config_flow.Verisure.login", return_value=True, ) as mock_verisure, patch( - "homeassistant.components.verisure.async_setup", return_value=True - ) as mock_setup, patch( "homeassistant.components.verisure.async_setup_entry", return_value=True, ) as mock_setup_entry: @@ -243,7 +235,6 @@ async def test_reauth_flow(hass: HomeAssistant) -> None: } assert len(mock_verisure.mock_calls) == 1 - assert len(mock_setup.mock_calls) == 1 assert len(mock_setup_entry.mock_calls) == 1 @@ -365,8 +356,6 @@ async def test_options_flow( entry.add_to_hass(hass) with patch( - "homeassistant.components.verisure.async_setup", return_value=True - ), patch( "homeassistant.components.verisure.async_setup_entry", return_value=True, ): @@ -397,8 +386,6 @@ async def test_options_flow_code_format_mismatch(hass: HomeAssistant) -> None: entry.add_to_hass(hass) with patch( - "homeassistant.components.verisure.async_setup", return_value=True - ), patch( "homeassistant.components.verisure.async_setup_entry", return_value=True, ): @@ -422,185 +409,3 @@ async def test_options_flow_code_format_mismatch(hass: HomeAssistant) -> None: assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "init" assert result["errors"] == {"base": "code_format_mismatch"} - - -# -# Below this line are tests that can be removed once the YAML configuration -# has been removed from this integration. -# -@pytest.mark.parametrize( - "giid,installations", - [ - ("12345", TEST_INSTALLATION), - ("12345", TEST_INSTALLATIONS), - (None, TEST_INSTALLATION), - ], -) -async def test_imports( - hass: HomeAssistant, giid: str | None, installations: dict[str, str] -) -> None: - """Test a YAML import with/without known giid on single/multiple installations.""" - with patch( - "homeassistant.components.verisure.config_flow.Verisure", - ) as mock_verisure, patch( - "homeassistant.components.verisure.async_setup", return_value=True - ) as mock_setup, patch( - "homeassistant.components.verisure.async_setup_entry", - return_value=True, - ) as mock_setup_entry: - type(mock_verisure.return_value).installations = PropertyMock( - return_value=installations - ) - mock_verisure.login.return_value = True - - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={ - CONF_EMAIL: "verisure_my_pages@example.com", - CONF_GIID: giid, - CONF_LOCK_CODE_DIGITS: 10, - CONF_LOCK_DEFAULT_CODE: "123456", - CONF_PASSWORD: "SuperS3cr3t!", - }, - ) - - assert result["type"] == RESULT_TYPE_CREATE_ENTRY - assert result["title"] == "ascending (12345th street)" - assert result["data"] == { - CONF_EMAIL: "verisure_my_pages@example.com", - CONF_GIID: "12345", - CONF_LOCK_CODE_DIGITS: 10, - CONF_LOCK_DEFAULT_CODE: "123456", - CONF_PASSWORD: "SuperS3cr3t!", - } - - assert len(mock_verisure.mock_calls) == 2 - assert len(mock_setup.mock_calls) == 1 - assert len(mock_setup_entry.mock_calls) == 1 - - -async def test_imports_invalid_login(hass: HomeAssistant) -> None: - """Test a YAML import that results in a invalid login.""" - with patch( - "homeassistant.components.verisure.config_flow.Verisure.login", - side_effect=VerisureLoginError, - ): - - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={ - CONF_EMAIL: "verisure_my_pages@example.com", - CONF_GIID: None, - CONF_LOCK_CODE_DIGITS: None, - CONF_LOCK_DEFAULT_CODE: None, - CONF_PASSWORD: "SuperS3cr3t!", - }, - ) - - assert result["step_id"] == "user" - assert result["type"] == RESULT_TYPE_FORM - assert result["errors"] == {"base": "invalid_auth"} - - with patch( - "homeassistant.components.verisure.config_flow.Verisure", - ) as mock_verisure, patch( - "homeassistant.components.verisure.async_setup", return_value=True - ) as mock_setup, patch( - "homeassistant.components.verisure.async_setup_entry", - return_value=True, - ) as mock_setup_entry: - type(mock_verisure.return_value).installations = PropertyMock( - return_value=TEST_INSTALLATION - ) - mock_verisure.login.return_value = True - - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - "email": "verisure_my_pages@example.com", - "password": "SuperS3cr3t!", - }, - ) - await hass.async_block_till_done() - - assert result2["type"] == RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "ascending (12345th street)" - assert result2["data"] == { - CONF_GIID: "12345", - CONF_EMAIL: "verisure_my_pages@example.com", - CONF_PASSWORD: "SuperS3cr3t!", - } - - assert len(mock_verisure.mock_calls) == 2 - assert len(mock_setup.mock_calls) == 1 - assert len(mock_setup_entry.mock_calls) == 1 - - -async def test_imports_needs_user_installation_choice(hass: HomeAssistant) -> None: - """Test a YAML import that needs to use to decide on the installation.""" - with patch( - "homeassistant.components.verisure.config_flow.Verisure", - ) as mock_verisure: - type(mock_verisure.return_value).installations = PropertyMock( - return_value=TEST_INSTALLATIONS - ) - mock_verisure.login.return_value = True - - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={ - CONF_EMAIL: "verisure_my_pages@example.com", - CONF_GIID: None, - CONF_LOCK_CODE_DIGITS: None, - CONF_LOCK_DEFAULT_CODE: None, - CONF_PASSWORD: "SuperS3cr3t!", - }, - ) - - assert result["step_id"] == "installation" - assert result["type"] == RESULT_TYPE_FORM - assert result["errors"] is None - - with patch( - "homeassistant.components.verisure.async_setup", return_value=True - ) as mock_setup, patch( - "homeassistant.components.verisure.async_setup_entry", - return_value=True, - ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], {"giid": "12345"} - ) - await hass.async_block_till_done() - - assert result2["type"] == RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "ascending (12345th street)" - assert result2["data"] == { - CONF_GIID: "12345", - CONF_EMAIL: "verisure_my_pages@example.com", - CONF_PASSWORD: "SuperS3cr3t!", - } - - assert len(mock_verisure.mock_calls) == 2 - assert len(mock_setup.mock_calls) == 1 - assert len(mock_setup_entry.mock_calls) == 1 - - -@pytest.mark.parametrize("giid", ["12345", None]) -async def test_import_already_exists(hass: HomeAssistant, giid: str | None) -> None: - """Test that import flow aborts if exists.""" - MockConfigEntry(domain=DOMAIN, data={}, unique_id="12345").add_to_hass(hass) - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={ - CONF_EMAIL: "verisure_my_pages@example.com", - CONF_PASSWORD: "SuperS3cr3t!", - CONF_GIID: giid, - }, - ) - - assert result["type"] == RESULT_TYPE_ABORT - assert result["reason"] == "already_configured"