From 81c8ba87ab41c800aa05c2b76a39bc565b2e3c33 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Thu, 25 Jul 2024 18:16:25 +0200 Subject: [PATCH] Use snapshot in UniFi button tests (#122602) --- .../unifi/snapshots/test_button.ambr | 236 ++++++++++++++++++ tests/components/unifi/test_button.py | 79 +++--- 2 files changed, 266 insertions(+), 49 deletions(-) create mode 100644 tests/components/unifi/snapshots/test_button.ambr diff --git a/tests/components/unifi/snapshots/test_button.ambr b/tests/components/unifi/snapshots/test_button.ambr new file mode 100644 index 00000000000..51a37620268 --- /dev/null +++ b/tests/components/unifi/snapshots/test_button.ambr @@ -0,0 +1,236 @@ +# serializer version: 1 +# name: test_entity_and_device_data[site_payload0-device_payload0][button.switch_port_1_power_cycle-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.switch_port_1_power_cycle', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Port 1 Power Cycle', + 'platform': 'unifi', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'power_cycle-00:00:00:00:01:01_1', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_and_device_data[site_payload0-device_payload0][button.switch_port_1_power_cycle-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'restart', + 'friendly_name': 'switch Port 1 Power Cycle', + }), + 'context': , + 'entity_id': 'button.switch_port_1_power_cycle', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_and_device_data[site_payload0-device_payload0][button.switch_restart-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.switch_restart', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Restart', + 'platform': 'unifi', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'device_restart-00:00:00:00:01:01', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_and_device_data[site_payload0-device_payload0][button.switch_restart-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'restart', + 'friendly_name': 'switch Restart', + }), + 'context': , + 'entity_id': 'button.switch_restart', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_and_device_data[site_payload0-wlan_payload0-device_payload0][button.ssid_1_regenerate_password-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.ssid_1_regenerate_password', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Regenerate Password', + 'platform': 'unifi', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'regenerate_password-012345678910111213141516', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_and_device_data[site_payload0-wlan_payload0-device_payload0][button.ssid_1_regenerate_password-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'update', + 'friendly_name': 'SSID 1 Regenerate Password', + }), + 'context': , + 'entity_id': 'button.ssid_1_regenerate_password', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_and_device_data[site_payload0-wlan_payload0-device_payload0][button.switch_port_1_power_cycle-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.switch_port_1_power_cycle', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Port 1 Power Cycle', + 'platform': 'unifi', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'power_cycle-00:00:00:00:01:01_1', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_and_device_data[site_payload0-wlan_payload0-device_payload0][button.switch_port_1_power_cycle-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'restart', + 'friendly_name': 'switch Port 1 Power Cycle', + }), + 'context': , + 'entity_id': 'button.switch_port_1_power_cycle', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entity_and_device_data[site_payload0-wlan_payload0-device_payload0][button.switch_restart-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'button', + 'entity_category': , + 'entity_id': 'button.switch_restart', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Restart', + 'platform': 'unifi', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': 'device_restart-00:00:00:00:01:01', + 'unit_of_measurement': None, + }) +# --- +# name: test_entity_and_device_data[site_payload0-wlan_payload0-device_payload0][button.switch_restart-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'restart', + 'friendly_name': 'switch Restart', + }), + 'context': , + 'entity_id': 'button.switch_restart', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- diff --git a/tests/components/unifi/test_button.py b/tests/components/unifi/test_button.py index b7bf19aedc2..9af96b64a50 100644 --- a/tests/components/unifi/test_button.py +++ b/tests/components/unifi/test_button.py @@ -7,23 +7,23 @@ from unittest.mock import patch from aiounifi.models.message import MessageKey import pytest +from syrupy import SnapshotAssertion -from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, ButtonDeviceClass +from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN from homeassistant.components.unifi.const import CONF_SITE_ID from homeassistant.config_entries import RELOAD_AFTER_UPDATE_DELAY, ConfigEntry from homeassistant.const import ( - ATTR_DEVICE_CLASS, CONF_HOST, CONTENT_TYPE_JSON, STATE_UNAVAILABLE, - EntityCategory, + Platform, ) from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.helpers.entity_registry import RegistryEntryDisabler import homeassistant.util.dt as dt_util -from tests.common import async_fire_time_changed +from tests.common import async_fire_time_changed, snapshot_platform from tests.test_util.aiohttp import AiohttpClientMocker RANDOM_TOKEN = "random_token" @@ -121,33 +121,44 @@ WLAN_REGENERATE_PASSWORD = [ ] -async def _test_button_entity( +@pytest.mark.parametrize("device_payload", [DEVICE_RESTART + DEVICE_POWER_CYCLE_POE]) +@pytest.mark.parametrize("wlan_payload", [WLAN_REGENERATE_PASSWORD]) +@pytest.mark.parametrize( + "site_payload", + [ + [{"desc": "Site name", "name": "site_id", "role": "admin", "_id": "1"}], + [{"desc": "Site name", "name": "site_id", "role": "not admin", "_id": "1"}], + ], +) +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_entity_and_device_data( hass: HomeAssistant, entity_registry: er.EntityRegistry, + config_entry_factory, + site_payload: dict[str, Any], + snapshot: SnapshotAssertion, +) -> None: + """Validate entity and device data with and without admin rights.""" + with patch("homeassistant.components.unifi.PLATFORMS", [Platform.BUTTON]): + config_entry = await config_entry_factory() + if site_payload[0]["role"] == "admin": + await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id) + else: + assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == 0 + + +async def _test_button_entity( + hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, mock_websocket_state, config_entry: ConfigEntry, - entity_count: int, entity_id: str, - unique_id: str, - device_class: ButtonDeviceClass, request_method: str, request_path: str, request_data: dict[str, Any], call: dict[str, str], ) -> None: """Test button entity.""" - assert len(hass.states.async_entity_ids(BUTTON_DOMAIN)) == entity_count - - ent_reg_entry = entity_registry.async_get(entity_id) - assert ent_reg_entry.unique_id == unique_id - assert ent_reg_entry.entity_category is EntityCategory.CONFIG - - # Validate state object - button = hass.states.get(entity_id) - assert button is not None - assert button.attributes.get(ATTR_DEVICE_CLASS) == device_class - # Send and validate device command aioclient_mock.clear_requests() aioclient_mock.request( @@ -177,10 +188,7 @@ async def _test_button_entity( @pytest.mark.parametrize( ( "device_payload", - "entity_count", "entity_id", - "unique_id", - "device_class", "request_method", "request_path", "call", @@ -188,10 +196,7 @@ async def _test_button_entity( [ ( DEVICE_RESTART, - 1, "button.switch_restart", - "device_restart-00:00:00:00:01:01", - ButtonDeviceClass.RESTART, "post", "/cmd/devmgr", { @@ -202,10 +207,7 @@ async def _test_button_entity( ), ( DEVICE_POWER_CYCLE_POE, - 2, "button.switch_port_1_power_cycle", - "power_cycle-00:00:00:00:01:01_1", - ButtonDeviceClass.RESTART, "post", "/cmd/devmgr", { @@ -218,14 +220,10 @@ async def _test_button_entity( ) async def test_device_button_entities( hass: HomeAssistant, - entity_registry: er.EntityRegistry, aioclient_mock: AiohttpClientMocker, config_entry_setup: ConfigEntry, mock_websocket_state, - entity_count: int, entity_id: str, - unique_id: str, - device_class: ButtonDeviceClass, request_method: str, request_path: str, call: dict[str, str], @@ -233,14 +231,10 @@ async def test_device_button_entities( """Test button entities based on device sources.""" await _test_button_entity( hass, - entity_registry, aioclient_mock, mock_websocket_state, config_entry_setup, - entity_count, entity_id, - unique_id, - device_class, request_method, request_path, {}, @@ -251,10 +245,7 @@ async def test_device_button_entities( @pytest.mark.parametrize( ( "wlan_payload", - "entity_count", "entity_id", - "unique_id", - "device_class", "request_method", "request_path", "request_data", @@ -263,10 +254,7 @@ async def test_device_button_entities( [ ( WLAN_REGENERATE_PASSWORD, - 1, "button.ssid_1_regenerate_password", - "regenerate_password-012345678910111213141516", - ButtonDeviceClass.UPDATE, "put", f"/rest/wlanconf/{WLAN_REGENERATE_PASSWORD[0]["_id"]}", { @@ -283,10 +271,7 @@ async def test_wlan_button_entities( aioclient_mock: AiohttpClientMocker, config_entry_setup: ConfigEntry, mock_websocket_state, - entity_count: int, entity_id: str, - unique_id: str, - device_class: ButtonDeviceClass, request_method: str, request_path: str, request_data: dict[str, Any], @@ -308,14 +293,10 @@ async def test_wlan_button_entities( await _test_button_entity( hass, - entity_registry, aioclient_mock, mock_websocket_state, config_entry_setup, - entity_count, entity_id, - unique_id, - device_class, request_method, request_path, request_data,