From 27b7fb6f910ea4298aa13f9f10aed01e3bfb265e Mon Sep 17 00:00:00 2001 From: Retha Runolfsson <137745329+zerzhang@users.noreply.github.com> Date: Sat, 19 Apr 2025 15:48:01 +0800 Subject: [PATCH] Add humidifier unit test for switchbot (#143207) --- tests/components/switchbot/__init__.py | 27 ++++ tests/components/switchbot/test_humidifier.py | 123 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 tests/components/switchbot/test_humidifier.py diff --git a/tests/components/switchbot/__init__.py b/tests/components/switchbot/__init__.py index f57c8c107b2..bb7f950b0da 100644 --- a/tests/components/switchbot/__init__.py +++ b/tests/components/switchbot/__init__.py @@ -436,3 +436,30 @@ ROLLER_SHADE_SERVICE_INFO = BluetoothServiceInfoBleak( connectable=True, tx_power=-127, ) + + +HUMIDIFIER_SERVICE_INFO = BluetoothServiceInfoBleak( + name="Humidifier", + manufacturer_data={ + 741: b"\xacg\xb2\xcd\xfa\xbe", + }, + service_data={"0000fd3d-0000-1000-8000-00805f9b34fb": b"e\x80\x00\xf9\x80Bc\x00"}, + service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"], + address="AA:BB:CC:DD:EE:FF", + rssi=-60, + source="local", + advertisement=generate_advertisement_data( + local_name="Humidifier", + manufacturer_data={ + 741: b"\xacg\xb2\xcd\xfa\xbe", + }, + service_data={ + "0000fd3d-0000-1000-8000-00805f9b34fb": b"e\x80\x00\xf9\x80Bc\x00" + }, + service_uuids=["cba20d00-224d-11e6-9fb8-0002a5d5c51b"], + ), + device=generate_ble_device("AA:BB:CC:DD:EE:FF", "Humidifier"), + time=0, + connectable=True, + tx_power=-127, +) diff --git a/tests/components/switchbot/test_humidifier.py b/tests/components/switchbot/test_humidifier.py new file mode 100644 index 00000000000..cb2882a7475 --- /dev/null +++ b/tests/components/switchbot/test_humidifier.py @@ -0,0 +1,123 @@ +"""Test the switchbot humidifiers.""" + +from collections.abc import Callable +from unittest.mock import AsyncMock, patch + +import pytest + +from homeassistant.components.humidifier import ( + ATTR_HUMIDITY, + ATTR_MODE, + DOMAIN as HUMIDIFIER_DOMAIN, + MODE_AUTO, + MODE_NORMAL, + SERVICE_SET_HUMIDITY, + SERVICE_SET_MODE, + SERVICE_TURN_OFF, + SERVICE_TURN_ON, +) +from homeassistant.const import ATTR_ENTITY_ID +from homeassistant.core import HomeAssistant + +from . import HUMIDIFIER_SERVICE_INFO + +from tests.common import MockConfigEntry +from tests.components.bluetooth import inject_bluetooth_service_info + + +@pytest.mark.parametrize( + ( + "service", + "service_data", + "mock_method", + "expected_args", + ), + [ + ( + SERVICE_TURN_OFF, + {}, + "turn_off", + (), + ), + ( + SERVICE_TURN_ON, + {}, + "turn_on", + (), + ), + ( + SERVICE_SET_HUMIDITY, + {ATTR_HUMIDITY: 50}, + "set_humidity_level", + (50,), + ), + ( + SERVICE_SET_MODE, + {ATTR_MODE: MODE_AUTO}, + "set_auto_mode", + (), + ), + ( + SERVICE_SET_MODE, + {ATTR_MODE: MODE_NORMAL}, + "set_manual_mode", + (), + ), + ], +) +async def test_humidifier_services( + hass: HomeAssistant, + mock_entry_factory: Callable[[str], MockConfigEntry], + service: str, + service_data: dict, + mock_method: str, + expected_args: tuple, +) -> None: + """Test all humidifier services with proper parameters.""" + inject_bluetooth_service_info(hass, HUMIDIFIER_SERVICE_INFO) + + entry = mock_entry_factory(sensor_type="humidifier") + entry.add_to_hass(hass) + entity_id = "humidifier.test_name" + + with ( + patch( + "homeassistant.components.switchbot.humidifier.switchbot.SwitchbotHumidifier.set_level", + new=AsyncMock(return_value=True), + ) as mock_set_humidity_level, + patch( + "homeassistant.components.switchbot.humidifier.switchbot.SwitchbotHumidifier.async_set_auto", + new=AsyncMock(return_value=True), + ) as mock_set_auto_mode, + patch( + "homeassistant.components.switchbot.humidifier.switchbot.SwitchbotHumidifier.async_set_manual", + new=AsyncMock(return_value=True), + ) as mock_set_manual_mode, + patch( + "homeassistant.components.switchbot.humidifier.switchbot.SwitchbotHumidifier.turn_off", + new=AsyncMock(return_value=True), + ) as mock_turn_off, + patch( + "homeassistant.components.switchbot.humidifier.switchbot.SwitchbotHumidifier.turn_on", + new=AsyncMock(return_value=True), + ) as mock_turn_on, + ): + assert await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + await hass.services.async_call( + HUMIDIFIER_DOMAIN, + service, + {**service_data, ATTR_ENTITY_ID: entity_id}, + blocking=True, + ) + + mock_map = { + "turn_off": mock_turn_off, + "turn_on": mock_turn_on, + "set_humidity_level": mock_set_humidity_level, + "set_auto_mode": mock_set_auto_mode, + "set_manual_mode": mock_set_manual_mode, + } + mock_instance = mock_map[mock_method] + mock_instance.assert_awaited_once_with(*expected_args)