Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

252 lines
8.3 KiB
Python
Raw Permalink Normal View History

2026-03-11 10:59:53 +01:00
"""Test gate trigger."""
from typing import Any
import pytest
from homeassistant.components.cover import ATTR_IS_CLOSED, CoverDeviceClass, CoverState
from homeassistant.const import ATTR_DEVICE_CLASS
2026-03-26 00:51:14 +01:00
from homeassistant.core import HomeAssistant
2026-03-11 10:59:53 +01:00
from tests.components.common import (
2026-03-11 10:59:53 +01:00
TriggerStateDescription,
2026-05-27 16:01:11 +02:00
assert_trigger_behavior_all,
assert_trigger_behavior_each,
assert_trigger_behavior_first,
assert_trigger_options_supported,
2026-03-11 10:59:53 +01:00
parametrize_target_entities,
parametrize_trigger_states,
target_entities,
)
@pytest.fixture
async def target_covers(hass: HomeAssistant) -> dict[str, list[str]]:
"""Create multiple cover entities associated with different targets."""
return await target_entities(hass, "cover")
@pytest.mark.parametrize(
("trigger_key", "base_options", "supports_behavior", "supports_duration"),
[
("gate.closed", {}, True, True),
("gate.opened", {}, True, True),
],
)
async def test_gate_trigger_options_validation(
hass: HomeAssistant,
trigger_key: str,
base_options: dict[str, Any] | None,
supports_behavior: bool,
supports_duration: bool,
) -> None:
"""Test that gate triggers support the expected options."""
await assert_trigger_options_supported(
hass,
trigger_key,
base_options,
supports_behavior=supports_behavior,
supports_duration=supports_duration,
)
2026-03-11 10:59:53 +01:00
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("cover"),
)
@pytest.mark.parametrize(
("trigger", "trigger_options", "states"),
[
*parametrize_trigger_states(
trigger="gate.opened",
target_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: False}),
(CoverState.OPENING, {ATTR_IS_CLOSED: False}),
],
other_states=[
(CoverState.CLOSED, {ATTR_IS_CLOSED: True}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: True}),
],
extra_invalid_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: None}),
(CoverState.OPEN, {}),
],
required_filter_attributes={ATTR_DEVICE_CLASS: CoverDeviceClass.GATE},
2026-03-11 10:59:53 +01:00
trigger_from_none=False,
),
*parametrize_trigger_states(
trigger="gate.closed",
target_states=[
(CoverState.CLOSED, {ATTR_IS_CLOSED: True}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: True}),
],
other_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: False}),
(CoverState.OPENING, {ATTR_IS_CLOSED: False}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: False}),
],
extra_invalid_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: None}),
(CoverState.OPEN, {}),
],
required_filter_attributes={ATTR_DEVICE_CLASS: CoverDeviceClass.GATE},
2026-03-11 10:59:53 +01:00
trigger_from_none=False,
),
],
)
2026-05-27 16:01:11 +02:00
async def test_gate_trigger_cover_behavior_each(
2026-03-11 10:59:53 +01:00
hass: HomeAssistant,
target_covers: dict[str, list[str]],
trigger_target_config: dict,
entity_id: str,
entities_in_target: int,
trigger: str,
trigger_options: dict[str, Any],
states: list[TriggerStateDescription],
) -> None:
"""Test gate trigger fires for cover entities with device_class gate."""
2026-05-27 16:01:11 +02:00
await assert_trigger_behavior_each(
hass,
target_entities=target_covers,
trigger_target_config=trigger_target_config,
entity_id=entity_id,
entities_in_target=entities_in_target,
trigger=trigger,
trigger_options=trigger_options,
states=states,
)
2026-03-11 10:59:53 +01:00
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("cover"),
)
@pytest.mark.parametrize(
("trigger", "trigger_options", "states"),
[
*parametrize_trigger_states(
trigger="gate.opened",
target_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: False}),
(CoverState.OPENING, {ATTR_IS_CLOSED: False}),
],
other_states=[
(CoverState.CLOSED, {ATTR_IS_CLOSED: True}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: True}),
],
extra_invalid_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: None}),
(CoverState.OPEN, {}),
],
required_filter_attributes={ATTR_DEVICE_CLASS: CoverDeviceClass.GATE},
2026-03-11 10:59:53 +01:00
trigger_from_none=False,
),
*parametrize_trigger_states(
trigger="gate.closed",
target_states=[
(CoverState.CLOSED, {ATTR_IS_CLOSED: True}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: True}),
],
other_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: False}),
(CoverState.OPENING, {ATTR_IS_CLOSED: False}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: False}),
],
extra_invalid_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: None}),
(CoverState.OPEN, {}),
],
required_filter_attributes={ATTR_DEVICE_CLASS: CoverDeviceClass.GATE},
2026-03-11 10:59:53 +01:00
trigger_from_none=False,
),
],
)
async def test_gate_trigger_cover_behavior_first(
hass: HomeAssistant,
target_covers: dict[str, list[str]],
trigger_target_config: dict,
entity_id: str,
entities_in_target: int,
trigger: str,
trigger_options: dict[str, Any],
states: list[TriggerStateDescription],
) -> None:
"""Test gate trigger fires on the first cover state change."""
await assert_trigger_behavior_first(
hass,
target_entities=target_covers,
trigger_target_config=trigger_target_config,
entity_id=entity_id,
entities_in_target=entities_in_target,
trigger=trigger,
trigger_options=trigger_options,
states=states,
)
2026-03-11 10:59:53 +01:00
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("cover"),
)
@pytest.mark.parametrize(
("trigger", "trigger_options", "states"),
[
*parametrize_trigger_states(
trigger="gate.opened",
target_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: False}),
(CoverState.OPENING, {ATTR_IS_CLOSED: False}),
],
other_states=[
(CoverState.CLOSED, {ATTR_IS_CLOSED: True}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: True}),
],
extra_invalid_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: None}),
(CoverState.OPEN, {}),
],
required_filter_attributes={ATTR_DEVICE_CLASS: CoverDeviceClass.GATE},
2026-03-11 10:59:53 +01:00
trigger_from_none=False,
),
*parametrize_trigger_states(
trigger="gate.closed",
target_states=[
(CoverState.CLOSED, {ATTR_IS_CLOSED: True}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: True}),
],
other_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: False}),
(CoverState.OPENING, {ATTR_IS_CLOSED: False}),
(CoverState.CLOSING, {ATTR_IS_CLOSED: False}),
],
extra_invalid_states=[
(CoverState.OPEN, {ATTR_IS_CLOSED: None}),
(CoverState.OPEN, {}),
],
required_filter_attributes={ATTR_DEVICE_CLASS: CoverDeviceClass.GATE},
2026-03-11 10:59:53 +01:00
trigger_from_none=False,
),
],
)
2026-05-27 16:01:11 +02:00
async def test_gate_trigger_cover_behavior_all(
2026-03-11 10:59:53 +01:00
hass: HomeAssistant,
target_covers: dict[str, list[str]],
trigger_target_config: dict,
entity_id: str,
entities_in_target: int,
trigger: str,
trigger_options: dict[str, Any],
states: list[TriggerStateDescription],
) -> None:
2026-05-27 16:01:11 +02:00
"""Test gate trigger fires when all covers have changed state."""
await assert_trigger_behavior_all(
hass,
target_entities=target_covers,
trigger_target_config=trigger_target_config,
entity_id=entity_id,
entities_in_target=entities_in_target,
trigger=trigger,
trigger_options=trigger_options,
states=states,
)