Fix ruckus_unleashed for python 3.11 (#94835)

Co-authored-by: Tony <29752086+ms264556@users.noreply.github.com>
This commit is contained in:
Ian Foster
2023-08-28 17:26:40 +02:00
committed by GitHub
co-authored by Tony
parent 739eeeccb0
commit ef7a246f09
13 changed files with 430 additions and 299 deletions
+149 -54
View File
@@ -1,45 +1,61 @@
"""Tests for the Ruckus Unleashed integration."""
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
from aioruckus import AjaxSession, RuckusAjaxApi
from homeassistant.components.ruckus_unleashed import DOMAIN
from homeassistant.components.ruckus_unleashed.const import (
API_ACCESS_POINT,
API_AP,
API_DEVICE_NAME,
API_ID,
API_IP,
API_MAC,
API_MODEL,
API_NAME,
API_SERIAL,
API_SYSTEM_OVERVIEW,
API_VERSION,
API_AP_DEVNAME,
API_AP_MAC,
API_AP_MODEL,
API_AP_SERIALNUMBER,
API_CLIENT_AP_MAC,
API_CLIENT_HOSTNAME,
API_CLIENT_IP,
API_CLIENT_MAC,
API_MESH_NAME,
API_MESH_PSK,
API_SYS_IDENTITY,
API_SYS_IDENTITY_NAME,
API_SYS_SYSINFO,
API_SYS_SYSINFO_SERIAL,
API_SYS_SYSINFO_VERSION,
API_SYS_UNLEASHEDNETWORK,
API_SYS_UNLEASHEDNETWORK_TOKEN,
DOMAIN,
)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from tests.common import MockConfigEntry
DEFAULT_TITLE = "Ruckus Mesh"
DEFAULT_UNIQUE_ID = "123456789012"
DEFAULT_SYSTEM_INFO = {
API_SYSTEM_OVERVIEW: {
API_SERIAL: DEFAULT_UNIQUE_ID,
API_VERSION: "v1.0.0",
}
API_SYS_IDENTITY: {API_SYS_IDENTITY_NAME: "RuckusUnleashed"},
API_SYS_SYSINFO: {
API_SYS_SYSINFO_SERIAL: "123456789012",
API_SYS_SYSINFO_VERSION: "200.7.10.202 build 141",
},
API_SYS_UNLEASHEDNETWORK: {
API_SYS_UNLEASHEDNETWORK_TOKEN: "un1234567890121680060227001"
},
}
DEFAULT_AP_INFO = {
API_AP: {
API_ID: {
"1": {
API_MAC: "00:11:22:33:44:55",
API_DEVICE_NAME: "Test Device",
API_MODEL: "r510",
}
}
}
DEFAULT_MESH_INFO = {
API_MESH_NAME: "Ruckus Mesh",
API_MESH_PSK: "",
}
DEFAULT_AP_INFO = [
{
API_AP_MAC: "00:11:22:33:44:55",
API_AP_DEVNAME: "Test Device",
API_AP_MODEL: "r510",
API_AP_SERIALNUMBER: DEFAULT_SYSTEM_INFO[API_SYS_SYSINFO][
API_SYS_SYSINFO_SERIAL
],
}
]
CONFIG = {
CONF_HOST: "1.1.1.1",
CONF_USERNAME: "test-username",
@@ -48,25 +64,28 @@ CONFIG = {
TEST_CLIENT_ENTITY_ID = "device_tracker.ruckus_test_device"
TEST_CLIENT = {
API_IP: "1.1.1.2",
API_MAC: "AA:BB:CC:DD:EE:FF",
API_NAME: "Ruckus Test Device",
API_ACCESS_POINT: "00:11:22:33:44:55",
API_CLIENT_IP: "1.1.1.2",
API_CLIENT_MAC: "AA:BB:CC:DD:EE:FF",
API_CLIENT_HOSTNAME: "Ruckus Test Device",
API_CLIENT_AP_MAC: DEFAULT_AP_INFO[0][API_AP_MAC],
}
DEFAULT_TITLE = DEFAULT_MESH_INFO[API_MESH_NAME]
DEFAULT_UNIQUEID = DEFAULT_SYSTEM_INFO[API_SYS_SYSINFO][API_SYS_SYSINFO_SERIAL]
def mock_config_entry() -> MockConfigEntry:
"""Return a Ruckus Unleashed mock config entry."""
return MockConfigEntry(
domain=DOMAIN,
title=DEFAULT_TITLE,
unique_id=DEFAULT_UNIQUE_ID,
unique_id=DEFAULT_UNIQUEID,
data=CONFIG,
options=None,
)
async def init_integration(hass) -> MockConfigEntry:
async def init_integration(hass: HomeAssistant) -> MockConfigEntry:
"""Set up the Ruckus Unleashed integration in Home Assistant."""
entry = mock_config_entry()
entry.add_to_hass(hass)
@@ -76,27 +95,103 @@ async def init_integration(hass) -> MockConfigEntry:
dr.async_get(hass).async_get_or_create(
name="Device from other integration",
config_entry_id=other_config_entry.entry_id,
connections={(dr.CONNECTION_NETWORK_MAC, TEST_CLIENT[API_MAC])},
connections={(dr.CONNECTION_NETWORK_MAC, TEST_CLIENT[API_CLIENT_MAC])},
)
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
return_value=None,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.mesh_name",
return_value=DEFAULT_TITLE,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.system_info",
return_value=DEFAULT_SYSTEM_INFO,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.ap_info",
return_value=DEFAULT_AP_INFO,
), patch(
"homeassistant.components.ruckus_unleashed.RuckusUnleashedDataUpdateCoordinator._fetch_clients",
return_value={
TEST_CLIENT[API_MAC]: TEST_CLIENT,
},
):
with RuckusAjaxApiPatchContext():
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
return entry
class RuckusAjaxApiPatchContext:
"""Context Manager which mocks the Ruckus AjaxSession and RuckusAjaxApi."""
def __init__(
self,
login_mock: AsyncMock = None,
system_info: dict | None = None,
mesh_info: dict | None = None,
active_clients: list[dict] | AsyncMock | None = None,
) -> None:
"""Initialize Ruckus Mock Context Manager."""
self.login_mock = login_mock
self.system_info = system_info
self.mesh_info = mesh_info
self.active_clients = active_clients
self.patchers = []
def __enter__(self):
"""Patch RuckusAjaxApi and AjaxSession methods."""
self.patchers.append(
patch.object(RuckusAjaxApi, "_get_conf", new=AsyncMock(return_value={}))
)
self.patchers.append(
patch.object(
RuckusAjaxApi, "get_aps", new=AsyncMock(return_value=DEFAULT_AP_INFO)
)
)
self.patchers.append(
patch.object(
RuckusAjaxApi,
"get_system_info",
new=AsyncMock(
return_value=DEFAULT_SYSTEM_INFO
if self.system_info is None
else self.system_info
),
)
)
self.patchers.append(
patch.object(
RuckusAjaxApi,
"get_mesh_info",
new=AsyncMock(
return_value=DEFAULT_MESH_INFO
if self.mesh_info is None
else self.mesh_info
),
)
)
self.patchers.append(
patch.object(
RuckusAjaxApi,
"get_active_clients",
new=self.active_clients
if isinstance(self.active_clients, AsyncMock)
else AsyncMock(
return_value=[TEST_CLIENT]
if self.active_clients is None
else self.active_clients
),
)
)
self.patchers.append(
patch.object(
AjaxSession,
"login",
new=self.login_mock or AsyncMock(return_value=self),
)
)
self.patchers.append(
patch.object(AjaxSession, "close", new=AsyncMock(return_value=None))
)
def _patched_async_create(
host: str, username: str, password: str
) -> "AjaxSession":
return AjaxSession(None, host, username, password)
self.patchers.append(
patch.object(AjaxSession, "async_create", new=_patched_async_create)
)
for patcher in self.patchers:
patcher.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""Remove RuckusAjaxApi and AjaxSession patches."""
for patcher in self.patchers:
patcher.stop()
@@ -1,15 +1,21 @@
"""Test the Ruckus Unleashed config flow."""
from datetime import timedelta
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
from pyruckus.exceptions import AuthenticationError
from aioruckus.const import (
ERROR_CONNECT_TEMPORARY,
ERROR_CONNECT_TIMEOUT,
ERROR_LOGIN_INCORRECT,
)
from aioruckus.exceptions import AuthenticationError
from homeassistant import config_entries
from homeassistant import config_entries, data_entry_flow
from homeassistant.components.ruckus_unleashed.const import DOMAIN
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.util import utcnow
from . import CONFIG, DEFAULT_SYSTEM_INFO, DEFAULT_TITLE
from . import CONFIG, DEFAULT_TITLE, RuckusAjaxApiPatchContext, mock_config_entry
from tests.common import async_fire_time_changed
@@ -22,16 +28,7 @@ async def test_form(hass: HomeAssistant) -> None:
assert result["type"] == "form"
assert result["errors"] == {}
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
return_value=None,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.mesh_name",
return_value=DEFAULT_TITLE,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.system_info",
return_value=DEFAULT_SYSTEM_INFO,
), patch(
with RuckusAjaxApiPatchContext(), patch(
"homeassistant.components.ruckus_unleashed.async_setup_entry",
return_value=True,
) as mock_setup_entry:
@@ -41,10 +38,10 @@ async def test_form(hass: HomeAssistant) -> None:
)
await hass.async_block_till_done()
assert result2["type"] == "create_entry"
assert result2["title"] == DEFAULT_TITLE
assert result2["data"] == CONFIG
assert len(mock_setup_entry.mock_calls) == 1
assert result2["type"] == "create_entry"
assert result2["title"] == DEFAULT_TITLE
assert result2["data"] == CONFIG
assert len(mock_setup_entry.mock_calls) == 1
async def test_form_invalid_auth(hass: HomeAssistant) -> None:
@@ -53,9 +50,8 @@ async def test_form_invalid_auth(hass: HomeAssistant) -> None:
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
side_effect=AuthenticationError,
with RuckusAjaxApiPatchContext(
login_mock=AsyncMock(side_effect=AuthenticationError(ERROR_LOGIN_INCORRECT))
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
@@ -66,15 +62,44 @@ async def test_form_invalid_auth(hass: HomeAssistant) -> None:
assert result2["errors"] == {"base": "invalid_auth"}
async def test_form_user_reauth(hass: HomeAssistant) -> None:
"""Test reauth."""
entry = mock_config_entry()
entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_REAUTH}
)
flows = hass.config_entries.flow.async_progress()
assert len(flows) == 1
assert "flow_id" in flows[0]
assert result["type"] == data_entry_flow.FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
result2 = await hass.config_entries.flow.async_configure(
flows[0]["flow_id"],
user_input={
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "new_name",
CONF_PASSWORD: "new_pass",
},
)
await hass.async_block_till_done()
assert result2["type"] == data_entry_flow.FlowResultType.FORM
assert result2["step_id"] == "user"
async def test_form_cannot_connect(hass: HomeAssistant) -> None:
"""Test we handle cannot connect error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
side_effect=ConnectionError,
with RuckusAjaxApiPatchContext(
login_mock=AsyncMock(side_effect=ConnectionError(ERROR_CONNECT_TIMEOUT))
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
@@ -85,15 +110,16 @@ async def test_form_cannot_connect(hass: HomeAssistant) -> None:
assert result2["errors"] == {"base": "cannot_connect"}
async def test_form_unknown_error(hass: HomeAssistant) -> None:
async def test_form_unexpected_response(hass: HomeAssistant) -> None:
"""Test we handle unknown error."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
side_effect=Exception,
with RuckusAjaxApiPatchContext(
login_mock=AsyncMock(
side_effect=ConnectionRefusedError(ERROR_CONNECT_TEMPORARY)
)
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
@@ -101,7 +127,7 @@ async def test_form_unknown_error(hass: HomeAssistant) -> None:
)
assert result2["type"] == "form"
assert result2["errors"] == {"base": "unknown"}
assert result2["errors"] == {"base": "cannot_connect"}
async def test_form_cannot_connect_unknown_serial(hass: HomeAssistant) -> None:
@@ -112,16 +138,7 @@ async def test_form_cannot_connect_unknown_serial(hass: HomeAssistant) -> None:
assert result["type"] == "form"
assert result["errors"] == {}
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
return_value=None,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.mesh_name",
return_value=DEFAULT_TITLE,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.system_info",
return_value={},
):
with RuckusAjaxApiPatchContext(system_info={}):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
@@ -137,16 +154,7 @@ async def test_form_duplicate_error(hass: HomeAssistant) -> None:
DOMAIN, context={"source": config_entries.SOURCE_USER}
)
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
return_value=None,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.mesh_name",
return_value=DEFAULT_TITLE,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.system_info",
return_value=DEFAULT_SYSTEM_INFO,
):
with RuckusAjaxApiPatchContext():
await hass.config_entries.flow.async_configure(
result["flow_id"],
CONFIG,
@@ -1,8 +1,11 @@
"""The sensor tests for the Ruckus Unleashed platform."""
from datetime import timedelta
from unittest.mock import patch
from unittest.mock import AsyncMock
from homeassistant.components.ruckus_unleashed import API_MAC, DOMAIN
from aioruckus.const import ERROR_CONNECT_EOF, ERROR_LOGIN_INCORRECT
from aioruckus.exceptions import AuthenticationError
from homeassistant.components.ruckus_unleashed import DOMAIN
from homeassistant.const import STATE_HOME, STATE_NOT_HOME, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
@@ -10,12 +13,9 @@ from homeassistant.helpers.entity_component import async_update_entity
from homeassistant.util import utcnow
from . import (
DEFAULT_AP_INFO,
DEFAULT_SYSTEM_INFO,
DEFAULT_TITLE,
DEFAULT_UNIQUE_ID,
TEST_CLIENT,
DEFAULT_UNIQUEID,
TEST_CLIENT_ENTITY_ID,
RuckusAjaxApiPatchContext,
init_integration,
mock_config_entry,
)
@@ -28,12 +28,7 @@ async def test_client_connected(hass: HomeAssistant) -> None:
await init_integration(hass)
future = utcnow() + timedelta(minutes=60)
with patch(
"homeassistant.components.ruckus_unleashed.RuckusUnleashedDataUpdateCoordinator._fetch_clients",
return_value={
TEST_CLIENT[API_MAC]: TEST_CLIENT,
},
):
with RuckusAjaxApiPatchContext():
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
await async_update_entity(hass, TEST_CLIENT_ENTITY_ID)
@@ -47,10 +42,7 @@ async def test_client_disconnected(hass: HomeAssistant) -> None:
await init_integration(hass)
future = utcnow() + timedelta(minutes=60)
with patch(
"homeassistant.components.ruckus_unleashed.RuckusUnleashedDataUpdateCoordinator._fetch_clients",
return_value={},
):
with RuckusAjaxApiPatchContext(active_clients={}):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
@@ -64,9 +56,24 @@ async def test_clients_update_failed(hass: HomeAssistant) -> None:
await init_integration(hass)
future = utcnow() + timedelta(minutes=60)
with patch(
"homeassistant.components.ruckus_unleashed.RuckusUnleashedDataUpdateCoordinator._fetch_clients",
side_effect=ConnectionError,
with RuckusAjaxApiPatchContext(
active_clients=AsyncMock(side_effect=ConnectionError(ERROR_CONNECT_EOF))
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
await async_update_entity(hass, TEST_CLIENT_ENTITY_ID)
test_client = hass.states.get(TEST_CLIENT_ENTITY_ID)
assert test_client.state == STATE_UNAVAILABLE
async def test_clients_update_auth_failed(hass: HomeAssistant) -> None:
"""Test failed update with bad auth."""
await init_integration(hass)
future = utcnow() + timedelta(minutes=60)
with RuckusAjaxApiPatchContext(
active_clients=AsyncMock(side_effect=AuthenticationError(ERROR_LOGIN_INCORRECT))
):
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
@@ -85,27 +92,12 @@ async def test_restoring_clients(hass: HomeAssistant) -> None:
registry.async_get_or_create(
"device_tracker",
DOMAIN,
DEFAULT_UNIQUE_ID,
DEFAULT_UNIQUEID,
suggested_object_id="ruckus_test_device",
config_entry=entry,
)
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
return_value=None,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.mesh_name",
return_value=DEFAULT_TITLE,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.system_info",
return_value=DEFAULT_SYSTEM_INFO,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.ap_info",
return_value=DEFAULT_AP_INFO,
), patch(
"homeassistant.components.ruckus_unleashed.RuckusUnleashedDataUpdateCoordinator._fetch_clients",
return_value={},
):
with RuckusAjaxApiPatchContext(active_clients={}):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
+27 -50
View File
@@ -1,18 +1,16 @@
"""Test the Ruckus Unleashed config flow."""
from unittest.mock import patch
from unittest.mock import AsyncMock
from pyruckus.exceptions import AuthenticationError
from aioruckus.const import ERROR_CONNECT_TIMEOUT, ERROR_LOGIN_INCORRECT
from aioruckus.exceptions import AuthenticationError
from homeassistant.components.ruckus_unleashed import (
API_AP,
API_DEVICE_NAME,
API_ID,
API_MAC,
API_MODEL,
API_SYSTEM_OVERVIEW,
API_VERSION,
DOMAIN,
MANUFACTURER,
from homeassistant.components.ruckus_unleashed import DOMAIN, MANUFACTURER
from homeassistant.components.ruckus_unleashed.const import (
API_AP_DEVNAME,
API_AP_MAC,
API_AP_MODEL,
API_SYS_SYSINFO,
API_SYS_SYSINFO_VERSION,
)
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
@@ -22,7 +20,7 @@ from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from . import (
DEFAULT_AP_INFO,
DEFAULT_SYSTEM_INFO,
DEFAULT_TITLE,
RuckusAjaxApiPatchContext,
init_integration,
mock_config_entry,
)
@@ -31,9 +29,8 @@ from . import (
async def test_setup_entry_login_error(hass: HomeAssistant) -> None:
"""Test entry setup failed due to login error."""
entry = mock_config_entry()
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
side_effect=AuthenticationError,
with RuckusAjaxApiPatchContext(
login_mock=AsyncMock(side_effect=AuthenticationError(ERROR_LOGIN_INCORRECT))
):
entry.add_to_hass(hass)
result = await hass.config_entries.async_setup(entry.entry_id)
@@ -45,9 +42,8 @@ async def test_setup_entry_login_error(hass: HomeAssistant) -> None:
async def test_setup_entry_connection_error(hass: HomeAssistant) -> None:
"""Test entry setup failed due to connection error."""
entry = mock_config_entry()
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
side_effect=ConnectionError,
with RuckusAjaxApiPatchContext(
login_mock=AsyncMock(side_effect=ConnectionError(ERROR_CONNECT_TIMEOUT))
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
@@ -60,19 +56,22 @@ async def test_router_device_setup(hass: HomeAssistant) -> None:
"""Test a router device is created."""
await init_integration(hass)
device_info = DEFAULT_AP_INFO[API_AP][API_ID]["1"]
device_info = DEFAULT_AP_INFO[0]
device_registry = dr.async_get(hass)
device = device_registry.async_get_device(
identifiers={(CONNECTION_NETWORK_MAC, device_info[API_MAC])},
connections={(CONNECTION_NETWORK_MAC, device_info[API_MAC])},
identifiers={(CONNECTION_NETWORK_MAC, device_info[API_AP_MAC])},
connections={(CONNECTION_NETWORK_MAC, device_info[API_AP_MAC])},
)
assert device
assert device.manufacturer == MANUFACTURER
assert device.model == device_info[API_MODEL]
assert device.name == device_info[API_DEVICE_NAME]
assert device.sw_version == DEFAULT_SYSTEM_INFO[API_SYSTEM_OVERVIEW][API_VERSION]
assert device.model == device_info[API_AP_MODEL]
assert device.name == device_info[API_AP_DEVNAME]
assert (
device.sw_version
== DEFAULT_SYSTEM_INFO[API_SYS_SYSINFO][API_SYS_SYSINFO_VERSION]
)
assert device.via_device_id is None
@@ -83,31 +82,9 @@ async def test_unload_entry(hass: HomeAssistant) -> None:
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert entry.state is ConfigEntryState.LOADED
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
with RuckusAjaxApiPatchContext():
assert await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.NOT_LOADED
assert not hass.data.get(DOMAIN)
async def test_config_not_ready_during_setup(hass: HomeAssistant) -> None:
"""Test we throw a ConfigNotReady if Coordinator update fails."""
entry = mock_config_entry()
with patch(
"homeassistant.components.ruckus_unleashed.Ruckus.connect",
return_value=None,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.mesh_name",
return_value=DEFAULT_TITLE,
), patch(
"homeassistant.components.ruckus_unleashed.Ruckus.system_info",
return_value=DEFAULT_SYSTEM_INFO,
), patch(
"homeassistant.components.ruckus_unleashed.RuckusUnleashedDataUpdateCoordinator._async_update_data",
side_effect=ConnectionError,
):
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.SETUP_RETRY