mirror of
https://github.com/esphome/esphome.git
synced 2026-05-18 01:32:27 +08:00
97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
"""Integration test for backward compatibility of deprecated ClimateTraits setters.
|
|
|
|
Verifies that external components using the old traits.set_supported_custom_fan_modes()
|
|
and traits.set_supported_custom_presets() API still work correctly during the
|
|
deprecation period.
|
|
|
|
Remove this entire test file and the legacy_climate_component external component
|
|
in 2026.11.0 when the deprecated ClimateTraits setters are removed.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from pathlib import Path
|
|
|
|
import aioesphomeapi
|
|
from aioesphomeapi import ClimateInfo
|
|
import pytest
|
|
|
|
from .state_utils import InitialStateHelper
|
|
from .types import APIClientConnectedFactory, RunCompiledFunction
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_legacy_climate_compat(
|
|
yaml_config: str,
|
|
run_compiled: RunCompiledFunction,
|
|
api_client_connected: APIClientConnectedFactory,
|
|
) -> None:
|
|
"""Test that deprecated ClimateTraits custom mode setters still work end-to-end."""
|
|
external_components_path = str(
|
|
Path(__file__).parent / "fixtures" / "external_components"
|
|
)
|
|
yaml_config = yaml_config.replace(
|
|
"EXTERNAL_COMPONENT_PATH", external_components_path
|
|
)
|
|
|
|
loop = asyncio.get_running_loop()
|
|
|
|
async with run_compiled(yaml_config), api_client_connected() as client:
|
|
entities, _ = await client.list_entities_services()
|
|
initial_state_helper = InitialStateHelper(entities)
|
|
|
|
climate_infos = [e for e in entities if isinstance(e, ClimateInfo)]
|
|
assert len(climate_infos) == 1, (
|
|
f"Expected 1 climate entity, got {len(climate_infos)}"
|
|
)
|
|
|
|
test_climate = climate_infos[0]
|
|
|
|
# Verify custom fan modes set via deprecated ClimateTraits setter are exposed
|
|
assert set(test_climate.supported_custom_fan_modes) == {
|
|
"Turbo",
|
|
"Silent",
|
|
"Auto",
|
|
}, (
|
|
f"Expected custom fan modes {{Turbo, Silent, Auto}}, "
|
|
f"got {test_climate.supported_custom_fan_modes}"
|
|
)
|
|
|
|
# Verify custom presets set via deprecated ClimateTraits setter are exposed
|
|
assert set(test_climate.supported_custom_presets) == {
|
|
"Eco Mode",
|
|
"Night Mode",
|
|
}, (
|
|
f"Expected custom presets {{Eco Mode, Night Mode}}, "
|
|
f"got {test_climate.supported_custom_presets}"
|
|
)
|
|
|
|
# Set up state tracking with InitialStateHelper
|
|
turbo_future: asyncio.Future[aioesphomeapi.ClimateState] = loop.create_future()
|
|
|
|
def on_state(state: aioesphomeapi.EntityState) -> None:
|
|
if (
|
|
isinstance(state, aioesphomeapi.ClimateState)
|
|
and state.custom_fan_mode == "Turbo"
|
|
and not turbo_future.done()
|
|
):
|
|
turbo_future.set_result(state)
|
|
|
|
client.subscribe_states(initial_state_helper.on_state_wrapper(on_state))
|
|
|
|
try:
|
|
await initial_state_helper.wait_for_initial_states()
|
|
except TimeoutError:
|
|
pytest.fail("Timeout waiting for initial states")
|
|
|
|
# Verify we can set a custom fan mode via API (tests find_custom_fan_mode_ compat path)
|
|
client.climate_command(test_climate.key, custom_fan_mode="Turbo")
|
|
|
|
try:
|
|
turbo_state = await asyncio.wait_for(turbo_future, timeout=5.0)
|
|
except TimeoutError:
|
|
pytest.fail("Custom fan mode 'Turbo' not received within 5 seconds")
|
|
|
|
assert turbo_state.custom_fan_mode == "Turbo"
|