diff --git a/homeassistant/components/deconz/gateway.py b/homeassistant/components/deconz/gateway.py index a090dca0d0c6..75898b0fdab8 100644 --- a/homeassistant/components/deconz/gateway.py +++ b/homeassistant/components/deconz/gateway.py @@ -184,11 +184,7 @@ def shutdown(self, event): self.api.close() async def async_reset(self): - """Reset this gateway to default state. - - Will cancel any scheduled setup retry and will unload - the config entry. - """ + """Reset this gateway to default state.""" self.api.async_connection_status_callback = None self.api.close() @@ -203,7 +199,7 @@ async def async_reset(self): for event in self.events: event.async_will_remove_from_hass() - self.events.remove(event) + self.events.clear() self.deconz_ids = {} return True diff --git a/homeassistant/components/deconz/scene.py b/homeassistant/components/deconz/scene.py index 8d27d386da26..a84e799d44d4 100644 --- a/homeassistant/components/deconz/scene.py +++ b/homeassistant/components/deconz/scene.py @@ -9,7 +9,6 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Old way of setting up deCONZ platforms.""" - pass async def async_setup_entry(hass, config_entry, async_add_entities): diff --git a/tests/components/deconz/test_binary_sensor.py b/tests/components/deconz/test_binary_sensor.py index c5c35f108296..2f42193291c8 100644 --- a/tests/components/deconz/test_binary_sensor.py +++ b/tests/components/deconz/test_binary_sensor.py @@ -1,14 +1,12 @@ """deCONZ binary sensor platform tests.""" from copy import deepcopy -from asynctest import patch - -from homeassistant import config_entries from homeassistant.components import deconz from homeassistant.setup import async_setup_component import homeassistant.components.binary_sensor as binary_sensor +from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration SENSORS = { "1": { @@ -50,50 +48,6 @@ }, } -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): """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") assert presence_sensor.state == "on" + await gateway.async_reset() + + assert len(hass.states.async_all()) == 0 + async def test_allow_clip_sensor(hass): """Test that CLIP sensors can be allowed.""" diff --git a/tests/components/deconz/test_climate.py b/tests/components/deconz/test_climate.py index 1211188d3db3..cee91f00c428 100644 --- a/tests/components/deconz/test_climate.py +++ b/tests/components/deconz/test_climate.py @@ -3,12 +3,13 @@ from asynctest import patch -from homeassistant import config_entries from homeassistant.components import deconz from homeassistant.setup import async_setup_component import homeassistant.components.climate as climate +from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration + SENSORS = { "1": { "id": "Thermostat id", @@ -42,50 +43,6 @@ }, } -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): """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}) + await gateway.async_reset() + + assert len(hass.states.async_all()) == 0 + async def test_clip_climate_device(hass): """Test successful creation of sensor entities.""" diff --git a/tests/components/deconz/test_cover.py b/tests/components/deconz/test_cover.py index 246c2bae7c56..5c7ee48a78a2 100644 --- a/tests/components/deconz/test_cover.py +++ b/tests/components/deconz/test_cover.py @@ -3,12 +3,13 @@ from asynctest import patch -from homeassistant import config_entries from homeassistant.components import deconz from homeassistant.setup import async_setup_component import homeassistant.components.cover as cover +from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration + COVERS = { "1": { "id": "Level controllable cover id", @@ -35,50 +36,6 @@ }, } -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): """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() set_callback.assert_called_with("/lights/1/state", {"bri_inc": 0}) + + await gateway.async_reset() + + assert len(hass.states.async_all()) == 2 diff --git a/tests/components/deconz/test_deconz_event.py b/tests/components/deconz/test_deconz_event.py index 72966ba6c66b..ade9aa02ad4a 100644 --- a/tests/components/deconz/test_deconz_event.py +++ b/tests/components/deconz/test_deconz_event.py @@ -1,60 +1,74 @@ """Test deCONZ remote events.""" -from unittest.mock import Mock - -from homeassistant.components.deconz.deconz_event import CONF_DECONZ_EVENT, DeconzEvent -from homeassistant.core import callback - - -async def test_create_event(hass): - """Successfully created a deCONZ event.""" - mock_remote = Mock() - mock_remote.name = "Name" - - mock_gateway = Mock() - mock_gateway.hass = hass - - event = DeconzEvent(mock_remote, mock_gateway) - - assert event.event_id == "name" - - -async def test_update_event(hass): - """Successfully update a deCONZ event.""" - mock_remote = Mock() - mock_remote.name = "Name" - - mock_gateway = Mock() - 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() +from copy import deepcopy + +from asynctest import Mock + +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_deconz_events(hass): + """Test successful creation of deconz events.""" + data = deepcopy(DECONZ_WEB_REQUEST) + 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 + + switch_1 = hass.states.get("sensor.switch_1") + assert switch_1 is None + + switch_1_battery_level = hass.states.get("sensor.switch_1_battery_level") + assert switch_1_battery_level is None + + 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" + + mock_listener = Mock() + unsub = hass.bus.async_listen(CONF_DECONZ_EVENT, mock_listener) + + gateway.api.sensors["1"].async_update({"state": {"buttonevent": 2000}}) 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() + await gateway.async_reset() -async def test_remove_event(hass): - """Successfully update a deCONZ event.""" - 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 + assert len(hass.states.async_all()) == 0 + assert len(gateway.events) == 0 diff --git a/tests/components/deconz/test_gateway.py b/tests/components/deconz/test_gateway.py index d84706430f46..25a1cd465c51 100644 --- a/tests/components/deconz/test_gateway.py +++ b/tests/components/deconz/test_gateway.py @@ -1,187 +1,178 @@ """Test deCONZ gateway.""" -from unittest.mock import Mock, patch +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.components.deconz import errors, gateway - -from tests.common import mock_coro +from homeassistant.helpers.dispatcher import async_dispatcher_connect import pydeconz +BRIDGEID = "0123456789" ENTRY_CONFIG = { - "host": "1.2.3.4", - "port": 80, - "api_key": "1234567890ABCDEF", - "bridgeid": "0123456789ABCDEF", - "allow_clip_sensor": True, - "allow_deconz_groups": True, + 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, + "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(): - """Successful setup.""" - 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 - - assert deconz_gateway.api is api - assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 7 - assert hass.config_entries.async_forward_entry_setup.mock_calls[0][1] == ( - 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", +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", ) - assert len(api.start.mock_calls) == 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() -async def test_gateway_retry(): - """Retry setup.""" - hass = Mock() - entry = Mock() - entry.data = ENTRY_CONFIG + hass.config_entries._entries.append(config_entry) - deconz_gateway = gateway.DeconzGateway(hass, entry) + return hass.data[deconz.DOMAIN].get(config[deconz.CONF_BRIDGEID]) - with patch.object( - gateway, "get_gateway", side_effect=errors.CannotConnect - ), pytest.raises(ConfigEntryNotReady): - await deconz_gateway.async_setup() - -async def test_gateway_setup_fails(): +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.""" - hass = Mock() - entry = Mock() - entry.data = ENTRY_CONFIG - - deconz_gateway = gateway.DeconzGateway(hass, entry) + 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 + ) - with patch.object(gateway, "get_gateway", side_effect=Exception): - result = await deconz_gateway.async_setup() - assert not result +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(hass): +async def test_connection_status_signalling(hass): """Make sure that connection status triggers a dispatcher send.""" - entry = Mock() - entry.data = ENTRY_CONFIG - - deconz_gateway = gateway.DeconzGateway(hass, entry) - with patch.object(gateway, "async_dispatcher_send") as mock_dispatch_send: - deconz_gateway.async_connection_status_callback(True) - - await hass.async_block_till_done() - assert len(mock_dispatch_send.mock_calls) == 1 - assert len(mock_dispatch_send.mock_calls[0]) == 3 - - -async def test_add_device(hass): - """Successful retry setup.""" - entry = Mock() - entry.data = ENTRY_CONFIG - - deconz_gateway = gateway.DeconzGateway(hass, entry) - with patch.object(gateway, "async_dispatcher_send") as mock_dispatch_send: - deconz_gateway.async_add_device_callback("sensor", Mock()) - - await hass.async_block_till_done() - assert len(mock_dispatch_send.mock_calls) == 1 - assert len(mock_dispatch_send.mock_calls[0]) == 3 - - -async def test_shutdown(): - """Successful shutdown.""" - hass = Mock() - entry = Mock() - entry.data = ENTRY_CONFIG - - deconz_gateway = gateway.DeconzGateway(hass, entry) - deconz_gateway.api = Mock() - deconz_gateway.shutdown(None) + data = deepcopy(DECONZ_WEB_REQUEST) + gateway = await setup_deconz_integration( + hass, ENTRY_CONFIG, options={}, get_state_response=data + ) - assert len(deconz_gateway.api.close.mock_calls) == 1 + 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() -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 = {} + assert gateway.available is False + assert len(event_call.mock_calls) == 1 - deconz_gateway = gateway.DeconzGateway(hass, entry) + unsub() - 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"} +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:1234", + }, + context={"source": "ssdp"}, + ) + await hass.async_block_till_done() - hass.config_entries.async_forward_entry_unload.return_value = mock_coro(True) - assert await deconz_gateway.async_reset() is True + assert gateway.api.host == "2.3.4.5" - assert len(hass.config_entries.async_forward_entry_unload.mock_calls) == 7 - assert len(listener.mock_calls) == 1 - assert len(deconz_gateway.listeners) == 0 +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 + ) - assert len(event.async_will_remove_from_hass.mock_calls) == 1 - assert len(deconz_gateway.events) == 0 + result = await gateway.async_reset() + await hass.async_block_till_done() - assert len(deconz_gateway.deconz_ids) == 0 + assert result is True async def test_get_gateway(hass): """Successful call.""" - with patch( - "pydeconz.DeconzSession.async_load_parameters", return_value=mock_coro(True) - ): - assert await gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) + 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): @@ -189,8 +180,11 @@ async def test_get_gateway_fails_unauthorized(hass): with patch( "pydeconz.DeconzSession.async_load_parameters", side_effect=pydeconz.errors.Unauthorized, - ), pytest.raises(errors.AuthenticationRequired): - assert await gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) is False + ), 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): @@ -198,5 +192,8 @@ async def test_get_gateway_fails_cannot_connect(hass): with patch( "pydeconz.DeconzSession.async_load_parameters", side_effect=pydeconz.errors.RequestError, - ), pytest.raises(errors.CannotConnect): - assert await gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) is False + ), pytest.raises(deconz.errors.CannotConnect): + assert ( + await deconz.gateway.get_gateway(hass, ENTRY_CONFIG, Mock(), Mock()) + is False + ) diff --git a/tests/components/deconz/test_light.py b/tests/components/deconz/test_light.py index 50a5b2adacab..14dc5cc8eac1 100644 --- a/tests/components/deconz/test_light.py +++ b/tests/components/deconz/test_light.py @@ -3,12 +3,13 @@ from asynctest import patch -from homeassistant import config_entries from homeassistant.components import deconz from homeassistant.setup import async_setup_component import homeassistant.components.light as light +from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration + GROUPS = { "1": { "id": "Light group id", @@ -61,50 +62,6 @@ }, } -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): """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() 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): """Test successful creation of sensor entities.""" diff --git a/tests/components/deconz/test_scene.py b/tests/components/deconz/test_scene.py index 074e943548de..dcc8ba500c32 100644 --- a/tests/components/deconz/test_scene.py +++ b/tests/components/deconz/test_scene.py @@ -1,67 +1,28 @@ """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.setup import async_setup_component import homeassistant.components.scene as scene -from tests.common import mock_coro - +from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration -GROUP = { +GROUPS = { "1": { - "id": "Group 1 id", - "name": "Group 1 name", - "state": {}, + "id": "Light group id", + "name": "Light group", + "type": "LightGroup", + "state": {"all_on": False, "any_on": True}, "action": {}, - "scenes": [{"id": "1", "name": "Scene 1"}], + "scenes": [{"id": "1", "name": "Scene"}], "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): """Test that we do not discover anything or try to set up a gateway.""" assert ( @@ -75,26 +36,38 @@ async def test_platform_manually_configured(hass): async def test_no_scenes(hass): """Test that scenes can be loaded without scenes being available.""" - gateway = await setup_gateway(hass, {}) - assert not hass.data[deconz.DOMAIN][gateway.bridgeid].deconz_ids + data = deepcopy(DECONZ_WEB_REQUEST) + 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 async def test_scenes(hass): """Test that scenes works.""" - with patch("pydeconz.DeconzSession.async_put_state", return_value=mock_coro(True)): - gateway = await setup_gateway(hass, {"groups": GROUP}) - assert "scene.group_1_name_scene_1" in gateway.deconz_ids + data = deepcopy(DECONZ_WEB_REQUEST) + data["groups"] = deepcopy(GROUPS) + gateway = await setup_deconz_integration( + hass, ENTRY_CONFIG, options={}, get_state_response=data + ) + + assert "scene.light_group_scene" in gateway.deconz_ids assert len(hass.states.async_all()) == 1 - await hass.services.async_call( - "scene", "turn_on", {"entity_id": "scene.group_1_name_scene_1"}, blocking=True - ) + light_group_scene = hass.states.get("scene.light_group_scene") + assert light_group_scene + group_scene = gateway.api.groups["1"].scenes["1"] -async def test_unload_scene(hass): - """Test that it works to unload scene entities.""" - gateway = await setup_gateway(hass, {"groups": GROUP}) + 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() diff --git a/tests/components/deconz/test_sensor.py b/tests/components/deconz/test_sensor.py index 947c42e69498..928e527dd070 100644 --- a/tests/components/deconz/test_sensor.py +++ b/tests/components/deconz/test_sensor.py @@ -1,14 +1,12 @@ """deCONZ sensor platform tests.""" from copy import deepcopy -from asynctest import patch - -from homeassistant import config_entries from homeassistant.components import deconz from homeassistant.setup import async_setup_component import homeassistant.components.sensor as sensor +from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration SENSORS = { "1": { @@ -77,50 +75,6 @@ }, } -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): """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") 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): """Test that CLIP sensors can be allowed.""" diff --git a/tests/components/deconz/test_services.py b/tests/components/deconz/test_services.py index 63934871fcbf..533d85eef7cb 100644 --- a/tests/components/deconz/test_services.py +++ b/tests/components/deconz/test_services.py @@ -1,30 +1,19 @@ """deCONZ service tests.""" +from copy import deepcopy + from asynctest import Mock, patch import pytest import voluptuous as vol -from homeassistant import config_entries from homeassistant.components import deconz -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} +from .test_gateway import ( + BRIDGEID, + ENTRY_CONFIG, + DECONZ_WEB_REQUEST, + setup_deconz_integration, +) GROUP = { "1": { @@ -60,31 +49,6 @@ } -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): """Verify service setup works.""" 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): """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", @@ -149,7 +116,10 @@ async def test_configure_service_with_field(hass): async def test_configure_service_with_entity(hass): """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" data = { @@ -169,7 +139,10 @@ async def test_configure_service_with_entity(hass): async def test_configure_service_with_entity_and_field(hass): """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" data = { @@ -192,7 +165,10 @@ async def test_configure_service_with_entity_and_field(hass): async def test_configure_service_with_faulty_field(hass): """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: {}} @@ -205,7 +181,10 @@ async def test_configure_service_with_faulty_field(hass): async def test_configure_service_with_faulty_entity(hass): """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_ENTITY: "light.nonexisting", @@ -224,7 +203,10 @@ async def test_configure_service_with_faulty_entity(hass): async def test_service_refresh_devices(hass): """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} diff --git a/tests/components/deconz/test_switch.py b/tests/components/deconz/test_switch.py index c574ed8911e0..262bd7001f58 100644 --- a/tests/components/deconz/test_switch.py +++ b/tests/components/deconz/test_switch.py @@ -3,13 +3,13 @@ from asynctest import patch -from homeassistant import config_entries from homeassistant.components import deconz from homeassistant.setup import async_setup_component - import homeassistant.components.switch as switch +from .test_gateway import ENTRY_CONFIG, DECONZ_WEB_REQUEST, setup_deconz_integration + SWITCHES = { "1": { "id": "On off switch id", @@ -41,50 +41,6 @@ }, } -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): """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() set_callback.assert_called_with("/lights/3/state", {"alert": "none"}) + + await gateway.async_reset() + + assert len(hass.states.async_all()) == 2