From 4aedd3a09a36d9385e1bcdd9ea7611a5a510ece6 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 24 Jun 2019 14:46:32 -0700 Subject: [PATCH] AdGuard to update entry (#24737) --- .../components/adguard/config_flow.py | 27 +++++- homeassistant/components/adguard/strings.json | 5 +- tests/components/adguard/test_config_flow.py | 87 +++++++++++++++++-- 3 files changed, 108 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/adguard/config_flow.py b/homeassistant/components/adguard/config_flow.py index 7e144a76e22..9ef789f83a8 100644 --- a/homeassistant/components/adguard/config_flow.py +++ b/homeassistant/components/adguard/config_flow.py @@ -104,12 +104,33 @@ class AdGuardHomeFlowHandler(ConfigFlow): This flow is triggered by the discovery component. """ - if self._async_current_entries(): + entries = self._async_current_entries() + + if not entries: + self._hassio_discovery = user_input + return await self.async_step_hassio_confirm() + + cur_entry = entries[0] + + if (cur_entry.data[CONF_HOST] == user_input[CONF_HOST] and + cur_entry.data[CONF_PORT] == user_input[CONF_PORT]): return self.async_abort(reason='single_instance_allowed') - self._hassio_discovery = user_input + is_loaded = cur_entry.state == config_entries.ENTRY_STATE_LOADED - return await self.async_step_hassio_confirm() + if is_loaded: + await self.hass.config_entries.async_unload(cur_entry.entry_id) + + self.hass.config_entries.async_update_entry(cur_entry, data={ + **cur_entry.data, + CONF_HOST: user_input[CONF_HOST], + CONF_PORT: user_input[CONF_PORT], + }) + + if is_loaded: + await self.hass.config_entries.async_setup(cur_entry.entry_id) + + return self.async_abort(reason='existing_instance_updated') async def async_step_hassio_confirm(self, user_input=None): """Confirm Hass.io discovery.""" diff --git a/homeassistant/components/adguard/strings.json b/homeassistant/components/adguard/strings.json index c88f7085e34..b3966bca820 100644 --- a/homeassistant/components/adguard/strings.json +++ b/homeassistant/components/adguard/strings.json @@ -23,7 +23,8 @@ "connection_error": "Failed to connect." }, "abort": { - "single_instance_allowed": "Only a single configuration of AdGuard Home is allowed." + "single_instance_allowed": "Only a single configuration of AdGuard Home is allowed.", + "existing_instance_updated": "Updated existing configuration." } } -} \ No newline at end of file +} diff --git a/tests/components/adguard/test_config_flow.py b/tests/components/adguard/test_config_flow.py index 451fd1436d4..41af02345a9 100644 --- a/tests/components/adguard/test_config_flow.py +++ b/tests/components/adguard/test_config_flow.py @@ -1,14 +1,16 @@ """Tests for the AdGuard Home config flow.""" +from unittest.mock import patch + import aiohttp -from homeassistant import data_entry_flow +from homeassistant import data_entry_flow, config_entries from homeassistant.components.adguard import config_flow from homeassistant.components.adguard.const import DOMAIN from homeassistant.const import ( CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_SSL, CONF_USERNAME, CONF_VERIFY_SSL) -from tests.common import MockConfigEntry +from tests.common import MockConfigEntry, mock_coro FIXTURE_USER_INPUT = { CONF_HOST: '127.0.0.1', @@ -94,17 +96,90 @@ async def test_integration_already_exists(hass): async def test_hassio_single_instance(hass): """Test we only allow a single config flow.""" - MockConfigEntry(domain='adguard', data={'host': '1.2.3.4'}).add_to_hass( - hass - ) + MockConfigEntry(domain='adguard', data={ + 'host': 'mock-adguard', + 'port': '3000' + }).add_to_hass(hass) result = await hass.config_entries.flow.async_init( - 'adguard', context={'source': 'hassio'} + 'adguard', + data={ + 'addon': 'AdGuard Home Addon', + 'host': 'mock-adguard', + 'port': '3000', + }, + context={'source': 'hassio'} ) assert result['type'] == data_entry_flow.RESULT_TYPE_ABORT assert result['reason'] == 'single_instance_allowed' +async def test_hassio_update_instance_not_running(hass): + """Test we only allow a single config flow.""" + entry = MockConfigEntry(domain='adguard', data={ + 'host': 'mock-adguard', + 'port': '3000' + }) + entry.add_to_hass(hass) + assert entry.state == config_entries.ENTRY_STATE_NOT_LOADED + + result = await hass.config_entries.flow.async_init( + 'adguard', + data={ + 'addon': 'AdGuard Home Addon', + 'host': 'mock-adguard-updated', + 'port': '3000', + }, + context={'source': 'hassio'} + ) + assert result['type'] == data_entry_flow.RESULT_TYPE_ABORT + assert result['reason'] == 'existing_instance_updated' + + +async def test_hassio_update_instance_running(hass): + """Test we only allow a single config flow.""" + entry = MockConfigEntry(domain='adguard', data={ + 'host': 'mock-adguard', + 'port': '3000', + 'verify_ssl': False, + 'username': None, + 'password': None, + 'ssl': False, + }) + entry.add_to_hass(hass) + + with patch.object( + hass.config_entries, 'async_forward_entry_setup', + side_effect=lambda *_: mock_coro(True) + ) as mock_load: + assert await hass.config_entries.async_setup(entry.entry_id) + assert entry.state == config_entries.ENTRY_STATE_LOADED + assert len(mock_load.mock_calls) == 2 + + with patch.object( + hass.config_entries, 'async_forward_entry_unload', + side_effect=lambda *_: mock_coro(True) + ) as mock_unload, patch.object( + hass.config_entries, 'async_forward_entry_setup', + side_effect=lambda *_: mock_coro(True) + ) as mock_load: + result = await hass.config_entries.flow.async_init( + 'adguard', + data={ + 'addon': 'AdGuard Home Addon', + 'host': 'mock-adguard-updated', + 'port': '3000', + }, + context={'source': 'hassio'} + ) + assert len(mock_unload.mock_calls) == 2 + assert len(mock_load.mock_calls) == 2 + + assert result['type'] == data_entry_flow.RESULT_TYPE_ABORT + assert result['reason'] == 'existing_instance_updated' + assert entry.data['host'] == 'mock-adguard-updated' + + async def test_hassio_confirm(hass, aioclient_mock): """Test we can finish a config flow.""" aioclient_mock.get(