deCONZ - Allow manual configuration to update existing configuration (#30469)

* Allow manual configuration to update existing configuration

* Harmonize tests
This commit is contained in:
Robert Svensson 2020-01-04 22:55:57 +01:00 committed by Paulus Schoutsen
parent 639cdf5eef
commit 967fe89f6d
3 changed files with 322 additions and 247 deletions

View File

@ -147,8 +147,17 @@ class DeconzFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
self.bridge_id = await async_get_bridge_id( self.bridge_id = await async_get_bridge_id(
session, **self.deconz_config session, **self.deconz_config
) )
for entry in self.hass.config_entries.async_entries(DOMAIN):
if self.bridge_id == entry.unique_id:
return self._update_entry(
entry,
host=self.deconz_config[CONF_HOST],
port=self.deconz_config[CONF_PORT],
api_key=self.deconz_config[CONF_API_KEY],
)
await self.async_set_unique_id(self.bridge_id) await self.async_set_unique_id(self.bridge_id)
self._abort_if_unique_id_configured()
except asyncio.TimeoutError: except asyncio.TimeoutError:
return self.async_abort(reason="no_bridges") return self.async_abort(reason="no_bridges")

View File

@ -1,36 +1,23 @@
"""Tests for deCONZ config flow.""" """Tests for deCONZ config flow."""
import asyncio import asyncio
from copy import deepcopy
from asynctest import Mock, patch
import pydeconz import pydeconz
from homeassistant.components import ssdp from homeassistant.components import ssdp
from homeassistant.components.deconz import config_flow from homeassistant.components.deconz import config_flow
from homeassistant.components.deconz.const import CONF_BRIDGEID
from .test_gateway import ( from .test_gateway import API_KEY, BRIDGEID, setup_deconz_integration
BRIDGEID,
DECONZ_WEB_REQUEST,
ENTRY_CONFIG,
setup_deconz_integration,
)
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
async def test_flow_works(hass, aioclient_mock): async def test_flow_1_discovered_bridge(hass, aioclient_mock):
"""Test that config flow works.""" """Test that config flow for one discovered bridge works."""
aioclient_mock.get( aioclient_mock.get(
pydeconz.utils.URL_DISCOVER, pydeconz.utils.URL_DISCOVER,
json=[{"id": BRIDGEID, "internalipaddress": "1.2.3.4", "internalport": 80}], json=[{"id": BRIDGEID, "internalipaddress": "1.2.3.4", "internalport": 80}],
headers={"content-type": "application/json"}, headers={"content-type": "application/json"},
) )
aioclient_mock.post(
"http://1.2.3.4:80/api",
json=[{"success": {"username": "1234567890ABCDEF"}}],
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, context={"source": "user"} config_flow.DOMAIN, context={"source": "user"}
@ -39,6 +26,12 @@ async def test_flow_works(hass, aioclient_mock):
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "link" assert result["step_id"] == "link"
aioclient_mock.post(
"http://1.2.3.4:80/api",
json=[{"success": {"username": API_KEY}}],
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={} result["flow_id"], user_input={}
) )
@ -48,65 +41,17 @@ async def test_flow_works(hass, aioclient_mock):
assert result["data"] == { assert result["data"] == {
config_flow.CONF_HOST: "1.2.3.4", config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80, config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: "1234567890ABCDEF", config_flow.CONF_API_KEY: API_KEY,
} }
async def test_user_step_bridge_discovery_fails(hass, aioclient_mock): async def test_flow_2_discovered_bridges(hass, aioclient_mock):
"""Test config flow works when discovery fails.""" """Test that config flow works for multiple discovered bridges."""
with patch(
"homeassistant.components.deconz.config_flow.async_discovery",
side_effect=asyncio.TimeoutError,
):
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, context={"source": "user"}
)
assert result["type"] == "form"
assert result["step_id"] == "init"
async def test_user_step_no_discovered_bridges(hass, aioclient_mock):
"""Test config flow discovers no bridges."""
aioclient_mock.get(
pydeconz.utils.URL_DISCOVER,
json=[],
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, context={"source": "user"}
)
assert result["type"] == "form"
assert result["step_id"] == "init"
async def test_user_step_one_bridge_discovered(hass, aioclient_mock):
"""Test config flow discovers one bridge."""
aioclient_mock.get(
pydeconz.utils.URL_DISCOVER,
json=[{"id": "id", "internalipaddress": "1.2.3.4", "internalport": 80}],
headers={"content-type": "application/json"},
)
flow = config_flow.DeconzFlowHandler()
flow.hass = hass
result = await flow.async_step_user()
assert result["type"] == "form"
assert result["step_id"] == "link"
assert flow.deconz_config[config_flow.CONF_HOST] == "1.2.3.4"
async def test_user_step_two_bridges_discovered(hass, aioclient_mock):
"""Test config flow discovers two bridges."""
aioclient_mock.get( aioclient_mock.get(
pydeconz.utils.URL_DISCOVER, pydeconz.utils.URL_DISCOVER,
json=[ json=[
{"id": "id1", "internalipaddress": "1.2.3.4", "internalport": 80}, {"id": BRIDGEID, "internalipaddress": "1.2.3.4", "internalport": 80},
{"id": "id2", "internalipaddress": "5.6.7.8", "internalport": 80}, {"id": "1234E567890A", "internalipaddress": "5.6.7.8", "internalport": 80},
], ],
headers={"content-type": "application/json"}, headers={"content-type": "application/json"},
) )
@ -115,37 +60,37 @@ async def test_user_step_two_bridges_discovered(hass, aioclient_mock):
config_flow.DOMAIN, context={"source": "user"} config_flow.DOMAIN, context={"source": "user"}
) )
assert result["data_schema"]({config_flow.CONF_HOST: "1.2.3.4"}) assert result["type"] == "form"
assert result["data_schema"]({config_flow.CONF_HOST: "5.6.7.8"}) assert result["step_id"] == "init"
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={config_flow.CONF_HOST: "1.2.3.4"}
)
async def test_user_step_two_bridges_selection(hass, aioclient_mock):
"""Test config flow selection of one of two bridges."""
flow = config_flow.DeconzFlowHandler()
flow.hass = hass
flow.bridges = [
{
CONF_BRIDGEID: "id1",
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
},
{
CONF_BRIDGEID: "id2",
config_flow.CONF_HOST: "5.6.7.8",
config_flow.CONF_PORT: 80,
},
]
result = await flow.async_step_user(user_input={config_flow.CONF_HOST: "1.2.3.4"})
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "link" assert result["step_id"] == "link"
assert flow.deconz_config[config_flow.CONF_HOST] == "1.2.3.4"
aioclient_mock.post(
"http://1.2.3.4:80/api",
json=[{"success": {"username": API_KEY}}],
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "create_entry"
assert result["title"] == BRIDGEID
assert result["data"] == {
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: API_KEY,
}
async def test_user_step_manual_configuration_no_bridges_discovered( async def test_flow_manual_configuration(hass, aioclient_mock):
hass, aioclient_mock """Test that config flow works with manual configuration after no discovered bridges."""
):
"""Test config flow with manual input."""
aioclient_mock.get( aioclient_mock.get(
pydeconz.utils.URL_DISCOVER, pydeconz.utils.URL_DISCOVER,
json=[], json=[],
@ -158,7 +103,6 @@ async def test_user_step_manual_configuration_no_bridges_discovered(
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "init" assert result["step_id"] == "init"
assert not hass.config_entries.flow._progress[result["flow_id"]].bridges
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
@ -168,63 +112,223 @@ async def test_user_step_manual_configuration_no_bridges_discovered(
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "link" assert result["step_id"] == "link"
aioclient_mock.post(
"http://1.2.3.4:80/api",
json=[{"success": {"username": API_KEY}}],
headers={"content-type": "application/json"},
)
async def test_user_step_manual_configuration_after_timeout(hass): aioclient_mock.get(
"""Test config flow with manual input.""" f"http://1.2.3.4:80/api/{API_KEY}/config",
with patch( json={"bridgeid": BRIDGEID},
"homeassistant.components.deconz.config_flow.async_discovery", headers={"content-type": "application/json"},
side_effect=asyncio.TimeoutError, )
):
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_configure(
config_flow.DOMAIN, context={"source": "user"} result["flow_id"], user_input={}
) )
assert result["type"] == "create_entry"
assert result["title"] == BRIDGEID
assert result["data"] == {
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: API_KEY,
}
async def test_manual_configuration_after_discovery_timeout(hass, aioclient_mock):
"""Test failed discovery fallbacks to manual configuration."""
aioclient_mock.get(pydeconz.utils.URL_DISCOVER, exc=asyncio.TimeoutError)
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, context={"source": "user"}
)
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "init" assert result["step_id"] == "init"
assert not hass.config_entries.flow._progress[result["flow_id"]].bridges assert not hass.config_entries.flow._progress[result["flow_id"]].bridges
async def test_user_step_manual_configuration_after_ResponseError(hass): async def test_manual_configuration_after_discovery_ResponseError(hass, aioclient_mock):
"""Test config flow with manual input.""" """Test failed discovery fallbacks to manual configuration."""
with patch( aioclient_mock.get(pydeconz.utils.URL_DISCOVER, exc=config_flow.ResponseError)
"homeassistant.components.deconz.config_flow.async_discovery",
side_effect=config_flow.ResponseError, result = await hass.config_entries.flow.async_init(
): config_flow.DOMAIN, context={"source": "user"}
result = await hass.config_entries.flow.async_init( )
config_flow.DOMAIN, context={"source": "user"}
)
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "init" assert result["step_id"] == "init"
assert not hass.config_entries.flow._progress[result["flow_id"]].bridges assert not hass.config_entries.flow._progress[result["flow_id"]].bridges
async def test_link_no_api_key(hass): async def test_manual_configuration_update_configuration(hass, aioclient_mock):
"""Test that manual configuration can update existing config entry."""
gateway = await setup_deconz_integration(hass)
aioclient_mock.get(
pydeconz.utils.URL_DISCOVER,
json=[],
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, context={"source": "user"}
)
assert result["type"] == "form"
assert result["step_id"] == "init"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={config_flow.CONF_HOST: "2.3.4.5", config_flow.CONF_PORT: 80},
)
assert result["type"] == "form"
assert result["step_id"] == "link"
aioclient_mock.post(
"http://2.3.4.5:80/api",
json=[{"success": {"username": API_KEY}}],
headers={"content-type": "application/json"},
)
aioclient_mock.get(
f"http://2.3.4.5:80/api/{API_KEY}/config",
json={"bridgeid": BRIDGEID},
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "abort"
assert result["reason"] == "updated_instance"
assert gateway.config_entry.data[config_flow.CONF_HOST] == "2.3.4.5"
async def test_manual_configuration_dont_update_configuration(hass, aioclient_mock):
"""Test that _create_entry work and that bridgeid can be requested."""
await setup_deconz_integration(hass)
aioclient_mock.get(
pydeconz.utils.URL_DISCOVER,
json=[],
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, context={"source": "user"}
)
assert result["type"] == "form"
assert result["step_id"] == "init"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={config_flow.CONF_HOST: "1.2.3.4", config_flow.CONF_PORT: 80},
)
assert result["type"] == "form"
assert result["step_id"] == "link"
aioclient_mock.post(
"http://1.2.3.4:80/api",
json=[{"success": {"username": API_KEY}}],
headers={"content-type": "application/json"},
)
aioclient_mock.get(
f"http://1.2.3.4:80/api/{API_KEY}/config",
json={"bridgeid": BRIDGEID},
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "abort"
assert result["reason"] == "already_configured"
async def test_manual_configuration_timeout_get_bridge(hass, aioclient_mock):
"""Test that _create_entry handles a timeout."""
aioclient_mock.get(
pydeconz.utils.URL_DISCOVER,
json=[],
headers={"content-type": "application/json"},
)
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, context={"source": "user"}
)
assert result["type"] == "form"
assert result["step_id"] == "init"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={config_flow.CONF_HOST: "1.2.3.4", config_flow.CONF_PORT: 80},
)
assert result["type"] == "form"
assert result["step_id"] == "link"
aioclient_mock.post(
"http://1.2.3.4:80/api",
json=[{"success": {"username": API_KEY}}],
headers={"content-type": "application/json"},
)
aioclient_mock.get(
f"http://1.2.3.4:80/api/{API_KEY}/config", exc=asyncio.TimeoutError
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "abort"
assert result["reason"] == "no_bridges"
async def test_link_get_api_key_ResponseError(hass, aioclient_mock):
"""Test config flow should abort if no API key was possible to retrieve.""" """Test config flow should abort if no API key was possible to retrieve."""
flow = config_flow.DeconzFlowHandler() aioclient_mock.get(
flow.hass = hass pydeconz.utils.URL_DISCOVER,
flow.deconz_config = {config_flow.CONF_HOST: "1.2.3.4", config_flow.CONF_PORT: 80} json=[{"id": BRIDGEID, "internalipaddress": "1.2.3.4", "internalport": 80}],
headers={"content-type": "application/json"},
)
with patch( result = await hass.config_entries.flow.async_init(
"homeassistant.components.deconz.config_flow.async_get_api_key", config_flow.DOMAIN, context={"source": "user"}
side_effect=pydeconz.errors.ResponseError, )
):
result = await flow.async_step_link(user_input={}) assert result["type"] == "form"
assert result["step_id"] == "link"
aioclient_mock.post("http://1.2.3.4:80/api", exc=pydeconz.errors.ResponseError)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "link" assert result["step_id"] == "link"
assert result["errors"] == {"base": "no_key"} assert result["errors"] == {"base": "no_key"}
async def test_bridge_ssdp_discovery(hass): async def test_flow_ssdp_discovery(hass, aioclient_mock):
"""Test a bridge being discovered over ssdp.""" """Test that config flow for one discovered bridge works."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, config_flow.DOMAIN,
data={ data={
ssdp.ATTR_SSDP_LOCATION: "http://1.2.3.4:80/", ssdp.ATTR_SSDP_LOCATION: "http://1.2.3.4:80/",
ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.DECONZ_MANUFACTURERURL, ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.DECONZ_MANUFACTURERURL,
ssdp.ATTR_UPNP_SERIAL: "id", ssdp.ATTR_UPNP_SERIAL: BRIDGEID,
ssdp.ATTR_UPNP_UDN: "uuid:1234",
}, },
context={"source": "ssdp"}, context={"source": "ssdp"},
) )
@ -232,8 +336,26 @@ async def test_bridge_ssdp_discovery(hass):
assert result["type"] == "form" assert result["type"] == "form"
assert result["step_id"] == "link" assert result["step_id"] == "link"
aioclient_mock.post(
"http://1.2.3.4:80/api",
json=[{"success": {"username": API_KEY}}],
headers={"content-type": "application/json"},
)
async def test_bridge_ssdp_discovery_not_deconz_bridge(hass): result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "create_entry"
assert result["title"] == BRIDGEID
assert result["data"] == {
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: API_KEY,
}
async def test_ssdp_discovery_not_deconz_bridge(hass):
"""Test a non deconz bridge being discovered over ssdp.""" """Test a non deconz bridge being discovered over ssdp."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, config_flow.DOMAIN,
@ -245,24 +367,14 @@ async def test_bridge_ssdp_discovery_not_deconz_bridge(hass):
assert result["reason"] == "not_deconz_bridge" assert result["reason"] == "not_deconz_bridge"
async def test_bridge_discovery_update_existing_entry(hass): async def test_ssdp_discovery_update_configuration(hass):
"""Test if a discovered bridge has already been configured.""" """Test if a discovered bridge is configured but updates with new attributes."""
entry = MockConfigEntry( gateway = await setup_deconz_integration(hass)
domain=config_flow.DOMAIN,
source="user",
data={config_flow.CONF_HOST: "1.2.3.4", config_flow.CONF_PORT: 80},
unique_id=BRIDGEID,
)
entry.add_to_hass(hass)
gateway = Mock()
gateway.config_entry = entry
hass.data[config_flow.DOMAIN] = {BRIDGEID: gateway}
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, config_flow.DOMAIN,
data={ data={
ssdp.ATTR_SSDP_LOCATION: "http://mock-deconz/", ssdp.ATTR_SSDP_LOCATION: "http://2.3.4.5:80/",
ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.DECONZ_MANUFACTURERURL, ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.DECONZ_MANUFACTURERURL,
ssdp.ATTR_UPNP_SERIAL: BRIDGEID, ssdp.ATTR_UPNP_SERIAL: BRIDGEID,
}, },
@ -271,96 +383,79 @@ async def test_bridge_discovery_update_existing_entry(hass):
assert result["type"] == "abort" assert result["type"] == "abort"
assert result["reason"] == "updated_instance" assert result["reason"] == "updated_instance"
assert entry.data[config_flow.CONF_HOST] == "mock-deconz" assert gateway.config_entry.data[config_flow.CONF_HOST] == "2.3.4.5"
async def test_bridge_discovery_dont_update_existing_hassio_entry(hass): async def test_ssdp_discovery_dont_update_configuration(hass):
"""Test to ensure the SSDP discovery does not update an Hass.io entry.""" """Test if a discovered bridge has already been configured."""
entry = MockConfigEntry( gateway = await setup_deconz_integration(hass)
domain=config_flow.DOMAIN,
source="hassio",
data={
config_flow.CONF_HOST: "core-deconz",
config_flow.CONF_BRIDGEID: "123ABC",
},
unique_id="123ABC",
)
entry.add_to_hass(hass)
gateway = Mock()
gateway.config_entry = entry
hass.data[config_flow.DOMAIN] = {"123ABC": gateway}
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, config_flow.DOMAIN,
data={ data={
ssdp.ATTR_SSDP_LOCATION: "http://mock-deconz/", ssdp.ATTR_SSDP_LOCATION: "http://1.2.3.4:80/",
ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.DECONZ_MANUFACTURERURL, ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.DECONZ_MANUFACTURERURL,
ssdp.ATTR_UPNP_SERIAL: "123ABC", ssdp.ATTR_UPNP_SERIAL: BRIDGEID,
}, },
context={"source": "ssdp"}, context={"source": "ssdp"},
) )
assert result["type"] == "abort" assert result["type"] == "abort"
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
assert entry.data[config_flow.CONF_HOST] == "core-deconz" assert gateway.config_entry.data[config_flow.CONF_HOST] == "1.2.3.4"
async def test_create_entry(hass, aioclient_mock): async def test_ssdp_discovery_dont_update_existing_hassio_configuration(hass):
"""Test that _create_entry work and that bridgeid can be requested.""" """Test to ensure the SSDP discovery does not update an Hass.io entry."""
aioclient_mock.get( gateway = await setup_deconz_integration(hass, source="hassio")
"http://1.2.3.4:80/api/1234567890ABCDEF/config",
json={"bridgeid": BRIDGEID, "uuid": "456DEF"}, result = await hass.config_entries.flow.async_init(
headers={"content-type": "application/json"}, config_flow.DOMAIN,
data={
ssdp.ATTR_SSDP_LOCATION: "http://1.2.3.4:80/",
ssdp.ATTR_UPNP_MANUFACTURER_URL: config_flow.DECONZ_MANUFACTURERURL,
ssdp.ATTR_UPNP_SERIAL: BRIDGEID,
},
context={"source": "ssdp"},
) )
flow = config_flow.DeconzFlowHandler()
flow.context = {}
flow.hass = hass
flow.deconz_config = {
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: "1234567890ABCDEF",
}
result = await flow._create_entry()
assert result["type"] == "create_entry"
assert result["title"] == BRIDGEID
assert result["data"] == {
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: "1234567890ABCDEF",
}
async def test_create_entry_timeout(hass, aioclient_mock):
"""Test that _create_entry handles a timeout."""
flow = config_flow.DeconzFlowHandler()
flow.hass = hass
flow.deconz_config = {
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: "1234567890ABCDEF",
}
with patch(
"homeassistant.components.deconz.config_flow.async_get_bridge_id",
side_effect=asyncio.TimeoutError,
):
result = await flow._create_entry()
assert result["type"] == "abort" assert result["type"] == "abort"
assert result["reason"] == "no_bridges" assert result["reason"] == "already_configured"
assert gateway.config_entry.data[config_flow.CONF_HOST] == "1.2.3.4"
async def test_hassio_update_instance(hass): async def test_flow_hassio_discovery(hass):
"""Test we can update an existing config entry.""" """Test hassio discovery flow works."""
data = deepcopy(DECONZ_WEB_REQUEST) result = await hass.config_entries.flow.async_init(
entry_config = deepcopy(ENTRY_CONFIG) config_flow.DOMAIN,
gateway = await setup_deconz_integration( data={
hass, entry_config, options={}, get_state_response=data "addon": "Mock Addon",
config_flow.CONF_HOST: "mock-deconz",
config_flow.CONF_PORT: 80,
config_flow.CONF_SERIAL: BRIDGEID,
config_flow.CONF_API_KEY: API_KEY,
},
context={"source": "hassio"},
) )
assert result["type"] == "form"
assert result["step_id"] == "hassio_confirm"
assert result["description_placeholders"] == {"addon": "Mock Addon"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "create_entry"
assert result["result"].data == {
config_flow.CONF_HOST: "mock-deconz",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: API_KEY,
}
async def test_hassio_discovery_update_configuration(hass):
"""Test we can update an existing config entry."""
gateway = await setup_deconz_integration(hass)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, config_flow.DOMAIN,
@ -380,19 +475,16 @@ async def test_hassio_update_instance(hass):
assert gateway.config_entry.data[config_flow.CONF_API_KEY] == "updated" assert gateway.config_entry.data[config_flow.CONF_API_KEY] == "updated"
async def test_hassio_dont_update_instance(hass): async def test_hassio_discovery_dont_update_configuration(hass):
"""Test we can update an existing config entry.""" """Test we can update an existing config entry."""
data = deepcopy(DECONZ_WEB_REQUEST) await setup_deconz_integration(hass)
await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN, config_flow.DOMAIN,
data={ data={
config_flow.CONF_HOST: "1.2.3.4", config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80, config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: "ABCDEF", config_flow.CONF_API_KEY: API_KEY,
config_flow.CONF_SERIAL: BRIDGEID, config_flow.CONF_SERIAL: BRIDGEID,
}, },
context={"source": "hassio"}, context={"source": "hassio"},
@ -402,35 +494,6 @@ async def test_hassio_dont_update_instance(hass):
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
async def test_hassio_confirm(hass):
"""Test we can finish a config flow."""
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN,
data={
"addon": "Mock Addon",
config_flow.CONF_HOST: "mock-deconz",
config_flow.CONF_PORT: 80,
config_flow.CONF_SERIAL: BRIDGEID,
config_flow.CONF_API_KEY: "1234567890ABCDEF",
},
context={"source": "hassio"},
)
assert result["type"] == "form"
assert result["step_id"] == "hassio_confirm"
assert result["description_placeholders"] == {"addon": "Mock Addon"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] == "create_entry"
assert result["result"].data == {
config_flow.CONF_HOST: "mock-deconz",
config_flow.CONF_PORT: 80,
config_flow.CONF_API_KEY: "1234567890ABCDEF",
}
async def test_option_flow(hass): async def test_option_flow(hass):
"""Test config flow options.""" """Test config flow options."""
entry = MockConfigEntry(domain=config_flow.DOMAIN, data={}, options=None) entry = MockConfigEntry(domain=config_flow.DOMAIN, data={}, options=None)

