From 99481e22580eecda6d3d2196dcf46da747a7a3d3 Mon Sep 17 00:00:00 2001 From: Jc2k Date: Sun, 16 Jan 2022 18:43:44 +0000 Subject: [PATCH] Refactor homekit_controller tests to reduce duplication. (#64198) --- tests/components/homekit_controller/common.py | 107 ++++++ .../test_ryse_smart_bridge.py | 308 +++++++++++------- .../test_simpleconnect_fan.py | 55 ++-- .../specific_devices/test_velux_gateway.py | 126 +++---- .../test_vocolinc_flowerbud.py | 129 +++----- 5 files changed, 435 insertions(+), 290 deletions(-) diff --git a/tests/components/homekit_controller/common.py b/tests/components/homekit_controller/common.py index 49c63a761c2..ce17311c513 100644 --- a/tests/components/homekit_controller/common.py +++ b/tests/components/homekit_controller/common.py @@ -1,6 +1,10 @@ """Code to support homekit_controller tests.""" +from __future__ import annotations + +from dataclasses import dataclass from datetime import timedelta import json +import logging import os from unittest import mock @@ -15,12 +19,45 @@ from homeassistant.components.homekit_controller.const import ( CONTROLLER, DOMAIN, HOMEKIT_ACCESSORY_DISPATCH, + IDENTIFIER_ACCESSORY_ID, + IDENTIFIER_SERIAL_NUMBER, ) +from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util from tests.common import MockConfigEntry, async_fire_time_changed, load_fixture +logger = logging.getLogger(__name__) + + +@dataclass +class EntityTestInfo: + """Describes how we expected an entity to be created by homekit_controller.""" + + entity_id: str + unique_id: str + friendly_name: str + state: str + supported_features: int = 0 + + +@dataclass +class DeviceTestInfo: + """Describes how we exepced a device to be created by homekit_controlller.""" + + unique_id: str + name: str + manufacturer: str + model: str + sw_version: str + hw_version: str + serial_number: str + + devices: list[DeviceTestInfo] + entities: list[EntityTestInfo] + class Helper: """Helper methods for interacting with HomeKit fakes.""" @@ -171,3 +208,73 @@ async def setup_test_component(hass, setup_accessory, capitalize=False, suffix=N config_entry, pairing = await setup_test_accessories(hass, [accessory]) entity = "testdevice" if suffix is None else f"testdevice_{suffix}" return Helper(hass, ".".join((domain, entity)), pairing, accessory, config_entry) + + +def assert_devices_and_entities_created(hass: HomeAssistant, expected: DeviceTestInfo): + """Check that all expected devices and entities are loaded and enumerated as expected.""" + entity_registry = er.async_get(hass) + device_registry = dr.async_get(hass) + + def _do_assertions(expected: DeviceTestInfo) -> dr.DeviceEntry: + # Note: homekit_controller currently uses a 3-tuple for device identifiers + # The current standard is a 2-tuple (hkc was not migrated when this change was brought in) + + # There are currently really 3 cases here: + # - We can match exactly one device by serial number. This won't work for devices like the Ryse. + # These have nlank or broken serial numbers. + # - The device unique id is "00:00:00:00:00:00" - this is the pairing id. This is only set for + # the root (bridge) device. + # - The device unique id is "00:00:00:00:00:00-X", where X is a HAP aid. This is only set when + # we have detected broken serial numbers (and serial number is not used as an identifier). + + device = device_registry.async_get_device( + { + (DOMAIN, IDENTIFIER_SERIAL_NUMBER, expected.serial_number), + (DOMAIN, IDENTIFIER_ACCESSORY_ID, expected.unique_id), + } + ) + + logger.debug("Comparing device %r to %r", device, expected) + + assert device + assert device.name == expected.name + assert device.model == expected.model + assert device.manufacturer == expected.manufacturer + assert device.hw_version == expected.hw_version + assert device.sw_version == expected.sw_version + + # We might have matched the device by one identifier only + # Lets check that the other one is correct. Otherwise the test might silently be wrong. + for _, key, value in device.identifiers: + if key == IDENTIFIER_SERIAL_NUMBER: + assert value == expected.serial_number + elif key == IDENTIFIER_ACCESSORY_ID: + assert value == expected.unique_id + + for entity_info in expected.entities: + entity = entity_registry.async_get(entity_info.entity_id) + logger.debug("Comparing entity %r to %r", entity, entity_info) + + assert entity + assert entity.device_id == device.id + assert entity.unique_id == entity_info.unique_id + assert entity.supported_features == entity_info.supported_features + + state = hass.states.get(entity_info.entity_id) + logger.debug("Comparing state %r to %r", state, entity_info) + + assert state is not None + assert state.state == entity_info.state + assert state.attributes["friendly_name"] == entity_info.friendly_name + + for child in expected.devices: + child_device = _do_assertions(child) + assert child_device.via_device_id == device.id + assert child_device.id != device.id + + return device + + root_device = _do_assertions(expected) + + # Root device must not have a via, otherwise its not the device + assert root_device.via_device_id is None diff --git a/tests/components/homekit_controller/specific_devices/test_ryse_smart_bridge.py b/tests/components/homekit_controller/specific_devices/test_ryse_smart_bridge.py index 302ebe70ac2..bc1eb76af85 100644 --- a/tests/components/homekit_controller/specific_devices/test_ryse_smart_bridge.py +++ b/tests/components/homekit_controller/specific_devices/test_ryse_smart_bridge.py @@ -1,143 +1,215 @@ """Test against characteristics captured from a ryse smart bridge platforms.""" -from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.components.cover import ( + SUPPORT_CLOSE, + SUPPORT_OPEN, + SUPPORT_SET_POSITION, +) from tests.components.homekit_controller.common import ( - Helper, + DeviceTestInfo, + EntityTestInfo, + assert_devices_and_entities_created, setup_accessories_from_file, setup_test_accessories, ) +RYSE_SUPPORTED_FEATURES = SUPPORT_CLOSE | SUPPORT_SET_POSITION | SUPPORT_OPEN + async def test_ryse_smart_bridge_setup(hass): """Test that a Ryse smart bridge can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "ryse_smart_bridge.json") - config_entry, pairing = await setup_test_accessories(hass, accessories) + await setup_test_accessories(hass, accessories) - entity_registry = er.async_get(hass) - - # Check that the cover.master_bath_south is correctly found and set up - cover_id = "cover.master_bath_south" - cover = entity_registry.async_get(cover_id) - assert cover.unique_id == "homekit-00:00:00:00:00:00-2-48" - - cover_helper = Helper( + assert_devices_and_entities_created( hass, - cover_id, - pairing, - accessories[0], - config_entry, + DeviceTestInfo( + unique_id="00:00:00:00:00:00", + name="RYSE SmartBridge", + model="RYSE SmartBridge", + manufacturer="RYSE Inc.", + sw_version="1.3.0", + hw_version="0101.3521.0436", + # This is an actual bug in the device.. + serial_number="0101.3521.0436", + devices=[ + DeviceTestInfo( + unique_id="00:00:00:00:00:00_2", + name="Master Bath South", + model="RYSE Shade", + manufacturer="RYSE Inc.", + sw_version="3.0.8", + hw_version="1.0.0", + serial_number="", + devices=[], + entities=[ + EntityTestInfo( + entity_id="cover.master_bath_south", + friendly_name="Master Bath South", + unique_id="homekit-00:00:00:00:00:00-2-48", + supported_features=RYSE_SUPPORTED_FEATURES, + state="closed", + ), + EntityTestInfo( + entity_id="sensor.master_bath_south_battery", + friendly_name="Master Bath South Battery", + unique_id="homekit-00:00:00:00:00:00-2-64", + state="100", + ), + ], + ), + DeviceTestInfo( + unique_id="00:00:00:00:00:00_3", + name="RYSE SmartShade", + model="RYSE Shade", + manufacturer="RYSE Inc.", + sw_version="", + hw_version="", + serial_number="", + devices=[], + entities=[ + EntityTestInfo( + entity_id="cover.ryse_smartshade", + friendly_name="RYSE SmartShade", + unique_id="homekit-00:00:00:00:00:00-3-48", + supported_features=RYSE_SUPPORTED_FEATURES, + state="open", + ), + EntityTestInfo( + entity_id="sensor.ryse_smartshade_battery", + friendly_name="RYSE SmartShade Battery", + unique_id="homekit-00:00:00:00:00:00-3-64", + state="100", + ), + ], + ), + ], + entities=[], + ), ) - cover_state = await cover_helper.poll_and_get_state() - assert cover_state.attributes["friendly_name"] == "Master Bath South" - assert cover_state.state == "closed" - - device_registry = dr.async_get(hass) - - device = device_registry.async_get(cover.device_id) - assert device.manufacturer == "RYSE Inc." - assert device.name == "Master Bath South" - assert device.model == "RYSE Shade" - assert device.sw_version == "3.0.8" - assert device.hw_version == "1.0.0" - - bridge = device_registry.async_get(device.via_device_id) - assert bridge.manufacturer == "RYSE Inc." - assert bridge.name == "RYSE SmartBridge" - assert bridge.model == "RYSE SmartBridge" - assert bridge.sw_version == "1.3.0" - assert bridge.hw_version == "0101.3521.0436" - - # Check that the cover.ryse_smartshade is correctly found and set up - cover_id = "cover.ryse_smartshade" - cover = entity_registry.async_get(cover_id) - assert cover.unique_id == "homekit-00:00:00:00:00:00-3-48" - - cover_helper = Helper( - hass, - cover_id, - pairing, - accessories[0], - config_entry, - ) - - cover_state = await cover_helper.poll_and_get_state() - assert cover_state.attributes["friendly_name"] == "RYSE SmartShade" - assert cover_state.state == "open" - - device_registry = dr.async_get(hass) - - device = device_registry.async_get(cover.device_id) - assert device.manufacturer == "RYSE Inc." - assert device.name == "RYSE SmartShade" - assert device.model == "RYSE Shade" - assert device.sw_version == "" - async def test_ryse_smart_bridge_four_shades_setup(hass): """Test that a Ryse smart bridge with four shades can be correctly setup in HA.""" accessories = await setup_accessories_from_file( hass, "ryse_smart_bridge_four_shades.json" ) - config_entry, pairing = await setup_test_accessories(hass, accessories) + await setup_test_accessories(hass, accessories) - entity_registry = er.async_get(hass) - - cover_id = "cover.lr_left" - cover = entity_registry.async_get(cover_id) - assert cover.unique_id == "homekit-00:00:00:00:00:00-2-48" - - cover_id = "cover.lr_right" - cover = entity_registry.async_get(cover_id) - assert cover.unique_id == "homekit-00:00:00:00:00:00-3-48" - - cover_id = "cover.br_left" - cover = entity_registry.async_get(cover_id) - assert cover.unique_id == "homekit-00:00:00:00:00:00-4-48" - - cover_id = "cover.rzss" - cover = entity_registry.async_get(cover_id) - assert cover.unique_id == "homekit-00:00:00:00:00:00-5-48" - - sensor_id = "sensor.lr_left_battery" - sensor = entity_registry.async_get(sensor_id) - assert sensor.unique_id == "homekit-00:00:00:00:00:00-2-64" - - sensor_id = "sensor.lr_right_battery" - sensor = entity_registry.async_get(sensor_id) - assert sensor.unique_id == "homekit-00:00:00:00:00:00-3-64" - - sensor_id = "sensor.br_left_battery" - sensor = entity_registry.async_get(sensor_id) - assert sensor.unique_id == "homekit-00:00:00:00:00:00-4-64" - - sensor_id = "sensor.rzss_battery" - sensor = entity_registry.async_get(sensor_id) - assert sensor.unique_id == "homekit-00:00:00:00:00:00-5-64" - - cover_helper = Helper( + assert_devices_and_entities_created( hass, - cover_id, - pairing, - accessories[0], - config_entry, + DeviceTestInfo( + unique_id="00:00:00:00:00:00", + name="RYSE SmartBridge", + model="RYSE SmartBridge", + manufacturer="RYSE Inc.", + sw_version="1.3.0", + hw_version="0401.3521.0679", + # This is an actual bug in the device.. + serial_number="0401.3521.0679", + devices=[ + DeviceTestInfo( + unique_id="00:00:00:00:00:00_2", + name="LR Left", + model="RYSE Shade", + manufacturer="RYSE Inc.", + sw_version="3.0.8", + hw_version="1.0.0", + serial_number="", + devices=[], + entities=[ + EntityTestInfo( + entity_id="cover.lr_left", + friendly_name="LR Left", + unique_id="homekit-00:00:00:00:00:00-2-48", + supported_features=RYSE_SUPPORTED_FEATURES, + state="closed", + ), + EntityTestInfo( + entity_id="sensor.lr_left_battery", + friendly_name="LR Left Battery", + unique_id="homekit-00:00:00:00:00:00-2-64", + state="89", + ), + ], + ), + DeviceTestInfo( + unique_id="00:00:00:00:00:00_3", + name="LR Right", + model="RYSE Shade", + manufacturer="RYSE Inc.", + sw_version="3.0.8", + hw_version="1.0.0", + serial_number="", + devices=[], + entities=[ + EntityTestInfo( + entity_id="cover.lr_right", + friendly_name="LR Right", + unique_id="homekit-00:00:00:00:00:00-3-48", + supported_features=RYSE_SUPPORTED_FEATURES, + state="closed", + ), + EntityTestInfo( + entity_id="sensor.lr_right_battery", + friendly_name="LR Right Battery", + unique_id="homekit-00:00:00:00:00:00-3-64", + state="100", + ), + ], + ), + DeviceTestInfo( + unique_id="00:00:00:00:00:00_4", + name="BR Left", + model="RYSE Shade", + manufacturer="RYSE Inc.", + sw_version="3.0.8", + hw_version="1.0.0", + serial_number="", + devices=[], + entities=[ + EntityTestInfo( + entity_id="cover.br_left", + friendly_name="BR Left", + unique_id="homekit-00:00:00:00:00:00-4-48", + supported_features=RYSE_SUPPORTED_FEATURES, + state="open", + ), + EntityTestInfo( + entity_id="sensor.br_left_battery", + friendly_name="BR Left Battery", + unique_id="homekit-00:00:00:00:00:00-4-64", + state="100", + ), + ], + ), + DeviceTestInfo( + unique_id="00:00:00:00:00:00_5", + name="RZSS", + model="RYSE Shade", + manufacturer="RYSE Inc.", + sw_version="3.0.8", + hw_version="1.0.0", + serial_number="", + devices=[], + entities=[ + EntityTestInfo( + entity_id="cover.rzss", + friendly_name="RZSS", + unique_id="homekit-00:00:00:00:00:00-5-48", + supported_features=RYSE_SUPPORTED_FEATURES, + state="open", + ), + EntityTestInfo( + entity_id="sensor.rzss_battery", + friendly_name="RZSS Battery", + unique_id="homekit-00:00:00:00:00:00-5-64", + state="0", + ), + ], + ), + ], + entities=[], + ), ) - - cover_state = await cover_helper.poll_and_get_state() - assert cover_state.attributes["friendly_name"] == "RZSS" - assert cover_state.state == "open" - - device_registry = dr.async_get(hass) - - device = device_registry.async_get(cover.device_id) - assert device.manufacturer == "RYSE Inc." - assert device.name == "RZSS" - assert device.model == "RYSE Shade" - assert device.sw_version == "3.0.8" - - bridge = device_registry.async_get(device.via_device_id) - assert bridge.manufacturer == "RYSE Inc." - assert bridge.name == "RYSE SmartBridge" - assert bridge.model == "RYSE SmartBridge" - assert bridge.sw_version == "1.3.0" diff --git a/tests/components/homekit_controller/specific_devices/test_simpleconnect_fan.py b/tests/components/homekit_controller/specific_devices/test_simpleconnect_fan.py index a2195320293..4bc564033fc 100644 --- a/tests/components/homekit_controller/specific_devices/test_simpleconnect_fan.py +++ b/tests/components/homekit_controller/specific_devices/test_simpleconnect_fan.py @@ -5,10 +5,11 @@ https://github.com/home-assistant/core/issues/26180 """ from homeassistant.components.fan import SUPPORT_DIRECTION, SUPPORT_SET_SPEED -from homeassistant.helpers import device_registry as dr, entity_registry as er from tests.components.homekit_controller.common import ( - Helper, + DeviceTestInfo, + EntityTestInfo, + assert_devices_and_entities_created, setup_accessories_from_file, setup_test_accessories, ) @@ -17,35 +18,27 @@ from tests.components.homekit_controller.common import ( async def test_simpleconnect_fan_setup(hass): """Test that a SIMPLEconnect fan can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "simpleconnect_fan.json") - config_entry, pairing = await setup_test_accessories(hass, accessories) + await setup_test_accessories(hass, accessories) - entity_registry = er.async_get(hass) - - # Check that the fan is correctly found and set up - fan_id = "fan.simpleconnect_fan_06f674" - fan = entity_registry.async_get(fan_id) - assert fan.unique_id == "homekit-1234567890abcd-8" - - fan_helper = Helper( + assert_devices_and_entities_created( hass, - "fan.simpleconnect_fan_06f674", - pairing, - accessories[0], - config_entry, + DeviceTestInfo( + unique_id="00:00:00:00:00:00", + name="SIMPLEconnect Fan-06F674", + model="SIMPLEconnect", + manufacturer="Hunter Fan", + sw_version="", + hw_version="", + serial_number="1234567890abcd", + devices=[], + entities=[ + EntityTestInfo( + entity_id="fan.simpleconnect_fan_06f674", + friendly_name="SIMPLEconnect Fan-06F674", + unique_id="homekit-1234567890abcd-8", + supported_features=SUPPORT_DIRECTION | SUPPORT_SET_SPEED, + state="off", + ), + ], + ), ) - - fan_state = await fan_helper.poll_and_get_state() - assert fan_state.attributes["friendly_name"] == "SIMPLEconnect Fan-06F674" - assert fan_state.state == "off" - assert fan_state.attributes["supported_features"] == ( - SUPPORT_DIRECTION | SUPPORT_SET_SPEED - ) - - device_registry = dr.async_get(hass) - - device = device_registry.async_get(fan.device_id) - assert device.manufacturer == "Hunter Fan" - assert device.name == "SIMPLEconnect Fan-06F674" - assert device.model == "SIMPLEconnect" - assert device.sw_version == "" - assert device.via_device_id is None diff --git a/tests/components/homekit_controller/specific_devices/test_velux_gateway.py b/tests/components/homekit_controller/specific_devices/test_velux_gateway.py index b93afdfbfa4..5bb947ae894 100644 --- a/tests/components/homekit_controller/specific_devices/test_velux_gateway.py +++ b/tests/components/homekit_controller/specific_devices/test_velux_gateway.py @@ -9,72 +9,84 @@ from homeassistant.components.cover import ( SUPPORT_OPEN, SUPPORT_SET_POSITION, ) -from homeassistant.helpers import device_registry as dr, entity_registry as er from tests.components.homekit_controller.common import ( - Helper, + DeviceTestInfo, + EntityTestInfo, + assert_devices_and_entities_created, setup_accessories_from_file, setup_test_accessories, ) -async def test_simpleconnect_cover_setup(hass): +async def test_velux_cover_setup(hass): """Test that a velux gateway can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "velux_gateway.json") - config_entry, pairing = await setup_test_accessories(hass, accessories) + await setup_test_accessories(hass, accessories) - entity_registry = er.async_get(hass) - - # Check that the cover is correctly found and set up - cover_id = "cover.velux_window" - cover = entity_registry.async_get(cover_id) - assert cover.unique_id == "homekit-1111111a114a111a-8" - - cover_helper = Helper( + assert_devices_and_entities_created( hass, - cover_id, - pairing, - accessories[0], - config_entry, + DeviceTestInfo( + unique_id="00:00:00:00:00:00", + name="VELUX Gateway", + model="VELUX Gateway", + manufacturer="VELUX", + sw_version="70", + hw_version="", + serial_number="a1a11a1", + devices=[ + DeviceTestInfo( + unique_id="00:00:00:00:00:00-1", + name="VELUX Window", + model="VELUX Window", + manufacturer="VELUX", + sw_version="48", + hw_version="", + serial_number="1111111a114a111a", + devices=[], + entities=[ + EntityTestInfo( + entity_id="cover.velux_window", + friendly_name="VELUX Window", + unique_id="homekit-1111111a114a111a-8", + supported_features=SUPPORT_CLOSE + | SUPPORT_SET_POSITION + | SUPPORT_OPEN, + state="closed", + ), + ], + ), + DeviceTestInfo( + unique_id="00:00:00:00:00:00-2", + name="VELUX Sensor", + model="VELUX Sensor", + manufacturer="VELUX", + sw_version="16", + hw_version="", + serial_number="a11b111", + devices=[], + entities=[ + EntityTestInfo( + entity_id="sensor.velux_sensor_temperature", + friendly_name="VELUX Sensor Temperature", + unique_id="homekit-a11b111-8", + state="18.9", + ), + EntityTestInfo( + entity_id="sensor.velux_sensor_humidity", + friendly_name="VELUX Sensor Humidity", + unique_id="homekit-a11b111-11", + state="58", + ), + EntityTestInfo( + entity_id="sensor.velux_sensor_co2", + friendly_name="VELUX Sensor CO2", + unique_id="homekit-a11b111-14", + state="400", + ), + ], + ), + ], + entities=[], + ), ) - - cover_state = await cover_helper.poll_and_get_state() - assert cover_state.attributes["friendly_name"] == "VELUX Window" - assert cover_state.state == "closed" - assert cover_state.attributes["supported_features"] == ( - SUPPORT_CLOSE | SUPPORT_SET_POSITION | SUPPORT_OPEN - ) - - # Check that one of the sensors is correctly found and set up - sensor_id = "sensor.velux_sensor_temperature" - sensor = entity_registry.async_get(sensor_id) - assert sensor.unique_id == "homekit-a11b111-8" - - sensor_helper = Helper( - hass, - sensor_id, - pairing, - accessories[0], - config_entry, - ) - - sensor_state = await sensor_helper.poll_and_get_state() - assert sensor_state.attributes["friendly_name"] == "VELUX Sensor Temperature" - assert sensor_state.state == "18.9" - - # The cover and sensor are different devices (accessories) attached to the same bridge - assert cover.device_id != sensor.device_id - - device_registry = dr.async_get(hass) - - device = device_registry.async_get(cover.device_id) - assert device.manufacturer == "VELUX" - assert device.name == "VELUX Window" - assert device.model == "VELUX Window" - assert device.sw_version == "48" - - bridge = device_registry.async_get(device.via_device_id) - assert bridge.manufacturer == "VELUX" - assert bridge.name == "VELUX Gateway" - assert bridge.model == "VELUX Gateway" - assert bridge.sw_version == "70" diff --git a/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py b/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py index a58f306a241..69b4b73fab3 100644 --- a/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py +++ b/tests/components/homekit_controller/specific_devices/test_vocolinc_flowerbud.py @@ -1,9 +1,12 @@ """Make sure that Vocolinc Flowerbud is enumerated properly.""" -from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.components.humidifier.const import SUPPORT_MODES +from homeassistant.components.light import SUPPORT_BRIGHTNESS, SUPPORT_COLOR from tests.components.homekit_controller.common import ( - Helper, + DeviceTestInfo, + EntityTestInfo, + assert_devices_and_entities_created, setup_accessories_from_file, setup_test_accessories, ) @@ -12,88 +15,46 @@ from tests.components.homekit_controller.common import ( async def test_vocolinc_flowerbud_setup(hass): """Test that a Vocolinc Flowerbud can be correctly setup in HA.""" accessories = await setup_accessories_from_file(hass, "vocolinc_flowerbud.json") - config_entry, pairing = await setup_test_accessories(hass, accessories) + await setup_test_accessories(hass, accessories) - entity_registry = er.async_get(hass) - device_registry = dr.async_get(hass) - - # Check that the switch entity is handled correctly - - entry = entity_registry.async_get("number.vocolinc_flowerbud_0d324b_spray_quantity") - assert entry.unique_id == "homekit-AM01121849000327-aid:1-sid:30-cid:38" - - helper = Helper( + assert_devices_and_entities_created( hass, - "number.vocolinc_flowerbud_0d324b_spray_quantity", - pairing, - accessories[0], - config_entry, + DeviceTestInfo( + unique_id="00:00:00:00:00:00", + name="VOCOlinc-Flowerbud-0d324b", + model="Flowerbud", + manufacturer="VOCOlinc", + sw_version="3.121.2", + hw_version="0.1", + serial_number="AM01121849000327", + devices=[], + entities=[ + EntityTestInfo( + entity_id="humidifier.vocolinc_flowerbud_0d324b", + friendly_name="VOCOlinc-Flowerbud-0d324b", + unique_id="homekit-AM01121849000327-30", + supported_features=SUPPORT_MODES, + state="off", + ), + EntityTestInfo( + entity_id="light.vocolinc_flowerbud_0d324b", + friendly_name="VOCOlinc-Flowerbud-0d324b", + unique_id="homekit-AM01121849000327-9", + supported_features=SUPPORT_BRIGHTNESS | SUPPORT_COLOR, + state="on", + ), + EntityTestInfo( + entity_id="number.vocolinc_flowerbud_0d324b_spray_quantity", + friendly_name="VOCOlinc-Flowerbud-0d324b Spray Quantity", + unique_id="homekit-AM01121849000327-aid:1-sid:30-cid:38", + state="5", + ), + EntityTestInfo( + entity_id="sensor.vocolinc_flowerbud_0d324b_current_humidity", + friendly_name="VOCOlinc-Flowerbud-0d324b - Current Humidity", + unique_id="homekit-AM01121849000327-aid:1-sid:30-cid:33", + state="45.0", + ), + ], + ), ) - state = await helper.poll_and_get_state() - assert ( - state.attributes["friendly_name"] == "VOCOlinc-Flowerbud-0d324b Spray Quantity" - ) - - device = device_registry.async_get(entry.device_id) - assert device.manufacturer == "VOCOlinc" - assert device.name == "VOCOlinc-Flowerbud-0d324b" - assert device.model == "Flowerbud" - assert device.sw_version == "3.121.2" - assert device.via_device_id is None - assert device.hw_version == "0.1" - - # Assert the humidifier is detected - entry = entity_registry.async_get("humidifier.vocolinc_flowerbud_0d324b") - assert entry.unique_id == "homekit-AM01121849000327-30" - - helper = Helper( - hass, - "humidifier.vocolinc_flowerbud_0d324b", - pairing, - accessories[0], - config_entry, - ) - state = await helper.poll_and_get_state() - assert state.attributes["friendly_name"] == "VOCOlinc-Flowerbud-0d324b" - - # The sensor and switch should be part of the same device - assert entry.device_id == device.id - - # Assert the light is detected - entry = entity_registry.async_get("light.vocolinc_flowerbud_0d324b") - assert entry.unique_id == "homekit-AM01121849000327-9" - - helper = Helper( - hass, - "light.vocolinc_flowerbud_0d324b", - pairing, - accessories[0], - config_entry, - ) - state = await helper.poll_and_get_state() - assert state.attributes["friendly_name"] == "VOCOlinc-Flowerbud-0d324b" - - # The sensor and switch should be part of the same device - assert entry.device_id == device.id - - # Assert the humidity sensory is detected - entry = entity_registry.async_get( - "sensor.vocolinc_flowerbud_0d324b_current_humidity" - ) - assert entry.unique_id == "homekit-AM01121849000327-aid:1-sid:30-cid:33" - - helper = Helper( - hass, - "sensor.vocolinc_flowerbud_0d324b_current_humidity", - pairing, - accessories[0], - config_entry, - ) - state = await helper.poll_and_get_state() - assert ( - state.attributes["friendly_name"] - == "VOCOlinc-Flowerbud-0d324b - Current Humidity" - ) - - # The sensor and humidifier should be part of the same device - assert entry.device_id == device.id