From 33222436d2d3e3ca9503c42fd6e981e717d8fdc1 Mon Sep 17 00:00:00 2001 From: Petro31 <35082313+Petro31@users.noreply.github.com> Date: Wed, 27 Nov 2024 03:18:02 -0500 Subject: [PATCH] Nested stop actions will now return response_variables (#126393) fix-nested-stop-variable-response --- homeassistant/helpers/script.py | 2 - tests/helpers/test_script.py | 85 +++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 86dcd858c1b..2ddfd2fe313 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -477,8 +477,6 @@ class _ScriptRun: # Let the _StopScript bubble up if this is a sub-script if not self._script.top_level: - # We already consumed the response, do not pass it on - err.response = None raise except Exception: script_execution_set("error") diff --git a/tests/helpers/test_script.py b/tests/helpers/test_script.py index f67519905a1..c438e333ae6 100644 --- a/tests/helpers/test_script.py +++ b/tests/helpers/test_script.py @@ -5632,6 +5632,91 @@ async def test_stop_action_subscript( ) +@pytest.mark.parametrize( + ("var", "response"), + [(1, "If: Then"), (2, "Testing 123")], +) +async def test_stop_action_response_variables( + hass: HomeAssistant, + var: int, + response: str, +) -> None: + """Test setting stop response_variable in a subscript.""" + sequence = cv.SCRIPT_SCHEMA( + [ + {"variables": {"output": {"value": "Testing 123"}}}, + { + "if": { + "condition": "template", + "value_template": "{{ var == 1 }}", + }, + "then": [ + {"variables": {"output": {"value": "If: Then"}}}, + {"stop": "In the name of love", "response_variable": "output"}, + ], + }, + {"stop": "In the name of love", "response_variable": "output"}, + ] + ) + script_obj = script.Script(hass, sequence, "Test Name", "test_domain") + + run_vars = MappingProxyType({"var": var}) + result = await script_obj.async_run(run_vars, context=Context()) + assert result.service_response == {"value": response} + + +@pytest.mark.parametrize( + ("var", "if_result", "choice", "response"), + [(1, True, "then", "If: Then"), (2, False, "else", "If: Else")], +) +async def test_stop_action_nested_response_variables( + hass: HomeAssistant, + var: int, + if_result: bool, + choice: str, + response: str, +) -> None: + """Test setting stop response_variable in a subscript.""" + sequence = cv.SCRIPT_SCHEMA( + [ + {"variables": {"output": {"value": "Testing 123"}}}, + { + "if": { + "condition": "template", + "value_template": "{{ var == 1 }}", + }, + "then": [ + {"variables": {"output": {"value": "If: Then"}}}, + {"stop": "In the name of love", "response_variable": "output"}, + ], + "else": [ + {"variables": {"output": {"value": "If: Else"}}}, + {"stop": "In the name of love", "response_variable": "output"}, + ], + }, + ] + ) + script_obj = script.Script(hass, sequence, "Test Name", "test_domain") + + run_vars = MappingProxyType({"var": var}) + result = await script_obj.async_run(run_vars, context=Context()) + assert result.service_response == {"value": response} + + expected_trace = { + "0": [ + { + "variables": {"var": var, "output": {"value": "Testing 123"}}, + } + ], + "1": [{"result": {"choice": choice}}], + "1/if": [{"result": {"result": if_result}}], + "1/if/condition/0": [{"result": {"result": var == 1, "entities": []}}], + f"1/{choice}/0": [{"variables": {"output": {"value": response}}}], + f"1/{choice}/1": [{"result": {"stop": "In the name of love", "error": False}}], + } + assert_action_trace(expected_trace) + + async def test_stop_action_with_error( hass: HomeAssistant, caplog: pytest.LogCaptureFixture ) -> None: