From bf8d880e5f7d06486879c75ebb920af2e01b5d24 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Sat, 23 Mar 2024 00:44:06 +0100 Subject: [PATCH] Improve axis tests (#114035) * Combine binary sensor tests into more logical groups * Improve light tests * Clean up switch tests * Improve typing in conftest * Add typing to camera * Improve binary sensor * Improve light * Improve switch --- tests/components/axis/conftest.py | 81 ++++++++----- tests/components/axis/test_binary_sensor.py | 119 ++++++++------------ tests/components/axis/test_camera.py | 13 ++- tests/components/axis/test_hub.py | 26 +++-- tests/components/axis/test_light.py | 35 ++---- tests/components/axis/test_switch.py | 27 ++--- 6 files changed, 142 insertions(+), 159 deletions(-) diff --git a/tests/components/axis/conftest.py b/tests/components/axis/conftest.py index f3c395d092d..b50a28df49f 100644 --- a/tests/components/axis/conftest.py +++ b/tests/components/axis/conftest.py @@ -2,8 +2,10 @@ from __future__ import annotations -from collections.abc import Generator +from collections.abc import Callable, Generator from copy import deepcopy +from types import MappingProxyType +from typing import Any from unittest.mock import AsyncMock, patch from axis.rtsp import Signal, State @@ -11,6 +13,7 @@ import pytest import respx from homeassistant.components.axis.const import DOMAIN as AXIS_DOMAIN +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_HOST, CONF_MODEL, @@ -19,6 +22,7 @@ from homeassistant.const import ( CONF_PORT, CONF_USERNAME, ) +from homeassistant.core import HomeAssistant from .const import ( API_DISCOVERY_RESPONSE, @@ -42,7 +46,6 @@ from .const import ( ) from tests.common import MockConfigEntry -from tests.components.light.conftest import mock_light_profiles # noqa: F401 @pytest.fixture @@ -58,28 +61,33 @@ def mock_setup_entry() -> Generator[AsyncMock, None, None]: @pytest.fixture(name="config_entry") -def config_entry_fixture(hass, config, options, config_entry_version): +def config_entry_fixture( + hass: HomeAssistant, + config_entry_data: MappingProxyType[str, Any], + config_entry_options: MappingProxyType[str, Any], + config_entry_version: int, +) -> ConfigEntry: """Define a config entry fixture.""" - entry = MockConfigEntry( + config_entry = MockConfigEntry( domain=AXIS_DOMAIN, entry_id="676abe5b73621446e6550a2e86ffe3dd", unique_id=FORMATTED_MAC, - data=config, - options=options, + data=config_entry_data, + options=config_entry_options, version=config_entry_version, ) - entry.add_to_hass(hass) - return entry + config_entry.add_to_hass(hass) + return config_entry @pytest.fixture(name="config_entry_version") -def config_entry_version_fixture(request): +def config_entry_version_fixture() -> int: """Define a config entry version fixture.""" return 3 -@pytest.fixture(name="config") -def config_fixture(): +@pytest.fixture(name="config_entry_data") +def config_entry_data_fixture() -> MappingProxyType[str, Any]: """Define a config entry data fixture.""" return { CONF_HOST: DEFAULT_HOST, @@ -91,8 +99,8 @@ def config_fixture(): } -@pytest.fixture(name="options") -def options_fixture(request): +@pytest.fixture(name="config_entry_options") +def config_entry_options_fixture() -> MappingProxyType[str, Any]: """Define a config entry options fixture.""" return {} @@ -102,11 +110,14 @@ def options_fixture(request): @pytest.fixture(name="mock_vapix_requests") def default_request_fixture( - respx_mock, port_management_payload, param_properties_payload, param_ports_payload -): + respx_mock: respx, + port_management_payload: dict[str, Any], + param_properties_payload: dict[str, Any], + param_ports_payload: dict[str, Any], +) -> Callable[[str], None]: """Mock default Vapix requests responses.""" - def __mock_default_requests(host): + def __mock_default_requests(host: str) -> None: respx_mock(base_url=f"http://{host}:80") if host != DEFAULT_HOST: @@ -196,13 +207,13 @@ def default_request_fixture( @pytest.fixture -def api_discovery_items(): +def api_discovery_items() -> dict[str, Any]: """Additional Apidiscovery items.""" return {} @pytest.fixture(autouse=True) -def api_discovery_fixture(api_discovery_items): +def api_discovery_fixture(api_discovery_items: dict[str, Any]) -> None: """Apidiscovery mock response.""" data = deepcopy(API_DISCOVERY_RESPONSE) if api_discovery_items: @@ -211,34 +222,36 @@ def api_discovery_fixture(api_discovery_items): @pytest.fixture(name="port_management_payload") -def io_port_management_data_fixture(): +def io_port_management_data_fixture() -> dict[str, Any]: """Property parameter data.""" return PORT_MANAGEMENT_RESPONSE @pytest.fixture(name="param_properties_payload") -def param_properties_data_fixture(): +def param_properties_data_fixture() -> dict[str, Any]: """Property parameter data.""" return PROPERTIES_RESPONSE @pytest.fixture(name="param_ports_payload") -def param_ports_data_fixture(): +def param_ports_data_fixture() -> dict[str, Any]: """Property parameter data.""" return PORTS_RESPONSE @pytest.fixture(name="setup_default_vapix_requests") -def default_vapix_requests_fixture(mock_vapix_requests): +def default_vapix_requests_fixture(mock_vapix_requests: Callable[[str], None]) -> None: """Mock default Vapix requests responses.""" mock_vapix_requests(DEFAULT_HOST) @pytest.fixture(name="prepare_config_entry") -async def prep_config_entry_fixture(hass, config_entry, setup_default_vapix_requests): +async def prep_config_entry_fixture( + hass: HomeAssistant, config_entry: ConfigEntry, setup_default_vapix_requests: None +) -> Callable[[], ConfigEntry]: """Fixture factory to set up Axis network device.""" - async def __mock_setup_config_entry(): + async def __mock_setup_config_entry() -> ConfigEntry: assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() return config_entry @@ -247,7 +260,9 @@ async def prep_config_entry_fixture(hass, config_entry, setup_default_vapix_requ @pytest.fixture(name="setup_config_entry") -async def setup_config_entry_fixture(hass, config_entry, setup_default_vapix_requests): +async def setup_config_entry_fixture( + hass: HomeAssistant, config_entry: ConfigEntry, setup_default_vapix_requests: None +) -> ConfigEntry: """Define a fixture to set up Axis network device.""" assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() @@ -258,24 +273,24 @@ async def setup_config_entry_fixture(hass, config_entry, setup_default_vapix_req @pytest.fixture(autouse=True) -def mock_axis_rtspclient(): +def mock_axis_rtspclient() -> Generator[Callable[[dict | None, str], None], None, None]: """No real RTSP communication allowed.""" with patch("axis.stream_manager.RTSPClient") as rtsp_client_mock: rtsp_client_mock.return_value.session.state = State.STOPPED - async def start_stream(): + async def start_stream() -> None: """Set state to playing when calling RTSPClient.start.""" rtsp_client_mock.return_value.session.state = State.PLAYING rtsp_client_mock.return_value.start = start_stream - def stop_stream(): + def stop_stream() -> None: """Set state to stopped when calling RTSPClient.stop.""" rtsp_client_mock.return_value.session.state = State.STOPPED rtsp_client_mock.return_value.stop = stop_stream - def make_rtsp_call(data: dict | None = None, state: str = ""): + def make_rtsp_call(data: dict | None = None, state: str = "") -> None: """Generate a RTSP call.""" axis_streammanager_session_callback = rtsp_client_mock.call_args[0][4] @@ -291,7 +306,9 @@ def mock_axis_rtspclient(): @pytest.fixture(autouse=True) -def mock_rtsp_event(mock_axis_rtspclient): +def mock_rtsp_event( + mock_axis_rtspclient: Callable[[dict | None, str], None], +) -> Callable[[str, str, str, str, str, str], None]: """Fixture to allow mocking received RTSP events.""" def send_event( @@ -342,7 +359,9 @@ def mock_rtsp_event(mock_axis_rtspclient): @pytest.fixture(autouse=True) -def mock_rtsp_signal_state(mock_axis_rtspclient): +def mock_rtsp_signal_state( + mock_axis_rtspclient: Callable[[dict | None, str], None], +) -> Callable[[bool], None]: """Fixture to allow mocking RTSP state signalling.""" def send_signal(connected: bool) -> None: diff --git a/tests/components/axis/test_binary_sensor.py b/tests/components/axis/test_binary_sensor.py index ce387655889..dd7674d7d3f 100644 --- a/tests/components/axis/test_binary_sensor.py +++ b/tests/components/axis/test_binary_sensor.py @@ -1,54 +1,20 @@ """Axis binary sensor platform tests.""" +from collections.abc import Callable + import pytest -from homeassistant.components.axis.const import DOMAIN as AXIS_DOMAIN from homeassistant.components.binary_sensor import ( DOMAIN as BINARY_SENSOR_DOMAIN, BinarySensorDeviceClass, ) +from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_OFF, STATE_ON from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component from .const import NAME -async def test_platform_manually_configured(hass: HomeAssistant) -> None: - """Test that nothing happens when platform is manually configured.""" - assert ( - await async_setup_component( - hass, - BINARY_SENSOR_DOMAIN, - {BINARY_SENSOR_DOMAIN: {"platform": AXIS_DOMAIN}}, - ) - is True - ) - - assert AXIS_DOMAIN not in hass.data - - -async def test_no_binary_sensors(hass: HomeAssistant, setup_config_entry) -> None: - """Test that no sensors in Axis results in no sensor entities.""" - assert not hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN) - - -async def test_unsupported_binary_sensors( - hass: HomeAssistant, setup_config_entry, mock_rtsp_event -) -> None: - """Test that unsupported sensors are not loaded.""" - mock_rtsp_event( - topic="tns1:PTZController/tnsaxis:PTZPresets/Channel_1", - data_type="on_preset", - data_value="1", - source_name="PresetToken", - source_idx="0", - ) - await hass.async_block_till_done() - - assert len(hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN)) == 0 - - @pytest.mark.parametrize( ("event", "entity"), [ @@ -178,10 +144,41 @@ async def test_unsupported_binary_sensors( "device_class": BinarySensorDeviceClass.MOTION, }, ), + # Events with names generated from event ID and topic + ( + { + "topic": "tnsaxis:CameraApplicationPlatform/VMD/Camera1Profile9", + "data_type": "active", + "data_value": "1", + }, + { + "id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_vmd4_camera1profile9", + "state": STATE_ON, + "name": f"{NAME} VMD4 Camera1Profile9", + "device_class": BinarySensorDeviceClass.MOTION, + }, + ), + ( + { + "topic": "tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario8", + "data_type": "active", + "data_value": "1", + }, + { + "id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_object_analytics_device1scenario8", + "state": STATE_ON, + "name": f"{NAME} Object Analytics Device1Scenario8", + "device_class": BinarySensorDeviceClass.MOTION, + }, + ), ], ) async def test_binary_sensors( - hass: HomeAssistant, setup_config_entry, mock_rtsp_event, event, entity + hass: HomeAssistant, + setup_config_entry: ConfigEntry, + mock_rtsp_event: Callable[[str, str, str, str, str, str], None], + event: dict[str, str], + entity: dict[str, str], ) -> None: """Test that sensors are loaded properly.""" mock_rtsp_event(**event) @@ -198,6 +195,15 @@ async def test_binary_sensors( @pytest.mark.parametrize( ("event"), [ + # Event with unsupported topic + { + "topic": "tns1:PTZController/tnsaxis:PTZPresets/Channel_1", + "data_type": "on_preset", + "data_value": "1", + "source_name": "PresetToken", + "source_idx": "0", + }, + # Event with unsupported source_idx { "topic": "tns1:Device/tnsaxis:IO/Port", "data_type": "state", @@ -206,6 +212,7 @@ async def test_binary_sensors( "source_name": "port", "source_idx": "-1", }, + # Event with unsupported ID in topic 'ANY' { "topic": "tnsaxis:CameraApplicationPlatform/VMD/Camera1ProfileANY", "data_type": "active", @@ -219,40 +226,12 @@ async def test_binary_sensors( ], ) async def test_unsupported_events( - hass: HomeAssistant, setup_config_entry, mock_rtsp_event, event + hass: HomeAssistant, + setup_config_entry: ConfigEntry, + mock_rtsp_event: Callable[[str, str, str, str, str, str], None], + event: dict[str, str], ) -> None: """Validate nothing breaks with unsupported events.""" mock_rtsp_event(**event) await hass.async_block_till_done() assert len(hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN)) == 0 - - -@pytest.mark.parametrize( - ("event", "entity_id"), - [ - ( - { - "topic": "tnsaxis:CameraApplicationPlatform/VMD/Camera1Profile9", - "data_type": "active", - "data_value": "1", - }, - "binary_sensor.name_vmd4_camera1profile9", - ), - ( - { - "topic": "tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario8", - "data_type": "active", - "data_value": "1", - }, - "binary_sensor.name_object_analytics_device1scenario8", - ), - ], -) -async def test_no_primary_name_for_event( - hass: HomeAssistant, setup_config_entry, mock_rtsp_event, event, entity_id -) -> None: - """Validate fallback method for getting name works.""" - mock_rtsp_event(**event) - await hass.async_block_till_done() - assert len(hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN)) == 1 - assert hass.states.get(entity_id) diff --git a/tests/components/axis/test_camera.py b/tests/components/axis/test_camera.py index 440bb17b08e..e184f2014b3 100644 --- a/tests/components/axis/test_camera.py +++ b/tests/components/axis/test_camera.py @@ -1,5 +1,7 @@ """Axis camera platform tests.""" +from collections.abc import Callable + import pytest from homeassistant.components import camera @@ -8,6 +10,7 @@ from homeassistant.components.axis.const import ( DOMAIN as AXIS_DOMAIN, ) from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN +from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_IDLE from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -27,7 +30,7 @@ async def test_platform_manually_configured(hass: HomeAssistant) -> None: assert AXIS_DOMAIN not in hass.data -async def test_camera(hass: HomeAssistant, setup_config_entry) -> None: +async def test_camera(hass: HomeAssistant, setup_config_entry: ConfigEntry) -> None: """Test that Axis camera platform is loaded properly.""" assert len(hass.states.async_entity_ids(CAMERA_DOMAIN)) == 1 @@ -46,9 +49,9 @@ async def test_camera(hass: HomeAssistant, setup_config_entry) -> None: ) -@pytest.mark.parametrize("options", [{CONF_STREAM_PROFILE: "profile_1"}]) +@pytest.mark.parametrize("config_entry_options", [{CONF_STREAM_PROFILE: "profile_1"}]) async def test_camera_with_stream_profile( - hass: HomeAssistant, setup_config_entry + hass: HomeAssistant, setup_config_entry: ConfigEntry ) -> None: """Test that Axis camera entity is using the correct path with stream profike.""" assert len(hass.states.async_entity_ids(CAMERA_DOMAIN)) == 1 @@ -83,7 +86,9 @@ root.Properties.System.SerialNumber={MAC} @pytest.mark.parametrize("param_properties_payload", [property_data]) -async def test_camera_disabled(hass: HomeAssistant, prepare_config_entry) -> None: +async def test_camera_disabled( + hass: HomeAssistant, prepare_config_entry: Callable[[], ConfigEntry] +) -> None: """Test that Axis camera platform is loaded properly but does not create camera entity.""" await prepare_config_entry() assert len(hass.states.async_entity_ids(CAMERA_DOMAIN)) == 0 diff --git a/tests/components/axis/test_hub.py b/tests/components/axis/test_hub.py index 70b71e45b45..b2fc210f541 100644 --- a/tests/components/axis/test_hub.py +++ b/tests/components/axis/test_hub.py @@ -45,7 +45,7 @@ def hass_mock_forward_entry_setup(hass): async def test_device_setup( hass: HomeAssistant, forward_entry_setup, - config, + config_entry_data, setup_config_entry, device_registry: dr.DeviceRegistry, ) -> None: @@ -63,9 +63,9 @@ async def test_device_setup( assert forward_entry_setup.mock_calls[2][1][1] == "light" assert forward_entry_setup.mock_calls[3][1][1] == "switch" - assert hub.config.host == config[CONF_HOST] - assert hub.config.model == config[CONF_MODEL] - assert hub.config.name == config[CONF_NAME] + assert hub.config.host == config_entry_data[CONF_HOST] + assert hub.config.model == config_entry_data[CONF_MODEL] + assert hub.config.name == config_entry_data[CONF_NAME] assert hub.unique_id == FORMATTED_MAC device_entry = device_registry.async_get_device( @@ -206,11 +206,11 @@ async def test_device_unknown_error( assert hass.data[AXIS_DOMAIN] == {} -async def test_shutdown(config) -> None: +async def test_shutdown(config_entry_data) -> None: """Successful shutdown.""" hass = Mock() entry = Mock() - entry.data = config + entry.data = config_entry_data mock_api = Mock() mock_api.vapix.serial_number = FORMATTED_MAC @@ -221,25 +221,27 @@ async def test_shutdown(config) -> None: assert len(axis_device.api.stream.stop.mock_calls) == 1 -async def test_get_device_fails(hass: HomeAssistant, config) -> None: +async def test_get_device_fails(hass: HomeAssistant, config_entry_data) -> None: """Device unauthorized yields authentication required error.""" with patch( "axis.vapix.vapix.Vapix.initialize", side_effect=axislib.Unauthorized ), pytest.raises(axis.errors.AuthenticationRequired): - await axis.hub.get_axis_api(hass, config) + await axis.hub.get_axis_api(hass, config_entry_data) -async def test_get_device_device_unavailable(hass: HomeAssistant, config) -> None: +async def test_get_device_device_unavailable( + hass: HomeAssistant, config_entry_data +) -> None: """Device unavailable yields cannot connect error.""" with patch( "axis.vapix.vapix.Vapix.request", side_effect=axislib.RequestError ), pytest.raises(axis.errors.CannotConnect): - await axis.hub.get_axis_api(hass, config) + await axis.hub.get_axis_api(hass, config_entry_data) -async def test_get_device_unknown_error(hass: HomeAssistant, config) -> None: +async def test_get_device_unknown_error(hass: HomeAssistant, config_entry_data) -> None: """Device yield unknown error.""" with patch( "axis.vapix.vapix.Vapix.request", side_effect=axislib.AxisException ), pytest.raises(axis.errors.AuthenticationRequired): - await axis.hub.get_axis_api(hass, config) + await axis.hub.get_axis_api(hass, config_entry_data) diff --git a/tests/components/axis/test_light.py b/tests/components/axis/test_light.py index 2b46330bd2d..b8983cd8b9b 100644 --- a/tests/components/axis/test_light.py +++ b/tests/components/axis/test_light.py @@ -1,13 +1,15 @@ """Axis light platform tests.""" +from collections.abc import Callable +from typing import Any from unittest.mock import patch from axis.vapix.models.api import CONTEXT import pytest import respx -from homeassistant.components.axis.const import DOMAIN as AXIS_DOMAIN from homeassistant.components.light import ATTR_BRIGHTNESS, DOMAIN as LIGHT_DOMAIN +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, SERVICE_TURN_OFF, @@ -16,7 +18,6 @@ from homeassistant.const import ( STATE_ON, ) from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component from .const import DEFAULT_HOST, NAME @@ -28,7 +29,7 @@ API_DISCOVERY_LIGHT_CONTROL = { @pytest.fixture -def light_control_items(): +def light_control_items() -> list[dict[str, Any]]: """Available lights.""" return [ { @@ -47,7 +48,7 @@ def light_control_items(): @pytest.fixture(autouse=True) -def light_control_fixture(light_control_items): +def light_control_fixture(light_control_items: list[dict[str, Any]]) -> None: """Light control mock response.""" data = { "apiVersion": "1.1", @@ -67,24 +68,12 @@ def light_control_fixture(light_control_items): ) -async def test_platform_manually_configured(hass: HomeAssistant) -> None: - """Test that nothing happens when platform is manually configured.""" - assert await async_setup_component( - hass, LIGHT_DOMAIN, {LIGHT_DOMAIN: {"platform": AXIS_DOMAIN}} - ) - - assert AXIS_DOMAIN not in hass.data - - -async def test_no_lights(hass: HomeAssistant, setup_config_entry) -> None: - """Test that no light events in Axis results in no light entities.""" - assert not hass.states.async_entity_ids(LIGHT_DOMAIN) - - @pytest.mark.parametrize("api_discovery_items", [API_DISCOVERY_LIGHT_CONTROL]) @pytest.mark.parametrize("light_control_items", [[]]) async def test_no_light_entity_without_light_control_representation( - hass: HomeAssistant, setup_config_entry, mock_rtsp_event + hass: HomeAssistant, + setup_config_entry: ConfigEntry, + mock_rtsp_event: Callable[[str, str, str, str, str, str], None], ) -> None: """Verify no lights entities get created without light control representation.""" mock_rtsp_event( @@ -102,10 +91,10 @@ async def test_no_light_entity_without_light_control_representation( @pytest.mark.parametrize("api_discovery_items", [API_DISCOVERY_LIGHT_CONTROL]) async def test_lights( hass: HomeAssistant, - respx_mock, - setup_config_entry, - mock_rtsp_event, - api_discovery_items, + respx_mock: respx, + setup_config_entry: ConfigEntry, + mock_rtsp_event: Callable[[str, str, str, str, str, str], None], + api_discovery_items: dict[str, Any], ) -> None: """Test that lights are loaded properly.""" # Add light diff --git a/tests/components/axis/test_switch.py b/tests/components/axis/test_switch.py index 13411d86943..a2a1088d7ef 100644 --- a/tests/components/axis/test_switch.py +++ b/tests/components/axis/test_switch.py @@ -1,12 +1,13 @@ """Axis switch platform tests.""" +from collections.abc import Callable from unittest.mock import patch from axis.vapix.models.api import CONTEXT import pytest -from homeassistant.components.axis.const import DOMAIN as AXIS_DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( ATTR_ENTITY_ID, SERVICE_TURN_OFF, @@ -15,25 +16,9 @@ from homeassistant.const import ( STATE_ON, ) from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component from .const import API_DISCOVERY_PORT_MANAGEMENT, NAME - -async def test_platform_manually_configured(hass: HomeAssistant) -> None: - """Test that nothing happens when platform is manually configured.""" - assert await async_setup_component( - hass, SWITCH_DOMAIN, {SWITCH_DOMAIN: {"platform": AXIS_DOMAIN}} - ) - - assert AXIS_DOMAIN not in hass.data - - -async def test_no_switches(hass: HomeAssistant, setup_config_entry) -> None: - """Test that no output events in Axis results in no switch entities.""" - assert not hass.states.async_entity_ids(SWITCH_DOMAIN) - - PORT_DATA = """root.IOPort.I0.Configurable=yes root.IOPort.I0.Direction=output root.IOPort.I0.Output.Name=Doorbell @@ -47,7 +32,9 @@ root.IOPort.I1.Output.Active=open @pytest.mark.parametrize("param_ports_payload", [PORT_DATA]) async def test_switches_with_port_cgi( - hass: HomeAssistant, setup_config_entry, mock_rtsp_event + hass: HomeAssistant, + setup_config_entry: ConfigEntry, + mock_rtsp_event: Callable[[str, str, str, str, str, str], None], ) -> None: """Test that switches are loaded properly using port.cgi.""" mock_rtsp_event( @@ -130,7 +117,9 @@ PORT_MANAGEMENT_RESPONSE = { @pytest.mark.parametrize("api_discovery_items", [API_DISCOVERY_PORT_MANAGEMENT]) @pytest.mark.parametrize("port_management_payload", [PORT_MANAGEMENT_RESPONSE]) async def test_switches_with_port_management( - hass: HomeAssistant, setup_config_entry, mock_rtsp_event + hass: HomeAssistant, + setup_config_entry: ConfigEntry, + mock_rtsp_event: Callable[[str, str, str, str, str, str], None], ) -> None: """Test that switches are loaded properly using port management.""" mock_rtsp_event(