Implement template rate_limit directive (#40667)

This commit is contained in:
J. Nick Koston 2020-10-01 14:39:44 -05:00 committed by GitHub
parent b3464c5087
commit b45215f1d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 669 additions and 18 deletions

View file

@ -1,5 +1,5 @@
"""Test Home Assistant template helper methods."""
from datetime import datetime
from datetime import datetime, timedelta
import math
import random
@ -149,6 +149,7 @@ def test_iterating_all_states(hass):
info = render_to_info(hass, tmpl_str)
assert_result_info(info, "", all_states=True)
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
hass.states.async_set("test.object", "happy")
hass.states.async_set("sensor.temperature", 10)
@ -165,6 +166,7 @@ def test_iterating_domain_states(hass):
info = render_to_info(hass, tmpl_str)
assert_result_info(info, "", domains=["sensor"])
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
hass.states.async_set("test.object", "happy")
hass.states.async_set("sensor.back_door", "open")
@ -1342,6 +1344,7 @@ async def test_closest_function_home_vs_group_entity_id(hass):
assert_result_info(
info, "test_domain.object", {"group.location_group", "test_domain.object"}
)
assert info.rate_limit is None
async def test_closest_function_home_vs_group_state(hass):
@ -1369,20 +1372,24 @@ async def test_closest_function_home_vs_group_state(hass):
assert_result_info(
info, "test_domain.object", {"group.location_group", "test_domain.object"}
)
assert info.rate_limit is None
info = render_to_info(hass, "{{ closest(states.group.location_group).entity_id }}")
assert_result_info(
info, "test_domain.object", {"test_domain.object", "group.location_group"}
)
assert info.rate_limit is None
async def test_expand(hass):
"""Test expand function."""
info = render_to_info(hass, "{{ expand('test.object') }}")
assert_result_info(info, "[]", ["test.object"])
assert info.rate_limit is None
info = render_to_info(hass, "{{ expand(56) }}")
assert_result_info(info, "[]")
assert info.rate_limit is None
hass.states.async_set("test.object", "happy")
@ -1390,17 +1397,20 @@ async def test_expand(hass):
hass, "{{ expand('test.object') | map(attribute='entity_id') | join(', ') }}"
)
assert_result_info(info, "test.object", ["test.object"])
assert info.rate_limit is None
info = render_to_info(
hass,
"{{ expand('group.new_group') | map(attribute='entity_id') | join(', ') }}",
)
assert_result_info(info, "", ["group.new_group"])
assert info.rate_limit is None
info = render_to_info(
hass, "{{ expand(states.group) | map(attribute='entity_id') | join(', ') }}"
)
assert_result_info(info, "", [], ["group"])
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
assert await async_setup_component(hass, "group", {})
await hass.async_block_till_done()
@ -1411,6 +1421,7 @@ async def test_expand(hass):
"{{ expand('group.new_group') | map(attribute='entity_id') | join(', ') }}",
)
assert_result_info(info, "test.object", {"group.new_group", "test.object"})
assert info.rate_limit is None
info = render_to_info(
hass, "{{ expand(states.group) | map(attribute='entity_id') | join(', ') }}"
@ -1418,6 +1429,7 @@ async def test_expand(hass):
assert_result_info(
info, "test.object", {"test.object", "group.new_group"}, ["group"]
)
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
info = render_to_info(
hass,
@ -1432,6 +1444,7 @@ async def test_expand(hass):
" | map(attribute='entity_id') | join(', ') }}",
)
assert_result_info(info, "test.object", {"test.object", "group.new_group"})
assert info.rate_limit is None
hass.states.async_set("sensor.power_1", 0)
hass.states.async_set("sensor.power_2", 200.2)
@ -1452,6 +1465,7 @@ async def test_expand(hass):
str(200.2 + 400.4),
{"group.power_sensors", "sensor.power_1", "sensor.power_2", "sensor.power_3"},
)
assert info.rate_limit is None
def test_closest_function_to_coord(hass):
@ -1517,6 +1531,7 @@ def test_async_render_to_info_with_branching(hass):
""",
)
assert_result_info(info, "off", {"light.a", "light.c"})
assert info.rate_limit is None
info = render_to_info(
hass,
@ -1528,6 +1543,7 @@ def test_async_render_to_info_with_branching(hass):
""",
)
assert_result_info(info, "on", {"light.a", "light.b"})
assert info.rate_limit is None
def test_async_render_to_info_with_complex_branching(hass):
@ -1564,6 +1580,7 @@ def test_async_render_to_info_with_complex_branching(hass):
)
assert_result_info(info, "['sensor.a']", {"light.a", "light.b"}, {"sensor"})
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
async def test_async_render_to_info_with_wildcard_matching_entity_id(hass):
@ -1589,6 +1606,7 @@ async def test_async_render_to_info_with_wildcard_matching_entity_id(hass):
"cover.office_skylight",
}
assert info.all_states is True
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
async def test_async_render_to_info_with_wildcard_matching_state(hass):
@ -1619,6 +1637,7 @@ async def test_async_render_to_info_with_wildcard_matching_state(hass):
"cover.office_skylight",
}
assert info.all_states is True
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
hass.states.async_set("binary_sensor.door", "closed")
info = render_to_info(hass, template_complex_str)
@ -1632,6 +1651,7 @@ async def test_async_render_to_info_with_wildcard_matching_state(hass):
"cover.office_skylight",
}
assert info.all_states is True
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
template_cover_str = """
@ -1653,6 +1673,7 @@ async def test_async_render_to_info_with_wildcard_matching_state(hass):
"cover.office_skylight",
}
assert info.all_states is False
assert info.rate_limit == template.DEFAULT_RATE_LIMIT
def test_nested_async_render_to_info_case(hass):
@ -1665,6 +1686,7 @@ def test_nested_async_render_to_info_case(hass):
hass, "{{ states[states['input_select.picker'].state].state }}", {}
)
assert_result_info(info, "off", {"input_select.picker", "vacuum.a"})
assert info.rate_limit is None
def test_result_as_boolean(hass):
@ -2459,6 +2481,7 @@ async def test_lifecycle(hass):
info = tmp.async_render_to_info()
assert info.all_states is False
assert info.all_states_lifecycle is True
assert info.rate_limit is None
assert info.entities == set()
assert info.domains == set()
assert info.domains_lifecycle == set()
@ -2594,3 +2617,28 @@ async def test_unavailable_states(hass):
hass,
)
assert tpl.async_render() == "light.none, light.unavailable, light.unknown"
async def test_rate_limit(hass):
"""Test we can pickup a rate limit directive."""
tmp = template.Template("{{ states | count }}", hass)
info = tmp.async_render_to_info()
assert info.rate_limit is None
tmp = template.Template("{{ rate_limit(minutes=1) }}{{ states | count }}", hass)
info = tmp.async_render_to_info()
assert info.rate_limit == timedelta(minutes=1)
tmp = template.Template("{{ rate_limit(minutes=1) }}random", hass)
info = tmp.async_render_to_info()
assert info.result() == "random"
assert info.rate_limit == timedelta(minutes=1)
tmp = template.Template("{{ rate_limit(seconds=0) }}random", hass)
info = tmp.async_render_to_info()
assert info.result() == "random"
assert info.rate_limit == timedelta(seconds=0)