* Improve ssdp discovery by storing uuid in config entry so discovery can update any deconz entry, loaded or not
200 lines
6.4 KiB
Python
200 lines
6.4 KiB
Python
"""Test deCONZ gateway."""
|
|
from copy import deepcopy
|
|
|
|
from asynctest import Mock, patch
|
|
|
|
import pytest
|
|
|
|
from homeassistant import config_entries
|
|
from homeassistant.components import deconz
|
|
from homeassistant.components import ssdp
|
|
from homeassistant.exceptions import ConfigEntryNotReady
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
|
|
import pydeconz
|
|
|
|
BRIDGEID = "0123456789"
|
|
|
|
ENTRY_CONFIG = {
|
|
deconz.config_flow.CONF_API_KEY: "ABCDEF",
|
|
deconz.config_flow.CONF_BRIDGEID: BRIDGEID,
|
|
deconz.config_flow.CONF_HOST: "1.2.3.4",
|
|
deconz.config_flow.CONF_PORT: 80,
|
|
deconz.config_flow.CONF_UUID: "456DEF",
|
|
}
|
|
|
|
DECONZ_CONFIG = {
|
|
"bridgeid": BRIDGEID,
|
|
"ipaddress": "1.2.3.4",
|
|
"mac": "00:11:22:33:44:55",
|
|
"modelid": "deCONZ",
|
|
"name": "deCONZ mock gateway",
|
|
"sw_version": "2.05.69",
|
|
"uuid": "1234",
|
|
"websocketport": 1234,
|
|
}
|
|
|
|
DECONZ_WEB_REQUEST = {"config": DECONZ_CONFIG}
|
|
|
|
|
|
async def setup_deconz_integration(hass, config, options, get_state_response):
|
|
"""Create the deCONZ gateway."""
|
|
config_entry = config_entries.ConfigEntry(
|
|
version=1,
|
|
domain=deconz.DOMAIN,
|
|
title="Mock Title",
|
|
data=config,
|
|
source="test",
|
|
connection_class=config_entries.CONN_CLASS_LOCAL_PUSH,
|
|
system_options={},
|
|
options=options,
|
|
entry_id="1",
|
|
)
|
|
|
|
with patch(
|
|
"pydeconz.DeconzSession.async_get_state", return_value=get_state_response
|
|
), patch("pydeconz.DeconzSession.start", return_value=True):
|
|
await deconz.async_setup_entry(hass, config_entry)
|
|
await hass.async_block_till_done()
|
|
|
|
hass.config_entries._entries.append(config_entry)
|
|
|
|
return hass.data[deconz.DOMAIN].get(config[deconz.CONF_BRIDGEID])
|
|
|
|
|
|
async def test_gateway_setup(hass):
|
|
"""Successful setup."""
|
|
data = deepcopy(DECONZ_WEB_REQUEST)
|
|
with patch(
|
|
"homeassistant.config_entries.ConfigEntries.async_forward_entry_setup",
|
|
return_value=True,
|
|
) as forward_entry_setup:
|
|
gateway = await setup_deconz_integration(
|
|
hass, ENTRY_CONFIG, options={}, get_state_response=data
|
|
)
|
|
assert gateway.bridgeid == BRIDGEID
|
|
assert gateway.master is True
|
|
assert gateway.option_allow_clip_sensor is False
|
|
assert gateway.option_allow_deconz_groups is True
|
|
|
|
assert len(gateway.deconz_ids) == 0
|
|
assert len(hass.states.async_all()) == 0
|
|
|
|
entry = gateway.config_entry
|
|
assert forward_entry_setup.mock_calls[0][1] == (entry, "binary_sensor")
|
|
assert forward_entry_setup.mock_calls[1][1] == (entry, "climate")
|
|
assert forward_entry_setup.mock_calls[2][1] == (entry, "cover")
|
|
assert forward_entry_setup.mock_calls[3][1] == (entry, "light")
|
|
assert forward_entry_setup.mock_calls[4][1] == (entry, "scene")
|
|
assert forward_entry_setup.mock_calls[5][1] == (entry, "sensor")
|
|
assert forward_entry_setup.mock_calls[6][1] == (entry, "switch")
|
|
|
|
|
|
async def test_gateway_retry(hass):
|
|
"""Retry setup."""
|
|
data = deepcopy(DECONZ_WEB_REQUEST)
|
|
with patch(
|
|
"homeassistant.components.deconz.gateway.get_gateway",
|
|
side_effect=deconz.errors.CannotConnect,
|
|
), pytest.raises(ConfigEntryNotReady):
|
|
await setup_deconz_integration(
|
|
hass, ENTRY_CONFIG, options={}, get_state_response=data
|
|
)
|
|
|
|
|
|
async def test_gateway_setup_fails(hass):
|
|
"""Retry setup."""
|
|
data = deepcopy(DECONZ_WEB_REQUEST)
|
|
with patch(
|
|
"homeassistant.components.deconz.gateway.get_gateway", side_effect=Exception
|
|
):
|
|
gateway = await setup_deconz_integration(
|
|
hass, ENTRY_CONFIG, options={}, get_state_response=data
|
|
)
|
|
assert gateway is None
|
|
|
|
|
|
async def test_connection_status_signalling(hass):
|
|
"""Make sure that connection status triggers a dispatcher send."""
|
|
data = deepcopy(DECONZ_WEB_REQUEST)
|
|
gateway = await setup_deconz_integration(
|
|
hass, ENTRY_CONFIG, options={}, get_state_response=data
|
|
)
|
|
|
|
event_call = Mock()
|
|
unsub = async_dispatcher_connect(hass, gateway.signal_reachable, event_call)
|
|
|
|
gateway.async_connection_status_callback(False)
|
|
await hass.async_block_till_done()
|
|
|
|
assert gateway.available is False
|
|
assert len(event_call.mock_calls) == 1
|
|
|
|
unsub()
|
|
|
|
|
|
async def test_update_address(hass):
|
|
"""Make sure that connection status triggers a dispatcher send."""
|
|
data = deepcopy(DECONZ_WEB_REQUEST)
|
|
gateway = await setup_deconz_integration(
|
|
hass, ENTRY_CONFIG, options={}, get_state_response=data
|
|
)
|
|
assert gateway.api.host == "1.2.3.4"
|
|
|
|
await hass.config_entries.flow.async_init(
|
|
deconz.config_flow.DOMAIN,
|
|
data={
|
|
deconz.config_flow.CONF_HOST: "2.3.4.5",
|
|
deconz.config_flow.CONF_PORT: 80,
|
|
ssdp.ATTR_SERIAL: BRIDGEID,
|
|
ssdp.ATTR_MANUFACTURERURL: deconz.config_flow.DECONZ_MANUFACTURERURL,
|
|
deconz.config_flow.ATTR_UUID: "uuid:456DEF",
|
|
},
|
|
context={"source": "ssdp"},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert gateway.api.host == "2.3.4.5"
|
|
|
|
|
|
async def test_reset_after_successful_setup(hass):
|
|
"""Make sure that connection status triggers a dispatcher send."""
|
|
data = deepcopy(DECONZ_WEB_REQUEST)
|
|
gateway = await setup_deconz_integration(
|
|
hass, ENTRY_CONFIG, options={}, get_state_response=data
|
|
)
|
|
|
|
result = await gateway.async_reset()
|
|
await hass.async_block_till_done()
|
|
|
|
assert result is True
|
|
|
|
|
|
async def test_get_gateway(hass):
|
|
"""Successful call."""
|
|
with patch("pydeconz.DeconzSession.async_load_parameters", return_value=True):
|
|
assert await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
|
|
|
|
|
|
async def test_get_gateway_fails_unauthorized(hass):
|
|
"""Failed call."""
|
|
with patch(
|
|
"pydeconz.DeconzSession.async_load_parameters",
|
|
side_effect=pydeconz.errors.Unauthorized,
|
|
), pytest.raises(deconz.errors.AuthenticationRequired):
|
|
assert (
|
|
await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
|
|
is False
|
|
)
|
|
|
|
|
|
async def test_get_gateway_fails_cannot_connect(hass):
|
|
"""Failed call."""
|
|
with patch(
|
|
"pydeconz.DeconzSession.async_load_parameters",
|
|
side_effect=pydeconz.errors.RequestError,
|
|
), pytest.raises(deconz.errors.CannotConnect):
|
|
assert (
|
|
await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
|
|
is False
|
|
)
|