Add default to inputs (#43636)

This commit is contained in:
Bram Kragten 2020-11-25 20:05:43 +01:00 committed by GitHub
parent 3767af14f3
commit 8533d9cae0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 4 deletions

View File

@ -10,7 +10,13 @@ import voluptuous as vol
from voluptuous.humanize import humanize_error
from homeassistant import loader
from homeassistant.const import CONF_DOMAIN, CONF_NAME, CONF_PATH, __version__
from homeassistant.const import (
CONF_DEFAULT,
CONF_DOMAIN,
CONF_NAME,
CONF_PATH,
__version__,
)
from homeassistant.core import DOMAIN as HA_DOMAIN, HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import placeholder
@ -82,6 +88,11 @@ class Blueprint:
"""Return blueprint name."""
return self.data[CONF_BLUEPRINT][CONF_NAME]
@property
def inputs(self) -> dict:
"""Return blueprint inputs."""
return self.data[CONF_BLUEPRINT][CONF_INPUT]
@property
def metadata(self) -> dict:
"""Return blueprint metadata."""
@ -129,9 +140,23 @@ class BlueprintInputs:
"""Return the inputs."""
return self.config_with_inputs[CONF_USE_BLUEPRINT][CONF_INPUT]
@property
def inputs_with_default(self):
"""Return the inputs and fallback to defaults."""
no_input = self.blueprint.placeholders - set(self.inputs)
inputs_with_default = dict(self.inputs)
for inp in no_input:
blueprint_input = self.blueprint.inputs[inp]
if isinstance(blueprint_input, dict) and CONF_DEFAULT in blueprint_input:
inputs_with_default[inp] = blueprint_input[CONF_DEFAULT]
return inputs_with_default
def validate(self) -> None:
"""Validate the inputs."""
missing = self.blueprint.placeholders - set(self.inputs)
missing = self.blueprint.placeholders - set(self.inputs_with_default)
if missing:
raise MissingPlaceholder(
@ -144,7 +169,9 @@ class BlueprintInputs:
@callback
def async_substitute(self) -> dict:
"""Get the blueprint value with the inputs substituted."""
processed = placeholder.substitute(self.blueprint.data, self.inputs)
processed = placeholder.substitute(
self.blueprint.data, self.inputs_with_default
)
combined = {**self.config_with_inputs, **processed}
# From config_with_inputs
combined.pop(CONF_USE_BLUEPRINT)

View File

@ -3,7 +3,13 @@ from typing import Any
import voluptuous as vol
from homeassistant.const import CONF_DOMAIN, CONF_NAME, CONF_PATH, CONF_SELECTOR
from homeassistant.const import (
CONF_DEFAULT,
CONF_DOMAIN,
CONF_NAME,
CONF_PATH,
CONF_SELECTOR,
)
from homeassistant.core import callback
from homeassistant.helpers import config_validation as cv, selector
@ -54,6 +60,7 @@ BLUEPRINT_INPUT_SCHEMA = vol.Schema(
{
vol.Optional(CONF_NAME): str,
vol.Optional(CONF_DESCRIPTION): str,
vol.Optional(CONF_DEFAULT): cv.match_all,
vol.Optional(CONF_SELECTOR): selector.validate_selector,
}
)

View File

@ -27,6 +27,26 @@ def blueprint_1():
)
@pytest.fixture
def blueprint_2():
"""Blueprint fixture with default placeholder."""
return models.Blueprint(
{
"blueprint": {
"name": "Hello",
"domain": "automation",
"source_url": "https://github.com/balloob/home-assistant-config/blob/main/blueprints/automation/motion_light.yaml",
"input": {
"test-placeholder": {"name": "Name", "description": "Description"},
"test-placeholder-default": {"default": "test"},
},
},
"example": Placeholder("test-placeholder"),
"example-default": Placeholder("test-placeholder-default"),
}
)
@pytest.fixture
def domain_bps(hass):
"""Domain blueprints fixture."""
@ -134,6 +154,44 @@ def test_blueprint_inputs_validation(blueprint_1):
inputs.validate()
def test_blueprint_inputs_default(blueprint_2):
"""Test blueprint inputs."""
inputs = models.BlueprintInputs(
blueprint_2,
{"use_blueprint": {"path": "bla", "input": {"test-placeholder": 1}}},
)
inputs.validate()
assert inputs.inputs == {"test-placeholder": 1}
assert inputs.inputs_with_default == {
"test-placeholder": 1,
"test-placeholder-default": "test",
}
assert inputs.async_substitute() == {"example": 1, "example-default": "test"}
def test_blueprint_inputs_override_default(blueprint_2):
"""Test blueprint inputs."""
inputs = models.BlueprintInputs(
blueprint_2,
{
"use_blueprint": {
"path": "bla",
"input": {"test-placeholder": 1, "test-placeholder-default": "custom"},
}
},
)
inputs.validate()
assert inputs.inputs == {
"test-placeholder": 1,
"test-placeholder-default": "custom",
}
assert inputs.inputs_with_default == {
"test-placeholder": 1,
"test-placeholder-default": "custom",
}
assert inputs.async_substitute() == {"example": 1, "example-default": "custom"}
async def test_domain_blueprints_get_blueprint_errors(hass, domain_bps):
"""Test domain blueprints."""
assert hass.data["blueprint"]["automation"] is domain_bps