Refactor Vodafone Station tests (#134956)

pull/135121/head
Simone Chemelli 2025-01-09 16:22:37 -05:00 committed by GitHub
parent 1abcac5fb5
commit 0deb46295d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 789 additions and 406 deletions

View File

@ -1 +1,13 @@
"""Tests for the Vodafone Station integration."""
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None:
"""Fixture for setting up the component."""
config_entry.add_to_hass(hass)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()

View File

@ -2,11 +2,31 @@
from datetime import UTC, datetime
from aiovodafone import VodafoneStationDevice
import pytest
from .const import DEVICE_DATA_QUERY, SENSOR_DATA_QUERY
from homeassistant.components.vodafone_station import DOMAIN
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from tests.common import AsyncMock, Generator, patch
from .const import DEVICE_1_MAC
from tests.common import (
AsyncMock,
Generator,
MockConfigEntry,
load_json_object_fixture,
patch,
)
@pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock]:
"""Override async_setup_entry."""
with patch(
"homeassistant.components.vodafone_station.async_setup_entry",
return_value=True,
) as mock_setup_entry:
yield mock_setup_entry
@pytest.fixture
@ -17,12 +37,41 @@ def mock_vodafone_station_router() -> Generator[AsyncMock]:
"homeassistant.components.vodafone_station.coordinator.VodafoneStationSercommApi",
autospec=True,
) as mock_router,
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi",
new=mock_router,
),
):
router = mock_router.return_value
router.get_devices_data.return_value = DEVICE_DATA_QUERY
router.get_sensor_data.return_value = SENSOR_DATA_QUERY
router.get_devices_data.return_value = {
DEVICE_1_MAC: VodafoneStationDevice(
connected=True,
connection_type="wifi",
ip_address="192.168.1.10",
name="WifiDevice0",
mac=DEVICE_1_MAC,
type="laptop",
wifi="2.4G",
),
}
router.get_sensor_data.return_value = load_json_object_fixture(
"get_sensor_data.json", DOMAIN
)
router.convert_uptime.return_value = datetime(
2024, 11, 19, 20, 19, 0, tzinfo=UTC
)
router.base_url = "https://fake_host"
yield router
@pytest.fixture
def mock_config_entry() -> Generator[MockConfigEntry]:
"""Mock a Vodafone Station config entry."""
return MockConfigEntry(
domain=DOMAIN,
data={
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
},
)

View File

