Fix importing blueprints (#71365)

Co-authored-by: Shay Levy <levyshay1@gmail.com>
This commit is contained in:
Paulus Schoutsen 2022-05-05 14:33:17 -07:00 committed by GitHub
parent aadfcc9a6e
commit 353cc0b8c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 12 deletions

View File

@ -5,11 +5,13 @@ from collections.abc import Callable, Sequence
from typing import Any, TypedDict, cast
import voluptuous as vol
import yaml
from homeassistant.backports.enum import StrEnum
from homeassistant.const import CONF_MODE, CONF_UNIT_OF_MEASUREMENT
from homeassistant.core import split_entity_id, valid_entity_id
from homeassistant.util import decorator
from homeassistant.util.yaml.dumper import represent_odict
from . import config_validation as cv
@ -71,7 +73,11 @@ class Selector:
def serialize(self) -> Any:
"""Serialize Selector for voluptuous_serialize."""
return {"selector": {self.selector_type: self.config}}
return {"selector": {self.selector_type: self.serialize_config()}}
def serialize_config(self) -> Any:
"""Serialize config."""
return self.config
SINGLE_ENTITY_SELECTOR_CONFIG_SCHEMA = vol.Schema(
@ -623,6 +629,13 @@ class NumberSelector(Selector):
"""Instantiate a selector."""
super().__init__(config)
def serialize_config(self) -> Any:
"""Serialize the selector config."""
return {
**self.config,
"mode": self.config["mode"].value,
}
def __call__(self, data: Any) -> float:
"""Validate the passed selection."""
value: float = vol.Coerce(float)(data)
@ -881,3 +894,11 @@ class TimeSelector(Selector):
"""Validate the passed selection."""
cv.time(data)
return cast(str, data)
yaml.SafeDumper.add_representer(
Selector,
lambda dumper, value: represent_odict(
dumper, "tag:yaml.org,2002:map", value.serialize()
),
)

View File

@ -198,7 +198,7 @@ async def test_fetch_blueprint_from_github_url(hass, aioclient_mock, url):
assert imported_blueprint.blueprint.domain == "automation"
assert imported_blueprint.blueprint.inputs == {
"service_to_call": None,
"trigger_event": None,
"trigger_event": {"selector": {"text": {}}},
}
assert imported_blueprint.suggested_filename == "balloob/motion_light"
assert imported_blueprint.blueprint.metadata["source_url"] == url

View File

@ -30,7 +30,10 @@ async def test_list_blueprints(hass, hass_ws_client):
"test_event_service.yaml": {
"metadata": {
"domain": "automation",
"input": {"service_to_call": None, "trigger_event": None},
"input": {
"service_to_call": None,
"trigger_event": {"selector": {"text": {}}},
},
"name": "Call service based on event",
},
},
@ -89,7 +92,10 @@ async def test_import_blueprint(hass, aioclient_mock, hass_ws_client):
"blueprint": {
"metadata": {
"domain": "automation",
"input": {"service_to_call": None, "trigger_event": None},
"input": {
"service_to_call": None,
"trigger_event": {"selector": {"text": {}}},
},
"name": "Call service based on event",
"source_url": "https://github.com/balloob/home-assistant-config/blob/main/blueprints/automation/motion_light.yaml",
},
@ -123,7 +129,7 @@ async def test_save_blueprint(hass, aioclient_mock, hass_ws_client):
assert msg["success"]
assert write_mock.mock_calls
assert write_mock.call_args[0] == (
"blueprint:\n name: Call service based on event\n domain: automation\n input:\n trigger_event:\n service_to_call:\n source_url: https://github.com/balloob/home-assistant-config/blob/main/blueprints/automation/motion_light.yaml\ntrigger:\n platform: event\n event_type: !input 'trigger_event'\naction:\n service: !input 'service_to_call'\n entity_id: light.kitchen\n",
"blueprint:\n name: Call service based on event\n domain: automation\n input:\n trigger_event:\n selector:\n text: {}\n service_to_call:\n source_url: https://github.com/balloob/home-assistant-config/blob/main/blueprints/automation/motion_light.yaml\ntrigger:\n platform: event\n event_type: !input 'trigger_event'\naction:\n service: !input 'service_to_call'\n entity_id: light.kitchen\n",
)

View File

@ -11,7 +11,7 @@ import pytest
import voluptuous as vol
import homeassistant
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers import config_validation as cv, selector, template
def test_boolean():
@ -720,6 +720,17 @@ def test_string_in_serializer():
}
def test_selector_in_serializer():
"""Test selector with custom_serializer."""
assert cv.custom_serializer(selector.selector({"text": {}})) == {
"selector": {
"text": {
"multiline": False,
}
}
}
def test_positive_time_period_dict_in_serializer():
"""Test positive_time_period_dict with custom_serializer."""
assert cv.custom_serializer(cv.positive_time_period_dict) == {

View File

@ -2,7 +2,8 @@
import pytest
import voluptuous as vol
from homeassistant.helpers import config_validation as cv, selector
from homeassistant.helpers import selector
from homeassistant.util import yaml
FAKE_UUID = "a266a680b608c32770e6c45bfe6b8411"
@ -48,10 +49,12 @@ def _test_selector(
converter = default_converter
# Validate selector configuration
selector.validate_selector({selector_type: schema})
config = {selector_type: schema}
selector.validate_selector(config)
selector_instance = selector.selector(config)
# Use selector in schema and validate
vol_schema = vol.Schema({"selection": selector.selector({selector_type: schema})})
vol_schema = vol.Schema({"selection": selector_instance})
for selection in valid_selections:
assert vol_schema({"selection": selection}) == {
"selection": converter(selection)
@ -62,9 +65,12 @@ def _test_selector(
# Serialize selector
selector_instance = selector.selector({selector_type: schema})
assert cv.custom_serializer(selector_instance) == {
"selector": {selector_type: selector_instance.config}
}
assert (
selector.selector(selector_instance.serialize()["selector"]).config
== selector_instance.config
)
# Test serialized selector can be dumped to YAML
yaml.dump(selector_instance.serialize())
@pytest.mark.parametrize(

View File

@ -3,6 +3,8 @@ blueprint:
domain: automation
input:
trigger_event:
selector:
text:
service_to_call:
trigger:
platform: event