View File

@ -11,10 +11,11 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
API_KEY = "1234567890ABCDEF"
BRIDGEID = "01234E56789A" BRIDGEID = "01234E56789A"
ENTRY_CONFIG = { ENTRY_CONFIG = {
deconz.config_flow.CONF_API_KEY: "ABCDEF", deconz.config_flow.CONF_API_KEY: API_KEY,
deconz.config_flow.CONF_HOST: "1.2.3.4", deconz.config_flow.CONF_HOST: "1.2.3.4",
deconz.config_flow.CONF_PORT: 80, deconz.config_flow.CONF_PORT: 80,
} }
@ -46,10 +47,12 @@ async def setup_deconz_integration(
options=ENTRY_OPTIONS, options=ENTRY_OPTIONS,
get_state_response=DECONZ_WEB_REQUEST, get_state_response=DECONZ_WEB_REQUEST,
entry_id="1", entry_id="1",
source="user",
): ):
"""Create the deCONZ gateway.""" """Create the deCONZ gateway."""
config_entry = MockConfigEntry( config_entry = MockConfigEntry(
domain=deconz.DOMAIN, domain=deconz.DOMAIN,
source=source,
data=deepcopy(config), data=deepcopy(config),
connection_class=config_entries.CONN_CLASS_LOCAL_PUSH, connection_class=config_entries.CONN_CLASS_LOCAL_PUSH,
options=deepcopy(options), options=deepcopy(options),