@ -1,118 +1,3 @@
"""Common stuff for Vodafone Station tests."""
from aiovodafone.api import VodafoneStationDevice
from homeassistant.components.vodafone_station.const import DOMAIN
from homeassistant.const import CONF_DEVICES, CONF_HOST, CONF_PASSWORD, CONF_USERNAME
MOCK_CONFIG = {
DOMAIN: {
CONF_DEVICES: [
{
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
}
]
}
}
MOCK_USER_DATA = MOCK_CONFIG[DOMAIN][CONF_DEVICES][0]
DEVICE_1_MAC = "xx:xx:xx:xx:xx:xx"
DEVICE_1 = {
DEVICE_1_MAC: VodafoneStationDevice(
connected=True,
connection_type="wifi",
ip_address="192.168.1.10",
name="WifiDevice0",
mac=DEVICE_1_MAC,
type="laptop",
wifi="2.4G",
),
}
DEVICE_DATA_QUERY = DEVICE_1
SERIAL = "m123456789"
SENSOR_DATA_QUERY = {
"sys_serial_number": SERIAL,
"sys_firmware_version": "XF6_4.0.05.04",
"sys_bootloader_version": "0220",
"sys_hardware_version": "RHG3006 v1",
"omci_software_version": "\t\t1.0.0.1_41032\t\t\n",
"sys_uptime": "12:16:41",
"sys_cpu_usage": "97%",
"sys_reboot_cause": "Web Reboot",
"sys_memory_usage": "51.94%",
"sys_wireless_driver_version": "17.10.188.75;17.10.188.75",
"sys_wireless_driver_version_5g": "17.10.188.75;17.10.188.75",
"vf_internet_key_online_since": "",
"vf_internet_key_ip_addr": "0.0.0.0",
"vf_internet_key_system": "0.0.0.0",
"vf_internet_key_mode": "Auto",
"sys_voip_version": "v02.01.00_01.13a\n",
"sys_date_time": "20.10.2024 | 03:44 pm",
"sys_build_time": "Sun Jun 23 17:55:49 CST 2024\n",
"sys_model_name": "RHG3006",
"inter_ip_address": "1.1.1.1",
"inter_gateway": "1.1.1.2",
"inter_primary_dns": "1.1.1.3",
"inter_secondary_dns": "1.1.1.4",
"inter_firewall": "601036",
"inter_wan_ip_address": "1.1.1.1",
"inter_ipv6_link_local_address": "",
"inter_ipv6_link_global_address": "",
"inter_ipv6_gateway": "",
"inter_ipv6_prefix_delegation": "",
"inter_ipv6_dns_address1": "",
"inter_ipv6_dns_address2": "",
"lan_ip_network": "192.168.0.1/24",
"lan_default_gateway": "192.168.0.1",
"lan_subnet_address_subnet1": "",
"lan_mac_address": "11:22:33:44:55:66",
"lan_dhcp_server": "601036",
"lan_dhcpv6_server": "601036",
"lan_router_advertisement": "601036",
"lan_ipv6_default_gateway": "fe80::1",
"lan_port1_switch_mode": "1301722",
"lan_port2_switch_mode": "1301722",
"lan_port3_switch_mode": "1301722",
"lan_port4_switch_mode": "1301722",
"lan_port1_switch_speed": "10",
"lan_port2_switch_speed": "100",
"lan_port3_switch_speed": "1000",
"lan_port4_switch_speed": "1000",
"lan_port1_switch_status": "1301724",
"lan_port2_switch_status": "1301724",
"lan_port3_switch_status": "1301724",
"lan_port4_switch_status": "1301724",
"wifi_status": "601036",
"wifi_name": "Wifi-Main-Network",
"wifi_mac_address": "AA:BB:CC:DD:EE:FF",
"wifi_security": "401027",
"wifi_channel": "8",
"wifi_bandwidth": "573",
"guest_wifi_status": "601037",
"guest_wifi_name": "Wifi-Guest",
"guest_wifi_mac_addr": "AA:BB:CC:DD:EE:GG",
"guest_wifi_security": "401027",
"guest_wifi_channel": "N/A",
"guest_wifi_ip": "192.168.2.1",
"guest_wifi_subnet_addr": "255.255.255.0",
"guest_wifi_dhcp_server": "192.168.2.1",
"wifi_status_5g": "601036",
"wifi_name_5g": "Wifi-Main-Network",
"wifi_mac_address_5g": "AA:BB:CC:DD:EE:HH",
"wifi_security_5g": "401027",
"wifi_channel_5g": "36",
"wifi_bandwidth_5g": "4803",
"guest_wifi_status_5g": "601037",
"guest_wifi_name_5g": "Wifi-Guest",
"guest_wifi_mac_addr_5g": "AA:BB:CC:DD:EE:II",
"guest_wifi_channel_5g": "N/A",
"guest_wifi_security_5g": "401027",
"guest_wifi_ip_5g": "192.168.2.1",
"guest_wifi_subnet_addr_5g": "255.255.255.0",
"guest_wifi_dhcp_server_5g": "192.168.2.1",
}

View File

