Use `mock_platform` for device_tracker entity component tests instead of `hass.components` (#114398)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>pull/114435/head
parent
282cbfc048
commit
530552b4f5
|
@ -1,16 +1,18 @@
|
|||
"""Fixtures for component testing."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from collections.abc import Callable, Generator
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockToggleEntity
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from tests.components.device_tracker.common import MockScanner
|
||||
from tests.components.light.common import MockLight
|
||||
from tests.components.sensor.common import MockSensor
|
||||
|
||||
|
@ -137,3 +139,21 @@ def mock_toggle_entities() -> list[MockToggleEntity]:
|
|||
from tests.components.switch.common import get_mock_toggle_entities
|
||||
|
||||
return get_mock_toggle_entities()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_legacy_device_scanner() -> "MockScanner":
|
||||
"""Return mocked legacy device scanner entity."""
|
||||
from tests.components.device_tracker.common import MockScanner
|
||||
|
||||
return MockScanner()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_legacy_device_tracker_setup() -> (
|
||||
Callable[[HomeAssistant, "MockScanner"], None]
|
||||
):
|
||||
"""Return setup callable for legacy device tracker setup."""
|
||||
from tests.components.device_tracker.common import mock_legacy_device_tracker_setup
|
||||
|
||||
return mock_legacy_device_tracker_setup
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""The tests device sun light trigger component."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
|
||||
|
@ -26,20 +27,24 @@ from homeassistant.core import CoreState, HomeAssistant
|
|||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
from tests.common import async_fire_time_changed, setup_test_component_platform
|
||||
from tests.components.device_tracker.common import MockScanner
|
||||
from tests.components.light.common import MockLight
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def scanner(hass, enable_custom_integrations):
|
||||
async def scanner(
|
||||
hass: HomeAssistant,
|
||||
mock_light_entities: list[MockLight],
|
||||
mock_legacy_device_scanner: MockScanner,
|
||||
mock_legacy_device_tracker_setup: Callable[[HomeAssistant, MockScanner], None],
|
||||
) -> None:
|
||||
"""Initialize components."""
|
||||
scanner = await getattr(hass.components, "test.device_tracker").async_get_scanner(
|
||||
None, None
|
||||
)
|
||||
mock_legacy_device_tracker_setup(hass, mock_legacy_device_scanner)
|
||||
mock_legacy_device_scanner.reset()
|
||||
mock_legacy_device_scanner.come_home("DEV1")
|
||||
|
||||
scanner.reset()
|
||||
scanner.come_home("DEV1")
|
||||
|
||||
getattr(hass.components, "test.light").init()
|
||||
setup_test_component_platform(hass, "light", mock_light_entities)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.device_tracker.legacy.load_yaml_config_file",
|
||||
|
|
|
@ -15,11 +15,16 @@ from homeassistant.components.device_tracker import (
|
|||
ATTR_MAC,
|
||||
DOMAIN,
|
||||
SERVICE_SEE,
|
||||
DeviceScanner,
|
||||
ScannerEntity,
|
||||
SourceType,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.typing import GPSType
|
||||
from homeassistant.loader import bind_hass
|
||||
|
||||
from tests.common import MockPlatform, mock_platform
|
||||
|
||||
|
||||
@callback
|
||||
@bind_hass
|
||||
|
@ -51,3 +56,97 @@ def async_see(
|
|||
if attributes:
|
||||
data[ATTR_ATTRIBUTES] = attributes
|
||||
hass.async_create_task(hass.services.async_call(DOMAIN, SERVICE_SEE, data))
|
||||
|
||||
|
||||
class MockScannerEntity(ScannerEntity):
|
||||
"""Test implementation of a ScannerEntity."""
|
||||
|
||||
def __init__(self):
|
||||
"""Init."""
|
||||
self.connected = False
|
||||
self._hostname = "test.hostname.org"
|
||||
self._ip_address = "0.0.0.0"
|
||||
self._mac_address = "ad:de:ef:be:ed:fe"
|
||||
|
||||
@property
|
||||
def source_type(self):
|
||||
"""Return the source type, eg gps or router, of the device."""
|
||||
return SourceType.ROUTER
|
||||
|
||||
@property
|
||||
def battery_level(self):
|
||||
"""Return the battery level of the device.
|
||||
|
||||
Percentage from 0-100.
|
||||
"""
|
||||
return 100
|
||||
|
||||
@property
|
||||
def ip_address(self) -> str:
|
||||
"""Return the primary ip address of the device."""
|
||||
return self._ip_address
|
||||
|
||||
@property
|
||||
def mac_address(self) -> str:
|
||||
"""Return the mac address of the device."""
|
||||
return self._mac_address
|
||||
|
||||
@property
|
||||
def hostname(self) -> str:
|
||||
"""Return hostname of the device."""
|
||||
return self._hostname
|
||||
|
||||
@property
|
||||
def is_connected(self):
|
||||
"""Return true if the device is connected to the network."""
|
||||
return self.connected
|
||||
|
||||
def set_connected(self):
|
||||
"""Set connected to True."""
|
||||
self.connected = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
|
||||
class MockScanner(DeviceScanner):
|
||||
"""Mock device scanner."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the MockScanner."""
|
||||
self.devices_home = []
|
||||
|
||||
def come_home(self, device):
|
||||
"""Make a device come home."""
|
||||
self.devices_home.append(device)
|
||||
|
||||
def leave_home(self, device):
|
||||
"""Make a device leave the house."""
|
||||
self.devices_home.remove(device)
|
||||
|
||||
def reset(self):
|
||||
"""Reset which devices are home."""
|
||||
self.devices_home = []
|
||||
|
||||
def scan_devices(self):
|
||||
"""Return a list of fake devices."""
|
||||
return list(self.devices_home)
|
||||
|
||||
def get_device_name(self, device):
|
||||
"""Return a name for a mock device.
|
||||
|
||||
Return None for dev1 for testing.
|
||||
"""
|
||||
return None if device == "DEV1" else device.lower()
|
||||
|
||||
|
||||
def mock_legacy_device_tracker_setup(
|
||||
hass: HomeAssistant, legacy_device_scanner: MockScanner
|
||||
) -> None:
|
||||
"""Mock legacy device tracker platform setup."""
|
||||
|
||||
async def _async_get_scanner(hass, config) -> MockScanner:
|
||||
"""Return the test scanner."""
|
||||
return legacy_device_scanner
|
||||
|
||||
mocked_platform = MockPlatform()
|
||||
mocked_platform.async_get_scanner = _async_get_scanner
|
||||
mock_platform(hass, "test.device_tracker", mocked_platform)
|
||||
|
|
|
@ -31,6 +31,7 @@ from homeassistant.setup import async_setup_component
|
|||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from . import common
|
||||
from .common import MockScanner, mock_legacy_device_tracker_setup
|
||||
|
||||
from tests.common import (
|
||||
assert_setup_component,
|
||||
|
@ -58,6 +59,14 @@ def mock_yaml_devices(hass):
|
|||
os.remove(yaml_devices)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _mock_legacy_device_tracker_setup(
|
||||
hass: HomeAssistant, mock_legacy_device_scanner: MockScanner
|
||||
) -> None:
|
||||
"""Mock legacy device tracker setup."""
|
||||
mock_legacy_device_tracker_setup(hass, mock_legacy_device_scanner)
|
||||
|
||||
|
||||
async def test_is_on(hass: HomeAssistant) -> None:
|
||||
"""Test is_on method."""
|
||||
entity_id = f"{const.DOMAIN}.test"
|
||||
|
@ -99,9 +108,7 @@ async def test_reading_broken_yaml_config(hass: HomeAssistant) -> None:
|
|||
assert res[0].dev_id == "my_device"
|
||||
|
||||
|
||||
async def test_reading_yaml_config(
|
||||
hass: HomeAssistant, yaml_devices, enable_custom_integrations: None
|
||||
) -> None:
|
||||
async def test_reading_yaml_config(hass: HomeAssistant, yaml_devices) -> None:
|
||||
"""Test the rendering of the YAML configuration."""
|
||||
dev_id = "test"
|
||||
device = legacy.Device(
|
||||
|
@ -179,9 +186,7 @@ async def test_duplicate_mac_dev_id(mock_warning, hass: HomeAssistant) -> None:
|
|||
assert "Duplicate device IDs" in args[0], "Duplicate device IDs warning expected"
|
||||
|
||||
|
||||
async def test_setup_without_yaml_file(
|
||||
hass: HomeAssistant, yaml_devices, enable_custom_integrations: None
|
||||
) -> None:
|
||||
async def test_setup_without_yaml_file(hass: HomeAssistant, yaml_devices) -> None:
|
||||
"""Test with no YAML file."""
|
||||
with assert_setup_component(1, device_tracker.DOMAIN):
|
||||
assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM)
|
||||
|
@ -280,13 +285,11 @@ async def test_discover_platform_missing_platform(
|
|||
async def test_update_stale(
|
||||
hass: HomeAssistant,
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
enable_custom_integrations: None,
|
||||
mock_legacy_device_scanner: MockScanner,
|
||||
) -> None:
|
||||
"""Test stalled update."""
|
||||
|
||||
scanner = getattr(hass.components, "test.device_tracker").SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home("DEV1")
|
||||
mock_legacy_device_scanner.reset()
|
||||
mock_legacy_device_scanner.come_home("DEV1")
|
||||
|
||||
now = dt_util.utcnow()
|
||||
register_time = datetime(now.year + 1, 9, 15, 23, tzinfo=dt_util.UTC)
|
||||
|
@ -313,7 +316,7 @@ async def test_update_stale(
|
|||
|
||||
assert hass.states.get("device_tracker.dev1").state == STATE_HOME
|
||||
|
||||
scanner.leave_home("DEV1")
|
||||
mock_legacy_device_scanner.leave_home("DEV1")
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.device_tracker.legacy.dt_util.utcnow",
|
||||
|
@ -328,7 +331,6 @@ async def test_update_stale(
|
|||
async def test_entity_attributes(
|
||||
hass: HomeAssistant,
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
enable_custom_integrations: None,
|
||||
) -> None:
|
||||
"""Test the entity attributes."""
|
||||
devices = mock_device_tracker_conf
|
||||
|
@ -362,9 +364,7 @@ async def test_entity_attributes(
|
|||
|
||||
|
||||
@patch("homeassistant.components.device_tracker.legacy.DeviceTracker.async_see")
|
||||
async def test_see_service(
|
||||
mock_see, hass: HomeAssistant, enable_custom_integrations: None
|
||||
) -> None:
|
||||
async def test_see_service(mock_see, hass: HomeAssistant) -> None:
|
||||
"""Test the see service with a unicode dev_id and NO MAC."""
|
||||
with assert_setup_component(1, device_tracker.DOMAIN):
|
||||
assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM)
|
||||
|
@ -395,7 +395,6 @@ async def test_see_service(
|
|||
async def test_see_service_guard_config_entry(
|
||||
hass: HomeAssistant,
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
enable_custom_integrations: None,
|
||||
) -> None:
|
||||
"""Test the guard if the device is registered in the entity registry."""
|
||||
mock_entry = Mock()
|
||||
|
@ -416,7 +415,6 @@ async def test_see_service_guard_config_entry(
|
|||
async def test_new_device_event_fired(
|
||||
hass: HomeAssistant,
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
enable_custom_integrations: None,
|
||||
) -> None:
|
||||
"""Test that the device tracker will fire an event."""
|
||||
with assert_setup_component(1, device_tracker.DOMAIN):
|
||||
|
@ -451,7 +449,6 @@ async def test_new_device_event_fired(
|
|||
async def test_duplicate_yaml_keys(
|
||||
hass: HomeAssistant,
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
enable_custom_integrations: None,
|
||||
) -> None:
|
||||
"""Test that the device tracker will not generate invalid YAML."""
|
||||
devices = mock_device_tracker_conf
|
||||
|
@ -471,7 +468,6 @@ async def test_duplicate_yaml_keys(
|
|||
async def test_invalid_dev_id(
|
||||
hass: HomeAssistant,
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
enable_custom_integrations: None,
|
||||
) -> None:
|
||||
"""Test that the device tracker will not allow invalid dev ids."""
|
||||
devices = mock_device_tracker_conf
|
||||
|
@ -485,9 +481,7 @@ async def test_invalid_dev_id(
|
|||
assert not devices
|
||||
|
||||
|
||||
async def test_see_state(
|
||||
hass: HomeAssistant, yaml_devices, enable_custom_integrations: None
|
||||
) -> None:
|
||||
async def test_see_state(hass: HomeAssistant, yaml_devices) -> None:
|
||||
"""Test device tracker see records state correctly."""
|
||||
assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -527,7 +521,7 @@ async def test_see_state(
|
|||
async def test_see_passive_zone_state(
|
||||
hass: HomeAssistant,
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
enable_custom_integrations: None,
|
||||
mock_legacy_device_scanner: MockScanner,
|
||||
) -> None:
|
||||
"""Test that the device tracker sets gps for passive trackers."""
|
||||
now = dt_util.utcnow()
|
||||
|
@ -547,9 +541,8 @@ async def test_see_passive_zone_state(
|
|||
await async_setup_component(hass, zone.DOMAIN, {"zone": zone_info})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
scanner = getattr(hass.components, "test.device_tracker").SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home("dev1")
|
||||
mock_legacy_device_scanner.reset()
|
||||
mock_legacy_device_scanner.come_home("dev1")
|
||||
|
||||
with (
|
||||
patch(
|
||||
|
@ -581,7 +574,7 @@ async def test_see_passive_zone_state(
|
|||
assert attrs.get("gps_accuracy") == 0
|
||||
assert attrs.get("source_type") == SourceType.ROUTER
|
||||
|
||||
scanner.leave_home("dev1")
|
||||
mock_legacy_device_scanner.leave_home("dev1")
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.device_tracker.legacy.dt_util.utcnow",
|
||||
|
@ -668,12 +661,11 @@ async def test_bad_platform(hass: HomeAssistant) -> None:
|
|||
async def test_adding_unknown_device_to_config(
|
||||
mock_device_tracker_conf: list[legacy.Device],
|
||||
hass: HomeAssistant,
|
||||
enable_custom_integrations: None,
|
||||
mock_legacy_device_scanner: MockScanner,
|
||||
) -> None:
|
||||
"""Test the adding of unknown devices to configuration file."""
|
||||
scanner = getattr(hass.components, "test.device_tracker").SCANNER
|
||||
scanner.reset()
|
||||
scanner.come_home("DEV1")
|
||||
mock_legacy_device_scanner.reset()
|
||||
mock_legacy_device_scanner.come_home("DEV1")
|
||||
|
||||
await async_setup_component(
|
||||
hass, device_tracker.DOMAIN, {device_tracker.DOMAIN: {CONF_PLATFORM: "test"}}
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
"""Provide a mock device scanner."""
|
||||
|
||||
from homeassistant.components.device_tracker import DeviceScanner
|
||||
from homeassistant.components.device_tracker.config_entry import ScannerEntity
|
||||
from homeassistant.components.device_tracker.const import SourceType
|
||||
|
||||
|
||||
async def async_get_scanner(hass, config):
|
||||
"""Return a mock scanner."""
|
||||
return SCANNER
|
||||
|
||||
|
||||
class MockScannerEntity(ScannerEntity):
|
||||
"""Test implementation of a ScannerEntity."""
|
||||
|
||||
def __init__(self):
|
||||
"""Init."""
|
||||
self.connected = False
|
||||
self._hostname = "test.hostname.org"
|
||||
self._ip_address = "0.0.0.0"
|
||||
self._mac_address = "ad:de:ef:be:ed:fe"
|
||||
|
||||
@property
|
||||
def source_type(self):
|
||||
"""Return the source type, eg gps or router, of the device."""
|
||||
return SourceType.ROUTER
|
||||
|
||||
@property
|
||||
def battery_level(self):
|
||||
"""Return the battery level of the device.
|
||||
|
||||
Percentage from 0-100.
|
||||
"""
|
||||
return 100
|
||||
|
||||
@property
|
||||
def ip_address(self) -> str:
|
||||
"""Return the primary ip address of the device."""
|
||||
return self._ip_address
|
||||
|
||||
@property
|
||||
def mac_address(self) -> str:
|
||||
"""Return the mac address of the device."""
|
||||
return self._mac_address
|
||||
|
||||
@property
|
||||
def hostname(self) -> str:
|
||||
"""Return hostname of the device."""
|
||||
return self._hostname
|
||||
|
||||
@property
|
||||
def is_connected(self):
|
||||
"""Return true if the device is connected to the network."""
|
||||
return self.connected
|
||||
|
||||
def set_connected(self):
|
||||
"""Set connected to True."""
|
||||
self.connected = True
|
||||
self.async_schedule_update_ha_state()
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up the config entry."""
|
||||
entity = MockScannerEntity()
|
||||
async_add_entities([entity])
|
||||
|
||||
|
||||
class MockScanner(DeviceScanner):
|
||||
"""Mock device scanner."""
|
||||
|
||||
def __init__(self):
|
||||
"""Initialize the MockScanner."""
|
||||
self.devices_home = []
|
||||
|
||||
def come_home(self, device):
|
||||
"""Make a device come home."""
|
||||
self.devices_home.append(device)
|
||||
|
||||
def leave_home(self, device):
|
||||
"""Make a device leave the house."""
|
||||
self.devices_home.remove(device)
|
||||
|
||||
def reset(self):
|
||||
"""Reset which devices are home."""
|
||||
self.devices_home = []
|
||||
|
||||
def scan_devices(self):
|
||||
"""Return a list of fake devices."""
|
||||
return list(self.devices_home)
|
||||
|
||||
def get_device_name(self, device):
|
||||
"""Return a name for a mock device.
|
||||
|
||||
Return None for dev1 for testing.
|
||||
"""
|
||||
return None if device == "DEV1" else device.lower()
|
||||
|
||||
|
||||
SCANNER = MockScanner()
|
Loading…
Reference in New Issue