Add more tests to vesync (#135681)

This commit is contained in:
Indu Prakash 2025-01-28 10:38:53 -06:00 committed by GitHub
parent 3680e39c43
commit 9b598ed69c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 118 additions and 26 deletions

View File

@ -161,11 +161,6 @@ class VeSyncFanHA(VeSyncBaseEntity, FanEntity):
return self.smartfan.mode return self.smartfan.mode
return None return None
@property
def unique_info(self):
"""Return the ID of this fan."""
return self.smartfan.uuid
@property @property
def extra_state_attributes(self) -> dict[str, Any]: def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes of the fan.""" """Return the state attributes of the fan."""

View File

@ -137,7 +137,7 @@ class VeSyncHumidifierHA(VeSyncBaseEntity, HumidifierEntity):
@property @property
def mode(self) -> str | None: def mode(self) -> str | None:
"""Get the current preset mode.""" """Get the current preset mode."""
return _get_ha_mode(self.device.mode) return None if self.device.mode is None else _get_ha_mode(self.device.mode)
def set_humidity(self, humidity: int) -> None: def set_humidity(self, humidity: int) -> None:
"""Set the target humidity of the device.""" """Set the target humidity of the device."""

View File

@ -108,7 +108,31 @@ def outlet_fixture():
@pytest.fixture(name="humidifier") @pytest.fixture(name="humidifier")
def humidifier_fixture(): def humidifier_fixture():
"""Create a mock VeSync humidifier fixture.""" """Create a mock VeSync humidifier fixture."""
return Mock(VeSyncHumid200300S) return Mock(
VeSyncHumid200300S,
cid="200s-humidifier",
config={
"auto_target_humidity": 40,
"display": "true",
"automatic_stop": "true",
},
details={
"humidity": 35,
"mode": "manual",
},
device_type="Classic200S",
device_name="Humidifier 200s",
device_status="on",
mist_level=6,
mist_modes=["auto", "manual"],
mode=None,
sub_device_no=0,
config_module="configModule",
connection_status="online",
current_firm_version="1.0.0",
water_lacks=False,
water_tank_lifted=False,
)
@pytest.fixture(name="humidifier_config_entry") @pytest.fixture(name="humidifier_config_entry")

View File

@ -6,7 +6,7 @@
"cid": "200s-humidifier", "cid": "200s-humidifier",
"deviceType": "Classic200S", "deviceType": "Classic200S",
"deviceName": "Humidifier 200s", "deviceName": "Humidifier 200s",
"subDeviceNo": null, "subDeviceNo": 4321,
"deviceStatus": "on", "deviceStatus": "on",
"connectionStatus": "online", "connectionStatus": "online",
"uuid": "00000000-1111-2222-3333-444444444444", "uuid": "00000000-1111-2222-3333-444444444444",

View File

@ -477,7 +477,7 @@
'identifiers': set({ 'identifiers': set({
tuple( tuple(
'vesync', 'vesync',
'200s-humidifier', '200s-humidifier4321',
), ),
}), }),
'is_new': False, 'is_new': False,

View File

@ -348,7 +348,7 @@
'identifiers': set({ 'identifiers': set({
tuple( tuple(
'vesync', 'vesync',
'200s-humidifier', '200s-humidifier4321',
), ),
}), }),
'is_new': False, 'is_new': False,

View File

@ -664,7 +664,7 @@
'identifiers': set({ 'identifiers': set({
tuple( tuple(
'vesync', 'vesync',
'200s-humidifier', '200s-humidifier4321',
), ),
}), }),
'is_new': False, 'is_new': False,
@ -715,7 +715,7 @@
'previous_unique_id': None, 'previous_unique_id': None,
'supported_features': 0, 'supported_features': 0,
'translation_key': None, 'translation_key': None,
'unique_id': '200s-humidifier-humidity', 'unique_id': '200s-humidifier4321-humidity',
'unit_of_measurement': '%', 'unit_of_measurement': '%',
}), }),
]) ])

View File

@ -242,7 +242,7 @@
'identifiers': set({ 'identifiers': set({
tuple( tuple(
'vesync', 'vesync',
'200s-humidifier', '200s-humidifier4321',
), ),
}), }),
'is_new': False, 'is_new': False,

View File

@ -1,6 +1,7 @@
"""Tests for the humidifier platform.""" """Tests for the humidifier platform."""
from contextlib import nullcontext from contextlib import nullcontext
import logging
from unittest.mock import patch from unittest.mock import patch
import pytest import pytest
@ -12,7 +13,7 @@ from homeassistant.components.humidifier import (
SERVICE_SET_HUMIDITY, SERVICE_SET_HUMIDITY,
SERVICE_SET_MODE, SERVICE_SET_MODE,
) )
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import ( from homeassistant.const import (
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
SERVICE_TURN_OFF, SERVICE_TURN_OFF,
@ -21,6 +22,7 @@ from homeassistant.const import (
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import entity_registry as er
from .common import ( from .common import (
ENTITY_HUMIDIFIER, ENTITY_HUMIDIFIER,
@ -225,3 +227,61 @@ async def test_set_mode(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
method_mock.assert_called_once() method_mock.assert_called_once()
async def test_base_unique_id(
hass: HomeAssistant,
humidifier_config_entry: MockConfigEntry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test that unique_id is based on subDeviceNo."""
# vesync-device.json defines subDeviceNo for 200s-humidifier as 4321.
entity = entity_registry.async_get(ENTITY_HUMIDIFIER)
assert entity.unique_id.endswith("4321")
async def test_invalid_mist_modes(
hass: HomeAssistant,
config_entry: ConfigEntry,
humidifier,
manager,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test unsupported mist mode."""
humidifier.mist_modes = ["invalid_mode"]
with patch(
"homeassistant.components.vesync.async_generate_device_list",
return_value=[humidifier],
):
caplog.clear()
caplog.set_level(logging.WARNING)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert "Unknown mode 'invalid_mode'" in caplog.text
async def test_valid_mist_modes(
hass: HomeAssistant,
config_entry: ConfigEntry,
humidifier,
manager,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test supported mist mode."""
humidifier.mist_modes = ["auto", "manual"]
with patch(
"homeassistant.components.vesync.async_generate_device_list",
return_value=[humidifier],
):
caplog.clear()
caplog.set_level(logging.WARNING)
await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
assert "Unknown mode 'auto'" not in caplog.text
assert "Unknown mode 'manual'" not in caplog.text

View File

@ -90,23 +90,36 @@ async def test_async_setup_entry__loads_fans(
assert hass.data[DOMAIN][VS_DEVICES] == [fan] assert hass.data[DOMAIN][VS_DEVICES] == [fan]
async def test_async_new_device_discovery__loads_fans( async def test_async_new_device_discovery(
hass: HomeAssistant, config_entry: ConfigEntry, manager: VeSync, fan hass: HomeAssistant, config_entry: ConfigEntry, manager: VeSync, fan, humidifier
) -> None: ) -> None:
"""Test setup connects to vesync and loads fan as an update call.""" """Test new device discovery."""
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
# Assert platforms loaded # Assert platforms loaded
await hass.async_block_till_done() await hass.async_block_till_done()
assert config_entry.state is ConfigEntryState.LOADED assert config_entry.state is ConfigEntryState.LOADED
assert not hass.data[DOMAIN][VS_DEVICES] assert not hass.data[DOMAIN][VS_DEVICES]
fans = [fan]
manager.fans = fans
manager._dev_list = {
"fans": fans,
}
await hass.services.async_call(DOMAIN, SERVICE_UPDATE_DEVS, {}, blocking=True)
assert manager.login.call_count == 1 # Mock discovery of new fan which would get added to VS_DEVICES.
assert hass.data[DOMAIN][VS_MANAGER] == manager with patch(
assert hass.data[DOMAIN][VS_DEVICES] == [fan] "homeassistant.components.vesync.async_generate_device_list",
return_value=[fan],
):
await hass.services.async_call(DOMAIN, SERVICE_UPDATE_DEVS, {}, blocking=True)
assert manager.login.call_count == 1
assert hass.data[DOMAIN][VS_MANAGER] == manager
assert hass.data[DOMAIN][VS_DEVICES] == [fan]
# Mock discovery of new humidifier which would invoke discovery in all platforms.
# The mocked humidifier needs to have all properties populated for correct processing.
with patch(
"homeassistant.components.vesync.async_generate_device_list",
return_value=[humidifier],
):
await hass.services.async_call(DOMAIN, SERVICE_UPDATE_DEVS, {}, blocking=True)
assert manager.login.call_count == 1
assert hass.data[DOMAIN][VS_MANAGER] == manager
assert hass.data[DOMAIN][VS_DEVICES] == [fan, humidifier]