@ -0,0 +1,81 @@
{
"sys_serial_number": "m123456789",
"sys_firmware_version": "XF6_4.0.05.04",
"sys_bootloader_version": "0220",
"sys_hardware_version": "RHG3006 v1",
"omci_software_version": "\t\t1.0.0.1_41032\t\t\n",
"sys_uptime": "12:16:41",
"sys_cpu_usage": "97%",
"sys_reboot_cause": "Web Reboot",
"sys_memory_usage": "51.94%",
"sys_wireless_driver_version": "17.10.188.75;17.10.188.75",
"sys_wireless_driver_version_5g": "17.10.188.75;17.10.188.75",
"vf_internet_key_online_since": "",
"vf_internet_key_ip_addr": "0.0.0.0",
"vf_internet_key_system": "0.0.0.0",
"vf_internet_key_mode": "Auto",
"sys_voip_version": "v02.01.00_01.13a\n",
"sys_date_time": "20.10.2024 | 03:44 pm",
"sys_build_time": "Sun Jun 23 17:55:49 CST 2024\n",
"sys_model_name": "RHG3006",
"inter_ip_address": "1.1.1.1",
"inter_gateway": "1.1.1.2",
"inter_primary_dns": "1.1.1.3",
"inter_secondary_dns": "1.1.1.4",
"inter_firewall": "601036",
"inter_wan_ip_address": "1.1.1.1",
"inter_ipv6_link_local_address": "",
"inter_ipv6_link_global_address": "",
"inter_ipv6_gateway": "",
"inter_ipv6_prefix_delegation": "",
"inter_ipv6_dns_address1": "",
"inter_ipv6_dns_address2": "",
"lan_ip_network": "192.168.0.1/24",
"lan_default_gateway": "192.168.0.1",
"lan_subnet_address_subnet1": "",
"lan_mac_address": "11:22:33:44:55:66",
"lan_dhcp_server": "601036",
"lan_dhcpv6_server": "601036",
"lan_router_advertisement": "601036",
"lan_ipv6_default_gateway": "fe80::1",
"lan_port1_switch_mode": "1301722",
"lan_port2_switch_mode": "1301722",
"lan_port3_switch_mode": "1301722",
"lan_port4_switch_mode": "1301722",
"lan_port1_switch_speed": "10",
"lan_port2_switch_speed": "100",
"lan_port3_switch_speed": "1000",
"lan_port4_switch_speed": "1000",
"lan_port1_switch_status": "1301724",
"lan_port2_switch_status": "1301724",
"lan_port3_switch_status": "1301724",
"lan_port4_switch_status": "1301724",
"wifi_status": "601036",
"wifi_name": "Wifi-Main-Network",
"wifi_mac_address": "AA:BB:CC:DD:EE:FF",
"wifi_security": "401027",
"wifi_channel": "8",
"wifi_bandwidth": "573",
"guest_wifi_status": "601037",
"guest_wifi_name": "Wifi-Guest",
"guest_wifi_mac_addr": "AA:BB:CC:DD:EE:GG",
"guest_wifi_security": "401027",
"guest_wifi_channel": "N/A",
"guest_wifi_ip": "192.168.2.1",
"guest_wifi_subnet_addr": "255.255.255.0",
"guest_wifi_dhcp_server": "192.168.2.1",
"wifi_status_5g": "601036",
"wifi_name_5g": "Wifi-Main-Network",
"wifi_mac_address_5g": "AA:BB:CC:DD:EE:HH",
"wifi_security_5g": "401027",
"wifi_channel_5g": "36",
"wifi_bandwidth_5g": "4803",
"guest_wifi_status_5g": "601037",
"guest_wifi_name_5g": "Wifi-Guest",
"guest_wifi_mac_addr_5g": "AA:BB:CC:DD:EE:II",
"guest_wifi_channel_5g": "N/A",
"guest_wifi_security_5g": "401027",
"guest_wifi_ip_5g": "192.168.2.1",
"guest_wifi_subnet_addr_5g": "255.255.255.0",
"guest_wifi_dhcp_server_5g": "192.168.2.1"
}

View File

