Complete test coverage for SFR Box (#85068)
* Complete test coverage for SFR Box * Add missing hint * renault -> sfr_box * Fixes following rebasepull/85184/head
parent
0d5bdaf037
commit
52032c6c7f
|
@ -1120,7 +1120,6 @@ omit =
|
||||||
homeassistant/components/sesame/lock.py
|
homeassistant/components/sesame/lock.py
|
||||||
homeassistant/components/seven_segments/image_processing.py
|
homeassistant/components/seven_segments/image_processing.py
|
||||||
homeassistant/components/seventeentrack/sensor.py
|
homeassistant/components/seventeentrack/sensor.py
|
||||||
homeassistant/components/sfr_box/sensor.py
|
|
||||||
homeassistant/components/shiftr/*
|
homeassistant/components/shiftr/*
|
||||||
homeassistant/components/shodan/sensor.py
|
homeassistant/components/shodan/sensor.py
|
||||||
homeassistant/components/sia/__init__.py
|
homeassistant/components/sia/__init__.py
|
||||||
|
|
|
@ -1 +1,53 @@
|
||||||
"""Tests for the SFR Box integration."""
|
"""Tests for the SFR Box integration."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from types import MappingProxyType
|
||||||
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
ATTR_IDENTIFIERS,
|
||||||
|
ATTR_MODEL,
|
||||||
|
ATTR_NAME,
|
||||||
|
ATTR_STATE,
|
||||||
|
ATTR_SW_VERSION,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.device_registry import DeviceRegistry
|
||||||
|
from homeassistant.helpers.entity_registry import EntityRegistry
|
||||||
|
|
||||||
|
from .const import ATTR_UNIQUE_ID, FIXED_ATTRIBUTES
|
||||||
|
|
||||||
|
|
||||||
|
def check_device_registry(
|
||||||
|
device_registry: DeviceRegistry, expected_device: MappingProxyType
|
||||||
|
) -> None:
|
||||||
|
"""Ensure that the expected_device is correctly registered."""
|
||||||
|
assert len(device_registry.devices) == 1
|
||||||
|
registry_entry = device_registry.async_get_device(expected_device[ATTR_IDENTIFIERS])
|
||||||
|
assert registry_entry is not None
|
||||||
|
assert registry_entry.identifiers == expected_device[ATTR_IDENTIFIERS]
|
||||||
|
assert registry_entry.name == expected_device[ATTR_NAME]
|
||||||
|
assert registry_entry.model == expected_device[ATTR_MODEL]
|
||||||
|
assert registry_entry.sw_version == expected_device[ATTR_SW_VERSION]
|
||||||
|
|
||||||
|
|
||||||
|
def check_entities(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entity_registry: EntityRegistry,
|
||||||
|
expected_entities: MappingProxyType,
|
||||||
|
) -> None:
|
||||||
|
"""Ensure that the expected_entities are correct."""
|
||||||
|
for expected_entity in expected_entities:
|
||||||
|
entity_id = expected_entity[ATTR_ENTITY_ID]
|
||||||
|
registry_entry = entity_registry.entities.get(entity_id)
|
||||||
|
assert registry_entry is not None
|
||||||
|
assert registry_entry.unique_id == expected_entity[ATTR_UNIQUE_ID]
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state, f"Expected valid state for {entity_id}, got {state}"
|
||||||
|
assert (
|
||||||
|
state.state == expected_entity[ATTR_STATE]
|
||||||
|
), f"Expected state {expected_entity[ATTR_STATE]}, got {state.state} for {entity_id}"
|
||||||
|
for attr in FIXED_ATTRIBUTES:
|
||||||
|
assert state.attributes.get(attr) == expected_entity.get(
|
||||||
|
attr
|
||||||
|
), f"Expected attribute {attr} == {expected_entity.get(attr)}, got {state.attributes.get(attr)} for {entity_id}"
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
"""Constants for SFR Box tests."""
|
||||||
|
from homeassistant.components.select.const import ATTR_OPTIONS
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
ATTR_STATE_CLASS,
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorStateClass,
|
||||||
|
)
|
||||||
|
from homeassistant.components.sfr_box.const import DOMAIN
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_DEVICE_CLASS,
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
ATTR_IDENTIFIERS,
|
||||||
|
ATTR_MODEL,
|
||||||
|
ATTR_NAME,
|
||||||
|
ATTR_STATE,
|
||||||
|
ATTR_SW_VERSION,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
Platform,
|
||||||
|
UnitOfDataRate,
|
||||||
|
)
|
||||||
|
|
||||||
|
ATTR_DEFAULT_DISABLED = "default_disabled"
|
||||||
|
ATTR_UNIQUE_ID = "unique_id"
|
||||||
|
FIXED_ATTRIBUTES = (
|
||||||
|
ATTR_DEVICE_CLASS,
|
||||||
|
ATTR_OPTIONS,
|
||||||
|
ATTR_STATE_CLASS,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
)
|
||||||
|
|
||||||
|
EXPECTED_ENTITIES = {
|
||||||
|
"expected_device": {
|
||||||
|
ATTR_IDENTIFIERS: {(DOMAIN, "e4:5d:51:00:11:22")},
|
||||||
|
ATTR_MODEL: "NB6VAC-FXC-r0",
|
||||||
|
ATTR_NAME: "SFR Box",
|
||||||
|
ATTR_SW_VERSION: "NB6VAC-MAIN-R4.0.44k",
|
||||||
|
},
|
||||||
|
Platform.SENSOR: [
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_line_mode",
|
||||||
|
ATTR_STATE: "ADSL2+",
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_linemode",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_counter",
|
||||||
|
ATTR_STATE: "16",
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_counter",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_crc",
|
||||||
|
ATTR_STATE: "0",
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_crc",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.SIGNAL_STRENGTH,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_noise_down",
|
||||||
|
ATTR_STATE: "5.8",
|
||||||
|
ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT,
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_noise_down",
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.SIGNAL_STRENGTH,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_noise_up",
|
||||||
|
ATTR_STATE: "6.0",
|
||||||
|
ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT,
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_noise_up",
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.SIGNAL_STRENGTH,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_attenuation_down",
|
||||||
|
ATTR_STATE: "28.5",
|
||||||
|
ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT,
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_attenuation_down",
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.SIGNAL_STRENGTH,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_attenuation_up",
|
||||||
|
ATTR_STATE: "20.8",
|
||||||
|
ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT,
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_attenuation_up",
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: SIGNAL_STRENGTH_DECIBELS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.DATA_RATE,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_rate_down",
|
||||||
|
ATTR_STATE: "5549",
|
||||||
|
ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT,
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_rate_down",
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: UnitOfDataRate.KILOBITS_PER_SECOND,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.DATA_RATE,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_rate_up",
|
||||||
|
ATTR_STATE: "187",
|
||||||
|
ATTR_STATE_CLASS: SensorStateClass.MEASUREMENT,
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_rate_up",
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT: UnitOfDataRate.KILOBITS_PER_SECOND,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.ENUM,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_line_status",
|
||||||
|
ATTR_OPTIONS: [
|
||||||
|
"no_defect",
|
||||||
|
"of_frame",
|
||||||
|
"loss_of_signal",
|
||||||
|
"loss_of_power",
|
||||||
|
"loss_of_signal_quality",
|
||||||
|
"unknown",
|
||||||
|
],
|
||||||
|
ATTR_STATE: "no_defect",
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_line_status",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ATTR_DEFAULT_DISABLED: True,
|
||||||
|
ATTR_DEVICE_CLASS: SensorDeviceClass.ENUM,
|
||||||
|
ATTR_ENTITY_ID: "sensor.sfr_box_training",
|
||||||
|
ATTR_OPTIONS: [
|
||||||
|
"idle",
|
||||||
|
"g_994_training",
|
||||||
|
"g_992_started",
|
||||||
|
"g_922_channel_analysis",
|
||||||
|
"g_992_message_exchange",
|
||||||
|
"g_993_started",
|
||||||
|
"g_993_channel_analysis",
|
||||||
|
"g_993_message_exchange",
|
||||||
|
"showtime",
|
||||||
|
"unknown",
|
||||||
|
],
|
||||||
|
ATTR_STATE: "showtime",
|
||||||
|
ATTR_UNIQUE_ID: "e4:5d:51:00:11:22_dsl_training",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
"""Test the SFR Box sensors."""
|
||||||
|
from collections.abc import Generator
|
||||||
|
from types import MappingProxyType
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_registry import EntityRegistry, RegistryEntryDisabler
|
||||||
|
|
||||||
|
from . import check_device_registry, check_entities
|
||||||
|
from .const import ATTR_DEFAULT_DISABLED, EXPECTED_ENTITIES
|
||||||
|
|
||||||
|
from tests.common import mock_device_registry, mock_registry
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.usefixtures("system_get_info", "dsl_get_info")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def override_platforms() -> Generator[None, None, None]:
|
||||||
|
"""Override PLATFORMS."""
|
||||||
|
with patch("homeassistant.components.sfr_box.PLATFORMS", [Platform.SENSOR]):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
def _check_and_enable_disabled_entities(
|
||||||
|
entity_registry: EntityRegistry, expected_entities: MappingProxyType
|
||||||
|
) -> None:
|
||||||
|
"""Ensure that the expected_entities are correctly disabled."""
|
||||||
|
for expected_entity in expected_entities:
|
||||||
|
if expected_entity.get(ATTR_DEFAULT_DISABLED):
|
||||||
|
entity_id = expected_entity[ATTR_ENTITY_ID]
|
||||||
|
registry_entry = entity_registry.entities.get(entity_id)
|
||||||
|
assert registry_entry.disabled
|
||||||
|
assert registry_entry.disabled_by is RegistryEntryDisabler.INTEGRATION
|
||||||
|
entity_registry.async_update_entity(entity_id, **{"disabled_by": None})
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sensors(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
|
||||||
|
"""Test for SFR Box sensors."""
|
||||||
|
entity_registry = mock_registry(hass)
|
||||||
|
device_registry = mock_device_registry(hass)
|
||||||
|
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
check_device_registry(device_registry, EXPECTED_ENTITIES["expected_device"])
|
||||||
|
|
||||||
|
expected_entities = EXPECTED_ENTITIES[Platform.SENSOR]
|
||||||
|
assert len(entity_registry.entities) == len(expected_entities)
|
||||||
|
|
||||||
|
_check_and_enable_disabled_entities(entity_registry, expected_entities)
|
||||||
|
await hass.config_entries.async_reload(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
check_entities(hass, entity_registry, expected_entities)
|
Loading…
Reference in New Issue