"""Test deCONZ component setup process.""" import asyncio from unittest.mock import patch import pydeconz import pytest from homeassistant.components.deconz.const import ( CONF_MASTER_GATEWAY, DOMAIN as DECONZ_DOMAIN, ) from homeassistant.components.deconz.errors import AuthenticationRequired from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant from .conftest import ConfigEntryFactoryType from tests.common import MockConfigEntry async def test_setup_entry(config_entry_setup: MockConfigEntry) -> None: """Test successful setup of entry.""" assert config_entry_setup.state is ConfigEntryState.LOADED assert config_entry_setup.options[CONF_MASTER_GATEWAY] is True @pytest.mark.parametrize( ("side_effect", "state"), [ # Failed authentication trigger a reauthentication flow (pydeconz.Unauthorized, ConfigEntryState.SETUP_ERROR), # Connection fails (TimeoutError, ConfigEntryState.SETUP_RETRY), (pydeconz.RequestError, ConfigEntryState.SETUP_RETRY), (pydeconz.ResponseError, ConfigEntryState.SETUP_RETRY), ], ) async def test_get_deconz_api_fails( hass: HomeAssistant, config_entry: MockConfigEntry, side_effect: Exception, state: ConfigEntryState, ) -> None: """Failed setup.""" config_entry.add_to_hass(hass) with patch( "homeassistant.components.deconz.hub.api.DeconzSession.refresh_state", side_effect=side_effect, ): await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() assert config_entry.state is state async def test_setup_entry_fails_trigger_reauth_flow( hass: HomeAssistant, config_entry_factory: ConfigEntryFactoryType ) -> None: """Failed authentication trigger a reauthentication flow.""" with ( patch( "homeassistant.components.deconz.get_deconz_api", side_effect=AuthenticationRequired, ), patch.object(hass.config_entries.flow, "async_init") as mock_flow_init, ): config_entry = await config_entry_factory() mock_flow_init.assert_called_once() assert config_entry.state is ConfigEntryState.SETUP_ERROR async def test_setup_entry_multiple_gateways( hass: HomeAssistant, config_entry_factory: ConfigEntryFactoryType ) -> None: """Test setup entry is successful with multiple gateways.""" config_entry = await config_entry_factory() entry2 = MockConfigEntry( domain=DECONZ_DOMAIN, entry_id="2", unique_id="01234E56789B", data=config_entry.data | {"host": "2.3.4.5"}, ) config_entry2 = await config_entry_factory(entry2) assert config_entry.state is ConfigEntryState.LOADED assert config_entry2.state is ConfigEntryState.LOADED assert config_entry.options[CONF_MASTER_GATEWAY] is True assert config_entry2.options[CONF_MASTER_GATEWAY] is False async def test_unload_entry( hass: HomeAssistant, config_entry_setup: MockConfigEntry ) -> None: """Test being able to unload an entry.""" assert config_entry_setup.state is ConfigEntryState.LOADED assert await hass.config_entries.async_unload(config_entry_setup.entry_id) assert config_entry_setup.state is ConfigEntryState.NOT_LOADED async def test_unload_entry_multiple_gateways( hass: HomeAssistant, config_entry_factory: ConfigEntryFactoryType ) -> None: """Test being able to unload an entry and master gateway gets moved.""" config_entry = await config_entry_factory() entry2 = MockConfigEntry( domain=DECONZ_DOMAIN, entry_id="2", unique_id="01234E56789B", data=config_entry.data | {"host": "2.3.4.5"}, ) config_entry2 = await config_entry_factory(entry2) assert config_entry.state is ConfigEntryState.LOADED assert config_entry2.state is ConfigEntryState.LOADED assert await hass.config_entries.async_unload(config_entry.entry_id) assert config_entry.state is ConfigEntryState.NOT_LOADED assert config_entry2.options[CONF_MASTER_GATEWAY] is True async def test_unload_entry_multiple_gateways_parallel( hass: HomeAssistant, config_entry_factory: ConfigEntryFactoryType ) -> None: """Test race condition when unloading multiple config entries in parallel.""" config_entry = await config_entry_factory() entry2 = MockConfigEntry( domain=DECONZ_DOMAIN, entry_id="2", unique_id="01234E56789B", data=config_entry.data | {"host": "2.3.4.5"}, ) config_entry2 = await config_entry_factory(entry2) assert config_entry.state is ConfigEntryState.LOADED assert config_entry2.state is ConfigEntryState.LOADED await asyncio.gather( hass.config_entries.async_unload(config_entry.entry_id), hass.config_entries.async_unload(config_entry2.entry_id), ) assert config_entry.state is ConfigEntryState.NOT_LOADED assert config_entry2.state is ConfigEntryState.NOT_LOADED