@ -0,0 +1,48 @@
# serializer version: 1
# name: test_all_entities[button.vodafone_station_m123456789_restart-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'button',
'entity_category': <EntityCategory.CONFIG: 'config'>,
'entity_id': 'button.vodafone_station_m123456789_restart',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <ButtonDeviceClass.RESTART: 'restart'>,
'original_icon': None,
'original_name': 'Restart',
'platform': 'vodafone_station',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'm123456789_reboot',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[button.vodafone_station_m123456789_restart-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'restart',
'friendly_name': 'Vodafone Station (m123456789) Restart',
}),
'context': <ANY>,
'entity_id': 'button.vodafone_station_m123456789_restart',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---

View File

@ -0,0 +1,50 @@
# serializer version: 1
# name: test_all_entities[device_tracker.vodafone_station_xx_xx_xx_xx_xx_xx-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'device_tracker',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'device_tracker.vodafone_station_xx_xx_xx_xx_xx_xx',
'has_entity_name': False,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': None,
'platform': 'vodafone_station',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'device_tracker',
'unique_id': 'xx:xx:xx:xx:xx:xx',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[device_tracker.vodafone_station_xx_xx_xx_xx_xx_xx-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'host_name': 'WifiDevice0',
'ip': '192.168.1.10',
'mac': 'xx:xx:xx:xx:xx:xx',
'source_type': <SourceType.ROUTER: 'router'>,
}),
'context': <ANY>,
'entity_id': 'device_tracker.vodafone_station_xx_xx_xx_xx_xx_xx',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'home',
})
# ---

View File

@ -0,0 +1,246 @@
# serializer version: 1
# name: test_all_entities[sensor.vodafone_station_m123456789_active_connection-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'options': list([
'dsl',
'fiber',
'internet_key',
]),
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.vodafone_station_m123456789_active_connection',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.ENUM: 'enum'>,
'original_icon': None,
'original_name': 'Active connection',
'platform': 'vodafone_station',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'active_connection',
'unique_id': 'm123456789_inter_ip_address',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_active_connection-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'enum',
'friendly_name': 'Vodafone Station (m123456789) Active connection',
'options': list([
'dsl',
'fiber',
'internet_key',
]),
}),
'context': <ANY>,
'entity_id': 'sensor.vodafone_station_m123456789_active_connection',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_cpu_usage-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.vodafone_station_m123456789_cpu_usage',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'CPU usage',
'platform': 'vodafone_station',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'sys_cpu_usage',
'unique_id': 'm123456789_sys_cpu_usage',
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_cpu_usage-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Vodafone Station (m123456789) CPU usage',
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.vodafone_station_m123456789_cpu_usage',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '97.0',
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_memory_usage-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.vodafone_station_m123456789_memory_usage',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Memory usage',
'platform': 'vodafone_station',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'sys_memory_usage',
'unique_id': 'm123456789_sys_memory_usage',
'unit_of_measurement': '%',
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_memory_usage-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Vodafone Station (m123456789) Memory usage',
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.vodafone_station_m123456789_memory_usage',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '51.94',
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_reboot_cause-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.vodafone_station_m123456789_reboot_cause',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Reboot cause',
'platform': 'vodafone_station',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'sys_reboot_cause',
'unique_id': 'm123456789_sys_reboot_cause',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_reboot_cause-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Vodafone Station (m123456789) Reboot cause',
}),
'context': <ANY>,
'entity_id': 'sensor.vodafone_station_m123456789_reboot_cause',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'Web Reboot',
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_uptime-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': <EntityCategory.DIAGNOSTIC: 'diagnostic'>,
'entity_id': 'sensor.vodafone_station_m123456789_uptime',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Uptime',
'platform': 'vodafone_station',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'sys_uptime',
'unique_id': 'm123456789_sys_uptime',
'unit_of_measurement': None,
})
# ---
# name: test_all_entities[sensor.vodafone_station_m123456789_uptime-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'friendly_name': 'Vodafone Station (m123456789) Uptime',
}),
'context': <ANY>,
'entity_id': 'sensor.vodafone_station_m123456789_uptime',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '2024-11-19T20:19:00+00:00',
})
# ---

