core/tests/components/tradfri/test_fan.py

145 lines
4.5 KiB
Python

"""Tradfri fan (recognised as air purifiers in the IKEA ecosystem) platform tests."""
from unittest.mock import MagicMock, Mock
import pytest
from pytradfri.device import Device
from pytradfri.device.air_purifier import AirPurifier
from pytradfri.device.air_purifier_control import AirPurifierControl
from .common import setup_integration
def mock_fan(test_features=None, test_state=None, device_number=0):
"""Mock a tradfri fan/air purifier."""
if test_features is None:
test_features = {}
if test_state is None:
test_state = {}
mock_fan_data = Mock(**test_state)
dev_info_mock = MagicMock()
dev_info_mock.manufacturer = "manufacturer"
dev_info_mock.model_number = "model"
dev_info_mock.firmware_version = "1.2.3"
_mock_fan = Mock(
id=f"mock-fan-id-{device_number}",
reachable=True,
observe=Mock(),
device_info=dev_info_mock,
has_light_control=False,
has_socket_control=False,
has_blind_control=False,
has_signal_repeater_control=False,
has_air_purifier_control=True,
)
_mock_fan.name = f"tradfri_fan_{device_number}"
air_purifier_control = AirPurifierControl(_mock_fan)
# Store the initial state.
setattr(air_purifier_control, "air_purifiers", [mock_fan_data])
_mock_fan.air_purifier_control = air_purifier_control
return _mock_fan
async def test_fan(hass, mock_gateway, mock_api_factory):
"""Test that fans are correctly added."""
state = {"fan_speed": 10, "air_quality": 12}
mock_gateway.mock_devices.append(mock_fan(test_state=state))
await setup_integration(hass)
fan_1 = hass.states.get("fan.tradfri_fan_0")
assert fan_1 is not None
assert fan_1.state == "on"
assert fan_1.attributes["percentage"] == 18
assert fan_1.attributes["preset_modes"] == ["Auto"]
assert fan_1.attributes["supported_features"] == 9
async def test_fan_observed(hass, mock_gateway, mock_api_factory):
"""Test that fans are correctly observed."""
state = {"fan_speed": 10, "air_quality": 12}
fan = mock_fan(test_state=state)
mock_gateway.mock_devices.append(fan)
await setup_integration(hass)
assert len(fan.observe.mock_calls) > 0
async def test_fan_available(hass, mock_gateway, mock_api_factory):
"""Test fan available property."""
fan = mock_fan(test_state={"fan_speed": 10, "air_quality": 12}, device_number=1)
fan.reachable = True
fan2 = mock_fan(test_state={"fan_speed": 10, "air_quality": 12}, device_number=2)
fan2.reachable = False
mock_gateway.mock_devices.append(fan)
mock_gateway.mock_devices.append(fan2)
await setup_integration(hass)
assert hass.states.get("fan.tradfri_fan_1").state == "on"
assert hass.states.get("fan.tradfri_fan_2").state == "unavailable"
@pytest.mark.parametrize(
"test_data, expected_result",
[
(
{"percentage": 50},
"on",
),
({"percentage": 0}, "off"),
],
)
async def test_set_percentage(
hass,
mock_gateway,
mock_api_factory,
test_data,
expected_result,
):
"""Test setting speed of a fan."""
# Note pytradfri style, not hass. Values not really important.
initial_state = {"percentage": 10, "fan_speed": 3, "air_quality": 12}
# Setup the gateway with a mock fan.
fan = mock_fan(test_state=initial_state, device_number=0)
mock_gateway.mock_devices.append(fan)
await setup_integration(hass)
# Use the turn_on service call to change the fan state.
await hass.services.async_call(
"fan",
"set_percentage",
{"entity_id": "fan.tradfri_fan_0", **test_data},
blocking=True,
)
await hass.async_block_till_done()
# Check that the fan is observed.
mock_func = fan.observe
assert len(mock_func.mock_calls) > 0
_, callkwargs = mock_func.call_args
assert "callback" in callkwargs
# Callback function to refresh fan state.
callback = callkwargs["callback"]
responses = mock_gateway.mock_responses
mock_gateway_response = responses[0]
# A KeyError is raised if we don't this to the response code
mock_gateway_response["15025"][0].update({"5908": 10, "5907": 12, "5910": 20})
# Use the callback function to update the fan state.
dev = Device(mock_gateway_response)
fan_data = AirPurifier(dev, 0)
fan.air_purifier_control.air_purifiers[0] = fan_data
callback(fan)
await hass.async_block_till_done()
# Check that the state is correct.
state = hass.states.get("fan.tradfri_fan_0")
assert state.state == expected_result