mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Improve condition validation error msg (#32135)
This commit is contained in:
parent
270758417b
commit
ca01e9a537
@ -704,6 +704,30 @@ def deprecated(
|
|||||||
return validator
|
return validator
|
||||||
|
|
||||||
|
|
||||||
|
def key_value_schemas(
|
||||||
|
key: str, value_schemas: Dict[str, vol.Schema]
|
||||||
|
) -> Callable[[Any], Dict[str, Any]]:
|
||||||
|
"""Create a validator that validates based on a value for specific key.
|
||||||
|
|
||||||
|
This gives better error messages.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def key_value_validator(value: Any) -> Dict[str, Any]:
|
||||||
|
if not isinstance(value, dict):
|
||||||
|
raise vol.Invalid("Expected a dictionary")
|
||||||
|
|
||||||
|
key_value = value.get(key)
|
||||||
|
|
||||||
|
if key_value not in value_schemas:
|
||||||
|
raise vol.Invalid(
|
||||||
|
f"Unexpected key {key_value}. Expected {', '.join(value_schemas)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return cast(Dict[str, Any], value_schemas[key_value](value))
|
||||||
|
|
||||||
|
return key_value_validator
|
||||||
|
|
||||||
|
|
||||||
# Validator helpers
|
# Validator helpers
|
||||||
|
|
||||||
|
|
||||||
@ -899,16 +923,19 @@ DEVICE_CONDITION_BASE_SCHEMA = vol.Schema(
|
|||||||
|
|
||||||
DEVICE_CONDITION_SCHEMA = DEVICE_CONDITION_BASE_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA)
|
DEVICE_CONDITION_SCHEMA = DEVICE_CONDITION_BASE_SCHEMA.extend({}, extra=vol.ALLOW_EXTRA)
|
||||||
|
|
||||||
CONDITION_SCHEMA: vol.Schema = vol.Any(
|
CONDITION_SCHEMA: vol.Schema = key_value_schemas(
|
||||||
NUMERIC_STATE_CONDITION_SCHEMA,
|
CONF_CONDITION,
|
||||||
STATE_CONDITION_SCHEMA,
|
{
|
||||||
SUN_CONDITION_SCHEMA,
|
"numeric_state": NUMERIC_STATE_CONDITION_SCHEMA,
|
||||||
TEMPLATE_CONDITION_SCHEMA,
|
"state": STATE_CONDITION_SCHEMA,
|
||||||
TIME_CONDITION_SCHEMA,
|
"sun": SUN_CONDITION_SCHEMA,
|
||||||
ZONE_CONDITION_SCHEMA,
|
"template": TEMPLATE_CONDITION_SCHEMA,
|
||||||
AND_CONDITION_SCHEMA,
|
"time": TIME_CONDITION_SCHEMA,
|
||||||
OR_CONDITION_SCHEMA,
|
"zone": ZONE_CONDITION_SCHEMA,
|
||||||
DEVICE_CONDITION_SCHEMA,
|
"and": AND_CONDITION_SCHEMA,
|
||||||
|
"or": OR_CONDITION_SCHEMA,
|
||||||
|
"device": DEVICE_CONDITION_SCHEMA,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
_SCRIPT_DELAY_SCHEMA = vol.Schema(
|
_SCRIPT_DELAY_SCHEMA = vol.Schema(
|
||||||
|
@ -987,3 +987,36 @@ def test_uuid4_hex(caplog):
|
|||||||
_hex = uuid.uuid4().hex
|
_hex = uuid.uuid4().hex
|
||||||
assert schema(_hex) == _hex
|
assert schema(_hex) == _hex
|
||||||
assert schema(_hex.upper()) == _hex
|
assert schema(_hex.upper()) == _hex
|
||||||
|
|
||||||
|
|
||||||
|
def test_key_value_schemas():
|
||||||
|
"""Test key value schemas."""
|
||||||
|
schema = vol.Schema(
|
||||||
|
cv.key_value_schemas(
|
||||||
|
"mode",
|
||||||
|
{
|
||||||
|
"number": vol.Schema({"mode": "number", "data": int}),
|
||||||
|
"string": vol.Schema({"mode": "string", "data": str}),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(vol.Invalid) as excinfo:
|
||||||
|
schema(True)
|
||||||
|
assert str(excinfo.value) == "Expected a dictionary"
|
||||||
|
|
||||||
|
for mode in None, "invalid":
|
||||||
|
with pytest.raises(vol.Invalid) as excinfo:
|
||||||
|
schema({"mode": mode})
|
||||||
|
assert str(excinfo.value) == f"Unexpected key {mode}. Expected number, string"
|
||||||
|
|
||||||
|
with pytest.raises(vol.Invalid) as excinfo:
|
||||||
|
schema({"mode": "number", "data": "string-value"})
|
||||||
|
assert str(excinfo.value) == "expected int for dictionary value @ data['data']"
|
||||||
|
|
||||||
|
with pytest.raises(vol.Invalid) as excinfo:
|
||||||
|
schema({"mode": "string", "data": 1})
|
||||||
|
assert str(excinfo.value) == "expected str for dictionary value @ data['data']"
|
||||||
|
|
||||||
|
for mode, data in (("number", 1), ("string", "hello")):
|
||||||
|
schema({"mode": mode, "data": data})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user