View File

@ -1,56 +1,48 @@
"""Tests for Vodafone Station button platform."""
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
from syrupy import SnapshotAssertion
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS
from homeassistant.components.vodafone_station.const import DOMAIN
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_registry import EntityRegistry
from homeassistant.helpers import entity_registry as er
from .const import DEVICE_DATA_QUERY, MOCK_USER_DATA, SENSOR_DATA_QUERY, SERIAL
from . import setup_integration
from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, snapshot_platform
async def test_button(hass: HomeAssistant, entity_registry: EntityRegistry) -> None:
async def test_all_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test all entities."""
with patch(
"homeassistant.components.vodafone_station.PLATFORMS", [Platform.BUTTON]
):
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
async def test_pressing_button(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test device restart button."""
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
entry.add_to_hass(hass)
await setup_integration(hass, mock_config_entry)
with (
patch("aiovodafone.api.VodafoneStationSercommApi.login"),
patch(
"aiovodafone.api.VodafoneStationSercommApi.get_devices_data",
return_value=DEVICE_DATA_QUERY,
),
patch(
"aiovodafone.api.VodafoneStationSercommApi.get_sensor_data",
return_value=SENSOR_DATA_QUERY,
),
patch(
"aiovodafone.api.VodafoneStationSercommApi.restart_router",
) as mock_router_restart,
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_id = f"button.vodafone_station_{SERIAL}_restart"
# restart button
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_UNKNOWN
entry = entity_registry.async_get(entity_id)
assert entry
assert entry.unique_id == f"{SERIAL}_reboot"
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{ATTR_ENTITY_ID: entity_id},
blocking=True,
)
assert mock_router_restart.call_count == 1
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{ATTR_ENTITY_ID: "button.vodafone_station_m123456789_restart"},
blocking=True,
)
mock_vodafone_station_router.restart_router.assert_called_once()

View File

