Fix variable scopes in scripts (#138883)

Co-authored-by: Erik <erik@montnemery.com>
This commit is contained in:
Artur Pragacz
2025-02-26 16:19:19 +01:00
committed by GitHub
parent bd80a78848
commit b964bc58be
4 changed files with 504 additions and 87 deletions

View File

@@ -452,6 +452,68 @@ async def test_service_response_data_errors(
await script_obj.async_run(context=context)
async def test_calling_service_response_data_in_scopes(hass: HomeAssistant) -> None:
"""Test response variable is still set after scopes end."""
expected_var = {"data": "value-12345"}
def mock_service(call: ServiceCall) -> ServiceResponse:
"""Mock service call."""
if call.return_response:
return expected_var
return None
hass.services.async_register(
"test", "script", mock_service, supports_response=SupportsResponse.OPTIONAL
)
sequence = cv.SCRIPT_SCHEMA(
{
"parallel": [
{
"alias": "Sequential group",
"sequence": [
{
"alias": "variables",
"variables": {"state": "off"},
},
{
"alias": "service step1",
"action": "test.script",
"response_variable": "my_response",
},
],
}
]
}
)
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
result = await script_obj.async_run(context=Context())
assert result.variables["my_response"] == expected_var
expected_trace = {
"0": [{"variables": {"my_response": expected_var}}],
"0/parallel/0/sequence/0": [{"variables": {"state": "off"}}],
"0/parallel/0/sequence/1": [
{
"result": {
"params": {
"domain": "test",
"service": "script",
"service_data": {},
"target": {},
},
"running_script": False,
},
"variables": {"my_response": expected_var},
}
],
}
assert_action_trace(expected_trace)
async def test_data_template_with_templated_key(hass: HomeAssistant) -> None:
"""Test the calling of a service with a data_template with a templated key."""
context = Context()
@@ -1706,6 +1768,90 @@ async def test_wait_variables_out(hass: HomeAssistant, mode, action_type) -> Non
assert float(remaining) == 0.0
async def test_wait_in_sequence(hass: HomeAssistant) -> None:
"""Test wait variable is still set after sequence ends."""
sequence = cv.SCRIPT_SCHEMA(
[
{
"alias": "Sequential group",
"sequence": [
{
"alias": "variables",
"variables": {"state": "off"},
},
{
"alias": "wait template",
"wait_template": "{{ state == 'off' }}",
},
],
},
]
)
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
result = await script_obj.async_run(context=Context())
expected_var = {"completed": True, "remaining": None}
assert result.variables["wait"] == expected_var
expected_trace = {
"0": [{"variables": {"wait": expected_var}}],
"0/sequence/0": [{"variables": {"state": "off"}}],
"0/sequence/1": [
{
"result": {"wait": expected_var},
"variables": {"wait": expected_var},
}
],
}
assert_action_trace(expected_trace)
async def test_wait_in_parallel(hass: HomeAssistant) -> None:
"""Test wait variable is not set after parallel ends."""
sequence = cv.SCRIPT_SCHEMA(
{
"parallel": [
{
"alias": "Sequential group",
"sequence": [
{
"alias": "variables",
"variables": {"state": "off"},
},
{
"alias": "wait template",
"wait_template": "{{ state == 'off' }}",
},
],
}
]
}
)
script_obj = script.Script(hass, sequence, "Test Name", "test_domain")
result = await script_obj.async_run(context=Context())
expected_var = {"completed": True, "remaining": None}
assert "wait" not in result.variables
expected_trace = {
"0": [{}],
"0/parallel/0/sequence/0": [{"variables": {"state": "off"}}],
"0/parallel/0/sequence/1": [
{
"result": {"wait": expected_var},
"variables": {"wait": expected_var},
}
],
}
assert_action_trace(expected_trace)
async def test_wait_for_trigger_bad(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None: