Improve UniFi config flow tests (#118587)

* Use proper fixtures in config flow tests

* Improve rest of config flow tests

* Small improvement

* Rename fixtures
This commit is contained in:
Robert Svensson 2024-06-01 00:27:53 +02:00 committed by GitHub
parent 738935a73a
commit 3232fd0eaf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 105 additions and 216 deletions

View File

@ -87,7 +87,6 @@ def config_entry_fixture(
unique_id="1", unique_id="1",
data=config_entry_data, data=config_entry_data,
options=config_entry_options, options=config_entry_options,
version=1,
) )
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
return config_entry return config_entry
@ -112,8 +111,8 @@ def config_entry_options_fixture() -> MappingProxyType[str, Any]:
return {} return {}
@pytest.fixture(name="mock_unifi_requests") @pytest.fixture(name="mock_requests")
def default_request_fixture( def request_fixture(
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
client_payload: list[dict[str, Any]], client_payload: list[dict[str, Any]],
clients_all_payload: list[dict[str, Any]], clients_all_payload: list[dict[str, Any]],
@ -127,7 +126,7 @@ def default_request_fixture(
) -> Callable[[str], None]: ) -> Callable[[str], None]:
"""Mock default UniFi requests responses.""" """Mock default UniFi requests responses."""
def __mock_default_requests(host: str, site_id: str) -> None: def __mock_requests(host: str = DEFAULT_HOST, site_id: str = DEFAULT_SITE) -> None:
url = f"https://{host}:{DEFAULT_PORT}" url = f"https://{host}:{DEFAULT_PORT}"
def mock_get_request(path: str, payload: list[dict[str, Any]]) -> None: def mock_get_request(path: str, payload: list[dict[str, Any]]) -> None:
@ -153,7 +152,7 @@ def default_request_fixture(
mock_get_request(f"/api/s/{site_id}/stat/sysinfo", system_information_payload) mock_get_request(f"/api/s/{site_id}/stat/sysinfo", system_information_payload)
mock_get_request(f"/api/s/{site_id}/rest/wlanconf", wlan_payload) mock_get_request(f"/api/s/{site_id}/rest/wlanconf", wlan_payload)
return __mock_default_requests return __mock_requests
# Request payload fixtures # Request payload fixtures
@ -229,22 +228,24 @@ def wlan_data_fixture() -> list[dict[str, Any]]:
return [] return []
@pytest.fixture(name="setup_default_unifi_requests") @pytest.fixture(name="mock_default_requests")
def default_vapix_requests_fixture( def default_requests_fixture(
config_entry: ConfigEntry, mock_requests: Callable[[str, str], None],
mock_unifi_requests: Callable[[str, str], None],
) -> None: ) -> None:
"""Mock default UniFi requests responses.""" """Mock UniFi requests responses with default host and site."""
mock_unifi_requests(config_entry.data[CONF_HOST], config_entry.data[CONF_SITE_ID]) mock_requests(DEFAULT_HOST, DEFAULT_SITE)
@pytest.fixture(name="prepare_config_entry") @pytest.fixture(name="config_entry_factory")
async def prep_config_entry_fixture( async def config_entry_factory_fixture(
hass: HomeAssistant, config_entry: ConfigEntry, setup_default_unifi_requests: None hass: HomeAssistant,
config_entry: ConfigEntry,
mock_requests: Callable[[str, str], None],
) -> Callable[[], ConfigEntry]: ) -> Callable[[], ConfigEntry]:
"""Fixture factory to set up UniFi network integration.""" """Fixture factory that can set up UniFi network integration."""
async def __mock_setup_config_entry() -> ConfigEntry: async def __mock_setup_config_entry() -> ConfigEntry:
mock_requests(config_entry.data[CONF_HOST], config_entry.data[CONF_SITE_ID])
await hass.config_entries.async_setup(config_entry.entry_id) await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
return config_entry return config_entry
@ -252,12 +253,12 @@ async def prep_config_entry_fixture(
return __mock_setup_config_entry return __mock_setup_config_entry
@pytest.fixture(name="setup_config_entry") @pytest.fixture(name="config_entry_setup")
async def setup_config_entry_fixture( async def config_entry_setup_fixture(
hass: HomeAssistant, prepare_config_entry: Callable[[], ConfigEntry] hass: HomeAssistant, config_entry_factory: Callable[[], ConfigEntry]
) -> ConfigEntry: ) -> ConfigEntry:
"""Fixture to set up UniFi network integration.""" """Fixture providing a set up instance of UniFi network integration."""
return await prepare_config_entry() return await config_entry_factory()
# Websocket fixtures # Websocket fixtures

View File

@ -83,11 +83,11 @@ async def test_restart_device_button(
hass: HomeAssistant, hass: HomeAssistant,
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
setup_config_entry, config_entry_setup,
websocket_mock, websocket_mock,
) -> None: ) -> None:
"""Test restarting device button.""" """Test restarting device button."""
config_entry = setup_config_entry config_entry = config_entry_setup
assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == 1 assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == 1
ent_reg_entry = entity_registry.async_get("button.switch_restart") ent_reg_entry = entity_registry.async_get("button.switch_restart")
@ -169,11 +169,11 @@ async def test_power_cycle_poe(
hass: HomeAssistant, hass: HomeAssistant,
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
setup_config_entry, config_entry_setup,
websocket_mock, websocket_mock,
) -> None: ) -> None:
"""Test restarting device button.""" """Test restarting device button."""
config_entry = setup_config_entry config_entry = config_entry_setup
assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == 2 assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == 2
ent_reg_entry = entity_registry.async_get("button.switch_port_1_power_cycle") ent_reg_entry = entity_registry.async_get("button.switch_port_1_power_cycle")
@ -225,11 +225,11 @@ async def test_wlan_regenerate_password(
hass: HomeAssistant, hass: HomeAssistant,
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
setup_config_entry, config_entry_setup,
websocket_mock, websocket_mock,
) -> None: ) -> None:
"""Test WLAN regenerate password button.""" """Test WLAN regenerate password button."""
config_entry = setup_config_entry config_entry = config_entry_setup
assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == 0 assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == 0
button_regenerate_password = "button.ssid_1_regenerate_password" button_regenerate_password = "button.ssid_1_regenerate_password"

View File

@ -1,9 +1,10 @@
"""Test UniFi Network config flow.""" """Test UniFi Network config flow."""
import socket import socket
from unittest.mock import patch from unittest.mock import PropertyMock, patch
import aiounifi import aiounifi
import pytest
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components import ssdp from homeassistant.components import ssdp
@ -23,20 +24,17 @@ from homeassistant.components.unifi.const import (
CONF_TRACK_WIRED_CLIENTS, CONF_TRACK_WIRED_CLIENTS,
DOMAIN as UNIFI_DOMAIN, DOMAIN as UNIFI_DOMAIN,
) )
from homeassistant.config_entries import SOURCE_REAUTH from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_HOST,
CONF_PASSWORD, CONF_PASSWORD,
CONF_PORT, CONF_PORT,
CONF_USERNAME, CONF_USERNAME,
CONF_VERIFY_SSL, CONF_VERIFY_SSL,
CONTENT_TYPE_JSON,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
from .test_hub import setup_unifi_integration
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker
@ -98,7 +96,7 @@ DPI_GROUPS = [
async def test_flow_works( async def test_flow_works(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, mock_discovery hass: HomeAssistant, mock_discovery, mock_default_requests: None
) -> None: ) -> None:
"""Test config flow.""" """Test config flow."""
mock_discovery.return_value = "1" mock_discovery.return_value = "1"
@ -116,25 +114,6 @@ async def test_flow_works(
CONF_VERIFY_SSL: False, CONF_VERIFY_SSL: False,
} }
aioclient_mock.get("https://1.2.3.4:1234", status=302)
aioclient_mock.post(
"https://1.2.3.4:1234/api/login",
json={"data": "login successful", "meta": {"rc": "ok"}},
headers={"content-type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
"https://1.2.3.4:1234/api/self/sites",
json={
"data": [
{"desc": "Site name", "name": "site_id", "role": "admin", "_id": "1"}
],
"meta": {"rc": "ok"},
},
headers={"content-type": CONTENT_TYPE_JSON},
)
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
user_input={ user_input={
@ -159,7 +138,7 @@ async def test_flow_works(
async def test_flow_works_negative_discovery( async def test_flow_works_negative_discovery(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, mock_discovery hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None: ) -> None:
"""Test config flow with a negative outcome of async_discovery_unifi.""" """Test config flow with a negative outcome of async_discovery_unifi."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
@ -177,8 +156,17 @@ async def test_flow_works_negative_discovery(
} }
@pytest.mark.parametrize(
"site_payload",
[
[
{"name": "default", "role": "admin", "desc": "site name", "_id": "1"},
{"name": "site2", "role": "admin", "desc": "site2 name", "_id": "2"},
]
],
)
async def test_flow_multiple_sites( async def test_flow_multiple_sites(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, mock_default_requests: None
) -> None: ) -> None:
"""Test config flow works when finding multiple sites.""" """Test config flow works when finding multiple sites."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
@ -188,26 +176,6 @@ async def test_flow_multiple_sites(
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
aioclient_mock.get("https://1.2.3.4:1234", status=302)
aioclient_mock.post(
"https://1.2.3.4:1234/api/login",
json={"data": "login successful", "meta": {"rc": "ok"}},
headers={"content-type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
"https://1.2.3.4:1234/api/self/sites",
json={
"data": [
{"name": "default", "role": "admin", "desc": "site name", "_id": "1"},
{"name": "site2", "role": "admin", "desc": "site2 name", "_id": "2"},
],
"meta": {"rc": "ok"},
},
headers={"content-type": CONTENT_TYPE_JSON},
)
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
user_input={ user_input={
@ -226,11 +194,9 @@ async def test_flow_multiple_sites(
async def test_flow_raise_already_configured( async def test_flow_raise_already_configured(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, config_entry_setup: ConfigEntry
) -> None: ) -> None:
"""Test config flow aborts since a connected config entry already exists.""" """Test config flow aborts since a connected config entry already exists."""
await setup_unifi_integration(hass, aioclient_mock)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
UNIFI_DOMAIN, context={"source": config_entries.SOURCE_USER} UNIFI_DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
@ -238,27 +204,6 @@ async def test_flow_raise_already_configured(
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
aioclient_mock.clear_requests()
aioclient_mock.get("https://1.2.3.4:1234", status=302)
aioclient_mock.post(
"https://1.2.3.4:1234/api/login",
json={"data": "login successful", "meta": {"rc": "ok"}},
headers={"content-type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
"https://1.2.3.4:1234/api/self/sites",
json={
"data": [
{"desc": "Site name", "name": "site_id", "role": "admin", "_id": "1"}
],
"meta": {"rc": "ok"},
},
headers={"content-type": CONTENT_TYPE_JSON},
)
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
user_input={ user_input={
@ -275,15 +220,9 @@ async def test_flow_raise_already_configured(
async def test_flow_aborts_configuration_updated( async def test_flow_aborts_configuration_updated(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, config_entry_setup: ConfigEntry
) -> None: ) -> None:
"""Test config flow aborts since a connected config entry already exists.""" """Test config flow aborts since a connected config entry already exists."""
entry = MockConfigEntry(
domain=UNIFI_DOMAIN, data={"host": "1.2.3.4", "site": "site_id"}, unique_id="1"
)
entry.add_to_hass(hass)
entry.runtime_data = None
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
UNIFI_DOMAIN, context={"source": config_entries.SOURCE_USER} UNIFI_DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
@ -291,33 +230,17 @@ async def test_flow_aborts_configuration_updated(
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
aioclient_mock.get("https://1.2.3.4:1234", status=302) with patch("homeassistant.components.unifi.async_setup_entry") and patch(
"homeassistant.components.unifi.UnifiHub.available", new_callable=PropertyMock
aioclient_mock.post( ) as ws_mock:
"https://1.2.3.4:1234/api/login", ws_mock.return_value = False
json={"data": "login successful", "meta": {"rc": "ok"}},
headers={"content-type": CONTENT_TYPE_JSON},
)
aioclient_mock.get(
"https://1.2.3.4:1234/api/self/sites",
json={
"data": [
{"desc": "Site name", "name": "site_id", "role": "admin", "_id": "1"}
],
"meta": {"rc": "ok"},
},
headers={"content-type": CONTENT_TYPE_JSON},
)
with patch("homeassistant.components.unifi.async_setup_entry"):
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
user_input={ user_input={
CONF_HOST: "1.2.3.4", CONF_HOST: "1.2.3.4",
CONF_USERNAME: "username", CONF_USERNAME: "username",
CONF_PASSWORD: "password", CONF_PASSWORD: "password",
CONF_PORT: 1234, CONF_PORT: 12345,
CONF_VERIFY_SSL: True, CONF_VERIFY_SSL: True,
}, },
) )
@ -327,7 +250,7 @@ async def test_flow_aborts_configuration_updated(
async def test_flow_fails_user_credentials_faulty( async def test_flow_fails_user_credentials_faulty(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, mock_default_requests: None
) -> None: ) -> None:
"""Test config flow.""" """Test config flow."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
@ -337,8 +260,6 @@ async def test_flow_fails_user_credentials_faulty(
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
aioclient_mock.get("https://1.2.3.4:1234", status=302)
with patch("aiounifi.Controller.login", side_effect=aiounifi.errors.Unauthorized): with patch("aiounifi.Controller.login", side_effect=aiounifi.errors.Unauthorized):
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
@ -356,7 +277,7 @@ async def test_flow_fails_user_credentials_faulty(
async def test_flow_fails_hub_unavailable( async def test_flow_fails_hub_unavailable(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, mock_default_requests: None
) -> None: ) -> None:
"""Test config flow.""" """Test config flow."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
@ -366,8 +287,6 @@ async def test_flow_fails_hub_unavailable(
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
aioclient_mock.get("https://1.2.3.4:1234", status=302)
with patch("aiounifi.Controller.login", side_effect=aiounifi.errors.RequestError): with patch("aiounifi.Controller.login", side_effect=aiounifi.errors.RequestError):
result = await hass.config_entries.flow.async_configure( result = await hass.config_entries.flow.async_configure(
result["flow_id"], result["flow_id"],
@ -385,12 +304,10 @@ async def test_flow_fails_hub_unavailable(
async def test_reauth_flow_update_configuration( async def test_reauth_flow_update_configuration(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, config_entry_setup: ConfigEntry
) -> None: ) -> None:
"""Verify reauth flow can update hub configuration.""" """Verify reauth flow can update hub configuration."""
config_entry = await setup_unifi_integration(hass, aioclient_mock) config_entry = config_entry_setup
hub = config_entry.runtime_data
hub.websocket.available = False
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
UNIFI_DOMAIN, UNIFI_DOMAIN,
@ -405,37 +322,20 @@ async def test_reauth_flow_update_configuration(
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
aioclient_mock.clear_requests() with patch(
"homeassistant.components.unifi.UnifiHub.available", new_callable=PropertyMock
aioclient_mock.get("https://1.2.3.4:1234", status=302) ) as ws_mock:
ws_mock.return_value = False
aioclient_mock.post( result = await hass.config_entries.flow.async_configure(
"https://1.2.3.4:1234/api/login", result["flow_id"],
json={"data": "login successful", "meta": {"rc": "ok"}}, user_input={
headers={"content-type": CONTENT_TYPE_JSON}, CONF_HOST: "1.2.3.4",
) CONF_USERNAME: "new_name",
CONF_PASSWORD: "new_pass",
aioclient_mock.get( CONF_PORT: 1234,
"https://1.2.3.4:1234/api/self/sites", CONF_VERIFY_SSL: True,
json={ },
"data": [ )
{"desc": "Site name", "name": "site_id", "role": "admin", "_id": "1"}
],
"meta": {"rc": "ok"},
},
headers={"content-type": CONTENT_TYPE_JSON},
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "new_name",
CONF_PASSWORD: "new_pass",
CONF_PORT: 1234,
CONF_VERIFY_SSL: True,
},
)
assert result["type"] is FlowResultType.ABORT assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful" assert result["reason"] == "reauth_successful"
@ -444,19 +344,15 @@ async def test_reauth_flow_update_configuration(
assert config_entry.data[CONF_PASSWORD] == "new_pass" assert config_entry.data[CONF_PASSWORD] == "new_pass"
@pytest.mark.parametrize("client_payload", [CLIENTS])
@pytest.mark.parametrize("device_payload", [DEVICES])
@pytest.mark.parametrize("wlan_payload", [WLANS])
@pytest.mark.parametrize("dpi_group_payload", [DPI_GROUPS])
async def test_advanced_option_flow( async def test_advanced_option_flow(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, config_entry_setup: ConfigEntry
) -> None: ) -> None:
"""Test advanced config flow options.""" """Test advanced config flow options."""
config_entry = await setup_unifi_integration( config_entry = config_entry_setup
hass,
aioclient_mock,
clients_response=CLIENTS,
devices_response=DEVICES,
wlans_response=WLANS,
dpigroup_response=DPI_GROUPS,
dpiapp_response=[],
)
result = await hass.config_entries.options.async_init( result = await hass.config_entries.options.async_init(
config_entry.entry_id, context={"show_advanced_options": True} config_entry.entry_id, context={"show_advanced_options": True}
@ -535,13 +431,12 @@ async def test_advanced_option_flow(
} }
@pytest.mark.parametrize("client_payload", [CLIENTS])
async def test_simple_option_flow( async def test_simple_option_flow(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, config_entry_setup: ConfigEntry
) -> None: ) -> None:
"""Test simple config flow options.""" """Test simple config flow options."""
config_entry = await setup_unifi_integration( config_entry = config_entry_setup
hass, aioclient_mock, clients_response=CLIENTS
)
result = await hass.config_entries.options.async_init( result = await hass.config_entries.options.async_init(
config_entry.entry_id, context={"show_advanced_options": False} config_entry.entry_id, context={"show_advanced_options": False}
@ -608,21 +503,18 @@ async def test_form_ssdp(hass: HomeAssistant) -> None:
} }
async def test_form_ssdp_aborts_if_host_already_exists(hass: HomeAssistant) -> None: async def test_form_ssdp_aborts_if_host_already_exists(
hass: HomeAssistant, config_entry: ConfigEntry
) -> None:
"""Test we abort if the host is already configured.""" """Test we abort if the host is already configured."""
entry = MockConfigEntry(
domain=UNIFI_DOMAIN,
data={"host": "192.168.208.1", "site": "site_id"},
)
entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
UNIFI_DOMAIN, UNIFI_DOMAIN,
context={"source": config_entries.SOURCE_SSDP}, context={"source": config_entries.SOURCE_SSDP},
data=ssdp.SsdpServiceInfo( data=ssdp.SsdpServiceInfo(
ssdp_usn="mock_usn", ssdp_usn="mock_usn",
ssdp_st="mock_st", ssdp_st="mock_st",
ssdp_location="http://192.168.208.1:41417/rootDesc.xml", ssdp_location="http://1.2.3.4:1234/rootDesc.xml",
upnp={ upnp={
"friendlyName": "UniFi Dream Machine", "friendlyName": "UniFi Dream Machine",
"modelDescription": "UniFi Dream Machine Pro", "modelDescription": "UniFi Dream Machine Pro",
@ -634,26 +526,22 @@ async def test_form_ssdp_aborts_if_host_already_exists(hass: HomeAssistant) -> N
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
async def test_form_ssdp_aborts_if_serial_already_exists(hass: HomeAssistant) -> None: async def test_form_ssdp_aborts_if_serial_already_exists(
hass: HomeAssistant, config_entry: ConfigEntry
) -> None:
"""Test we abort if the serial is already configured.""" """Test we abort if the serial is already configured."""
entry = MockConfigEntry(
domain=UNIFI_DOMAIN,
data={"controller": {"host": "1.2.3.4", "site": "site_id"}},
unique_id="e0:63:da:20:14:a9",
)
entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
UNIFI_DOMAIN, UNIFI_DOMAIN,
context={"source": config_entries.SOURCE_SSDP}, context={"source": config_entries.SOURCE_SSDP},
data=ssdp.SsdpServiceInfo( data=ssdp.SsdpServiceInfo(
ssdp_usn="mock_usn", ssdp_usn="mock_usn",
ssdp_st="mock_st", ssdp_st="mock_st",
ssdp_location="http://192.168.208.1:41417/rootDesc.xml", ssdp_location="http://1.2.3.4:1234/rootDesc.xml",
upnp={ upnp={
"friendlyName": "UniFi Dream Machine", "friendlyName": "UniFi Dream Machine",
"modelDescription": "UniFi Dream Machine Pro", "modelDescription": "UniFi Dream Machine Pro",
"serialNumber": "e0:63:da:20:14:a9", "serialNumber": "1",
}, },
), ),
) )
@ -662,7 +550,7 @@ async def test_form_ssdp_aborts_if_serial_already_exists(hass: HomeAssistant) ->
async def test_form_ssdp_gets_form_with_ignored_entry(hass: HomeAssistant) -> None: async def test_form_ssdp_gets_form_with_ignored_entry(hass: HomeAssistant) -> None:
"""Test we can still setup if there is an ignored entry.""" """Test we can still setup if there is an ignored never configured entry."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain=UNIFI_DOMAIN, domain=UNIFI_DOMAIN,
@ -676,11 +564,11 @@ async def test_form_ssdp_gets_form_with_ignored_entry(hass: HomeAssistant) -> No
data=ssdp.SsdpServiceInfo( data=ssdp.SsdpServiceInfo(
ssdp_usn="mock_usn", ssdp_usn="mock_usn",
ssdp_st="mock_st", ssdp_st="mock_st",
ssdp_location="http://1.2.3.4:41417/rootDesc.xml", ssdp_location="http://1.2.3.4:1234/rootDesc.xml",
upnp={ upnp={
"friendlyName": "UniFi Dream Machine New", "friendlyName": "UniFi Dream Machine New",
"modelDescription": "UniFi Dream Machine Pro", "modelDescription": "UniFi Dream Machine Pro",
"serialNumber": "e0:63:da:20:14:a9", "serialNumber": "1",
}, },
), ),
) )

View File

@ -239,14 +239,14 @@ async def setup_unifi_integration(
async def test_hub_setup( async def test_hub_setup(
device_registry: dr.DeviceRegistry, device_registry: dr.DeviceRegistry,
prepare_config_entry: Callable[[], ConfigEntry], config_entry_factory: Callable[[], ConfigEntry],
) -> None: ) -> None:
"""Successful setup.""" """Successful setup."""
with patch( with patch(
"homeassistant.config_entries.ConfigEntries.async_forward_entry_setups", "homeassistant.config_entries.ConfigEntries.async_forward_entry_setups",
return_value=True, return_value=True,
) as forward_entry_setup: ) as forward_entry_setup:
config_entry = await prepare_config_entry() config_entry = await config_entry_factory()
hub = config_entry.runtime_data hub = config_entry.runtime_data
entry = hub.config.entry entry = hub.config.entry
@ -288,10 +288,10 @@ async def test_hub_setup(
async def test_reset_after_successful_setup( async def test_reset_after_successful_setup(
hass: HomeAssistant, setup_config_entry: ConfigEntry hass: HomeAssistant, config_entry_setup: ConfigEntry
) -> None: ) -> None:
"""Calling reset when the entry has been setup.""" """Calling reset when the entry has been setup."""
config_entry = setup_config_entry config_entry = config_entry_setup
assert config_entry.state is ConfigEntryState.LOADED assert config_entry.state is ConfigEntryState.LOADED
assert await hass.config_entries.async_unload(config_entry.entry_id) assert await hass.config_entries.async_unload(config_entry.entry_id)
@ -299,10 +299,10 @@ async def test_reset_after_successful_setup(
async def test_reset_fails( async def test_reset_fails(
hass: HomeAssistant, setup_config_entry: ConfigEntry hass: HomeAssistant, config_entry_setup: ConfigEntry
) -> None: ) -> None:
"""Calling reset when the entry has been setup can return false.""" """Calling reset when the entry has been setup can return false."""
config_entry = setup_config_entry config_entry = config_entry_setup
assert config_entry.state is ConfigEntryState.LOADED assert config_entry.state is ConfigEntryState.LOADED
with patch( with patch(
@ -330,7 +330,7 @@ async def test_reset_fails(
async def test_connection_state_signalling( async def test_connection_state_signalling(
hass: HomeAssistant, hass: HomeAssistant,
mock_device_registry, mock_device_registry,
setup_config_entry: ConfigEntry, config_entry_setup: ConfigEntry,
websocket_mock, websocket_mock,
) -> None: ) -> None:
"""Verify connection statesignalling and connection state are working.""" """Verify connection statesignalling and connection state are working."""
@ -349,7 +349,7 @@ async def test_connection_state_signalling(
async def test_reconnect_mechanism( async def test_reconnect_mechanism(
hass: HomeAssistant, hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
setup_config_entry: ConfigEntry, config_entry_setup: ConfigEntry,
websocket_mock, websocket_mock,
) -> None: ) -> None:
"""Verify reconnect prints only on first reconnection try.""" """Verify reconnect prints only on first reconnection try."""
@ -378,7 +378,7 @@ async def test_reconnect_mechanism(
async def test_reconnect_mechanism_exceptions( async def test_reconnect_mechanism_exceptions(
hass: HomeAssistant, hass: HomeAssistant,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
setup_config_entry: ConfigEntry, config_entry_setup: ConfigEntry,
websocket_mock, websocket_mock,
exception, exception,
) -> None: ) -> None:

View File

@ -35,20 +35,20 @@ async def test_setup_with_no_config(hass: HomeAssistant) -> None:
async def test_setup_entry_fails_config_entry_not_ready( async def test_setup_entry_fails_config_entry_not_ready(
hass: HomeAssistant, prepare_config_entry: Callable[[], ConfigEntry] hass: HomeAssistant, config_entry_factory: Callable[[], ConfigEntry]
) -> None: ) -> None:
"""Failed authentication trigger a reauthentication flow.""" """Failed authentication trigger a reauthentication flow."""
with patch( with patch(
"homeassistant.components.unifi.get_unifi_api", "homeassistant.components.unifi.get_unifi_api",
side_effect=CannotConnect, side_effect=CannotConnect,
): ):
config_entry = await prepare_config_entry() config_entry = await config_entry_factory()
assert config_entry.state == ConfigEntryState.SETUP_RETRY assert config_entry.state == ConfigEntryState.SETUP_RETRY
async def test_setup_entry_fails_trigger_reauth_flow( async def test_setup_entry_fails_trigger_reauth_flow(
hass: HomeAssistant, prepare_config_entry: Callable[[], ConfigEntry] hass: HomeAssistant, config_entry_factory: Callable[[], ConfigEntry]
) -> None: ) -> None:
"""Failed authentication trigger a reauthentication flow.""" """Failed authentication trigger a reauthentication flow."""
with ( with (
@ -58,7 +58,7 @@ async def test_setup_entry_fails_trigger_reauth_flow(
), ),
patch.object(hass.config_entries.flow, "async_init") as mock_flow_init, patch.object(hass.config_entries.flow, "async_init") as mock_flow_init,
): ):
config_entry = await prepare_config_entry() config_entry = await config_entry_factory()
mock_flow_init.assert_called_once() mock_flow_init.assert_called_once()
assert config_entry.state == ConfigEntryState.SETUP_ERROR assert config_entry.state == ConfigEntryState.SETUP_ERROR
@ -86,7 +86,7 @@ async def test_setup_entry_fails_trigger_reauth_flow(
async def test_wireless_clients( async def test_wireless_clients(
hass: HomeAssistant, hass: HomeAssistant,
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
prepare_config_entry: Callable[[], ConfigEntry], config_entry_factory: Callable[[], ConfigEntry],
) -> None: ) -> None:
"""Verify wireless clients class.""" """Verify wireless clients class."""
hass_storage[unifi.STORAGE_KEY] = { hass_storage[unifi.STORAGE_KEY] = {
@ -98,7 +98,7 @@ async def test_wireless_clients(
}, },
} }
await prepare_config_entry() await config_entry_factory()
await flush_store(hass.data[unifi.UNIFI_WIRELESS_CLIENTS]._store) await flush_store(hass.data[unifi.UNIFI_WIRELESS_CLIENTS]._store)
assert sorted(hass_storage[unifi.STORAGE_KEY]["data"]["wireless_clients"]) == [ assert sorted(hass_storage[unifi.STORAGE_KEY]["data"]["wireless_clients"]) == [
@ -173,14 +173,14 @@ async def test_remove_config_entry_device(
hass_storage: dict[str, Any], hass_storage: dict[str, Any],
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
device_registry: dr.DeviceRegistry, device_registry: dr.DeviceRegistry,
prepare_config_entry: Callable[[], ConfigEntry], config_entry_factory: Callable[[], ConfigEntry],
client_payload: list[dict[str, Any]], client_payload: list[dict[str, Any]],
device_payload: list[dict[str, Any]], device_payload: list[dict[str, Any]],
mock_unifi_websocket, mock_unifi_websocket,
hass_ws_client: WebSocketGenerator, hass_ws_client: WebSocketGenerator,
) -> None: ) -> None:
"""Verify removing a device manually.""" """Verify removing a device manually."""
config_entry = await prepare_config_entry() config_entry = await config_entry_factory()
assert await async_setup_component(hass, "config", {}) assert await async_setup_component(hass, "config", {})
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)