mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 10:12:52 +00:00
[haier] Reject deferring actions in on_status_message (#20539)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
2ab06fa937
commit
eb56ce2b76
@@ -0,0 +1,61 @@
|
||||
"""Tests that haier on_status_message automations reject deferring actions.
|
||||
|
||||
The trigger passes a pointer into the protocol's receive buffer, which is reused for the next
|
||||
frame, so the deferring-actions guard is a safety property.
|
||||
"""
|
||||
|
||||
from collections.abc import Callable
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome import config_validation as cv
|
||||
from esphome.components.haier.climate import (
|
||||
CONF_ON_STATUS_MESSAGE,
|
||||
HonClimate,
|
||||
Smartair2Climate,
|
||||
_base_config_schema,
|
||||
)
|
||||
from esphome.core import Lambda
|
||||
from esphome.cpp_generator import MockObjClass
|
||||
from esphome.types import ConfigType
|
||||
|
||||
CLIMATE_CLASSES = [HonClimate, Smartair2Climate]
|
||||
|
||||
DEFERRING_ACTION = {"delay": "1s"}
|
||||
SYNCHRONOUS_ACTION = {"lambda": Lambda('ESP_LOGD("test", "ran");')}
|
||||
TRUE_CONDITION = {"lambda": Lambda("return true;")}
|
||||
|
||||
DEFER_MESSAGE = "Deferring actions"
|
||||
|
||||
|
||||
def _trigger_schema(
|
||||
class_: MockObjClass,
|
||||
) -> Callable[[list[ConfigType]], list[ConfigType]]:
|
||||
"""The validator the protocol's schema applies to on_status_message."""
|
||||
return _base_config_schema(class_).schema[cv.Optional(CONF_ON_STATUS_MESSAGE)]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("class_", CLIMATE_CLASSES)
|
||||
def test_synchronous_automation_accepted(class_: MockObjClass) -> None:
|
||||
_trigger_schema(class_)([{"then": [SYNCHRONOUS_ACTION]}])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("class_", CLIMATE_CLASSES)
|
||||
def test_deferring_action_rejected(class_: MockObjClass) -> None:
|
||||
with pytest.raises(cv.Invalid, match=DEFER_MESSAGE):
|
||||
_trigger_schema(class_)([{"then": [SYNCHRONOUS_ACTION, DEFERRING_ACTION]}])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("class_", CLIMATE_CLASSES)
|
||||
def test_nested_deferring_action_rejected(class_: MockObjClass) -> None:
|
||||
actions = [{"if": {"condition": TRUE_CONDITION, "then": [DEFERRING_ACTION]}}]
|
||||
with pytest.raises(cv.Invalid, match=DEFER_MESSAGE):
|
||||
_trigger_schema(class_)([{"then": actions}])
|
||||
|
||||
|
||||
@pytest.mark.parametrize("class_", CLIMATE_CLASSES)
|
||||
def test_deferring_action_in_second_automation_rejected(class_: MockObjClass) -> None:
|
||||
with pytest.raises(cv.Invalid, match=DEFER_MESSAGE):
|
||||
_trigger_schema(class_)(
|
||||
[{"then": [SYNCHRONOUS_ACTION]}, {"then": [DEFERRING_ACTION]}]
|
||||
)
|
||||
@@ -43,6 +43,12 @@ climate:
|
||||
level: DEBUG
|
||||
format: "Alarm deactivated. Code: %d. Message: \"%s\""
|
||||
args: [code, message]
|
||||
on_status_message:
|
||||
then:
|
||||
- logger.log:
|
||||
level: DEBUG
|
||||
format: "Status message: %u bytes"
|
||||
args: [(unsigned) data_size]
|
||||
|
||||
sensor:
|
||||
- platform: haier
|
||||
|
||||
Reference in New Issue
Block a user