From f8755a52c2c2a548f8e6c48f94b3662082fa4213 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Sat, 20 Mar 2021 15:16:04 +0100 Subject: [PATCH] Warn on undefined variables in templates (#48140) * Warn on undefined variables in templates * Add test * fix tests * fix tests --- homeassistant/helpers/template.py | 2 +- tests/components/influxdb/test_sensor.py | 16 +++++++++++++--- tests/helpers/test_script.py | 3 +-- tests/helpers/test_template.py | 7 +++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index cfb7223752e..24c91ec5468 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -1318,7 +1318,7 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment): def __init__(self, hass, limited=False): """Initialise template environment.""" - super().__init__() + super().__init__(undefined=jinja2.make_logging_undefined(logger=_LOGGER)) self.hass = hass self.template_cache = weakref.WeakValueDictionary() self.filters["round"] = forgiving_round diff --git a/tests/components/influxdb/test_sensor.py b/tests/components/influxdb/test_sensor.py index 55172011f4f..9a353f59e42 100644 --- a/tests/components/influxdb/test_sensor.py +++ b/tests/components/influxdb/test_sensor.py @@ -442,7 +442,7 @@ async def test_error_querying_influx( @pytest.mark.parametrize( - "mock_client, config_ext, queries, set_query_mock, make_resultset", + "mock_client, config_ext, queries, set_query_mock, make_resultset, key", [ ( DEFAULT_API_VERSION, @@ -459,6 +459,7 @@ async def test_error_querying_influx( }, _set_query_mock_v1, _make_v1_resultset, + "where", ), ( API_VERSION_2, @@ -466,12 +467,13 @@ async def test_error_querying_influx( {"queries_flux": [{"name": "test", "query": "{{ illegal.template }}"}]}, _set_query_mock_v2, _make_v2_resultset, + "query", ), ], indirect=["mock_client"], ) async def test_error_rendering_template( - hass, caplog, mock_client, config_ext, queries, set_query_mock, make_resultset + hass, caplog, mock_client, config_ext, queries, set_query_mock, make_resultset, key ): """Test behavior of sensor with error rendering template.""" set_query_mock(mock_client, return_value=make_resultset(42)) @@ -479,7 +481,15 @@ async def test_error_rendering_template( sensors = await _setup(hass, config_ext, queries, ["sensor.test"]) assert sensors[0].state == STATE_UNKNOWN assert ( - len([record for record in caplog.records if record.levelname == "ERROR"]) == 1 + len( + [ + record + for record in caplog.records + if record.levelname == "ERROR" + and f"Could not render {key} template" in record.msg + ] + ) + == 1 ) diff --git a/tests/helpers/test_script.py b/tests/helpers/test_script.py index 1f47aa9dbba..8a93d769775 100644 --- a/tests/helpers/test_script.py +++ b/tests/helpers/test_script.py @@ -1277,8 +1277,7 @@ async def test_repeat_condition_warning(hass, caplog, condition): hass.async_create_task(script_obj.async_run(context=Context())) await asyncio.wait_for(hass.async_block_till_done(), 1) - assert len(caplog.record_tuples) == 1 - assert caplog.record_tuples[0][1] == logging.WARNING + assert f"Error in '{condition}[0]' evaluation" in caplog.text assert len(events) == count diff --git a/tests/helpers/test_template.py b/tests/helpers/test_template.py index 193c7e2aa55..da6a8663cc3 100644 --- a/tests/helpers/test_template.py +++ b/tests/helpers/test_template.py @@ -2497,3 +2497,10 @@ async def test_parse_result(hass): ("0011101.00100001010001", "0011101.00100001010001"), ): assert template.Template(tpl, hass).async_render() == result + + +async def test_undefined_variable(hass, caplog): + """Test a warning is logged on undefined variables.""" + tpl = template.Template("{{ no_such_variable }}", hass) + assert tpl.async_render() == "" + assert "Template variable warning: no_such_variable is undefined" in caplog.text