@ -1,8 +1,13 @@
"""Tests for Vodafone Station config flow."""
from unittest.mock import patch
from unittest.mock import AsyncMock
from aiovodafone import exceptions as aiovodafone_exceptions
from aiovodafone import (
AlreadyLogged,
CannotAuthenticate,
CannotConnect,
ModelNotSupported,
)
import pytest
from homeassistant.components.device_tracker import CONF_CONSIDER_HOME
@ -12,39 +17,36 @@ from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from .const import MOCK_USER_DATA
from tests.common import MockConfigEntry
async def test_user(hass: HomeAssistant) -> None:
async def test_user(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_setup_entry: AsyncMock,
) -> None:
"""Test starting a flow by user."""
with (
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.login",
),
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.logout",
),
patch(
"homeassistant.components.vodafone_station.async_setup_entry"
) as mock_setup_entry,
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=MOCK_USER_DATA
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"][CONF_HOST] == "fake_host"
assert result["data"][CONF_USERNAME] == "fake_username"
assert result["data"][CONF_PASSWORD] == "fake_password"
assert not result["result"].unique_id
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"] == {
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
}
assert not result["result"].unique_id
assert mock_setup_entry.called
@ -52,14 +54,20 @@ async def test_user(hass: HomeAssistant) -> None:
@pytest.mark.parametrize(
("side_effect", "error"),
[
(aiovodafone_exceptions.CannotConnect, "cannot_connect"),
(aiovodafone_exceptions.CannotAuthenticate, "invalid_auth"),
(aiovodafone_exceptions.AlreadyLogged, "already_logged"),
(aiovodafone_exceptions.ModelNotSupported, "model_not_supported"),
(CannotConnect, "cannot_connect"),
(CannotAuthenticate, "invalid_auth"),
(AlreadyLogged, "already_logged"),
(ModelNotSupported, "model_not_supported"),
(ConnectionResetError, "unknown"),
],
)
async def test_exception_connection(hass: HomeAssistant, side_effect, error) -> None:
async def test_exception_connection(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_setup_entry: AsyncMock,
side_effect: Exception,
error: str,
) -> None:
"""Test starting a flow by user with a connection error."""
result = await hass.config_entries.flow.async_init(
@ -68,178 +76,153 @@ async def test_exception_connection(hass: HomeAssistant, side_effect, error) ->
assert result.get("type") is FlowResultType.FORM
assert result.get("step_id") == "user"
with patch(
"aiovodafone.api.VodafoneStationSercommApi.login",
side_effect=side_effect,
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=MOCK_USER_DATA
)
mock_vodafone_station_router.login.side_effect = side_effect
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] is not None
assert result["errors"]["base"] == error
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
},
)
# Should be recoverable after hits error
with (
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.get_devices_data",
return_value={
"wifi_user": "on|laptop|device-1|xx:xx:xx:xx:xx:xx|192.168.100.1||2.4G",
"ethernet": "laptop|device-2|yy:yy:yy:yy:yy:yy|192.168.100.2|;",
},
),
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.login",
),
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.logout",
),
patch(
"homeassistant.components.vodafone_station.async_setup_entry",
),
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": error}
assert result2["type"] is FlowResultType.CREATE_ENTRY
assert result2["title"] == "fake_host"
assert result2["data"] == {
"host": "fake_host",
"username": "fake_username",
"password": "fake_password",
}
mock_vodafone_station_router.login.side_effect = None
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "fake_host"
assert result["data"] == {
"host": "fake_host",
"username": "fake_username",
"password": "fake_password",
}
async def test_reauth_successful(hass: HomeAssistant) -> None:
async def test_duplicate_entry(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test starting a flow by user with a duplicate entry."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "fake_host",
CONF_USERNAME: "fake_username",
CONF_PASSWORD: "fake_password",
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_reauth_successful(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_setup_entry: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test starting a reauthentication flow."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
result = await mock_config.start_reauth_flow(hass)
mock_config_entry.add_to_hass(hass)
result = await mock_config_entry.start_reauth_flow(hass)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
with (
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.login",
),
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.logout",
),
patch(
"homeassistant.components.vodafone_station.async_setup_entry",
),
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PASSWORD: "other_fake_password",
},
)
await hass.async_block_till_done()
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PASSWORD: "other_fake_password",
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
@pytest.mark.parametrize(
("side_effect", "error"),
[
(aiovodafone_exceptions.CannotConnect, "cannot_connect"),
(aiovodafone_exceptions.CannotAuthenticate, "invalid_auth"),
(aiovodafone_exceptions.AlreadyLogged, "already_logged"),
(CannotConnect, "cannot_connect"),
(CannotAuthenticate, "invalid_auth"),
(AlreadyLogged, "already_logged"),
(ConnectionResetError, "unknown"),
],
)
async def test_reauth_not_successful(hass: HomeAssistant, side_effect, error) -> None:
async def test_reauth_not_successful(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_setup_entry: AsyncMock,
mock_config_entry: MockConfigEntry,
side_effect: Exception,
error: str,
) -> None:
"""Test starting a reauthentication flow but no connection found."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
result = await mock_config.start_reauth_flow(hass)
mock_config_entry.add_to_hass(hass)
result = await mock_config_entry.start_reauth_flow(hass)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
with (
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.login",
side_effect=side_effect,
),
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.logout",
),
patch(
"homeassistant.components.vodafone_station.async_setup_entry",
),
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PASSWORD: "other_fake_password",
},
)
mock_vodafone_station_router.login.side_effect = side_effect
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PASSWORD: "other_fake_password",
},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
assert result["errors"] is not None
assert result["errors"]["base"] == error
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
assert result["errors"] == {"base": error}
# Should be recoverable after hits error
with (
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.get_devices_data",
return_value={
"wifi_user": "on|laptop|device-1|xx:xx:xx:xx:xx:xx|192.168.100.1||2.4G",
"ethernet": "laptop|device-2|yy:yy:yy:yy:yy:yy|192.168.100.2|;",
},
),
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.login",
),
patch(
"homeassistant.components.vodafone_station.config_flow.VodafoneStationSercommApi.logout",
),
patch(
"homeassistant.components.vodafone_station.async_setup_entry",
),
):
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PASSWORD: "fake_password",
},
)
await hass.async_block_till_done()
mock_vodafone_station_router.login.side_effect = None
assert result2["type"] is FlowResultType.ABORT
assert result2["reason"] == "reauth_successful"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_PASSWORD: "fake_password",
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert mock_config_entry.data[CONF_PASSWORD] == "fake_password"
async def test_options_flow(hass: HomeAssistant) -> None:
async def test_options_flow(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_setup_entry: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test options flow."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
result = await hass.config_entries.options.async_init(mock_config.entry_id)
await hass.async_block_till_done()
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.options.async_init(mock_config_entry.entry_id)
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_CONSIDER_HOME: 37,
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"] == {

View File

@ -1,43 +1,59 @@
"""Define tests for the Vodafone Station device tracker."""
from unittest.mock import AsyncMock
from unittest.mock import AsyncMock, patch
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.vodafone_station.const import DOMAIN, SCAN_INTERVAL
from homeassistant.components.vodafone_station.const import SCAN_INTERVAL
from homeassistant.components.vodafone_station.coordinator import CONSIDER_HOME_SECONDS
from homeassistant.const import STATE_HOME, STATE_NOT_HOME
from homeassistant.const import STATE_HOME, STATE_NOT_HOME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .const import DEVICE_1, DEVICE_1_MAC, DEVICE_DATA_QUERY, MOCK_USER_DATA
from . import setup_integration
from .const import DEVICE_1_MAC
from tests.common import MockConfigEntry, async_fire_time_changed
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_coordinator_consider_home(
async def test_all_entities(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
snapshot: SnapshotAssertion,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test all entities."""
with patch(
"homeassistant.components.vodafone_station.PLATFORMS", [Platform.DEVICE_TRACKER]
):
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_consider_home(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test if device is considered not_home when disconnected."""
await setup_integration(hass, mock_config_entry)
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
entry.add_to_hass(hass)
device_tracker = f"device_tracker.vodafone_station_{DEVICE_1_MAC.replace(":", "_")}"
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
device_tracker = "device_tracker.vodafone_station_xx_xx_xx_xx_xx_xx"
state = hass.states.get(device_tracker)
assert state
assert state.state == STATE_HOME
DEVICE_1[DEVICE_1_MAC].connected = False
DEVICE_DATA_QUERY.update(DEVICE_1)
mock_vodafone_station_router.get_devices_data.return_value = DEVICE_DATA_QUERY
mock_vodafone_station_router.get_devices_data.return_value[
DEVICE_1_MAC
].connected = False
freezer.tick(SCAN_INTERVAL + CONSIDER_HOME_SECONDS)
async_fire_time_changed(hass)

View File

@ -2,16 +2,14 @@
from __future__ import annotations
from unittest.mock import patch
from unittest.mock import AsyncMock
from syrupy import SnapshotAssertion
from syrupy.filters import props
from homeassistant.components.vodafone_station.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from .const import DEVICE_DATA_QUERY, MOCK_USER_DATA, SENSOR_DATA_QUERY
from . import setup_integration
from tests.common import MockConfigEntry
from tests.components.diagnostics import get_diagnostics_for_config_entry
@ -20,29 +18,17 @@ from tests.typing import ClientSessionGenerator
async def test_entry_diagnostics(
hass: HomeAssistant,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
hass_client: ClientSessionGenerator,
snapshot: SnapshotAssertion,
) -> None:
"""Test config entry diagnostics."""
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
entry.add_to_hass(hass)
await setup_integration(hass, mock_config_entry)
with (
patch("aiovodafone.api.VodafoneStationSercommApi.login"),
patch(
"aiovodafone.api.VodafoneStationSercommApi.get_devices_data",
return_value=DEVICE_DATA_QUERY,
),
patch(
"aiovodafone.api.VodafoneStationSercommApi.get_sensor_data",
return_value=SENSOR_DATA_QUERY,
),
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state == ConfigEntryState.LOADED
assert await get_diagnostics_for_config_entry(hass, hass_client, entry) == snapshot(
assert await get_diagnostics_for_config_entry(
hass, hass_client, mock_config_entry
) == snapshot(
exclude=props(
"entry_id",
"created_at",

View File

@ -1,21 +1,37 @@
"""Tests for Vodafone Station sensor platform."""
from copy import deepcopy
from unittest.mock import AsyncMock
from unittest.mock import AsyncMock, patch
from aiovodafone import CannotAuthenticate
from aiovodafone.exceptions import AlreadyLogged, CannotConnect
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.vodafone_station.const import (
DOMAIN,
LINE_TYPES,
SCAN_INTERVAL,
)
from homeassistant.components.vodafone_station.const import LINE_TYPES, SCAN_INTERVAL
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from .const import MOCK_USER_DATA, SENSOR_DATA_QUERY
from . import setup_integration
from tests.common import MockConfigEntry, async_fire_time_changed
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
async def test_all_entities(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test all entities."""
with patch(
"homeassistant.components.vodafone_station.PLATFORMS", [Platform.SENSOR]
):
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
@pytest.mark.parametrize(
@ -30,26 +46,22 @@ async def test_active_connection_type(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
mock_vodafone_station_router: AsyncMock,
connection_type,
index,
mock_config_entry: MockConfigEntry,
connection_type: str,
index: int,
) -> None:
"""Test device connection type."""
await setup_integration(hass, mock_config_entry)
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
entry.add_to_hass(hass)
active_connection_entity = f"sensor.vodafone_station_{SENSOR_DATA_QUERY['sys_serial_number']}_active_connection"
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
active_connection_entity = "sensor.vodafone_station_m123456789_active_connection"
state = hass.states.get(active_connection_entity)
assert state
assert state.state == "unknown"
assert state.state == STATE_UNKNOWN
sensor_data = deepcopy(SENSOR_DATA_QUERY)
sensor_data[connection_type] = "1.1.1.1"
mock_vodafone_station_router.get_sensor_data.return_value = sensor_data
mock_vodafone_station_router.get_sensor_data.return_value[connection_type] = (
"1.1.1.1"
)
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
@ -65,19 +77,13 @@ async def test_uptime(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test device uptime shift."""
entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
entry.add_to_hass(hass)
await setup_integration(hass, mock_config_entry)
uptime = "2024-11-19T20:19:00+00:00"
uptime_entity = (
f"sensor.vodafone_station_{SENSOR_DATA_QUERY['sys_serial_number']}_uptime"
)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
uptime_entity = "sensor.vodafone_station_m123456789_uptime"
state = hass.states.get(uptime_entity)
assert state
@ -92,3 +98,32 @@ async def test_uptime(
state = hass.states.get(uptime_entity)
assert state
assert state.state == uptime
@pytest.mark.parametrize(
"side_effect",
[
CannotConnect,
CannotAuthenticate,
AlreadyLogged,
ConnectionResetError,
],
)
async def test_coordinator_client_connector_error(
hass: HomeAssistant,
freezer: FrozenDateTimeFactory,
mock_vodafone_station_router: AsyncMock,
mock_config_entry: MockConfigEntry,
side_effect: Exception,
) -> None:
"""Test ClientConnectorError on coordinator update."""
await setup_integration(hass, mock_config_entry)
mock_vodafone_station_router.get_devices_data.side_effect = side_effect
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done(wait_background_tasks=True)
state = hass.states.get("sensor.vodafone_station_m123456789_uptime")
assert state
assert state.state == STATE_UNAVAILABLE