From ba4cc373c8696cc25b7e6084c6026944eb7299c0 Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Mon, 24 Feb 2020 22:37:38 -0700 Subject: [PATCH] Modernize Ambient PWS config flow (#32164) * Modernize Ambient PWS config flow * Linting --- .../ambient_station/.translations/en.json | 4 ++- .../components/ambient_station/__init__.py | 9 +++--- .../components/ambient_station/config_flow.py | 31 +++++++------------ .../components/ambient_station/manifest.json | 2 +- .../components/ambient_station/strings.json | 4 ++- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../ambient_station/test_config_flow.py | 20 +++++++++--- 8 files changed, 41 insertions(+), 33 deletions(-) diff --git a/homeassistant/components/ambient_station/.translations/en.json b/homeassistant/components/ambient_station/.translations/en.json index 5bd643da55c..c3e2a40ab13 100644 --- a/homeassistant/components/ambient_station/.translations/en.json +++ b/homeassistant/components/ambient_station/.translations/en.json @@ -1,7 +1,9 @@ { "config": { + "abort": { + "already_configured": "This app key is already in use." + }, "error": { - "identifier_exists": "Application Key and/or API Key already registered", "invalid_key": "Invalid API Key and/or Application Key", "no_devices": "No devices found in account" }, diff --git a/homeassistant/components/ambient_station/__init__.py b/homeassistant/components/ambient_station/__init__.py index 4d068b2d0d8..63c00b05038 100644 --- a/homeassistant/components/ambient_station/__init__.py +++ b/homeassistant/components/ambient_station/__init__.py @@ -25,7 +25,6 @@ from homeassistant.helpers.dispatcher import ( from homeassistant.helpers.entity import Entity from homeassistant.helpers.event import async_call_later -from .config_flow import configured_instances from .const import ( ATTR_LAST_DATA, ATTR_MONITORED_CONDITIONS, @@ -254,9 +253,6 @@ async def async_setup(hass, config): # Store config for use during entry setup: hass.data[DOMAIN][DATA_CONFIG] = conf - if conf[CONF_APP_KEY] in configured_instances(hass): - return True - hass.async_create_task( hass.config_entries.flow.async_init( DOMAIN, @@ -270,6 +266,11 @@ async def async_setup(hass, config): async def async_setup_entry(hass, config_entry): """Set up the Ambient PWS as config entry.""" + if not config_entry.unique_id: + hass.config_entries.async_update_entry( + config_entry, unique_id=config_entry.data[CONF_APP_KEY] + ) + session = aiohttp_client.async_get_clientsession(hass) try: diff --git a/homeassistant/components/ambient_station/config_flow.py b/homeassistant/components/ambient_station/config_flow.py index c20b43598ca..c363a2839fb 100644 --- a/homeassistant/components/ambient_station/config_flow.py +++ b/homeassistant/components/ambient_station/config_flow.py @@ -5,35 +5,29 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_API_KEY -from homeassistant.core import callback from homeassistant.helpers import aiohttp_client -from .const import CONF_APP_KEY, DOMAIN +from .const import CONF_APP_KEY, DOMAIN # pylint: disable=unused-import -@callback -def configured_instances(hass): - """Return a set of configured Ambient PWS instances.""" - return set( - entry.data[CONF_APP_KEY] for entry in hass.config_entries.async_entries(DOMAIN) - ) - - -@config_entries.HANDLERS.register(DOMAIN) -class AmbientStationFlowHandler(config_entries.ConfigFlow): +class AmbientStationFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """Handle an Ambient PWS config flow.""" VERSION = 2 CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_PUSH - async def _show_form(self, errors=None): - """Show the form to the user.""" - data_schema = vol.Schema( + def __init__(self): + """Initialize the config flow.""" + self.data_schema = vol.Schema( {vol.Required(CONF_API_KEY): str, vol.Required(CONF_APP_KEY): str} ) + async def _show_form(self, errors=None): + """Show the form to the user.""" return self.async_show_form( - step_id="user", data_schema=data_schema, errors=errors if errors else {} + step_id="user", + data_schema=self.data_schema, + errors=errors if errors else {}, ) async def async_step_import(self, import_config): @@ -42,12 +36,11 @@ class AmbientStationFlowHandler(config_entries.ConfigFlow): async def async_step_user(self, user_input=None): """Handle the start of the config flow.""" - if not user_input: return await self._show_form() - if user_input[CONF_APP_KEY] in configured_instances(self.hass): - return await self._show_form({CONF_APP_KEY: "identifier_exists"}) + await self.async_set_unique_id(user_input[CONF_APP_KEY]) + self._abort_if_unique_id_configured() session = aiohttp_client.async_get_clientsession(self.hass) client = Client(user_input[CONF_API_KEY], user_input[CONF_APP_KEY], session) diff --git a/homeassistant/components/ambient_station/manifest.json b/homeassistant/components/ambient_station/manifest.json index 25f60f63abf..a6572070a5e 100644 --- a/homeassistant/components/ambient_station/manifest.json +++ b/homeassistant/components/ambient_station/manifest.json @@ -3,7 +3,7 @@ "name": "Ambient Weather Station", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/ambient_station", - "requirements": ["aioambient==1.0.2"], + "requirements": ["aioambient==1.0.4"], "dependencies": [], "codeowners": ["@bachya"] } diff --git a/homeassistant/components/ambient_station/strings.json b/homeassistant/components/ambient_station/strings.json index 657b3477bb2..3cfe36b3220 100644 --- a/homeassistant/components/ambient_station/strings.json +++ b/homeassistant/components/ambient_station/strings.json @@ -11,9 +11,11 @@ } }, "error": { - "identifier_exists": "Application Key and/or API Key already registered", "invalid_key": "Invalid API Key and/or Application Key", "no_devices": "No devices found in account" + }, + "abort": { + "already_configured": "This app key is already in use." } } } diff --git a/requirements_all.txt b/requirements_all.txt index ecc4d8d82a0..112d8c15cce 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -136,7 +136,7 @@ aio_geojson_nsw_rfs_incidents==0.3 aio_georss_gdacs==0.3 # homeassistant.components.ambient_station -aioambient==1.0.2 +aioambient==1.0.4 # homeassistant.components.asuswrt aioasuswrt==1.2.2 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index cfb9afdff5c..34745f8e253 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -47,7 +47,7 @@ aio_geojson_nsw_rfs_incidents==0.3 aio_georss_gdacs==0.3 # homeassistant.components.ambient_station -aioambient==1.0.2 +aioambient==1.0.4 # homeassistant.components.asuswrt aioasuswrt==1.2.2 diff --git a/tests/components/ambient_station/test_config_flow.py b/tests/components/ambient_station/test_config_flow.py index 25e46090009..a64b7761338 100644 --- a/tests/components/ambient_station/test_config_flow.py +++ b/tests/components/ambient_station/test_config_flow.py @@ -7,6 +7,7 @@ import pytest from homeassistant import data_entry_flow from homeassistant.components.ambient_station import CONF_APP_KEY, DOMAIN, config_flow +from homeassistant.config_entries import SOURCE_USER from homeassistant.const import CONF_API_KEY from tests.common import MockConfigEntry, load_fixture, mock_coro @@ -30,12 +31,16 @@ async def test_duplicate_error(hass): """Test that errors are shown when duplicates are added.""" conf = {CONF_API_KEY: "12345abcde12345abcde", CONF_APP_KEY: "67890fghij67890fghij"} - MockConfigEntry(domain=DOMAIN, data=conf).add_to_hass(hass) - flow = config_flow.AmbientStationFlowHandler() - flow.hass = hass + MockConfigEntry( + domain=DOMAIN, unique_id="67890fghij67890fghij", data=conf + ).add_to_hass(hass) - result = await flow.async_step_user(user_input=conf) - assert result["errors"] == {CONF_APP_KEY: "identifier_exists"} + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": SOURCE_USER}, data=conf + ) + + assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result["reason"] == "already_configured" @pytest.mark.parametrize( @@ -47,6 +52,7 @@ async def test_invalid_api_key(hass, mock_aioambient): flow = config_flow.AmbientStationFlowHandler() flow.hass = hass + flow.context = {"source": SOURCE_USER} result = await flow.async_step_user(user_input=conf) assert result["errors"] == {"base": "invalid_key"} @@ -59,6 +65,7 @@ async def test_no_devices(hass, mock_aioambient): flow = config_flow.AmbientStationFlowHandler() flow.hass = hass + flow.context = {"source": SOURCE_USER} result = await flow.async_step_user(user_input=conf) assert result["errors"] == {"base": "no_devices"} @@ -68,6 +75,7 @@ async def test_show_form(hass): """Test that the form is served with no input.""" flow = config_flow.AmbientStationFlowHandler() flow.hass = hass + flow.context = {"source": SOURCE_USER} result = await flow.async_step_user(user_input=None) @@ -85,6 +93,7 @@ async def test_step_import(hass, mock_aioambient): flow = config_flow.AmbientStationFlowHandler() flow.hass = hass + flow.context = {"source": SOURCE_USER} result = await flow.async_step_import(import_config=conf) assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY @@ -105,6 +114,7 @@ async def test_step_user(hass, mock_aioambient): flow = config_flow.AmbientStationFlowHandler() flow.hass = hass + flow.context = {"source": SOURCE_USER} result = await flow.async_step_user(user_input=conf) assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY