mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Fix HEOS discovery could result in multiple config entries (#22903)
* Prevent duplicate entries from discovery * Update reqs files * Prevent duplicate entries from discovery
This commit is contained in:
parent
d577955d1e
commit
38f063a158
@ -19,7 +19,7 @@ from .const import (
|
||||
COMMAND_RETRY_ATTEMPTS, COMMAND_RETRY_DELAY, DATA_CONTROLLER,
|
||||
DATA_SOURCE_MANAGER, DOMAIN, SIGNAL_HEOS_SOURCES_UPDATED)
|
||||
|
||||
REQUIREMENTS = ['pyheos==0.3.0']
|
||||
REQUIREMENTS = ['pyheos==0.3.1']
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
|
@ -23,8 +23,13 @@ class HeosFlowHandler(config_entries.ConfigFlow):
|
||||
|
||||
async def async_step_discovery(self, discovery_info):
|
||||
"""Handle a discovered Heos device."""
|
||||
return await self.async_step_user(
|
||||
{CONF_HOST: discovery_info[CONF_HOST]})
|
||||
# Only continue if this is the only active flow
|
||||
flows = self.hass.config_entries.flow.async_progress()
|
||||
heos_flows = [flow for flow in flows if flow['handler'] == DOMAIN]
|
||||
if len(heos_flows) == 1:
|
||||
return await self.async_step_user(
|
||||
{CONF_HOST: discovery_info[CONF_HOST]})
|
||||
return self.async_abort(reason='already_setup')
|
||||
|
||||
async def async_step_import(self, user_input=None):
|
||||
"""Occurs when an entry is setup through config."""
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "Heos",
|
||||
"documentation": "https://www.home-assistant.io/components/heos",
|
||||
"requirements": [
|
||||
"pyheos==0.3.0"
|
||||
"pyheos==0.3.1"
|
||||
],
|
||||
"dependencies": [],
|
||||
"codeowners": [
|
||||
|
@ -1064,7 +1064,7 @@ pygtt==1.1.2
|
||||
pyhaversion==2.0.3
|
||||
|
||||
# homeassistant.components.heos
|
||||
pyheos==0.3.0
|
||||
pyheos==0.3.1
|
||||
|
||||
# homeassistant.components.hikvision
|
||||
pyhik==0.2.2
|
||||
|
@ -204,7 +204,7 @@ pydeconz==54
|
||||
pydispatcher==2.0.5
|
||||
|
||||
# homeassistant.components.heos
|
||||
pyheos==0.3.0
|
||||
pyheos==0.3.1
|
||||
|
||||
# homeassistant.components.homematic
|
||||
pyhomematic==0.1.58
|
||||
|
@ -103,3 +103,21 @@ def input_sources_fixture() -> Sequence[InputSource]:
|
||||
def dispatcher_fixture() -> Dispatcher:
|
||||
"""Create a dispatcher for testing."""
|
||||
return Dispatcher()
|
||||
|
||||
|
||||
@pytest.fixture(name="discovery_data")
|
||||
def discovery_data_fixture() -> dict:
|
||||
"""Return mock discovery data for testing."""
|
||||
return {
|
||||
'host': '127.0.0.1',
|
||||
'manufacturer': 'Denon',
|
||||
'model_name': 'HEOS Drive',
|
||||
'model_number': 'DWSA-10 4.0',
|
||||
'name': 'Office',
|
||||
'port': 60006,
|
||||
'serial': None,
|
||||
'ssdp_description':
|
||||
'http://127.0.0.1:60006/upnp/desc/aios_device/aios_device.xml',
|
||||
'udn': 'uuid:e61de70c-2250-1c22-0080-0005cdf512be',
|
||||
'upnp_device_type': 'urn:schemas-denon-com:device:AiosDevice:1'
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import asyncio
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components.heos.config_flow import HeosFlowHandler
|
||||
from homeassistant.components.heos.const import DOMAIN
|
||||
from homeassistant.const import CONF_HOST
|
||||
|
||||
|
||||
@ -57,26 +58,41 @@ async def test_create_entry_when_host_valid(hass, controller):
|
||||
assert controller.disconnect.call_count == 1
|
||||
|
||||
|
||||
async def test_create_entry_with_discovery(hass, controller):
|
||||
"""Test result type is create entry when valid through discovery."""
|
||||
flow = HeosFlowHandler()
|
||||
flow.hass = hass
|
||||
data = {
|
||||
'host': '127.0.0.1',
|
||||
'manufacturer': 'Denon',
|
||||
'model_name': 'HEOS Drive',
|
||||
'model_number': 'DWSA-10 4.0',
|
||||
'name': 'Office',
|
||||
'port': 60006,
|
||||
'serial': None,
|
||||
'ssdp_description':
|
||||
'http://127.0.0.1:60006/upnp/desc/aios_device/aios_device.xml',
|
||||
'udn': 'uuid:e61de70c-2250-1c22-0080-0005cdf512be',
|
||||
'upnp_device_type': 'urn:schemas-denon-com:device:AiosDevice:1'
|
||||
}
|
||||
result = await flow.async_step_discovery(data)
|
||||
assert result['type'] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
|
||||
assert result['title'] == 'Controller (127.0.0.1)'
|
||||
assert result['data'] == {'host': '127.0.0.1'}
|
||||
assert controller.connect.call_count == 1
|
||||
assert controller.disconnect.call_count == 1
|
||||
async def test_create_entry_with_discovery(hass, controller, discovery_data):
|
||||
"""Test discovery creates entry."""
|
||||
await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={'source': 'discovery'},
|
||||
data=discovery_data)
|
||||
await hass.async_block_till_done()
|
||||
entries = hass.config_entries.async_entries(DOMAIN)
|
||||
assert len(entries) == 1
|
||||
assert entries[0].data == {CONF_HOST: discovery_data[CONF_HOST]}
|
||||
assert entries[0].title == 'Controller (127.0.0.1)'
|
||||
|
||||
|
||||
async def test_entry_already_exists_discovery(
|
||||
hass, controller, discovery_data, config_entry):
|
||||
"""Test discovery does not create multiple entries when already setup."""
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={'source': 'discovery'},
|
||||
data=discovery_data)
|
||||
await hass.async_block_till_done()
|
||||
entries = hass.config_entries.async_entries(DOMAIN)
|
||||
assert len(entries) == 1
|
||||
|
||||
|
||||
async def test_multiple_discovery_creates_single_entry(
|
||||
hass, controller, discovery_data):
|
||||
"""Test discovery of multiple devices creates a single entry."""
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={'source': 'discovery'},
|
||||
data={CONF_HOST: discovery_data}))
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={'source': 'discovery'},
|
||||
data={CONF_HOST: discovery_data}))
|
||||
await hass.async_block_till_done()
|
||||
entries = hass.config_entries.async_entries(DOMAIN)
|
||||
assert len(entries) == 1
|
||||
|
Loading…
x
Reference in New Issue
Block a user