mirror of
https://github.com/Electric-Special/ha-core.git
synced 2026-03-21 08:06:00 +01:00
Improve test coverage for switch in Fritz (#161630)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from homeassistant.components.network import async_get_source_ip
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
@@ -382,7 +382,7 @@ class FritzBoxPortSwitch(FritzBoxBaseSwitch):
|
||||
self,
|
||||
avm_wrapper: AvmWrapper,
|
||||
device_friendly_name: str,
|
||||
port_mapping: dict[str, Any] | None,
|
||||
port_mapping: dict[str, Any],
|
||||
port_name: str,
|
||||
idx: int,
|
||||
connection_type: str,
|
||||
@@ -396,9 +396,6 @@ class FritzBoxPortSwitch(FritzBoxBaseSwitch):
|
||||
self._idx = idx # needed for update routine
|
||||
self._attr_entity_category = EntityCategory.CONFIG
|
||||
|
||||
if port_mapping is None:
|
||||
return
|
||||
|
||||
switch_info = SwitchInfo(
|
||||
description=f"Port forward {port_name}",
|
||||
friendly_name=device_friendly_name,
|
||||
@@ -438,9 +435,6 @@ class FritzBoxPortSwitch(FritzBoxBaseSwitch):
|
||||
self._attributes[attr] = self.port_mapping[key]
|
||||
|
||||
async def _async_switch_on_off_executor(self, turn_on: bool) -> bool:
|
||||
if self.port_mapping is None:
|
||||
return False
|
||||
|
||||
self.port_mapping["NewEnabled"] = "1" if turn_on else "0"
|
||||
|
||||
resp = await self._avm_wrapper.async_add_port_mapping(
|
||||
@@ -530,8 +524,8 @@ class FritzBoxProfileSwitch(FritzDeviceBase, SwitchEntity):
|
||||
|
||||
async def _async_handle_turn_on_off(self, turn_on: bool) -> bool:
|
||||
"""Handle switch state change request."""
|
||||
if not self.ip_address:
|
||||
return False
|
||||
if TYPE_CHECKING:
|
||||
assert self.ip_address
|
||||
await self._avm_wrapper.async_set_allow_wan_access(self.ip_address, turn_on)
|
||||
self._avm_wrapper.devices[self._mac].wan_access = turn_on
|
||||
self.async_write_ha_state()
|
||||
|
||||
@@ -5,6 +5,8 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
from fritzconnection.core.processor import Service
|
||||
from fritzconnection.lib.fritzhosts import FritzHosts
|
||||
from fritzconnection.lib.fritzstatus import FritzStatus
|
||||
from fritzconnection.lib.fritztools import ArgumentNamespace
|
||||
import pytest
|
||||
|
||||
from .const import (
|
||||
@@ -12,6 +14,9 @@ from .const import (
|
||||
MOCK_HOST_ATTRIBUTES_DATA,
|
||||
MOCK_MESH_DATA,
|
||||
MOCK_MODELNAME,
|
||||
MOCK_STATUS_AVM_DEVICE_LOG_DATA,
|
||||
MOCK_STATUS_CONNECTION_DATA,
|
||||
MOCK_STATUS_DEVICE_INFO_DATA,
|
||||
)
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
@@ -121,3 +126,25 @@ def fh_class_mock():
|
||||
result.get_mesh_topology = MagicMock(return_value=MOCK_MESH_DATA)
|
||||
result.get_hosts_attributes = MagicMock(return_value=MOCK_HOST_ATTRIBUTES_DATA)
|
||||
yield result
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fs_class_mock():
|
||||
"""Fixture that sets up a mocked FritzStatus class."""
|
||||
with patch(
|
||||
"homeassistant.components.fritz.coordinator.FritzStatus",
|
||||
new=FritzStatus,
|
||||
) as result:
|
||||
result.get_default_connection_service = MagicMock(
|
||||
return_value=MOCK_STATUS_CONNECTION_DATA
|
||||
)
|
||||
result.get_device_info = MagicMock(
|
||||
return_value=ArgumentNamespace(MOCK_STATUS_DEVICE_INFO_DATA)
|
||||
)
|
||||
result.get_monitor_data = MagicMock(return_value={})
|
||||
result.get_cpu_temperatures = MagicMock(return_value=[42, 38])
|
||||
result.get_avm_device_log = MagicMock(
|
||||
return_value=MOCK_STATUS_AVM_DEVICE_LOG_DATA
|
||||
)
|
||||
result.has_wan_enabled = True
|
||||
yield result
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Common stuff for Fritz!Tools tests."""
|
||||
|
||||
from fritzconnection.lib.fritzstatus import DefaultConnectionService
|
||||
|
||||
from homeassistant.components.fritz.const import DOMAIN
|
||||
from homeassistant.const import (
|
||||
CONF_DEVICES,
|
||||
@@ -57,9 +59,17 @@ MOCK_FB_SERVICES: dict[str, dict] = {
|
||||
"GetInfo": {
|
||||
"NewSerialNumber": MOCK_MESH_MASTER_MAC,
|
||||
"NewName": "TheName",
|
||||
"NewManufacturerName": "AVM",
|
||||
"NewManufacturerOUI": "00040E",
|
||||
"NewModelName": MOCK_MODELNAME,
|
||||
"NewDescription": f"{MOCK_MODELNAME} {MOCK_FIRMWARE}",
|
||||
"NewProductClass": "AVMFB7590AX",
|
||||
"NewSoftwareVersion": MOCK_FIRMWARE,
|
||||
"NewHardwareVersion": MOCK_MODELNAME,
|
||||
"NewSpecVersion": "1.0",
|
||||
"NewDeviceLog": "long string here ...",
|
||||
"NewUpTime": 2518179,
|
||||
"NewProvisioningCode": "000.044.004.000",
|
||||
},
|
||||
},
|
||||
"Hosts1": {
|
||||
@@ -147,7 +157,27 @@ MOCK_FB_SERVICES: dict[str, dict] = {
|
||||
"NewDownstreamMaxBitRate": 43430530,
|
||||
"NewExternalIPAddress": "1.2.3.4",
|
||||
},
|
||||
"GetPortMappingNumberOfEntries": {},
|
||||
"GetPortMappingNumberOfEntries": {
|
||||
"NewPortMappingNumberOfEntries": 2,
|
||||
},
|
||||
"GetGenericPortMappingEntry": {
|
||||
0: {
|
||||
"NewInternalClient": "10.10.10.10",
|
||||
"NewPortMappingDescription": "Test Port Mapping",
|
||||
"NewInternalPort": 8080,
|
||||
"NewExternalPort": 80,
|
||||
"NewProtocol": "TCP",
|
||||
"NewEnabled": True,
|
||||
},
|
||||
1: {
|
||||
"NewInternalClient": "10.10.10.10",
|
||||
"NewPortMappingDescription": "Test Port Mapping",
|
||||
"NewInternalPort": 8081,
|
||||
"NewExternalPort": 81,
|
||||
"NewProtocol": "UDP",
|
||||
"NewEnabled": True,
|
||||
},
|
||||
},
|
||||
},
|
||||
"WLANConfiguration1": {
|
||||
"GetInfo": {
|
||||
@@ -158,11 +188,15 @@ MOCK_FB_SERVICES: dict[str, dict] = {
|
||||
"NewX_AVM-DE_PossibleBeaconTypes": "None,11i,11iandWPA3",
|
||||
"NewStandard": "ax",
|
||||
"NewBSSID": "1C:ED:6F:12:34:13",
|
||||
"NewMACAddressControlEnabled": True,
|
||||
},
|
||||
"GetSSID": {
|
||||
"NewSSID": "MyWifi",
|
||||
},
|
||||
"GetSecurityKeys": {"NewKeyPassphrase": "1234567890"},
|
||||
"GetBeaconAdvertisement": {
|
||||
"NewBeaconAdvertisementEnabled": True,
|
||||
},
|
||||
},
|
||||
"X_AVM-DE_Homeauto1": {
|
||||
"GetGenericDeviceInfos": [
|
||||
@@ -938,6 +972,12 @@ MOCK_CALL_DEFLECTION_DATA = {
|
||||
}
|
||||
}
|
||||
|
||||
MOCK_STATUS_CONNECTION_DATA = DefaultConnectionService("1", "WANPPPConnection", "1")
|
||||
MOCK_STATUS_DEVICE_INFO_DATA = MOCK_FB_SERVICES["DeviceInfo1"]["GetInfo"]
|
||||
MOCK_STATUS_AVM_DEVICE_LOG_DATA = MOCK_FB_SERVICES["DeviceInfo1"]["GetInfo"][
|
||||
"NewDeviceLog"
|
||||
]
|
||||
|
||||
MOCK_USER_DATA = MOCK_CONFIG[DOMAIN][CONF_DEVICES][0]
|
||||
MOCK_USER_INPUT_ADVANCED = MOCK_USER_DATA
|
||||
MOCK_USER_INPUT_SIMPLE = {
|
||||
|
||||
@@ -1,4 +1,104 @@
|
||||
# serializer version: 1
|
||||
# name: test_switch_setup[fc_data0][switch.mock_title_port_forward_test_port_mapping-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data0][switch.mock_title_port_forward_test_port_mapping-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data0][switch.mock_title_port_forward_test_port_mapping_81-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping_81',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data0][switch.mock_title_port_forward_test_port_mapping_81-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data0][switch.mock_title_wi_fi_wifi_2_4ghz-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@@ -148,6 +248,106 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data1][switch.mock_title_port_forward_test_port_mapping-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data1][switch.mock_title_port_forward_test_port_mapping-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data1][switch.mock_title_port_forward_test_port_mapping_81-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping_81',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data1][switch.mock_title_port_forward_test_port_mapping_81-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data1][switch.mock_title_wi_fi_wifi-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@@ -297,6 +497,106 @@
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data2][switch.mock_title_port_forward_test_port_mapping-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data2][switch.mock_title_port_forward_test_port_mapping-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data2][switch.mock_title_port_forward_test_port_mapping_81-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping_81',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data2][switch.mock_title_port_forward_test_port_mapping_81-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data2][switch.mock_title_wi_fi_wifi_2_4ghz-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
@@ -502,6 +802,106 @@
|
||||
'state': 'off',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data3][switch.mock_title_port_forward_test_port_mapping-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data3][switch.mock_title_port_forward_test_port_mapping-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data3][switch.mock_title_port_forward_test_port_mapping_81-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': None,
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'switch',
|
||||
'entity_category': <EntityCategory.CONFIG: 'config'>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'has_entity_name': False,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'object_id_base': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': 'mdi:check-network',
|
||||
'original_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'platform': 'fritz',
|
||||
'previous_unique_id': None,
|
||||
'suggested_object_id': None,
|
||||
'supported_features': 0,
|
||||
'translation_key': None,
|
||||
'unique_id': '1C:ED:6F:12:34:11-port_forward_test_port_mapping_81',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data3][switch.mock_title_port_forward_test_port_mapping_81-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'friendly_name': 'Mock Title Port forward Test Port Mapping 81',
|
||||
'icon': 'mdi:check-network',
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'switch.mock_title_port_forward_test_port_mapping_81',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'on',
|
||||
})
|
||||
# ---
|
||||
# name: test_switch_setup[fc_data3][switch.mock_title_wi_fi_mywifi-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
|
||||
@@ -2,17 +2,38 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import patch
|
||||
from copy import deepcopy
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from fritzconnection.core.exceptions import FritzActionError
|
||||
from fritzconnection.lib.fritzstatus import DefaultConnectionService
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.fritz.const import DOMAIN
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.components.switch import (
|
||||
DOMAIN as SWITCH_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
STATE_OFF,
|
||||
STATE_ON,
|
||||
STATE_UNAVAILABLE,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .const import MOCK_CALL_DEFLECTION_DATA, MOCK_FB_SERVICES, MOCK_USER_DATA
|
||||
from .conftest import FritzConnectionMock
|
||||
from .const import (
|
||||
MOCK_CALL_DEFLECTION_DATA,
|
||||
MOCK_FB_SERVICES,
|
||||
MOCK_HOST_ATTRIBUTES_DATA,
|
||||
MOCK_USER_DATA,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
|
||||
@@ -194,3 +215,205 @@ async def test_switch_setup(
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
await snapshot_platform(hass, entity_registry, snapshot, entry.entry_id)
|
||||
|
||||
|
||||
async def test_switch_no_device_conn_type(
|
||||
hass: HomeAssistant,
|
||||
fc_class_mock,
|
||||
fh_class_mock,
|
||||
fs_class_mock,
|
||||
) -> None:
|
||||
"""Test Fritz!Tools switches when no device connection type is available."""
|
||||
|
||||
entity_id = "switch.mock_title_port_forward_test_port_mapping"
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
fs_class_mock.get_default_connection_service.return_value = (
|
||||
DefaultConnectionService("", "", "")
|
||||
)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert hass.states.get(entity_id) is None
|
||||
|
||||
|
||||
async def test_switch_empty_port_entities_list(
|
||||
hass: HomeAssistant,
|
||||
fc_class_mock,
|
||||
fh_class_mock,
|
||||
fs_class_mock,
|
||||
) -> None:
|
||||
"""Test Fritz!Tools switches with empty port entities."""
|
||||
|
||||
entity_id = "switch.mock_title_port_forward_test_port_mapping"
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.fritz.coordinator.AvmWrapper.async_get_num_port_mapping",
|
||||
return_value=None,
|
||||
):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert hass.states.get(entity_id) is None
|
||||
|
||||
|
||||
async def test_switch_no_port_entities_list(
|
||||
hass: HomeAssistant,
|
||||
fc_class_mock,
|
||||
fh_class_mock,
|
||||
fs_class_mock,
|
||||
) -> None:
|
||||
"""Test Fritz!Tools switches with no port entities."""
|
||||
|
||||
entity_id = "switch.mock_title_port_forward_test_port_mapping"
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.fritz.coordinator.AvmWrapper.async_get_port_mapping",
|
||||
return_value=None,
|
||||
):
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert hass.states.get(entity_id) is None
|
||||
|
||||
|
||||
async def test_switch_no_profile_entities_list(
|
||||
hass: HomeAssistant,
|
||||
fc_class_mock,
|
||||
fh_class_mock,
|
||||
) -> None:
|
||||
"""Test Fritz!Tools switches with no profile entities."""
|
||||
|
||||
entity_id = "sswitch.printer_internet_access"
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
services = deepcopy(MOCK_FB_SERVICES)
|
||||
services.pop("X_AVM-DE_HostFilter1")
|
||||
fc_class_mock.return_value = FritzConnectionMock(services)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert hass.states.get(entity_id) is None
|
||||
|
||||
|
||||
async def test_switch_no_mesh_wifi_uplink(
|
||||
hass: HomeAssistant,
|
||||
fc_class_mock,
|
||||
fh_class_mock,
|
||||
) -> None:
|
||||
"""Test Fritz!Tools switches when no mesh WiFi uplink."""
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
fh_class_mock.get_mesh_topology.side_effect = FritzActionError(
|
||||
"No mesh WiFi uplink"
|
||||
)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
|
||||
async def test_switch_device_no_wan_access(
|
||||
hass: HomeAssistant,
|
||||
fc_class_mock,
|
||||
fh_class_mock,
|
||||
) -> None:
|
||||
"""Test Fritz!Tools switches when device has no WAN access."""
|
||||
|
||||
entity_id = "switch.printer_internet_access"
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
attributes = [
|
||||
{k: v for k, v in host.items() if k != "X_AVM-DE_WANAccess"}
|
||||
for host in MOCK_HOST_ATTRIBUTES_DATA
|
||||
]
|
||||
fh_class_mock.get_hosts_attributes = MagicMock(return_value=attributes)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert (state := hass.states.get(entity_id))
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("entity_id", "wrapper_method", "state_value"),
|
||||
[
|
||||
(
|
||||
"switch.mock_title_port_forward_test_port_mapping",
|
||||
"async_add_port_mapping",
|
||||
STATE_OFF,
|
||||
),
|
||||
(
|
||||
"switch.printer_internet_access",
|
||||
"async_set_allow_wan_access",
|
||||
STATE_ON,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_switch_turn_on_off(
|
||||
hass: HomeAssistant,
|
||||
fc_class_mock,
|
||||
fh_class_mock,
|
||||
entity_id: str,
|
||||
wrapper_method: str,
|
||||
state_value: str,
|
||||
) -> None:
|
||||
"""Test Fritz!Tools switches turn on and turn off."""
|
||||
|
||||
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
fc_class_mock.return_value = FritzConnectionMock(
|
||||
MOCK_FB_SERVICES | MOCK_CALL_DEFLECTION_DATA
|
||||
)
|
||||
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
assert entry.state is ConfigEntryState.LOADED
|
||||
|
||||
assert (state := hass.states.get(entity_id))
|
||||
assert state.state == STATE_ON
|
||||
|
||||
with patch(
|
||||
f"homeassistant.components.fritz.coordinator.AvmWrapper.{wrapper_method}",
|
||||
) as mock_set_action:
|
||||
await hass.services.async_call(
|
||||
SWITCH_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
mock_set_action.assert_called_once()
|
||||
|
||||
assert (state := hass.states.get(entity_id))
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
with patch(
|
||||
f"homeassistant.components.fritz.coordinator.AvmWrapper.{wrapper_method}",
|
||||
) as mock_set_action_2:
|
||||
await hass.services.async_call(
|
||||
SWITCH_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
mock_set_action_2.assert_called_once()
|
||||
|
||||
assert (state := hass.states.get(entity_id))
|
||||
assert state.state == state_value
|
||||
|
||||
Reference in New Issue
Block a user