deCONZ improve gateway tests (#26709)

* Improve gateway tests

* Harmonize all tests to use the same gateway initialization method

* Improve scene tests

* Add gateway resync call to platform tests

* Forgot to change switch tests to use common gateway method

* Improve event tests
This commit is contained in:
Robert Svensson 2019-09-19 23:44:09 +02:00 committed by Paulus Schoutsen
parent 9e2cd5116a
commit f5d12669a5
12 changed files with 305 additions and 585 deletions

View file

@ -184,11 +184,7 @@ class DeconzGateway:
self.api.close() self.api.close()
async def async_reset(self): async def async_reset(self):
"""Reset this gateway to default state. """Reset this gateway to default state."""
Will cancel any scheduled setup retry and will unload
the config entry.
"""
self.api.async_connection_status_callback = None self.api.async_connection_status_callback = None
self.api.close() self.api.close()
@ -203,7 +199,7 @@ class DeconzGateway:
for event in self.events: for event in self.events:
event.async_will_remove_from_hass() event.async_will_remove_from_hass()
self.events.remove(event) self.events.clear()
self.deconz_ids = {} self.deconz_ids = {}
return True return True

View file

@ -9,7 +9,6 @@ from .gateway import get_gateway_from_config_entry
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Old way of setting up deCONZ platforms.""" """Old way of setting up deCONZ platforms."""
pass
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):

View file

@ -1,14 +1,12 @@
"""deCONZ binary sensor platform tests.""" """deCONZ binary sensor platform tests."""
from copy import deepcopy from copy import deepcopy
from asynctest import patch
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.binary_sensor as binary_sensor import homeassistant.components.binary_sensor as binary_sensor
from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
SENSORS = { SENSORS = {
"1": { "1": {
@ -50,50 +48,6 @@ SENSORS = {
}, },
} }
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 = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"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][config[deconz.CONF_BRIDGEID]]
async def test_platform_manually_configured(hass): async def test_platform_manually_configured(hass):
"""Test that we do not discover anything or try to set up a gateway.""" """Test that we do not discover anything or try to set up a gateway."""
@ -147,6 +101,10 @@ async def test_binary_sensors(hass):
presence_sensor = hass.states.get("binary_sensor.presence_sensor") presence_sensor = hass.states.get("binary_sensor.presence_sensor")
assert presence_sensor.state == "on" assert presence_sensor.state == "on"
await gateway.async_reset()
assert len(hass.states.async_all()) == 0
async def test_allow_clip_sensor(hass): async def test_allow_clip_sensor(hass):
"""Test that CLIP sensors can be allowed.""" """Test that CLIP sensors can be allowed."""

View file

@ -3,12 +3,13 @@ from copy import deepcopy
from asynctest import patch from asynctest import patch
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.climate as climate import homeassistant.components.climate as climate
from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
SENSORS = { SENSORS = {
"1": { "1": {
"id": "Thermostat id", "id": "Thermostat id",
@ -42,50 +43,6 @@ SENSORS = {
}, },
} }
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 = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"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][config[deconz.CONF_BRIDGEID]]
async def test_platform_manually_configured(hass): async def test_platform_manually_configured(hass):
"""Test that we do not discover anything or try to set up a gateway.""" """Test that we do not discover anything or try to set up a gateway."""
@ -205,6 +162,10 @@ async def test_climate_devices(hass):
) )
set_callback.assert_called_with("/sensors/1/config", {"heatsetpoint": 2000.0}) set_callback.assert_called_with("/sensors/1/config", {"heatsetpoint": 2000.0})
await gateway.async_reset()
assert len(hass.states.async_all()) == 0
async def test_clip_climate_device(hass): async def test_clip_climate_device(hass):
"""Test successful creation of sensor entities.""" """Test successful creation of sensor entities."""

View file

@ -3,12 +3,13 @@ from copy import deepcopy
from asynctest import patch from asynctest import patch
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.cover as cover import homeassistant.components.cover as cover
from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
COVERS = { COVERS = {
"1": { "1": {
"id": "Level controllable cover id", "id": "Level controllable cover id",
@ -35,50 +36,6 @@ COVERS = {
}, },
} }
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 = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"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][config[deconz.CONF_BRIDGEID]]
async def test_platform_manually_configured(hass): async def test_platform_manually_configured(hass):
"""Test that we do not discover anything or try to set up a gateway.""" """Test that we do not discover anything or try to set up a gateway."""
@ -159,3 +116,7 @@ async def test_cover(hass):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"bri_inc": 0}) set_callback.assert_called_with("/lights/1/state", {"bri_inc": 0})
await gateway.async_reset()
assert len(hass.states.async_all()) == 2

View file

@ -1,60 +1,74 @@
"""Test deCONZ remote events.""" """Test deCONZ remote events."""
from unittest.mock import Mock from copy import deepcopy
from homeassistant.components.deconz.deconz_event import CONF_DECONZ_EVENT, DeconzEvent from asynctest import Mock
from homeassistant.core import callback
from homeassistant.components.deconz.deconz_event import CONF_DECONZ_EVENT
from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
SENSORS = {
"1": {
"id": "Switch 1 id",
"name": "Switch 1",
"type": "ZHASwitch",
"state": {"buttonevent": 1000},
"config": {},
"uniqueid": "00:00:00:00:00:00:00:01-00",
},
"2": {
"id": "Switch 2 id",
"name": "Switch 2",
"type": "ZHASwitch",
"state": {"buttonevent": 1000},
"config": {"battery": 100},
"uniqueid": "00:00:00:00:00:00:00:02-00",
},
}
async def test_create_event(hass): async def test_deconz_events(hass):
"""Successfully created a deCONZ event.""" """Test successful creation of deconz events."""
mock_remote = Mock() data = deepcopy(DECONZ_WEB_REQUEST)
mock_remote.name = "Name" data["sensors"] = deepcopy(SENSORS)
gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
assert "sensor.switch_1" not in gateway.deconz_ids
assert "sensor.switch_1_battery_level" not in gateway.deconz_ids
assert "sensor.switch_2" not in gateway.deconz_ids
assert "sensor.switch_2_battery_level" in gateway.deconz_ids
assert len(hass.states.async_all()) == 1
assert len(gateway.events) == 2
mock_gateway = Mock() switch_1 = hass.states.get("sensor.switch_1")
mock_gateway.hass = hass assert switch_1 is None
event = DeconzEvent(mock_remote, mock_gateway) switch_1_battery_level = hass.states.get("sensor.switch_1_battery_level")
assert switch_1_battery_level is None
assert event.event_id == "name" switch_2 = hass.states.get("sensor.switch_2")
assert switch_2 is None
switch_2_battery_level = hass.states.get("sensor.switch_2_battery_level")
assert switch_2_battery_level.state == "100"
async def test_update_event(hass): mock_listener = Mock()
"""Successfully update a deCONZ event.""" unsub = hass.bus.async_listen(CONF_DECONZ_EVENT, mock_listener)
mock_remote = Mock()
mock_remote.name = "Name"
mock_gateway = Mock() gateway.api.sensors["1"].async_update({"state": {"buttonevent": 2000}})
mock_gateway.hass = hass
event = DeconzEvent(mock_remote, mock_gateway)
mock_remote.changed_keys = {"state": True}
calls = []
@callback
def listener(event):
"""Mock listener."""
calls.append(event)
unsub = hass.bus.async_listen(CONF_DECONZ_EVENT, listener)
event.async_update_callback()
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(calls) == 1 assert len(mock_listener.mock_calls) == 1
assert mock_listener.mock_calls[0][1][0].data == {
"id": "switch_1",
"unique_id": "00:00:00:00:00:00:00:01",
"event": 2000,
}
unsub() unsub()
await gateway.async_reset()
async def test_remove_event(hass): assert len(hass.states.async_all()) == 0
"""Successfully update a deCONZ event.""" assert len(gateway.events) == 0
mock_remote = Mock()
mock_remote.name = "Name"
mock_gateway = Mock()
mock_gateway.hass = hass
event = DeconzEvent(mock_remote, mock_gateway)
event.async_will_remove_from_hass()
assert event._device is None

View file

@ -1,187 +1,178 @@
"""Test deCONZ gateway.""" """Test deCONZ gateway."""
from unittest.mock import Mock, patch from copy import deepcopy
from asynctest import Mock, patch
import pytest import pytest
from homeassistant import config_entries
from homeassistant.components import deconz
from homeassistant.components import ssdp
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.components.deconz import errors, gateway from homeassistant.helpers.dispatcher import async_dispatcher_connect
from tests.common import mock_coro
import pydeconz import pydeconz
BRIDGEID = "0123456789"
ENTRY_CONFIG = { ENTRY_CONFIG = {
"host": "1.2.3.4", deconz.config_flow.CONF_API_KEY: "ABCDEF",
"port": 80, deconz.config_flow.CONF_BRIDGEID: BRIDGEID,
"api_key": "1234567890ABCDEF", deconz.config_flow.CONF_HOST: "1.2.3.4",
"bridgeid": "0123456789ABCDEF", deconz.config_flow.CONF_PORT: 80,
"allow_clip_sensor": True,
"allow_deconz_groups": True,
} }
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,
}
async def test_gateway_setup(): 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.""" """Successful setup."""
hass = Mock() data = deepcopy(DECONZ_WEB_REQUEST)
entry = Mock() with patch(
entry.data = ENTRY_CONFIG "homeassistant.config_entries.ConfigEntries.async_forward_entry_setup",
api = Mock() return_value=True,
api.async_add_remote.return_value = Mock() ) as forward_entry_setup:
api.sensors = {} 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
deconz_gateway = gateway.DeconzGateway(hass, entry) assert len(gateway.deconz_ids) == 0
assert len(hass.states.async_all()) == 0
with patch.object( entry = gateway.config_entry
gateway, "get_gateway", return_value=mock_coro(api) assert forward_entry_setup.mock_calls[0][1] == (entry, "binary_sensor")
), patch.object(gateway, "async_dispatcher_connect", return_value=Mock()): assert forward_entry_setup.mock_calls[1][1] == (entry, "climate")
assert await deconz_gateway.async_setup() is True assert forward_entry_setup.mock_calls[2][1] == (entry, "cover")
assert forward_entry_setup.mock_calls[3][1] == (entry, "light")
assert deconz_gateway.api is api assert forward_entry_setup.mock_calls[4][1] == (entry, "scene")
assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 7 assert forward_entry_setup.mock_calls[5][1] == (entry, "sensor")
assert hass.config_entries.async_forward_entry_setup.mock_calls[0][1] == ( assert forward_entry_setup.mock_calls[6][1] == (entry, "switch")
entry,
"binary_sensor",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[1][1] == (
entry,
"climate",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[2][1] == (
entry,
"cover",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[3][1] == (
entry,
"light",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[4][1] == (
entry,
"scene",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[5][1] == (
entry,
"sensor",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[6][1] == (
entry,
"switch",
)
assert len(api.start.mock_calls) == 1
async def test_gateway_retry(): async def test_gateway_retry(hass):
"""Retry setup.""" """Retry setup."""
hass = Mock() data = deepcopy(DECONZ_WEB_REQUEST)
entry = Mock() with patch(
entry.data = ENTRY_CONFIG "homeassistant.components.deconz.gateway.get_gateway",
side_effect=deconz.errors.CannotConnect,
deconz_gateway = gateway.DeconzGateway(hass, entry)
with patch.object(
gateway, "get_gateway", side_effect=errors.CannotConnect
), pytest.raises(ConfigEntryNotReady): ), pytest.raises(ConfigEntryNotReady):
await deconz_gateway.async_setup() await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
async def test_gateway_setup_fails(): async def test_gateway_setup_fails(hass):
"""Retry setup.""" """Retry setup."""
hass = Mock() data = deepcopy(DECONZ_WEB_REQUEST)
entry = Mock() with patch(
entry.data = ENTRY_CONFIG "homeassistant.components.deconz.gateway.get_gateway", side_effect=Exception
):
deconz_gateway = gateway.DeconzGateway(hass, entry) gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
with patch.object(gateway, "get_gateway", side_effect=Exception): )
result = await deconz_gateway.async_setup() assert gateway is None
assert not result
async def test_connection_status(hass): async def test_connection_status_signalling(hass):
"""Make sure that connection status triggers a dispatcher send.""" """Make sure that connection status triggers a dispatcher send."""
entry = Mock() data = deepcopy(DECONZ_WEB_REQUEST)
entry.data = ENTRY_CONFIG gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
deconz_gateway = gateway.DeconzGateway(hass, entry) event_call = Mock()
with patch.object(gateway, "async_dispatcher_send") as mock_dispatch_send: unsub = async_dispatcher_connect(hass, gateway.signal_reachable, event_call)
deconz_gateway.async_connection_status_callback(True)
await hass.async_block_till_done() gateway.async_connection_status_callback(False)
assert len(mock_dispatch_send.mock_calls) == 1 await hass.async_block_till_done()
assert len(mock_dispatch_send.mock_calls[0]) == 3
assert gateway.available is False
assert len(event_call.mock_calls) == 1
unsub()
async def test_add_device(hass): async def test_update_address(hass):
"""Successful retry setup.""" """Make sure that connection status triggers a dispatcher send."""
entry = Mock() data = deepcopy(DECONZ_WEB_REQUEST)
entry.data = ENTRY_CONFIG gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
assert gateway.api.host == "1.2.3.4"
deconz_gateway = gateway.DeconzGateway(hass, entry) await hass.config_entries.flow.async_init(
with patch.object(gateway, "async_dispatcher_send") as mock_dispatch_send: deconz.config_flow.DOMAIN,
deconz_gateway.async_add_device_callback("sensor", Mock()) 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:1234",
},
context={"source": "ssdp"},
)
await hass.async_block_till_done()
await hass.async_block_till_done() assert gateway.api.host == "2.3.4.5"
assert len(mock_dispatch_send.mock_calls) == 1
assert len(mock_dispatch_send.mock_calls[0]) == 3
async def test_shutdown(): async def test_reset_after_successful_setup(hass):
"""Successful shutdown.""" """Make sure that connection status triggers a dispatcher send."""
hass = Mock() data = deepcopy(DECONZ_WEB_REQUEST)
entry = Mock() gateway = await setup_deconz_integration(
entry.data = ENTRY_CONFIG hass, ENTRY_CONFIG, options={}, get_state_response=data
)
deconz_gateway = gateway.DeconzGateway(hass, entry) result = await gateway.async_reset()
deconz_gateway.api = Mock() await hass.async_block_till_done()
deconz_gateway.shutdown(None)
assert len(deconz_gateway.api.close.mock_calls) == 1 assert result is True
async def test_reset_after_successful_setup():
"""Verify that reset works on a setup component."""
hass = Mock()
entry = Mock()
entry.data = ENTRY_CONFIG
api = Mock()
api.async_add_remote.return_value = Mock()
api.sensors = {}
deconz_gateway = gateway.DeconzGateway(hass, entry)
with patch.object(
gateway, "get_gateway", return_value=mock_coro(api)
), patch.object(gateway, "async_dispatcher_connect", return_value=Mock()):
assert await deconz_gateway.async_setup() is True
listener = Mock()
deconz_gateway.listeners = [listener]
event = Mock()
event.async_will_remove_from_hass = Mock()
deconz_gateway.events = [event]
deconz_gateway.deconz_ids = {"key": "value"}
hass.config_entries.async_forward_entry_unload.return_value = mock_coro(True)
assert await deconz_gateway.async_reset() is True
assert len(hass.config_entries.async_forward_entry_unload.mock_calls) == 7
assert len(listener.mock_calls) == 1
assert len(deconz_gateway.listeners) == 0
assert len(event.async_will_remove_from_hass.mock_calls) == 1
assert len(deconz_gateway.events) == 0
assert len(deconz_gateway.deconz_ids) == 0
async def test_get_gateway(hass): async def test_get_gateway(hass):
"""Successful call.""" """Successful call."""
with patch( with patch("pydeconz.DeconzSession.async_load_parameters", return_value=True):
"pydeconz.DeconzSession.async_load_parameters", return_value=mock_coro(True) assert await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
):
assert await gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
async def test_get_gateway_fails_unauthorized(hass): async def test_get_gateway_fails_unauthorized(hass):
@ -189,8 +180,11 @@ async def test_get_gateway_fails_unauthorized(hass):
with patch( with patch(
"pydeconz.DeconzSession.async_load_parameters", "pydeconz.DeconzSession.async_load_parameters",
side_effect=pydeconz.errors.Unauthorized, side_effect=pydeconz.errors.Unauthorized,
), pytest.raises(errors.AuthenticationRequired): ), pytest.raises(deconz.errors.AuthenticationRequired):
assert await gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) is False assert (
await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
is False
)
async def test_get_gateway_fails_cannot_connect(hass): async def test_get_gateway_fails_cannot_connect(hass):
@ -198,5 +192,8 @@ async def test_get_gateway_fails_cannot_connect(hass):
with patch( with patch(
"pydeconz.DeconzSession.async_load_parameters", "pydeconz.DeconzSession.async_load_parameters",
side_effect=pydeconz.errors.RequestError, side_effect=pydeconz.errors.RequestError,
), pytest.raises(errors.CannotConnect): ), pytest.raises(deconz.errors.CannotConnect):
assert await gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) is False assert (
await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock())
is False
)

View file

@ -3,12 +3,13 @@ from copy import deepcopy
from asynctest import patch from asynctest import patch
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.light as light import homeassistant.components.light as light
from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
GROUPS = { GROUPS = {
"1": { "1": {
"id": "Light group id", "id": "Light group id",
@ -61,50 +62,6 @@ LIGHTS = {
}, },
} }
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 = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"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][config[deconz.CONF_BRIDGEID]]
async def test_platform_manually_configured(hass): async def test_platform_manually_configured(hass):
"""Test that we do not discover anything or try to set up a gateway.""" """Test that we do not discover anything or try to set up a gateway."""
@ -242,6 +199,10 @@ async def test_lights_and_groups(hass):
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/1/state", {"alert": "lselect"}) set_callback.assert_called_with("/lights/1/state", {"alert": "lselect"})
await gateway.async_reset()
assert len(hass.states.async_all()) == 2
async def test_disable_light_groups(hass): async def test_disable_light_groups(hass):
"""Test successful creation of sensor entities.""" """Test successful creation of sensor entities."""

View file

@ -1,67 +1,28 @@
"""deCONZ scene platform tests.""" """deCONZ scene platform tests."""
from unittest.mock import Mock, patch from copy import deepcopy
from asynctest import patch
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.scene as scene import homeassistant.components.scene as scene
from tests.common import mock_coro from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
GROUPS = {
GROUP = {
"1": { "1": {
"id": "Group 1 id", "id": "Light group id",
"name": "Group 1 name", "name": "Light group",
"state": {}, "type": "LightGroup",
"state": {"all_on": False, "any_on": True},
"action": {}, "action": {},
"scenes": [{"id": "1", "name": "Scene 1"}], "scenes": [{"id": "1", "name": "Scene"}],
"lights": [], "lights": [],
} }
} }
ENTRY_CONFIG = {
deconz.const.CONF_ALLOW_CLIP_SENSOR: True,
deconz.const.CONF_ALLOW_DECONZ_GROUPS: True,
deconz.config_flow.CONF_API_KEY: "ABCDEF",
deconz.config_flow.CONF_BRIDGEID: "0123456789",
deconz.config_flow.CONF_HOST: "1.2.3.4",
deconz.config_flow.CONF_PORT: 80,
}
async def setup_gateway(hass, data):
"""Load the deCONZ scene platform."""
from pydeconz import DeconzSession
loop = Mock()
session = Mock()
config_entry = config_entries.ConfigEntry(
1,
deconz.DOMAIN,
"Mock Title",
ENTRY_CONFIG,
"test",
config_entries.CONN_CLASS_LOCAL_PUSH,
system_options={},
)
gateway = deconz.DeconzGateway(hass, config_entry)
gateway.api = DeconzSession(loop, session, **config_entry.data)
gateway.api.config = Mock()
hass.data[deconz.DOMAIN] = {gateway.bridgeid: gateway}
with patch("pydeconz.DeconzSession.async_get_state", return_value=mock_coro(data)):
await gateway.api.async_load_parameters()
await hass.config_entries.async_forward_entry_setup(config_entry, "scene")
# To flush out the service call to update the group
await hass.async_block_till_done()
return gateway
async def test_platform_manually_configured(hass): async def test_platform_manually_configured(hass):
"""Test that we do not discover anything or try to set up a gateway.""" """Test that we do not discover anything or try to set up a gateway."""
assert ( assert (
@ -75,26 +36,38 @@ async def test_platform_manually_configured(hass):
async def test_no_scenes(hass): async def test_no_scenes(hass):
"""Test that scenes can be loaded without scenes being available.""" """Test that scenes can be loaded without scenes being available."""
gateway = await setup_gateway(hass, {}) data = deepcopy(DECONZ_WEB_REQUEST)
assert not hass.data[deconz.DOMAIN][gateway.bridgeid].deconz_ids gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
assert len(gateway.deconz_ids) == 0
assert len(hass.states.async_all()) == 0 assert len(hass.states.async_all()) == 0
async def test_scenes(hass): async def test_scenes(hass):
"""Test that scenes works.""" """Test that scenes works."""
with patch("pydeconz.DeconzSession.async_put_state", return_value=mock_coro(True)): data = deepcopy(DECONZ_WEB_REQUEST)
gateway = await setup_gateway(hass, {"groups": GROUP}) data["groups"] = deepcopy(GROUPS)
assert "scene.group_1_name_scene_1" in gateway.deconz_ids gateway = await setup_deconz_integration(
assert len(hass.states.async_all()) == 1 hass, ENTRY_CONFIG, options={}, get_state_response=data
await hass.services.async_call(
"scene", "turn_on", {"entity_id": "scene.group_1_name_scene_1"}, blocking=True
) )
assert "scene.light_group_scene" in gateway.deconz_ids
assert len(hass.states.async_all()) == 1
async def test_unload_scene(hass): light_group_scene = hass.states.get("scene.light_group_scene")
"""Test that it works to unload scene entities.""" assert light_group_scene
gateway = await setup_gateway(hass, {"groups": GROUP})
group_scene = gateway.api.groups["1"].scenes["1"]
with patch.object(
group_scene, "_async_set_state_callback", return_value=True
) as set_callback:
await hass.services.async_call(
"scene", "turn_on", {"entity_id": "scene.light_group_scene"}, blocking=True
)
await hass.async_block_till_done()
set_callback.assert_called_with("/groups/1/scenes/1/recall", {})
await gateway.async_reset() await gateway.async_reset()

View file

@ -1,14 +1,12 @@
"""deCONZ sensor platform tests.""" """deCONZ sensor platform tests."""
from copy import deepcopy from copy import deepcopy
from asynctest import patch
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.sensor as sensor import homeassistant.components.sensor as sensor
from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
SENSORS = { SENSORS = {
"1": { "1": {
@ -77,50 +75,6 @@ SENSORS = {
}, },
} }
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 = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"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][config[deconz.CONF_BRIDGEID]]
async def test_platform_manually_configured(hass): async def test_platform_manually_configured(hass):
"""Test that we do not discover anything or try to set up a gateway.""" """Test that we do not discover anything or try to set up a gateway."""
@ -199,6 +153,10 @@ async def test_sensors(hass):
switch_2_battery_level = hass.states.get("sensor.switch_2_battery_level") switch_2_battery_level = hass.states.get("sensor.switch_2_battery_level")
assert switch_2_battery_level.state == "75" assert switch_2_battery_level.state == "75"
await gateway.async_reset()
assert len(hass.states.async_all()) == 0
async def test_allow_clip_sensors(hass): async def test_allow_clip_sensors(hass):
"""Test that CLIP sensors can be allowed.""" """Test that CLIP sensors can be allowed."""

View file

@ -1,30 +1,19 @@
"""deCONZ service tests.""" """deCONZ service tests."""
from copy import deepcopy
from asynctest import Mock, patch from asynctest import Mock, patch
import pytest import pytest
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
BRIDGEID = "0123456789" from .test_gateway import (
BRIDGEID,
ENTRY_CONFIG = { ENTRY_CONFIG,
deconz.config_flow.CONF_API_KEY: "ABCDEF", DECONZ_WEB_REQUEST,
deconz.config_flow.CONF_BRIDGEID: BRIDGEID, setup_deconz_integration,
deconz.config_flow.CONF_HOST: "1.2.3.4", )
deconz.config_flow.CONF_PORT: 80,
}
DECONZ_CONFIG = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"websocketport": 1234,
}
DECONZ_WEB_REQUEST = {"config": DECONZ_CONFIG}
GROUP = { GROUP = {
"1": { "1": {
@ -60,31 +49,6 @@ SENSOR = {
} }
async def setup_deconz_integration(hass, options):
"""Create the deCONZ gateway."""
config_entry = config_entries.ConfigEntry(
version=1,
domain=deconz.DOMAIN,
title="Mock Title",
data=ENTRY_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=DECONZ_WEB_REQUEST
):
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][BRIDGEID]
async def test_service_setup(hass): async def test_service_setup(hass):
"""Verify service setup works.""" """Verify service setup works."""
assert deconz.services.DECONZ_SERVICES not in hass.data assert deconz.services.DECONZ_SERVICES not in hass.data
@ -129,7 +93,10 @@ async def test_service_unload_not_registered(hass):
async def test_configure_service_with_field(hass): async def test_configure_service_with_field(hass):
"""Test that service invokes pydeconz with the correct path and data.""" """Test that service invokes pydeconz with the correct path and data."""
await setup_deconz_integration(hass, options={}) data = deepcopy(DECONZ_WEB_REQUEST)
await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
data = { data = {
deconz.services.SERVICE_FIELD: "/light/2", deconz.services.SERVICE_FIELD: "/light/2",
@ -149,7 +116,10 @@ async def test_configure_service_with_field(hass):
async def test_configure_service_with_entity(hass): async def test_configure_service_with_entity(hass):
"""Test that service invokes pydeconz with the correct path and data.""" """Test that service invokes pydeconz with the correct path and data."""
gateway = await setup_deconz_integration(hass, options={}) data = deepcopy(DECONZ_WEB_REQUEST)
gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
gateway.deconz_ids["light.test"] = "/light/1" gateway.deconz_ids["light.test"] = "/light/1"
data = { data = {
@ -169,7 +139,10 @@ async def test_configure_service_with_entity(hass):
async def test_configure_service_with_entity_and_field(hass): async def test_configure_service_with_entity_and_field(hass):
"""Test that service invokes pydeconz with the correct path and data.""" """Test that service invokes pydeconz with the correct path and data."""
gateway = await setup_deconz_integration(hass, options={}) data = deepcopy(DECONZ_WEB_REQUEST)
gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
gateway.deconz_ids["light.test"] = "/light/1" gateway.deconz_ids["light.test"] = "/light/1"
data = { data = {
@ -192,7 +165,10 @@ async def test_configure_service_with_entity_and_field(hass):
async def test_configure_service_with_faulty_field(hass): async def test_configure_service_with_faulty_field(hass):
"""Test that service invokes pydeconz with the correct path and data.""" """Test that service invokes pydeconz with the correct path and data."""
await setup_deconz_integration(hass, options={}) data = deepcopy(DECONZ_WEB_REQUEST)
await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
data = {deconz.services.SERVICE_FIELD: "light/2", deconz.services.SERVICE_DATA: {}} data = {deconz.services.SERVICE_FIELD: "light/2", deconz.services.SERVICE_DATA: {}}
@ -205,7 +181,10 @@ async def test_configure_service_with_faulty_field(hass):
async def test_configure_service_with_faulty_entity(hass): async def test_configure_service_with_faulty_entity(hass):
"""Test that service invokes pydeconz with the correct path and data.""" """Test that service invokes pydeconz with the correct path and data."""
await setup_deconz_integration(hass, options={}) data = deepcopy(DECONZ_WEB_REQUEST)
await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
data = { data = {
deconz.services.SERVICE_ENTITY: "light.nonexisting", deconz.services.SERVICE_ENTITY: "light.nonexisting",
@ -224,7 +203,10 @@ async def test_configure_service_with_faulty_entity(hass):
async def test_service_refresh_devices(hass): async def test_service_refresh_devices(hass):
"""Test that service can refresh devices.""" """Test that service can refresh devices."""
gateway = await setup_deconz_integration(hass, options={}) data = deepcopy(DECONZ_WEB_REQUEST)
gateway = await setup_deconz_integration(
hass, ENTRY_CONFIG, options={}, get_state_response=data
)
data = {deconz.CONF_BRIDGEID: BRIDGEID} data = {deconz.CONF_BRIDGEID: BRIDGEID}

View file

@ -3,13 +3,13 @@ from copy import deepcopy
from asynctest import patch from asynctest import patch
from homeassistant import config_entries
from homeassistant.components import deconz from homeassistant.components import deconz
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.components.switch as switch import homeassistant.components.switch as switch
from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration
SWITCHES = { SWITCHES = {
"1": { "1": {
"id": "On off switch id", "id": "On off switch id",
@ -41,50 +41,6 @@ SWITCHES = {
}, },
} }
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 = {
"bridgeid": BRIDGEID,
"mac": "00:11:22:33:44:55",
"name": "deCONZ mock gateway",
"sw_version": "2.05.69",
"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][config[deconz.CONF_BRIDGEID]]
async def test_platform_manually_configured(hass): async def test_platform_manually_configured(hass):
"""Test that we do not discover anything or try to set up a gateway.""" """Test that we do not discover anything or try to set up a gateway."""
@ -189,3 +145,7 @@ async def test_switches(hass):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
set_callback.assert_called_with("/lights/3/state", {"alert": "none"}) set_callback.assert_called_with("/lights/3/state", {"alert": "none"})
await gateway.async_reset()
assert len(hass.states.async_all()) == 2