Add typing hints to mikrotik tests (#79144)

This commit is contained in:
Rami Mosleh 2022-09-28 14:05:45 +03:00 committed by GitHub
parent 4843d330f3
commit 9bd2117240
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 51 deletions

View File

@ -25,7 +25,7 @@ class Device:
@property @property
def name(self) -> str: def name(self) -> str:
"""Return device name.""" """Return device name."""
return self._params.get("host-name", self.mac) return str(self._params.get("host-name", self.mac))
@property @property
def ip_address(self) -> str | None: def ip_address(self) -> str | None:

View File

@ -83,7 +83,7 @@ class MikrotikDataUpdateCoordinatorTracker(
"""Initialize the tracked device.""" """Initialize the tracked device."""
super().__init__(coordinator) super().__init__(coordinator)
self.device = device self.device = device
self._attr_name = str(device.name) self._attr_name = device.name
self._attr_unique_id = device.mac self._attr_unique_id = device.mac
@property @property

View File

@ -1,4 +1,7 @@
"""Tests for the Mikrotik component.""" """Tests for the Mikrotik component."""
from __future__ import annotations
from typing import Any
from unittest.mock import patch from unittest.mock import patch
from homeassistant.components import mikrotik from homeassistant.components import mikrotik
@ -16,6 +19,7 @@ from homeassistant.const import (
CONF_USERNAME, CONF_USERNAME,
CONF_VERIFY_SSL, CONF_VERIFY_SSL,
) )
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@ -137,13 +141,13 @@ ARP_DATA = [
] ]
async def setup_mikrotik_entry(hass, **kwargs): async def setup_mikrotik_entry(hass: HomeAssistant, **kwargs: Any) -> None:
"""Set up Mikrotik integration successfully.""" """Set up Mikrotik integration successfully."""
support_wireless = kwargs.get("support_wireless", True) support_wireless: bool = kwargs.get("support_wireless", True)
dhcp_data = kwargs.get("dhcp_data", DHCP_DATA) dhcp_data: list[dict[str, Any]] = kwargs.get("dhcp_data", DHCP_DATA)
wireless_data = kwargs.get("wireless_data", WIRELESS_DATA) wireless_data: list[dict[str, Any]] = kwargs.get("wireless_data", WIRELESS_DATA)
def mock_command(self, cmd, params=None): def mock_command(self, cmd: str, params: dict[str, Any] | None = None) -> Any:
if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]: if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]:
return support_wireless return support_wireless
if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.DHCP]: if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.DHCP]:
@ -154,16 +158,17 @@ async def setup_mikrotik_entry(hass, **kwargs):
return ARP_DATA return ARP_DATA
return {} return {}
config_entry = MockConfigEntry( options: dict[str, Any] = {}
domain=mikrotik.DOMAIN, data=MOCK_DATA, options=MOCK_OPTIONS
)
config_entry.add_to_hass(hass)
if "force_dhcp" in kwargs: if "force_dhcp" in kwargs:
config_entry.options = {**config_entry.options, "force_dhcp": True} options.update({"force_dhcp": True})
if "arp_ping" in kwargs: if "arp_ping" in kwargs:
config_entry.options = {**config_entry.options, "arp_ping": True} options.update({"arp_ping": True})
config_entry = MockConfigEntry(
domain=mikrotik.DOMAIN, data=MOCK_DATA, options=options
)
config_entry.add_to_hass(hass)
with patch("librouteros.connect"), patch.object( with patch("librouteros.connect"), patch.object(
mikrotik.hub.MikrotikData, "command", new=mock_command mikrotik.hub.MikrotikData, "command", new=mock_command

View File

@ -1,5 +1,8 @@
"""The tests for the Mikrotik device tracker platform.""" """The tests for the Mikrotik device tracker platform."""
from __future__ import annotations
from datetime import timedelta from datetime import timedelta
from typing import Any
from freezegun import freeze_time from freezegun import freeze_time
import pytest import pytest
@ -7,6 +10,7 @@ import pytest
from homeassistant.components import mikrotik from homeassistant.components import mikrotik
import homeassistant.components.device_tracker as device_tracker import homeassistant.components.device_tracker as device_tracker
from homeassistant.const import STATE_UNAVAILABLE from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
@ -25,7 +29,7 @@ from tests.common import MockConfigEntry, async_fire_time_changed, patch
@pytest.fixture @pytest.fixture
def mock_device_registry_devices(hass): def mock_device_registry_devices(hass: HomeAssistant) -> None:
"""Create device registry devices so the device tracker entities are enabled.""" """Create device registry devices so the device tracker entities are enabled."""
dev_reg = dr.async_get(hass) dev_reg = dr.async_get(hass)
config_entry = MockConfigEntry(domain="something_else") config_entry = MockConfigEntry(domain="something_else")
@ -44,7 +48,7 @@ def mock_device_registry_devices(hass):
) )
def mock_command(self, cmd, params=None): def mock_command(self, cmd: str, params: dict[str, Any] | None = None) -> Any:
"""Mock the Mikrotik command method.""" """Mock the Mikrotik command method."""
if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]: if cmd == mikrotik.const.MIKROTIK_SERVICES[mikrotik.const.IS_WIRELESS]:
return True return True
@ -55,20 +59,20 @@ def mock_command(self, cmd, params=None):
return {} return {}
async def test_device_trackers(hass, mock_device_registry_devices): async def test_device_trackers(
hass: HomeAssistant, mock_device_registry_devices
) -> None:
"""Test device_trackers created by mikrotik.""" """Test device_trackers created by mikrotik."""
# test devices are added from wireless list only # test devices are added from wireless list only
await setup_mikrotik_entry(hass) await setup_mikrotik_entry(hass)
device_1 = hass.states.get("device_tracker.device_1") device_1 = hass.states.get("device_tracker.device_1")
assert device_1 is not None assert device_1
assert device_1.state == "home" assert device_1.state == "home"
assert device_1.attributes["ip"] == "0.0.0.1" assert device_1.attributes["ip"] == "0.0.0.1"
assert "ip_address" not in device_1.attributes
assert device_1.attributes["mac"] == "00:00:00:00:00:01" assert device_1.attributes["mac"] == "00:00:00:00:00:01"
assert device_1.attributes["host_name"] == "Device_1" assert device_1.attributes["host_name"] == "Device_1"
assert "mac_address" not in device_1.attributes
device_2 = hass.states.get("device_tracker.device_2") device_2 = hass.states.get("device_tracker.device_2")
assert device_2 is None assert device_2 is None
@ -80,33 +84,33 @@ async def test_device_trackers(hass, mock_device_registry_devices):
await hass.async_block_till_done() await hass.async_block_till_done()
device_2 = hass.states.get("device_tracker.device_2") device_2 = hass.states.get("device_tracker.device_2")
assert device_2 is not None assert device_2
assert device_2.state == "home" assert device_2.state == "home"
assert device_2.attributes["ip"] == "0.0.0.2" assert device_2.attributes["ip"] == "0.0.0.2"
assert "ip_address" not in device_2.attributes
assert device_2.attributes["mac"] == "00:00:00:00:00:02" assert device_2.attributes["mac"] == "00:00:00:00:00:02"
assert "mac_address" not in device_2.attributes
assert device_2.attributes["host_name"] == "Device_2" assert device_2.attributes["host_name"] == "Device_2"
# test state remains home if last_seen consider_home_interval # test state remains home if last_seen within consider_home_interval
del WIRELESS_DATA[1] # device 2 is removed from wireless list del WIRELESS_DATA[1] # device 2 is removed from wireless list
with freeze_time(utcnow() + timedelta(minutes=4)): with freeze_time(utcnow() + timedelta(minutes=4)):
async_fire_time_changed(hass, utcnow() + timedelta(minutes=4)) async_fire_time_changed(hass, utcnow() + timedelta(minutes=4))
await hass.async_block_till_done() await hass.async_block_till_done()
device_2 = hass.states.get("device_tracker.device_2") device_2 = hass.states.get("device_tracker.device_2")
assert device_2
assert device_2.state == "home" assert device_2.state == "home"
# test state changes to away if last_seen > consider_home_interval # test state changes to away if last_seen past consider_home_interval
with freeze_time(utcnow() + timedelta(minutes=6)): with freeze_time(utcnow() + timedelta(minutes=6)):
async_fire_time_changed(hass, utcnow() + timedelta(minutes=6)) async_fire_time_changed(hass, utcnow() + timedelta(minutes=6))
await hass.async_block_till_done() await hass.async_block_till_done()
device_2 = hass.states.get("device_tracker.device_2") device_2 = hass.states.get("device_tracker.device_2")
assert device_2
assert device_2.state == "not_home" assert device_2.state == "not_home"
async def test_force_dhcp(hass, mock_device_registry_devices): async def test_force_dhcp(hass: HomeAssistant, mock_device_registry_devices) -> None:
"""Test updating hub that supports wireless with forced dhcp method.""" """Test updating hub that supports wireless with forced dhcp method."""
# hub supports wireless by default, force_dhcp is enabled to override # hub supports wireless by default, force_dhcp is enabled to override
@ -120,7 +124,9 @@ async def test_force_dhcp(hass, mock_device_registry_devices):
assert device_2.state == "home" assert device_2.state == "home"
async def test_hub_not_support_wireless(hass, mock_device_registry_devices): async def test_hub_not_support_wireless(
hass: HomeAssistant, mock_device_registry_devices
) -> None:
"""Test device_trackers created when hub doesn't support wireless.""" """Test device_trackers created when hub doesn't support wireless."""
await setup_mikrotik_entry(hass, support_wireless=False) await setup_mikrotik_entry(hass, support_wireless=False)
@ -133,7 +139,9 @@ async def test_hub_not_support_wireless(hass, mock_device_registry_devices):
assert device_2.state == "home" assert device_2.state == "home"
async def test_arp_ping_success(hass, mock_device_registry_devices): async def test_arp_ping_success(
hass: HomeAssistant, mock_device_registry_devices
) -> None:
"""Test arp ping devices to confirm they are connected.""" """Test arp ping devices to confirm they are connected."""
with patch.object(mikrotik.hub.MikrotikData, "do_arp_ping", return_value=True): with patch.object(mikrotik.hub.MikrotikData, "do_arp_ping", return_value=True):
@ -145,7 +153,9 @@ async def test_arp_ping_success(hass, mock_device_registry_devices):
assert device_2.state == "home" assert device_2.state == "home"
async def test_arp_ping_timeout(hass, mock_device_registry_devices): async def test_arp_ping_timeout(
hass: HomeAssistant, mock_device_registry_devices
) -> None:
"""Test arp ping timeout so devices are shown away.""" """Test arp ping timeout so devices are shown away."""
with patch.object(mikrotik.hub.MikrotikData, "do_arp_ping", return_value=False): with patch.object(mikrotik.hub.MikrotikData, "do_arp_ping", return_value=False):
await setup_mikrotik_entry(hass, arp_ping=True, force_dhcp=True) await setup_mikrotik_entry(hass, arp_ping=True, force_dhcp=True)
@ -156,7 +166,9 @@ async def test_arp_ping_timeout(hass, mock_device_registry_devices):
assert device_2.state == "not_home" assert device_2.state == "not_home"
async def test_device_trackers_numerical_name(hass, mock_device_registry_devices): async def test_device_trackers_numerical_name(
hass: HomeAssistant, mock_device_registry_devices
) -> None:
"""Test device_trackers created by mikrotik with numerical device name.""" """Test device_trackers created by mikrotik with numerical device name."""
await setup_mikrotik_entry( await setup_mikrotik_entry(
@ -164,17 +176,15 @@ async def test_device_trackers_numerical_name(hass, mock_device_registry_devices
) )
device_3 = hass.states.get("device_tracker.123") device_3 = hass.states.get("device_tracker.123")
assert device_3 is not None assert device_3
assert device_3.state == "home" assert device_3.state == "home"
assert device_3.attributes["friendly_name"] == "123" assert device_3.attributes["friendly_name"] == "123"
assert device_3.attributes["ip"] == "0.0.0.3" assert device_3.attributes["ip"] == "0.0.0.3"
assert "ip_address" not in device_3.attributes
assert device_3.attributes["mac"] == "00:00:00:00:00:03" assert device_3.attributes["mac"] == "00:00:00:00:00:03"
assert device_3.attributes["host_name"] == 123 assert device_3.attributes["host_name"] == "123"
assert "mac_address" not in device_3.attributes
async def test_restoring_devices(hass): async def test_restoring_devices(hass: HomeAssistant) -> None:
"""Test restoring existing device_tracker entities if not detected on startup.""" """Test restoring existing device_tracker entities if not detected on startup."""
config_entry = MockConfigEntry( config_entry = MockConfigEntry(
domain=mikrotik.DOMAIN, data=MOCK_DATA, options=MOCK_OPTIONS domain=mikrotik.DOMAIN, data=MOCK_DATA, options=MOCK_OPTIONS
@ -219,7 +229,7 @@ async def test_restoring_devices(hass):
assert device_3 is None assert device_3 is None
async def test_update_failed(hass, mock_device_registry_devices): async def test_update_failed(hass: HomeAssistant, mock_device_registry_devices) -> None:
"""Test failing to connect during update.""" """Test failing to connect during update."""
await setup_mikrotik_entry(hass) await setup_mikrotik_entry(hass)
@ -231,4 +241,5 @@ async def test_update_failed(hass, mock_device_registry_devices):
await hass.async_block_till_done() await hass.async_block_till_done()
device_1 = hass.states.get("device_tracker.device_1") device_1 = hass.states.get("device_tracker.device_1")
assert device_1
assert device_1.state == STATE_UNAVAILABLE assert device_1.state == STATE_UNAVAILABLE

View File

@ -1,5 +1,5 @@
"""Test Mikrotik setup process.""" """Test Mikrotik setup process."""
from unittest.mock import patch from unittest.mock import MagicMock, patch
from librouteros.exceptions import ConnectionClosed, LibRouterosError from librouteros.exceptions import ConnectionClosed, LibRouterosError
import pytest import pytest
@ -7,7 +7,7 @@ import pytest
from homeassistant.components import mikrotik from homeassistant.components import mikrotik
from homeassistant.components.mikrotik.const import DOMAIN from homeassistant.components.mikrotik.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.setup import async_setup_component from homeassistant.core import HomeAssistant
from . import MOCK_DATA from . import MOCK_DATA
@ -23,13 +23,7 @@ def mock_api():
yield mock_api yield mock_api
async def test_setup_with_no_config(hass): async def test_successful_config_entry(hass: HomeAssistant) -> None:
"""Test that we do not discover anything or try to set up a hub."""
assert await async_setup_component(hass, mikrotik.DOMAIN, {}) is True
assert mikrotik.DOMAIN not in hass.data
async def test_successful_config_entry(hass):
"""Test config entry successful setup.""" """Test config entry successful setup."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain=mikrotik.DOMAIN, domain=mikrotik.DOMAIN,
@ -41,8 +35,8 @@ async def test_successful_config_entry(hass):
assert entry.state == ConfigEntryState.LOADED assert entry.state == ConfigEntryState.LOADED
async def test_hub_conn_error(hass, mock_api): async def test_hub_connection_error(hass: HomeAssistant, mock_api: MagicMock) -> None:
"""Test that a failed setup will not store the hub.""" """Test setup fails due to connection error."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain=mikrotik.DOMAIN, domain=mikrotik.DOMAIN,
data=MOCK_DATA, data=MOCK_DATA,
@ -56,8 +50,10 @@ async def test_hub_conn_error(hass, mock_api):
assert entry.state == ConfigEntryState.SETUP_RETRY assert entry.state == ConfigEntryState.SETUP_RETRY
async def test_hub_auth_error(hass, mock_api): async def test_hub_authentication_error(
"""Test that a failed setup will not store the hub.""" hass: HomeAssistant, mock_api: MagicMock
) -> None:
"""Test setup fails due to authentication error."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain=mikrotik.DOMAIN, domain=mikrotik.DOMAIN,
data=MOCK_DATA, data=MOCK_DATA,
@ -71,8 +67,8 @@ async def test_hub_auth_error(hass, mock_api):
assert entry.state == ConfigEntryState.SETUP_ERROR assert entry.state == ConfigEntryState.SETUP_ERROR
async def test_unload_entry(hass) -> None: async def test_unload_entry(hass: HomeAssistant) -> None:
"""Test being able to unload an entry.""" """Test unloading an entry."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain=mikrotik.DOMAIN, domain=mikrotik.DOMAIN,
data=MOCK_DATA, data=MOCK_DATA,