mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Fix execute device actions with WS execute_script (#95783)
This commit is contained in:
parent
3f9d5a0192
commit
78880f0c9d
@ -704,10 +704,12 @@ async def handle_execute_script(
|
||||
"""Handle execute script command."""
|
||||
# Circular dep
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from homeassistant.helpers.script import Script
|
||||
from homeassistant.helpers.script import Script, async_validate_actions_config
|
||||
|
||||
script_config = await async_validate_actions_config(hass, msg["sequence"])
|
||||
|
||||
context = connection.context(msg)
|
||||
script_obj = Script(hass, msg["sequence"], f"{const.DOMAIN} script", const.DOMAIN)
|
||||
script_obj = Script(hass, script_config, f"{const.DOMAIN} script", const.DOMAIN)
|
||||
response = await script_obj.async_run(msg.get("variables"), context=context)
|
||||
connection.send_result(
|
||||
msg["id"],
|
||||
|
@ -1,12 +1,14 @@
|
||||
"""Tests for WebSocket API commands."""
|
||||
from copy import deepcopy
|
||||
import datetime
|
||||
from unittest.mock import ANY, patch
|
||||
from unittest.mock import ANY, AsyncMock, Mock, patch
|
||||
|
||||
from async_timeout import timeout
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, loader
|
||||
from homeassistant.components.device_automation import toggle_entity
|
||||
from homeassistant.components.websocket_api import const
|
||||
from homeassistant.components.websocket_api.auth import (
|
||||
TYPE_AUTH,
|
||||
@ -17,13 +19,20 @@ from homeassistant.components.websocket_api.const import FEATURE_COALESCE_MESSAG
|
||||
from homeassistant.const import SIGNAL_BOOTSTRAP_INTEGRATIONS
|
||||
from homeassistant.core import Context, HomeAssistant, State, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import entity
|
||||
from homeassistant.helpers import device_registry as dr, entity
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
from homeassistant.loader import async_get_integration
|
||||
from homeassistant.setup import DATA_SETUP_TIME, async_setup_component
|
||||
from homeassistant.util.json import json_loads
|
||||
|
||||
from tests.common import MockEntity, MockEntityPlatform, MockUser, async_mock_service
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
MockEntity,
|
||||
MockEntityPlatform,
|
||||
MockUser,
|
||||
async_mock_service,
|
||||
mock_platform,
|
||||
)
|
||||
from tests.typing import (
|
||||
ClientSessionGenerator,
|
||||
WebSocketGenerator,
|
||||
@ -40,6 +49,25 @@ STATE_KEY_SHORT_NAMES = {
|
||||
STATE_KEY_LONG_NAMES = {v: k for k, v in STATE_KEY_SHORT_NAMES.items()}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fake_integration(hass: HomeAssistant):
|
||||
"""Set up a mock integration with device automation support."""
|
||||
DOMAIN = "fake_integration"
|
||||
|
||||
hass.config.components.add(DOMAIN)
|
||||
|
||||
mock_platform(
|
||||
hass,
|
||||
f"{DOMAIN}.device_action",
|
||||
Mock(
|
||||
ACTION_SCHEMA=toggle_entity.ACTION_SCHEMA.extend(
|
||||
{vol.Required("domain"): DOMAIN}
|
||||
),
|
||||
spec=["ACTION_SCHEMA"],
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def _apply_entities_changes(state_dict: dict, change_dict: dict) -> None:
|
||||
"""Apply a diff set to a dict.
|
||||
|
||||
@ -1775,6 +1803,52 @@ async def test_execute_script_complex_response(
|
||||
}
|
||||
|
||||
|
||||
async def test_execute_script_with_dynamically_validated_action(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
fake_integration,
|
||||
) -> None:
|
||||
"""Test executing a script with an action which is dynamically validated."""
|
||||
|
||||
ws_client = await hass_ws_client(hass)
|
||||
|
||||
module_cache = hass.data.setdefault(loader.DATA_COMPONENTS, {})
|
||||
module = module_cache["fake_integration.device_action"]
|
||||
module.async_call_action_from_config = AsyncMock()
|
||||
module.async_validate_action_config = AsyncMock(
|
||||
side_effect=lambda hass, config: config
|
||||
)
|
||||
|
||||
config_entry = MockConfigEntry(domain="fake_integration", data={})
|
||||
config_entry.state = config_entries.ConfigEntryState.LOADED
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_registry.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
|
||||
await ws_client.send_json_auto_id(
|
||||
{
|
||||
"type": "execute_script",
|
||||
"sequence": [
|
||||
{
|
||||
"device_id": device_entry.id,
|
||||
"domain": "fake_integration",
|
||||
},
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
msg_no_var = await ws_client.receive_json()
|
||||
assert msg_no_var["type"] == const.TYPE_RESULT
|
||||
assert msg_no_var["success"]
|
||||
assert msg_no_var["result"]["response"] is None
|
||||
|
||||
module.async_validate_action_config.assert_awaited_once()
|
||||
module.async_call_action_from_config.assert_awaited_once()
|
||||
|
||||
|
||||
async def test_subscribe_unsubscribe_bootstrap_integrations(
|
||||
hass: HomeAssistant, websocket_client, hass_admin_user: MockUser
|
||||
) -> None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user