* improve device_automation trigger validation Validates the trigger configuration against the device_trigger schema before trying to access any of the properties in order to provide better error messages. Updates the error message to include an explicit indication that the error is coming from a trigger configuration. The inner error message from the validator can be accessed by viewing the stack trace. Add test case for trigger missing domain. Make action and condition validation consistent with trigger. This is not strictly necessary, but should be helpful for certain use cases that bypass some of the outer validation. Removed redundant schema elements from humidifier device_trigger. **Blueprint with missing `domain`** ``` 2022-07-12 06:02:18.351 ERROR (MainThread) [homeassistant.setup] Error during setup of component automation Traceback (most recent call last): File "/workspaces/core/homeassistant/setup.py", line 235, in _async_setup_component result = await task File "/workspaces/core/homeassistant/components/automation/__init__.py", line 241, in async_setup if not await _async_process_config(hass, config, component): File "/workspaces/core/homeassistant/components/automation/__init__.py", line 648, in _async_process_config await async_validate_config_item(hass, raw_config), File "/workspaces/core/homeassistant/components/automation/config.py", line 74, in async_validate_config_item config[CONF_TRIGGER] = await async_validate_trigger_config( File "/workspaces/core/homeassistant/helpers/trigger.py", line 59, in async_validate_trigger_config conf = await platform.async_validate_trigger_config(hass, conf) File "/workspaces/core/homeassistant/components/device_automation/trigger.py", line 67, in async_validate_trigger_config hass, config[CONF_DOMAIN], DeviceAutomationType.TRIGGER KeyError: 'domain' ``` **Blueprint with missing `property` (specific to zwave_js event schema)** ``` 2022-07-12 06:09:54.206 ERROR (MainThread) [homeassistant.components.automation] Blueprint Missing Property generated invalid automation with inputs OrderedDict([('control_switch', '498be56d796836a67406e9ad373d23db')]): required key not provided @ data['property']. Got None ``` **Blueprint with missing `domain`** ``` 2022-07-12 06:12:16.080 ERROR (MainThread) [homeassistant.components.automation] Blueprint Missing Domain generated invalid automation with inputs OrderedDict([('control_switch', '498be56d796836a67406e9ad373d23db')]): invalid trigger configuration: required key not provided @ data['domain']. Got <homeassistant.components.blueprint.models.BlueprintInputs object at 0x7f581e097820> ``` **Blueprint with missing `property` (specific to zwave_js event schema)** ``` 2022-07-12 06:12:16.680 ERROR (MainThread) [homeassistant.components.automation] Blueprint Missing Property generated invalid automation with inputs OrderedDict([('control_switch', '498be56d796836a67406e9ad373d23db')]): invalid trigger configuration: required key not provided @ data['property']. Got <homeassistant.components.blueprint.models.BlueprintInputs object at 0x7f581c0dc9d0> ``` * Revert humifidier TRIGGER_SCHEMA change.
178 lines
5.6 KiB
Python
178 lines
5.6 KiB
Python
"""The tests for WebOS TV device triggers."""
|
|
import pytest
|
|
|
|
from homeassistant.components import automation
|
|
from homeassistant.components.device_automation import DeviceAutomationType
|
|
from homeassistant.components.device_automation.exceptions import (
|
|
InvalidDeviceAutomationConfig,
|
|
)
|
|
from homeassistant.components.webostv import DOMAIN, device_trigger
|
|
from homeassistant.config_entries import ConfigEntryState
|
|
from homeassistant.exceptions import HomeAssistantError
|
|
from homeassistant.helpers.device_registry import async_get as get_dev_reg
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from . import setup_webostv
|
|
from .const import ENTITY_ID, FAKE_UUID
|
|
|
|
from tests.common import MockConfigEntry, async_get_device_automations
|
|
|
|
|
|
async def test_get_triggers(hass, client):
|
|
"""Test we get the expected triggers."""
|
|
await setup_webostv(hass)
|
|
|
|
device_reg = get_dev_reg(hass)
|
|
device = device_reg.async_get_device(identifiers={(DOMAIN, FAKE_UUID)})
|
|
|
|
turn_on_trigger = {
|
|
"platform": "device",
|
|
"domain": DOMAIN,
|
|
"type": "webostv.turn_on",
|
|
"device_id": device.id,
|
|
"metadata": {},
|
|
}
|
|
|
|
triggers = await async_get_device_automations(
|
|
hass, DeviceAutomationType.TRIGGER, device.id
|
|
)
|
|
assert turn_on_trigger in triggers
|
|
|
|
|
|
async def test_if_fires_on_turn_on_request(hass, calls, client):
|
|
"""Test for turn_on and turn_off triggers firing."""
|
|
await setup_webostv(hass)
|
|
|
|
device_reg = get_dev_reg(hass)
|
|
device = device_reg.async_get_device(identifiers={(DOMAIN, FAKE_UUID)})
|
|
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
{
|
|
"trigger": {
|
|
"platform": "device",
|
|
"domain": DOMAIN,
|
|
"device_id": device.id,
|
|
"type": "webostv.turn_on",
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"some": "{{ trigger.device_id }}",
|
|
"id": "{{ trigger.id }}",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
"trigger": {
|
|
"platform": "webostv.turn_on",
|
|
"entity_id": ENTITY_ID,
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"some": ENTITY_ID,
|
|
"id": "{{ trigger.id }}",
|
|
},
|
|
},
|
|
},
|
|
],
|
|
},
|
|
)
|
|
|
|
await hass.services.async_call(
|
|
"media_player",
|
|
"turn_on",
|
|
{"entity_id": ENTITY_ID},
|
|
blocking=True,
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
assert len(calls) == 2
|
|
assert calls[0].data["some"] == device.id
|
|
assert calls[0].data["id"] == 0
|
|
assert calls[1].data["some"] == ENTITY_ID
|
|
assert calls[1].data["id"] == 0
|
|
|
|
|
|
async def test_get_triggers_for_invalid_device_id(hass, caplog):
|
|
"""Test error raised for invalid shelly device_id."""
|
|
await async_setup_component(hass, "persistent_notification", {})
|
|
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
{
|
|
"trigger": {
|
|
"platform": "device",
|
|
"domain": DOMAIN,
|
|
"device_id": "invalid_device_id",
|
|
"type": "webostv.turn_on",
|
|
},
|
|
"action": {
|
|
"service": "test.automation",
|
|
"data_template": {
|
|
"some": "{{ trigger.invalid_device }}",
|
|
"id": "{{ trigger.id }}",
|
|
},
|
|
},
|
|
}
|
|
]
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert (
|
|
"Invalid config for [automation]: invalid trigger configuration" in caplog.text
|
|
)
|
|
|
|
|
|
async def test_failure_scenarios(hass, client):
|
|
"""Test failure scenarios."""
|
|
await setup_webostv(hass)
|
|
|
|
# Test wrong trigger platform type
|
|
with pytest.raises(HomeAssistantError):
|
|
await device_trigger.async_attach_trigger(
|
|
hass, {"type": "wrong.type", "device_id": "invalid_device_id"}, None, {}
|
|
)
|
|
|
|
# Test invalid device id
|
|
with pytest.raises(InvalidDeviceAutomationConfig):
|
|
await device_trigger.async_validate_trigger_config(
|
|
hass,
|
|
{
|
|
"platform": "device",
|
|
"domain": DOMAIN,
|
|
"type": "webostv.turn_on",
|
|
"device_id": "invalid_device_id",
|
|
},
|
|
)
|
|
|
|
entry = MockConfigEntry(domain="fake", state=ConfigEntryState.LOADED, data={})
|
|
entry.add_to_hass(hass)
|
|
device_reg = get_dev_reg(hass)
|
|
|
|
device = device_reg.async_get_or_create(
|
|
config_entry_id=entry.entry_id, identifiers={("fake", "fake")}
|
|
)
|
|
|
|
config = {
|
|
"platform": "device",
|
|
"domain": DOMAIN,
|
|
"device_id": device.id,
|
|
"type": "webostv.turn_on",
|
|
}
|
|
|
|
# Test that device id from non webostv domain raises exception
|
|
with pytest.raises(InvalidDeviceAutomationConfig):
|
|
await device_trigger.async_validate_trigger_config(hass, config)
|
|
|
|
# Test no exception if device is not loaded
|
|
await hass.config_entries.async_unload(entry.entry_id)
|
|
assert await device_trigger.async_validate_trigger_config(hass, config) == config
|