From 52032c6c7fd970c28ac0f2124b59c0299e98024c Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 6 Jan 2023 12:30:07 +0100 Subject: [PATCH] Complete test coverage for SFR Box (#85068) * Complete test coverage for SFR Box * Add missing hint * renault -> sfr_box * Fixes following rebase --- .coveragerc | 1 - tests/components/sfr_box/__init__.py | 52 +++++++++ tests/components/sfr_box/const.py | 145 ++++++++++++++++++++++++ tests/components/sfr_box/test_sensor.py | 58 ++++++++++ 4 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 tests/components/sfr_box/const.py create mode 100644 tests/components/sfr_box/test_sensor.py diff --git a/.coveragerc b/.coveragerc index 95c535de46f..eb391a32754 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1120,7 +1120,6 @@ omit = homeassistant/components/sesame/lock.py homeassistant/components/seven_segments/image_processing.py homeassistant/components/seventeentrack/sensor.py - homeassistant/components/sfr_box/sensor.py homeassistant/components/shiftr/* homeassistant/components/shodan/sensor.py homeassistant/components/sia/__init__.py diff --git a/tests/components/sfr_box/__init__.py b/tests/components/sfr_box/__init__.py index 52d911ef832..90ab88c7c9c 100644 --- a/tests/components/sfr_box/__init__.py +++ b/tests/components/sfr_box/__init__.py @@ -1 +1,53 @@ """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}" diff --git a/tests/components/sfr_box/const.py b/tests/components/sfr_box/const.py new file mode 100644 index 00000000000..6b121402e9f --- /dev/null +++ b/tests/components/sfr_box/const.py @@ -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", + }, + ], +} diff --git a/tests/components/sfr_box/test_sensor.py b/tests/components/sfr_box/test_sensor.py new file mode 100644 index 00000000000..ceb2e38d692 --- /dev/null +++ b/tests/components/sfr_box/test_sensor.py @@ -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)