"""Test deCONZ component setup process.""" from unittest.mock import Mock, patch import pytest import voluptuous as vol from homeassistant.setup import async_setup_component from homeassistant.components import deconz from tests.common import mock_coro, MockConfigEntry CONFIG = { "config": { "bridgeid": "0123456789ABCDEF", "mac": "12:34:56:78:90:ab", "modelid": "deCONZ", "name": "Phoscon", "swversion": "2.05.35" } } async def test_config_with_host_passed_to_config_entry(hass): """Test that configured options for a host are loaded via config entry.""" with patch.object(hass, 'config_entries') as mock_config_entries, \ patch.object(deconz, 'configured_hosts', return_value=[]): assert await async_setup_component(hass, deconz.DOMAIN, { deconz.DOMAIN: { deconz.CONF_HOST: '1.2.3.4', deconz.CONF_PORT: 80 } }) is True # Import flow started assert len(mock_config_entries.flow.mock_calls) == 2 async def test_config_without_host_not_passed_to_config_entry(hass): """Test that a configuration without a host does not initiate an import.""" with patch.object(hass, 'config_entries') as mock_config_entries, \ patch.object(deconz, 'configured_hosts', return_value=[]): assert await async_setup_component(hass, deconz.DOMAIN, { deconz.DOMAIN: {} }) is True # No flow started assert len(mock_config_entries.flow.mock_calls) == 0 async def test_config_already_registered_not_passed_to_config_entry(hass): """Test that an already registered host does not initiate an import.""" with patch.object(hass, 'config_entries') as mock_config_entries, \ patch.object(deconz, 'configured_hosts', return_value=['1.2.3.4']): assert await async_setup_component(hass, deconz.DOMAIN, { deconz.DOMAIN: { deconz.CONF_HOST: '1.2.3.4', deconz.CONF_PORT: 80 } }) is True # No flow started assert len(mock_config_entries.flow.mock_calls) == 0 async def test_config_discovery(hass): """Test that a discovered bridge does not initiate an import.""" with patch.object(hass, 'config_entries') as mock_config_entries: assert await async_setup_component(hass, deconz.DOMAIN, {}) is True # No flow started assert len(mock_config_entries.flow.mock_calls) == 0 async def test_setup_entry_already_registered_bridge(hass): """Test setup entry doesn't allow more than one instance of deCONZ.""" hass.data[deconz.DOMAIN] = True assert await deconz.async_setup_entry(hass, {}) is False async def test_setup_entry_no_available_bridge(hass): """Test setup entry fails if deCONZ is not available.""" entry = Mock() entry.data = {'host': '1.2.3.4', 'port': 80, 'api_key': '1234567890ABCDEF'} with patch('pydeconz.DeconzSession.async_load_parameters', return_value=mock_coro(False)): assert await deconz.async_setup_entry(hass, entry) is False async def test_setup_entry_successful(hass): """Test setup entry is successful.""" entry = MockConfigEntry(domain=deconz.DOMAIN, data={ 'host': '1.2.3.4', 'port': 80, 'api_key': '1234567890ABCDEF' }) entry.add_to_hass(hass) mock_registry = Mock() with patch.object(deconz, 'DeconzGateway') as mock_gateway, \ patch('homeassistant.helpers.device_registry.async_get_registry', return_value=mock_coro(mock_registry)): mock_gateway.return_value.async_setup.return_value = mock_coro(True) assert await deconz.async_setup_entry(hass, entry) is True assert hass.data[deconz.DOMAIN] async def test_unload_entry(hass): """Test being able to unload an entry.""" entry = MockConfigEntry(domain=deconz.DOMAIN, data={ 'host': '1.2.3.4', 'port': 80, 'api_key': '1234567890ABCDEF' }) entry.add_to_hass(hass) mock_registry = Mock() with patch.object(deconz, 'DeconzGateway') as mock_gateway, \ patch('homeassistant.helpers.device_registry.async_get_registry', return_value=mock_coro(mock_registry)): mock_gateway.return_value.async_setup.return_value = mock_coro(True) assert await deconz.async_setup_entry(hass, entry) is True mock_gateway.return_value.async_reset.return_value = mock_coro(True) assert await deconz.async_unload_entry(hass, entry) assert deconz.DOMAIN not in hass.data async def test_service_configure(hass): """Test that service invokes pydeconz with the correct path and data.""" entry = MockConfigEntry(domain=deconz.DOMAIN, data={ 'host': '1.2.3.4', 'port': 80, 'api_key': '1234567890ABCDEF' }) entry.add_to_hass(hass) mock_registry = Mock() with patch.object(deconz, 'DeconzGateway') as mock_gateway, \ patch('homeassistant.helpers.device_registry.async_get_registry', return_value=mock_coro(mock_registry)): mock_gateway.return_value.async_setup.return_value = mock_coro(True) assert await deconz.async_setup_entry(hass, entry) is True hass.data[deconz.DOMAIN].deconz_ids = { 'light.test': '/light/1' } data = {'on': True, 'attr1': 10, 'attr2': 20} # only field with patch('pydeconz.DeconzSession.async_put_state', return_value=mock_coro(True)): await hass.services.async_call('deconz', 'configure', service_data={ 'field': '/light/42', 'data': data }) await hass.async_block_till_done() # only entity with patch('pydeconz.DeconzSession.async_put_state', return_value=mock_coro(True)): await hass.services.async_call('deconz', 'configure', service_data={ 'entity': 'light.test', 'data': data }) await hass.async_block_till_done() # entity + field with patch('pydeconz.DeconzSession.async_put_state', return_value=mock_coro(True)): await hass.services.async_call('deconz', 'configure', service_data={ 'entity': 'light.test', 'field': '/state', 'data': data}) await hass.async_block_till_done() # non-existing entity (or not from deCONZ) with patch('pydeconz.DeconzSession.async_put_state', return_value=mock_coro(True)): await hass.services.async_call('deconz', 'configure', service_data={ 'entity': 'light.nonexisting', 'field': '/state', 'data': data}) await hass.async_block_till_done() # field does not start with / with pytest.raises(vol.Invalid): with patch('pydeconz.DeconzSession.async_put_state', return_value=mock_coro(True)): await hass.services.async_call( 'deconz', 'configure', service_data={ 'entity': 'light.test', 'field': 'state', 'data': data}) await hass.async_block_till_done() async def test_service_refresh_devices(hass): """Test that service can refresh devices.""" entry = MockConfigEntry(domain=deconz.DOMAIN, data={ 'host': '1.2.3.4', 'port': 80, 'api_key': '1234567890ABCDEF' }) entry.add_to_hass(hass) mock_registry = Mock() with patch.object(deconz, 'DeconzGateway') as mock_gateway, \ patch('homeassistant.helpers.device_registry.async_get_registry', return_value=mock_coro(mock_registry)): mock_gateway.return_value.async_setup.return_value = mock_coro(True) assert await deconz.async_setup_entry(hass, entry) is True with patch.object(hass.data[deconz.DOMAIN].api, 'async_load_parameters', return_value=mock_coro(True)): await hass.services.async_call( 'deconz', 'device_refresh', service_data={}) await hass.async_block_till_done() with patch.object(hass.data[deconz.DOMAIN].api, 'async_load_parameters', return_value=mock_coro(False)): await hass.services.async_call( 'deconz', 'device_refresh', service_data={}) await hass.async_block_till_done()