1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-25 21:47:08 +00:00
Files
core/tests/helpers/template/extensions/test_base.py

296 lines
8.3 KiB
Python

"""Test base template extension."""
from __future__ import annotations
import pytest
from homeassistant.exceptions import TemplateError
from homeassistant.helpers.template import TemplateEnvironment
from homeassistant.helpers.template.extensions.base import (
BaseTemplateExtension,
TemplateFunction,
)
def test_hass_property_raises_when_hass_is_none() -> None:
"""Test that accessing hass property raises RuntimeError when hass is None."""
# Create an environment without hass
env = TemplateEnvironment(None)
# Create a simple extension
extension = BaseTemplateExtension(env)
# Accessing hass property should raise RuntimeError
with pytest.raises(
RuntimeError,
match=(
"Home Assistant instance is not available. "
"This property should only be used in extensions with "
"functions marked requires_hass=True."
),
):
_ = extension.hass
def test_requires_hass_functions_not_registered_without_hass() -> None:
"""Test that functions requiring hass are not registered when hass is None."""
# Create an environment without hass
env = TemplateEnvironment(None)
# Create a test function
def test_func() -> str:
return "test"
# Create extension with a function that requires hass
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"test_func",
test_func,
as_global=True,
requires_hass=True,
),
],
)
# Function should not be registered
assert "test_func" not in env.globals
assert extension is not None # Extension is created but function not registered
def test_requires_hass_false_functions_registered_without_hass() -> None:
"""Test that functions not requiring hass are registered even when hass is None."""
# Create an environment without hass
env = TemplateEnvironment(None)
# Create a test function
def test_func() -> str:
return "test"
# Create extension with a function that does not require hass
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"test_func",
test_func,
as_global=True,
requires_hass=False, # Explicitly False (default)
),
],
)
# Function should be registered
assert "test_func" in env.globals
assert extension is not None
def test_limited_ok_functions_not_registered_in_limited_env() -> None:
"""Test that functions with limited_ok=False raise error in limited env."""
# Create a limited environment without hass
env = TemplateEnvironment(None, limited=True)
# Create test functions
def allowed_func() -> str:
return "allowed"
def restricted_func() -> str:
return "restricted"
# Create extension with both types of functions
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"allowed_func",
allowed_func,
as_global=True,
limited_ok=True, # Allowed in limited environments
),
TemplateFunction(
"restricted_func",
restricted_func,
as_global=True,
limited_ok=False, # Not allowed in limited environments
),
],
)
# The allowed function should be registered and work
assert "allowed_func" in env.globals
assert env.globals["allowed_func"]() == "allowed"
# The restricted function should be registered but raise TemplateError
assert "restricted_func" in env.globals
with pytest.raises(
TemplateError,
match="Use of 'restricted_func' is not supported in limited templates",
):
env.globals["restricted_func"]()
assert extension is not None
def test_limited_ok_true_functions_registered_in_limited_env() -> None:
"""Test that functions with limited_ok=True are registered in limited env."""
# Create a limited environment without hass
env = TemplateEnvironment(None, limited=True)
# Create a test function
def test_func() -> str:
return "test"
# Create extension with a function allowed in limited environments
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"test_func",
test_func,
as_global=True,
limited_ok=True, # Default is True
),
],
)
# Function should be registered
assert "test_func" in env.globals
assert extension is not None
def test_function_registered_as_global() -> None:
"""Test that functions can be registered as globals."""
env = TemplateEnvironment(None)
def test_func() -> str:
return "global"
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"test_func",
test_func,
as_global=True,
),
],
)
# Function should be registered as a global
assert "test_func" in env.globals
assert env.globals["test_func"] is test_func
assert extension is not None
def test_function_registered_as_filter() -> None:
"""Test that functions can be registered as filters."""
env = TemplateEnvironment(None)
def test_filter(value: str) -> str:
return f"filtered_{value}"
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"test_filter",
test_filter,
as_filter=True,
),
],
)
# Function should be registered as a filter
assert "test_filter" in env.filters
assert env.filters["test_filter"] is test_filter
# Should not be in globals since as_global=False
assert "test_filter" not in env.globals
assert extension is not None
def test_function_registered_as_test() -> None:
"""Test that functions can be registered as tests."""
env = TemplateEnvironment(None)
def test_check(value: str) -> bool:
return value == "test"
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"test_check",
test_check,
as_test=True,
),
],
)
# Function should be registered as a test
assert "test_check" in env.tests
assert env.tests["test_check"] is test_check
# Should not be in globals or filters
assert "test_check" not in env.globals
assert "test_check" not in env.filters
assert extension is not None
def test_function_registered_as_multiple_types() -> None:
"""Test that functions can be registered as multiple types simultaneously."""
env = TemplateEnvironment(None)
def multi_func(value: str = "default") -> str:
return f"multi_{value}"
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction(
"multi_func",
multi_func,
as_global=True,
as_filter=True,
as_test=True,
),
],
)
# Function should be registered in all three places
assert "multi_func" in env.globals
assert env.globals["multi_func"] is multi_func
assert "multi_func" in env.filters
assert env.filters["multi_func"] is multi_func
assert "multi_func" in env.tests
assert env.tests["multi_func"] is multi_func
assert extension is not None
def test_multiple_functions_registered() -> None:
"""Test that multiple functions can be registered at once."""
env = TemplateEnvironment(None)
def func1() -> str:
return "one"
def func2() -> str:
return "two"
def func3() -> str:
return "three"
extension = BaseTemplateExtension(
env,
functions=[
TemplateFunction("func1", func1, as_global=True),
TemplateFunction("func2", func2, as_filter=True),
TemplateFunction("func3", func3, as_test=True),
],
)
# All functions should be registered in their respective places
assert "func1" in env.globals
assert "func2" in env.filters
assert "func3" in env.tests
assert extension is not None