core/tests/components/fan/test_init.py

190 lines
6.0 KiB
Python

"""Tests for fan platforms."""
import pytest
from homeassistant.components import fan
from homeassistant.components.fan import (
ATTR_PRESET_MODE,
ATTR_PRESET_MODES,
DOMAIN,
SERVICE_SET_PRESET_MODE,
FanEntity,
FanEntityFeature,
NotValidPresetModeError,
)
from homeassistant.core import HomeAssistant
import homeassistant.helpers.entity_registry as er
from homeassistant.setup import async_setup_component
from tests.common import (
help_test_all,
import_and_test_deprecated_constant_enum,
setup_test_component_platform,
)
from tests.components.fan.common import MockFan
class BaseFan(FanEntity):
"""Implementation of the abstract FanEntity."""
def __init__(self):
"""Initialize the fan."""
def test_fanentity() -> None:
"""Test fan entity methods."""
fan = BaseFan()
assert fan.state == "off"
assert fan.preset_modes is None
assert fan.supported_features == 0
assert fan.percentage_step == 1
assert fan.speed_count == 100
assert fan.capability_attributes == {}
# Test set_speed not required
with pytest.raises(NotImplementedError):
fan.oscillate(True)
with pytest.raises(AttributeError):
fan.set_speed("low")
with pytest.raises(NotImplementedError):
fan.set_percentage(0)
with pytest.raises(NotImplementedError):
fan.set_preset_mode("auto")
with pytest.raises(NotImplementedError):
fan.turn_on()
with pytest.raises(NotImplementedError):
fan.turn_off()
async def test_async_fanentity(hass: HomeAssistant) -> None:
"""Test async fan entity methods."""
fan = BaseFan()
fan.hass = hass
assert fan.state == "off"
assert fan.preset_modes is None
assert fan.supported_features == 0
assert fan.percentage_step == 1
assert fan.speed_count == 100
assert fan.capability_attributes == {}
# Test set_speed not required
with pytest.raises(NotImplementedError):
await fan.async_oscillate(True)
with pytest.raises(AttributeError):
await fan.async_set_speed("low")
with pytest.raises(NotImplementedError):
await fan.async_set_percentage(0)
with pytest.raises(NotImplementedError):
await fan.async_set_preset_mode("auto")
with pytest.raises(NotImplementedError):
await fan.async_turn_on()
with pytest.raises(NotImplementedError):
await fan.async_turn_off()
with pytest.raises(NotImplementedError):
await fan.async_increase_speed()
with pytest.raises(NotImplementedError):
await fan.async_decrease_speed()
@pytest.mark.parametrize(
("attribute_name", "attribute_value"),
[
("current_direction", "forward"),
("oscillating", True),
("percentage", 50),
("preset_mode", "medium"),
("preset_modes", ["low", "medium", "high"]),
("speed_count", 50),
("supported_features", 1),
],
)
def test_fanentity_attributes(attribute_name, attribute_value) -> None:
"""Test fan entity attribute shorthand."""
fan = BaseFan()
setattr(fan, f"_attr_{attribute_name}", attribute_value)
assert getattr(fan, attribute_name) == attribute_value
async def test_preset_mode_validation(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
entity_registry: er.EntityRegistry,
) -> None:
"""Test preset mode validation."""
await hass.async_block_till_done()
test_fan = MockFan(
name="Support fan with preset_mode support",
supported_features=FanEntityFeature.PRESET_MODE,
unique_id="unique_support_preset_mode",
preset_modes=["auto", "eco"],
)
setup_test_component_platform(hass, "fan", [test_fan])
assert await async_setup_component(hass, "fan", {"fan": {"platform": "test"}})
await hass.async_block_till_done()
state = hass.states.get("fan.support_fan_with_preset_mode_support")
assert state.attributes.get(ATTR_PRESET_MODES) == ["auto", "eco"]
await hass.services.async_call(
DOMAIN,
SERVICE_SET_PRESET_MODE,
{
"entity_id": "fan.support_fan_with_preset_mode_support",
"preset_mode": "eco",
},
blocking=True,
)
state = hass.states.get("fan.support_fan_with_preset_mode_support")
assert state.attributes.get(ATTR_PRESET_MODE) == "eco"
with pytest.raises(NotValidPresetModeError) as exc:
await hass.services.async_call(
DOMAIN,
SERVICE_SET_PRESET_MODE,
{
"entity_id": "fan.support_fan_with_preset_mode_support",
"preset_mode": "invalid",
},
blocking=True,
)
assert exc.value.translation_key == "not_valid_preset_mode"
with pytest.raises(NotValidPresetModeError) as exc:
await test_fan._valid_preset_mode_or_raise("invalid")
assert exc.value.translation_key == "not_valid_preset_mode"
def test_all() -> None:
"""Test module.__all__ is correctly set."""
help_test_all(fan)
@pytest.mark.parametrize(("enum"), list(fan.FanEntityFeature))
def test_deprecated_constants(
caplog: pytest.LogCaptureFixture,
enum: fan.FanEntityFeature,
) -> None:
"""Test deprecated constants."""
import_and_test_deprecated_constant_enum(caplog, fan, enum, "SUPPORT_", "2025.1")
def test_deprecated_supported_features_ints(caplog: pytest.LogCaptureFixture) -> None:
"""Test deprecated supported features ints."""
class MockFan(FanEntity):
@property
def supported_features(self) -> int:
"""Return supported features."""
return 1
entity = MockFan()
assert entity.supported_features_compat is FanEntityFeature(1)
assert "MockFan" in caplog.text
assert "is using deprecated supported features values" in caplog.text
assert "Instead it should use" in caplog.text
assert "FanEntityFeature.SET_SPEED" in caplog.text
caplog.clear()
assert entity.supported_features_compat is FanEntityFeature(1)
assert "is using deprecated supported features values" not in caplog.text