1
0
mirror of https://github.com/home-assistant/core.git synced 2026-06-06 15:36:51 +01:00

Improve helpers.condition.async_subscribe_platform_events (#157710)

This commit is contained in:
Erik Montnemery
2025-12-02 11:32:14 +01:00
committed by Franck Nijhof
parent ef4062a565
commit 97c50b2d86
2 changed files with 135 additions and 1 deletions
+16 -1
View File
@@ -198,7 +198,12 @@ def async_subscribe_platform_events(
async def _register_condition_platform(
hass: HomeAssistant, integration_domain: str, platform: ConditionProtocol
) -> None:
"""Register a condition platform."""
"""Register a condition platform and notify listeners.
If the condition platform does not provide any conditions, or it is disabled,
listeners will not be notified.
"""
from homeassistant.components import automation # noqa: PLC0415
new_conditions: set[str] = set()
@@ -209,6 +214,12 @@ async def _register_condition_platform(
)
hass.data[CONDITIONS][condition_key] = integration_domain
new_conditions.add(condition_key)
if not new_conditions:
_LOGGER.debug(
"Integration %s returned no conditions in async_get_conditions",
integration_domain,
)
return
else:
_LOGGER.debug(
"Integration %s does not provide condition support, skipping",
@@ -216,6 +227,10 @@ async def _register_condition_platform(
)
return
if automation.is_disabled_experimental_condition(hass, integration_domain):
_LOGGER.debug("Conditions for integration %s are disabled", integration_domain)
return
# We don't use gather here because gather adds additional overhead
# when wrapping each coroutine in a task, and we expect our listeners
# to call condition.async_get_all_descriptions which will only yield
+119
View File
@@ -2878,3 +2878,122 @@ async def test_subscribe_conditions(
assert condition_events == [{"sun"}]
assert "Error while notifying condition platform listener" in caplog.text
@patch("annotatedyaml.loader.load_yaml")
@patch.object(Integration, "has_conditions", return_value=True)
@pytest.mark.parametrize(
("new_triggers_conditions_enabled", "expected_events"),
[
(True, [{"light.is_off", "light.is_on"}]),
(False, []),
],
)
async def test_subscribe_conditions_experimental_conditions(
mock_has_conditions: Mock,
mock_load_yaml: Mock,
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
caplog: pytest.LogCaptureFixture,
new_triggers_conditions_enabled: bool,
expected_events: list[set[str]],
) -> None:
"""Test condition.async_subscribe_platform_events doesn't send events for disabled conditions."""
# Return empty conditions.yaml for light integration, the actual condition
# descriptions are irrelevant for this test
light_condition_descriptions = ""
def _load_yaml(fname, secrets=None):
if fname.endswith("light/conditions.yaml"):
condition_descriptions = light_condition_descriptions
else:
raise FileNotFoundError
with io.StringIO(condition_descriptions) as file:
return parse_yaml(file)
mock_load_yaml.side_effect = _load_yaml
condition_events = []
async def good_subscriber(new_conditions: set[str]):
"""Simulate a working subscriber."""
condition_events.append(new_conditions)
ws_client = await hass_ws_client(hass)
assert await async_setup_component(hass, "labs", {})
await ws_client.send_json_auto_id(
{
"type": "labs/update",
"domain": "automation",
"preview_feature": "new_triggers_conditions",
"enabled": new_triggers_conditions_enabled,
}
)
msg = await ws_client.receive_json()
assert msg["success"]
await hass.async_block_till_done()
condition.async_subscribe_platform_events(hass, good_subscriber)
assert await async_setup_component(hass, "light", {})
await hass.async_block_till_done()
assert condition_events == expected_events
@patch("annotatedyaml.loader.load_yaml")
@patch.object(Integration, "has_conditions", return_value=True)
@patch(
"homeassistant.components.light.condition.async_get_conditions",
new=AsyncMock(return_value={}),
)
async def test_subscribe_conditions_no_conditions(
mock_has_conditions: Mock,
mock_load_yaml: Mock,
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test condition.async_subscribe_platform_events doesn't send events for platforms without conditions."""
# Return empty conditions.yaml for light integration, the actual condition
# descriptions are irrelevant for this test
light_condition_descriptions = ""
def _load_yaml(fname, secrets=None):
if fname.endswith("light/conditions.yaml"):
condition_descriptions = light_condition_descriptions
else:
raise FileNotFoundError
with io.StringIO(condition_descriptions) as file:
return parse_yaml(file)
mock_load_yaml.side_effect = _load_yaml
condition_events = []
async def good_subscriber(new_conditions: set[str]):
"""Simulate a working subscriber."""
condition_events.append(new_conditions)
ws_client = await hass_ws_client(hass)
assert await async_setup_component(hass, "labs", {})
await ws_client.send_json_auto_id(
{
"type": "labs/update",
"domain": "automation",
"preview_feature": "new_triggers_conditions",
"enabled": True,
}
)
msg = await ws_client.receive_json()
assert msg["success"]
await hass.async_block_till_done()
condition.async_subscribe_platform_events(hass, good_subscriber)
assert await async_setup_component(hass, "light", {})
await hass.async_block_till_done()
assert condition_events == []