mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Refactor Whirlpool climate tests (#142689)
This commit is contained in:
parent
187024367a
commit
5beb415ada
189
tests/components/whirlpool/snapshots/test_climate.ambr
Normal file
189
tests/components/whirlpool/snapshots/test_climate.ambr
Normal file
@ -0,0 +1,189 @@
|
||||
# serializer version: 1
|
||||
# name: test_all_entities[climate.aircon_said1-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'high',
|
||||
'medium',
|
||||
'low',
|
||||
'off',
|
||||
]),
|
||||
'hvac_modes': list([
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 30,
|
||||
'min_temp': 16,
|
||||
'swing_modes': list([
|
||||
'horizontal',
|
||||
'off',
|
||||
]),
|
||||
'target_temp_step': 1,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.aircon_said1',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'whirlpool',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 425>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'said1',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[climate.aircon_said1-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_humidity': 80,
|
||||
'current_temperature': 15,
|
||||
'fan_mode': 'auto',
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'high',
|
||||
'medium',
|
||||
'low',
|
||||
'off',
|
||||
]),
|
||||
'friendly_name': 'Aircon said1',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 30,
|
||||
'min_temp': 16,
|
||||
'supported_features': <ClimateEntityFeature: 425>,
|
||||
'swing_mode': 'horizontal',
|
||||
'swing_modes': list([
|
||||
'horizontal',
|
||||
'off',
|
||||
]),
|
||||
'target_temp_step': 1,
|
||||
'temperature': 20,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.aircon_said1',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'cool',
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[climate.aircon_said2-entry]
|
||||
EntityRegistryEntrySnapshot({
|
||||
'aliases': set({
|
||||
}),
|
||||
'area_id': None,
|
||||
'capabilities': dict({
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'high',
|
||||
'medium',
|
||||
'low',
|
||||
'off',
|
||||
]),
|
||||
'hvac_modes': list([
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 30,
|
||||
'min_temp': 16,
|
||||
'swing_modes': list([
|
||||
'horizontal',
|
||||
'off',
|
||||
]),
|
||||
'target_temp_step': 1,
|
||||
}),
|
||||
'config_entry_id': <ANY>,
|
||||
'config_subentry_id': <ANY>,
|
||||
'device_class': None,
|
||||
'device_id': <ANY>,
|
||||
'disabled_by': None,
|
||||
'domain': 'climate',
|
||||
'entity_category': None,
|
||||
'entity_id': 'climate.aircon_said2',
|
||||
'has_entity_name': True,
|
||||
'hidden_by': None,
|
||||
'icon': None,
|
||||
'id': <ANY>,
|
||||
'labels': set({
|
||||
}),
|
||||
'name': None,
|
||||
'options': dict({
|
||||
}),
|
||||
'original_device_class': None,
|
||||
'original_icon': None,
|
||||
'original_name': None,
|
||||
'platform': 'whirlpool',
|
||||
'previous_unique_id': None,
|
||||
'supported_features': <ClimateEntityFeature: 425>,
|
||||
'translation_key': None,
|
||||
'unique_id': 'said2',
|
||||
'unit_of_measurement': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_all_entities[climate.aircon_said2-state]
|
||||
StateSnapshot({
|
||||
'attributes': ReadOnlyDict({
|
||||
'current_humidity': 80,
|
||||
'current_temperature': 15,
|
||||
'fan_mode': 'auto',
|
||||
'fan_modes': list([
|
||||
'auto',
|
||||
'high',
|
||||
'medium',
|
||||
'low',
|
||||
'off',
|
||||
]),
|
||||
'friendly_name': 'Aircon said2',
|
||||
'hvac_modes': list([
|
||||
<HVACMode.COOL: 'cool'>,
|
||||
<HVACMode.HEAT: 'heat'>,
|
||||
<HVACMode.FAN_ONLY: 'fan_only'>,
|
||||
<HVACMode.OFF: 'off'>,
|
||||
]),
|
||||
'max_temp': 30,
|
||||
'min_temp': 16,
|
||||
'supported_features': <ClimateEntityFeature: 425>,
|
||||
'swing_mode': 'horizontal',
|
||||
'swing_modes': list([
|
||||
'horizontal',
|
||||
'off',
|
||||
]),
|
||||
'target_temp_step': 1,
|
||||
'temperature': 20,
|
||||
}),
|
||||
'context': <ANY>,
|
||||
'entity_id': 'climate.aircon_said2',
|
||||
'last_changed': <ANY>,
|
||||
'last_reported': <ANY>,
|
||||
'last_updated': <ANY>,
|
||||
'state': 'cool',
|
||||
})
|
||||
# ---
|
@ -2,22 +2,16 @@
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from attr import dataclass
|
||||
import pytest
|
||||
from syrupy import SnapshotAssertion
|
||||
import whirlpool
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_CURRENT_HUMIDITY,
|
||||
ATTR_CURRENT_TEMPERATURE,
|
||||
ATTR_FAN_MODE,
|
||||
ATTR_FAN_MODES,
|
||||
ATTR_HVAC_MODE,
|
||||
ATTR_HVAC_MODES,
|
||||
ATTR_MAX_TEMP,
|
||||
ATTR_MIN_TEMP,
|
||||
ATTR_SWING_MODE,
|
||||
ATTR_SWING_MODES,
|
||||
ATTR_TARGET_TEMP_STEP,
|
||||
DOMAIN as CLIMATE_DOMAIN,
|
||||
FAN_AUTO,
|
||||
FAN_HIGH,
|
||||
@ -31,23 +25,33 @@ from homeassistant.components.climate import (
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
SWING_HORIZONTAL,
|
||||
SWING_OFF,
|
||||
ClimateEntityFeature,
|
||||
HVACMode,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_FRIENDLY_NAME,
|
||||
ATTR_SUPPORTED_FEATURES,
|
||||
ATTR_TEMPERATURE,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
STATE_UNAVAILABLE,
|
||||
Platform,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from . import init_integration
|
||||
from . import init_integration, snapshot_whirlpool_entities
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
("climate.aircon_said1", "mock_aircon1_api"),
|
||||
("climate.aircon_said2", "mock_aircon2_api"),
|
||||
]
|
||||
)
|
||||
def multiple_climate_entities(request: pytest.FixtureRequest) -> tuple[str, str]:
|
||||
"""Fixture for multiple climate entities."""
|
||||
entity_id, mock_fixture = request.param
|
||||
return entity_id, mock_fixture
|
||||
|
||||
|
||||
async def update_ac_state(
|
||||
@ -63,307 +67,266 @@ async def update_ac_state(
|
||||
return hass.states.get(entity_id)
|
||||
|
||||
|
||||
async def test_static_attributes(
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
async def test_all_entities(
|
||||
hass: HomeAssistant,
|
||||
snapshot: SnapshotAssertion,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
"""Test static climate attributes."""
|
||||
"""Test all entities."""
|
||||
await init_integration(hass)
|
||||
|
||||
for said in ("said1", "said2"):
|
||||
entity_id = f"climate.aircon_{said}"
|
||||
entry = entity_registry.async_get(entity_id)
|
||||
assert entry
|
||||
assert entry.unique_id == said
|
||||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
assert state.state == HVACMode.COOL
|
||||
|
||||
attributes = state.attributes
|
||||
assert attributes[ATTR_FRIENDLY_NAME] == f"Aircon {said}"
|
||||
|
||||
assert (
|
||||
attributes[ATTR_SUPPORTED_FEATURES]
|
||||
== ClimateEntityFeature.TARGET_TEMPERATURE
|
||||
| ClimateEntityFeature.FAN_MODE
|
||||
| ClimateEntityFeature.SWING_MODE
|
||||
| ClimateEntityFeature.TURN_OFF
|
||||
| ClimateEntityFeature.TURN_ON
|
||||
)
|
||||
assert attributes[ATTR_HVAC_MODES] == [
|
||||
HVACMode.COOL,
|
||||
HVACMode.HEAT,
|
||||
HVACMode.FAN_ONLY,
|
||||
HVACMode.OFF,
|
||||
]
|
||||
assert attributes[ATTR_FAN_MODES] == [
|
||||
FAN_AUTO,
|
||||
FAN_HIGH,
|
||||
FAN_MEDIUM,
|
||||
FAN_LOW,
|
||||
FAN_OFF,
|
||||
]
|
||||
assert attributes[ATTR_SWING_MODES] == [SWING_HORIZONTAL, SWING_OFF]
|
||||
assert attributes[ATTR_TARGET_TEMP_STEP] == 1
|
||||
assert attributes[ATTR_MIN_TEMP] == 16
|
||||
assert attributes[ATTR_MAX_TEMP] == 30
|
||||
snapshot_whirlpool_entities(hass, entity_registry, snapshot, Platform.CLIMATE)
|
||||
|
||||
|
||||
async def test_dynamic_attributes(
|
||||
hass: HomeAssistant,
|
||||
mock_aircon1_api: MagicMock,
|
||||
mock_aircon2_api: MagicMock,
|
||||
multiple_climate_entities: tuple[str, str],
|
||||
request: pytest.FixtureRequest,
|
||||
) -> None:
|
||||
"""Test dynamic attributes."""
|
||||
entity_id, mock_fixture = multiple_climate_entities
|
||||
mock_instance = request.getfixturevalue(mock_fixture)
|
||||
await init_integration(hass)
|
||||
|
||||
@dataclass
|
||||
class ClimateTestInstance:
|
||||
"""Helper class for multiple climate and mock instances."""
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state == HVACMode.COOL
|
||||
|
||||
entity_id: str
|
||||
mock_instance: MagicMock
|
||||
mock_instance_idx: int
|
||||
mock_instance.get_power_on.return_value = False
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.OFF
|
||||
|
||||
for clim_test_instance in (
|
||||
ClimateTestInstance("climate.aircon_said1", mock_aircon1_api, 0),
|
||||
ClimateTestInstance("climate.aircon_said2", mock_aircon2_api, 1),
|
||||
):
|
||||
entity_id = clim_test_instance.entity_id
|
||||
mock_instance = clim_test_instance.mock_instance
|
||||
state = hass.states.get(entity_id)
|
||||
assert state is not None
|
||||
assert state.state == HVACMode.COOL
|
||||
mock_instance.get_online.return_value = False
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
mock_instance.get_power_on.return_value = False
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.OFF
|
||||
mock_instance.get_power_on.return_value = True
|
||||
mock_instance.get_online.return_value = True
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.COOL
|
||||
|
||||
mock_instance.get_online.return_value = False
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Heat
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.HEAT
|
||||
|
||||
mock_instance.get_power_on.return_value = True
|
||||
mock_instance.get_online.return_value = True
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.COOL
|
||||
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Fan
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.FAN_ONLY
|
||||
|
||||
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Heat
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.HEAT
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Auto
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == HVACMode.AUTO
|
||||
|
||||
mock_instance.get_mode.return_value = whirlpool.aircon.Mode.Fan
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.state == HVACMode.FAN_ONLY
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Low
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_LOW
|
||||
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Auto
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == HVACMode.AUTO
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Medium
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_MEDIUM
|
||||
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Low
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_LOW
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.High
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_HIGH
|
||||
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Medium
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_MEDIUM
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Off
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_OFF
|
||||
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.High
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_HIGH
|
||||
mock_instance.get_current_temp.return_value = 15
|
||||
mock_instance.get_temp.return_value = 20
|
||||
mock_instance.get_current_humidity.return_value = 80
|
||||
mock_instance.get_h_louver_swing.return_value = True
|
||||
attributes = (await update_ac_state(hass, entity_id, mock_instance)).attributes
|
||||
assert attributes[ATTR_CURRENT_TEMPERATURE] == 15
|
||||
assert attributes[ATTR_TEMPERATURE] == 20
|
||||
assert attributes[ATTR_CURRENT_HUMIDITY] == 80
|
||||
assert attributes[ATTR_SWING_MODE] == SWING_HORIZONTAL
|
||||
|
||||
mock_instance.get_fanspeed.return_value = whirlpool.aircon.FanSpeed.Off
|
||||
state = await update_ac_state(hass, entity_id, mock_instance)
|
||||
assert state.attributes[ATTR_FAN_MODE] == FAN_OFF
|
||||
|
||||
mock_instance.get_current_temp.return_value = 15
|
||||
mock_instance.get_temp.return_value = 20
|
||||
mock_instance.get_current_humidity.return_value = 80
|
||||
mock_instance.get_h_louver_swing.return_value = True
|
||||
attributes = (await update_ac_state(hass, entity_id, mock_instance)).attributes
|
||||
assert attributes[ATTR_CURRENT_TEMPERATURE] == 15
|
||||
assert attributes[ATTR_TEMPERATURE] == 20
|
||||
assert attributes[ATTR_CURRENT_HUMIDITY] == 80
|
||||
assert attributes[ATTR_SWING_MODE] == SWING_HORIZONTAL
|
||||
|
||||
mock_instance.get_current_temp.return_value = 16
|
||||
mock_instance.get_temp.return_value = 21
|
||||
mock_instance.get_current_humidity.return_value = 70
|
||||
mock_instance.get_h_louver_swing.return_value = False
|
||||
attributes = (await update_ac_state(hass, entity_id, mock_instance)).attributes
|
||||
assert attributes[ATTR_CURRENT_TEMPERATURE] == 16
|
||||
assert attributes[ATTR_TEMPERATURE] == 21
|
||||
assert attributes[ATTR_CURRENT_HUMIDITY] == 70
|
||||
assert attributes[ATTR_SWING_MODE] == SWING_OFF
|
||||
mock_instance.get_current_temp.return_value = 16
|
||||
mock_instance.get_temp.return_value = 21
|
||||
mock_instance.get_current_humidity.return_value = 70
|
||||
mock_instance.get_h_louver_swing.return_value = False
|
||||
attributes = (await update_ac_state(hass, entity_id, mock_instance)).attributes
|
||||
assert attributes[ATTR_CURRENT_TEMPERATURE] == 16
|
||||
assert attributes[ATTR_TEMPERATURE] == 21
|
||||
assert attributes[ATTR_CURRENT_HUMIDITY] == 70
|
||||
assert attributes[ATTR_SWING_MODE] == SWING_OFF
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service", "service_data", "expected_call", "expected_args"),
|
||||
[
|
||||
(SERVICE_TURN_OFF, {}, "set_power_on", [False]),
|
||||
(SERVICE_TURN_ON, {}, "set_power_on", [True]),
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_HVAC_MODE: HVACMode.COOL},
|
||||
"set_mode",
|
||||
[whirlpool.aircon.Mode.Cool],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_HVAC_MODE: HVACMode.HEAT},
|
||||
"set_mode",
|
||||
[whirlpool.aircon.Mode.Heat],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_HVAC_MODE: HVACMode.FAN_ONLY},
|
||||
"set_mode",
|
||||
[whirlpool.aircon.Mode.Fan],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_HVAC_MODE: HVACMode.OFF},
|
||||
"set_power_on",
|
||||
[False],
|
||||
),
|
||||
(SERVICE_SET_TEMPERATURE, {ATTR_TEMPERATURE: 20}, "set_temp", [20]),
|
||||
(
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_FAN_MODE: FAN_AUTO},
|
||||
"set_fanspeed",
|
||||
[whirlpool.aircon.FanSpeed.Auto],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_FAN_MODE: FAN_LOW},
|
||||
"set_fanspeed",
|
||||
[whirlpool.aircon.FanSpeed.Low],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_FAN_MODE: FAN_MEDIUM},
|
||||
"set_fanspeed",
|
||||
[whirlpool.aircon.FanSpeed.Medium],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_FAN_MODE: FAN_HIGH},
|
||||
"set_fanspeed",
|
||||
[whirlpool.aircon.FanSpeed.High],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_SWING_MODE,
|
||||
{ATTR_SWING_MODE: SWING_HORIZONTAL},
|
||||
"set_h_louver_swing",
|
||||
[True],
|
||||
),
|
||||
(
|
||||
SERVICE_SET_SWING_MODE,
|
||||
{ATTR_SWING_MODE: SWING_OFF},
|
||||
"set_h_louver_swing",
|
||||
[False],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_service_calls(
|
||||
hass: HomeAssistant,
|
||||
mock_aircon1_api: MagicMock,
|
||||
mock_aircon2_api: MagicMock,
|
||||
service: str,
|
||||
service_data: dict,
|
||||
expected_call: str,
|
||||
expected_args: list,
|
||||
multiple_climate_entities: tuple[str, str],
|
||||
request: pytest.FixtureRequest,
|
||||
) -> None:
|
||||
"""Test controlling the entity through service calls."""
|
||||
await init_integration(hass)
|
||||
entity_id, mock_fixture = multiple_climate_entities
|
||||
mock_instance = request.getfixturevalue(mock_fixture)
|
||||
|
||||
@dataclass
|
||||
class ClimateInstancesData:
|
||||
"""Helper class for multiple climate and mock instances."""
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
service,
|
||||
{ATTR_ENTITY_ID: entity_id, **service_data},
|
||||
blocking=True,
|
||||
)
|
||||
assert getattr(mock_instance, expected_call).call_count == 1
|
||||
getattr(mock_instance, expected_call).assert_called_once_with(*expected_args)
|
||||
|
||||
entity_id: str
|
||||
mock_instance: MagicMock
|
||||
|
||||
for clim_test_instance in (
|
||||
ClimateInstancesData("climate.aircon_said1", mock_aircon1_api),
|
||||
ClimateInstancesData("climate.aircon_said2", mock_aircon2_api),
|
||||
):
|
||||
mock_instance = clim_test_instance.mock_instance
|
||||
entity_id = clim_test_instance.entity_id
|
||||
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_power_on.assert_called_once_with(False)
|
||||
|
||||
mock_instance.set_power_on.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_power_on.assert_called_once_with(True)
|
||||
|
||||
mock_instance.set_power_on.reset_mock()
|
||||
mock_instance.get_power_on.return_value = False
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
@pytest.mark.parametrize(
|
||||
("service", "service_data"),
|
||||
[
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.COOL},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_power_on.assert_called_once_with(True)
|
||||
|
||||
mock_instance.set_temp.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_TEMPERATURE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_TEMPERATURE: 16},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_temp.assert_called_once_with(16)
|
||||
|
||||
mock_instance.set_mode.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
{ATTR_HVAC_MODE: HVACMode.COOL},
|
||||
),
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.COOL},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_mode.assert_called_once_with(whirlpool.aircon.Mode.Cool)
|
||||
|
||||
mock_instance.set_mode.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
{ATTR_HVAC_MODE: HVACMode.HEAT},
|
||||
),
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.HEAT},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_mode.assert_called_once_with(whirlpool.aircon.Mode.Heat)
|
||||
{ATTR_HVAC_MODE: HVACMode.FAN_ONLY},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_service_hvac_mode_turn_on(
|
||||
hass: HomeAssistant,
|
||||
service: str,
|
||||
service_data: dict,
|
||||
multiple_climate_entities: tuple[str, str],
|
||||
request: pytest.FixtureRequest,
|
||||
) -> None:
|
||||
"""Test that the HVAC mode service call turns on the entity, if it is off."""
|
||||
await init_integration(hass)
|
||||
entity_id, mock_fixture = multiple_climate_entities
|
||||
mock_instance = request.getfixturevalue(mock_fixture)
|
||||
|
||||
mock_instance.set_mode.reset_mock()
|
||||
# HVACMode.DRY is not supported
|
||||
with pytest.raises(ValueError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.DRY},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_mode.assert_not_called()
|
||||
mock_instance.get_power_on.return_value = False
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
service,
|
||||
{ATTR_ENTITY_ID: entity_id, **service_data},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_power_on.assert_called_once_with(True)
|
||||
|
||||
mock_instance.set_mode.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
# Test that set_power_on is not called if the device is already on
|
||||
mock_instance.set_power_on.reset_mock()
|
||||
mock_instance.get_power_on.return_value = True
|
||||
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
service,
|
||||
{ATTR_ENTITY_ID: entity_id, **service_data},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_power_on.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("service", "service_data", "exception"),
|
||||
[
|
||||
(
|
||||
SERVICE_SET_HVAC_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_HVAC_MODE: HVACMode.FAN_ONLY},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_mode.assert_called_once_with(whirlpool.aircon.Mode.Fan)
|
||||
|
||||
mock_instance.set_fanspeed.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
{ATTR_HVAC_MODE: HVACMode.DRY},
|
||||
ValueError,
|
||||
),
|
||||
(
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_AUTO},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_fanspeed.assert_called_once_with(
|
||||
whirlpool.aircon.FanSpeed.Auto
|
||||
)
|
||||
{ATTR_FAN_MODE: FAN_MIDDLE},
|
||||
ServiceValidationError,
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_service_unsupported(
|
||||
hass: HomeAssistant,
|
||||
service: str,
|
||||
service_data: dict,
|
||||
exception: type[Exception],
|
||||
multiple_climate_entities: tuple[str, str],
|
||||
) -> None:
|
||||
"""Test that unsupported service calls are handled properly."""
|
||||
await init_integration(hass)
|
||||
entity_id, _ = multiple_climate_entities
|
||||
|
||||
mock_instance.set_fanspeed.reset_mock()
|
||||
with pytest.raises(exception):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_LOW},
|
||||
service,
|
||||
{ATTR_ENTITY_ID: entity_id, **service_data},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_fanspeed.assert_called_once_with(
|
||||
whirlpool.aircon.FanSpeed.Low
|
||||
)
|
||||
|
||||
mock_instance.set_fanspeed.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_MEDIUM},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_fanspeed.assert_called_once_with(
|
||||
whirlpool.aircon.FanSpeed.Medium
|
||||
)
|
||||
|
||||
mock_instance.set_fanspeed.reset_mock()
|
||||
# FAN_MIDDLE is not supported
|
||||
with pytest.raises(ServiceValidationError):
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_MIDDLE},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_fanspeed.assert_not_called()
|
||||
|
||||
mock_instance.set_fanspeed.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_FAN_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_FAN_MODE: FAN_HIGH},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_fanspeed.assert_called_once_with(
|
||||
whirlpool.aircon.FanSpeed.High
|
||||
)
|
||||
|
||||
mock_instance.set_h_louver_swing.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_SWING_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_SWING_MODE: SWING_HORIZONTAL},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_h_louver_swing.assert_called_with(True)
|
||||
|
||||
mock_instance.set_h_louver_swing.reset_mock()
|
||||
await hass.services.async_call(
|
||||
CLIMATE_DOMAIN,
|
||||
SERVICE_SET_SWING_MODE,
|
||||
{ATTR_ENTITY_ID: entity_id, ATTR_SWING_MODE: SWING_OFF},
|
||||
blocking=True,
|
||||
)
|
||||
mock_instance.set_h_louver_swing.assert_called_with(False)
|
||||
|
Loading…
x
Reference in New Issue
Block a user