From 8b42d0c4718e275893cc6a9ad482cb13cb1248c2 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Fri, 21 Sep 2018 16:34:37 +0200 Subject: [PATCH] Add confirmation to Cast/Sonos/iOS config entries (#16769) * Add confirmation to Cast/Sonos/iOS config entries * Remove redundant code --- homeassistant/helpers/config_entry_flow.py | 49 +++++++++++----------- tests/components/cast/test_init.py | 6 +++ tests/components/ios/test_init.py | 6 +++ tests/components/sonos/test_init.py | 6 +++ tests/helpers/test_config_entry_flow.py | 25 +++++++---- 5 files changed, 59 insertions(+), 33 deletions(-) diff --git a/homeassistant/helpers/config_entry_flow.py b/homeassistant/helpers/config_entry_flow.py index d940afc1152..569a101b3dd 100644 --- a/homeassistant/helpers/config_entry_flow.py +++ b/homeassistant/helpers/config_entry_flow.py @@ -31,40 +31,39 @@ class DiscoveryFlowHandler(config_entries.ConfigFlow): reason='single_instance_allowed' ) - # Get current discovered entries. - in_progress = self._async_in_progress() + return await self.async_step_confirm() - has_devices = in_progress - if not has_devices: - has_devices = await self.hass.async_add_job( - self._discovery_function, self.hass) - - if not has_devices: - return self.async_abort( - reason='no_devices_found' + async def async_step_confirm(self, user_input=None): + """Confirm setup.""" + if user_input is None: + return self.async_show_form( + step_id='confirm', ) - # Cancel the discovered one. - for flow in in_progress: - self.hass.config_entries.flow.async_abort(flow['flow_id']) + if self.context and self.context.get('source') != \ + config_entries.SOURCE_DISCOVERY: + # Get current discovered entries. + in_progress = self._async_in_progress() + + has_devices = in_progress + if not has_devices: + has_devices = await self.hass.async_add_job( + self._discovery_function, self.hass) + + if not has_devices: + return self.async_abort( + reason='no_devices_found' + ) + + # Cancel the discovered one. + for flow in in_progress: + self.hass.config_entries.flow.async_abort(flow['flow_id']) return self.async_create_entry( title=self._title, data={}, ) - async def async_step_confirm(self, user_input=None): - """Confirm setup.""" - if user_input is not None: - return self.async_create_entry( - title=self._title, - data={}, - ) - - return self.async_show_form( - step_id='confirm', - ) - async def async_step_discovery(self, discovery_info): """Handle a flow initialized by discovery.""" if self._async_in_progress() or self._async_current_entries(): diff --git a/tests/components/cast/test_init.py b/tests/components/cast/test_init.py index 1ffbd375b75..0121cd1c794 100644 --- a/tests/components/cast/test_init.py +++ b/tests/components/cast/test_init.py @@ -17,6 +17,12 @@ async def test_creating_entry_sets_up_media_player(hass): return_value=True): result = await hass.config_entries.flow.async_init( cast.DOMAIN, context={'source': config_entries.SOURCE_USER}) + + # Confirmation form + assert result['type'] == data_entry_flow.RESULT_TYPE_FORM + + result = await hass.config_entries.flow.async_configure( + result['flow_id'], {}) assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY await hass.async_block_till_done() diff --git a/tests/components/ios/test_init.py b/tests/components/ios/test_init.py index 9a45fac3ce1..ad1ab328325 100644 --- a/tests/components/ios/test_init.py +++ b/tests/components/ios/test_init.py @@ -30,6 +30,12 @@ async def test_creating_entry_sets_up_sensor(hass): return_value=mock_coro(True)) as mock_setup: result = await hass.config_entries.flow.async_init( ios.DOMAIN, context={'source': config_entries.SOURCE_USER}) + + # Confirmation form + assert result['type'] == data_entry_flow.RESULT_TYPE_FORM + + result = await hass.config_entries.flow.async_configure( + result['flow_id'], {}) assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY await hass.async_block_till_done() diff --git a/tests/components/sonos/test_init.py b/tests/components/sonos/test_init.py index 455ce6d4cc2..8d46f4d57a3 100644 --- a/tests/components/sonos/test_init.py +++ b/tests/components/sonos/test_init.py @@ -15,6 +15,12 @@ async def test_creating_entry_sets_up_media_player(hass): patch('pysonos.discover', return_value=True): result = await hass.config_entries.flow.async_init( sonos.DOMAIN, context={'source': config_entries.SOURCE_USER}) + + # Confirmation form + assert result['type'] == data_entry_flow.RESULT_TYPE_FORM + + result = await hass.config_entries.flow.async_configure( + result['flow_id'], {}) assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY await hass.async_block_till_done() diff --git a/tests/helpers/test_config_entry_flow.py b/tests/helpers/test_config_entry_flow.py index a578afae1d2..9d858e31a06 100644 --- a/tests/helpers/test_config_entry_flow.py +++ b/tests/helpers/test_config_entry_flow.py @@ -42,22 +42,24 @@ async def test_user_no_devices_found(hass, flow_conf): """Test if no devices found.""" flow = config_entries.HANDLERS['test']() flow.hass = hass - - result = await flow.async_step_user() + flow.context = { + 'source': config_entries.SOURCE_USER + } + result = await flow.async_step_confirm(user_input={}) assert result['type'] == data_entry_flow.RESULT_TYPE_ABORT assert result['reason'] == 'no_devices_found' -async def test_user_no_confirmation(hass, flow_conf): - """Test user requires no confirmation to set up.""" +async def test_user_has_confirmation(hass, flow_conf): + """Test user requires no confirmation to setup.""" flow = config_entries.HANDLERS['test']() flow.hass = hass flow_conf['discovered'] = True result = await flow.async_step_user() - assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result['type'] == data_entry_flow.RESULT_TYPE_FORM async def test_discovery_single_instance(hass, flow_conf): @@ -100,7 +102,7 @@ async def test_multiple_discoveries(hass, flow_conf): assert result['type'] == data_entry_flow.RESULT_TYPE_ABORT -async def test_user_init_trumps_discovery(hass, flow_conf): +async def test_only_one_in_progress(hass, flow_conf): """Test a user initialized one will finish and cancel discovered one.""" loader.set_component(hass, 'test', MockModule('test')) @@ -112,9 +114,16 @@ async def test_user_init_trumps_discovery(hass, flow_conf): # User starts flow result = await hass.config_entries.flow.async_init( 'test', context={'source': config_entries.SOURCE_USER}, data={}) - assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY - # Discovery flow has been aborted + assert result['type'] == data_entry_flow.RESULT_TYPE_FORM + + # Discovery flow has not been aborted + assert len(hass.config_entries.flow.async_progress()) == 2 + + # Discovery should be aborted once user confirms + result = await hass.config_entries.flow.async_configure( + result['flow_id'], {}) + assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY assert len(hass.config_entries.flow.async_progress()) == 0