Get ServiceValidationError message from translation cache only (#113704)
* Get ServiceValidationError message from translation cache only * Remove message for NotValidPresetModeError
This commit is contained in:
parent
ec7aecef84
commit
3dc8df2403
18 changed files with 16 additions and 43 deletions
|
@ -150,7 +150,6 @@ class BSBLANClimate(
|
||||||
await self.async_set_data(preset_mode=preset_mode)
|
await self.async_set_data(preset_mode=preset_mode)
|
||||||
else:
|
else:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
"Can't set preset mode when hvac mode is not auto",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="set_preset_mode_error",
|
translation_key="set_preset_mode_error",
|
||||||
translation_placeholders={"preset_mode": preset_mode},
|
translation_placeholders={"preset_mode": preset_mode},
|
||||||
|
|
|
@ -95,7 +95,6 @@ def __get_coordinator(
|
||||||
|
|
||||||
if not entry:
|
if not entry:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Invalid config entry: {entry_id}",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_config_entry",
|
translation_key="invalid_config_entry",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
@ -104,7 +103,6 @@ def __get_coordinator(
|
||||||
)
|
)
|
||||||
if entry.state != ConfigEntryState.LOADED:
|
if entry.state != ConfigEntryState.LOADED:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"{entry.title} is not loaded",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="unloaded_config_entry",
|
translation_key="unloaded_config_entry",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
|
|
@ -337,7 +337,6 @@ class EcovacsVacuum(
|
||||||
params = {}
|
params = {}
|
||||||
elif isinstance(params, list):
|
elif isinstance(params, list):
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
"Params must be a dict!",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="vacuum_send_command_params_dict",
|
translation_key="vacuum_send_command_params_dict",
|
||||||
)
|
)
|
||||||
|
@ -345,7 +344,6 @@ class EcovacsVacuum(
|
||||||
if command in ["spot_area", "custom_area"]:
|
if command in ["spot_area", "custom_area"]:
|
||||||
if params is None:
|
if params is None:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Params are required for {command}!",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="vacuum_send_command_params_required",
|
translation_key="vacuum_send_command_params_required",
|
||||||
translation_placeholders={"command": command},
|
translation_placeholders={"command": command},
|
||||||
|
@ -354,7 +352,6 @@ class EcovacsVacuum(
|
||||||
info = self._device.device_info
|
info = self._device.device_info
|
||||||
name = info.get("nick", info["name"])
|
name = info.get("nick", info["name"])
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Vacuum {name} does not support area capability!",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="vacuum_send_command_area_not_supported",
|
translation_key="vacuum_send_command_area_not_supported",
|
||||||
translation_placeholders={"name": name},
|
translation_placeholders={"name": name},
|
||||||
|
|
|
@ -62,7 +62,6 @@ def __get_date(date_input: str | None) -> date | datetime:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
"Invalid datetime provided.",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_date",
|
translation_key="invalid_date",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
@ -93,7 +92,6 @@ def __get_coordinator(
|
||||||
|
|
||||||
if not entry:
|
if not entry:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Invalid config entry: {entry_id}",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_config_entry",
|
translation_key="invalid_config_entry",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
@ -102,7 +100,6 @@ def __get_coordinator(
|
||||||
)
|
)
|
||||||
if entry.state != ConfigEntryState.LOADED:
|
if entry.state != ConfigEntryState.LOADED:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"{entry.title} is not loaded",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="unloaded_config_entry",
|
translation_key="unloaded_config_entry",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
|
|
@ -297,8 +297,6 @@ class FanEntity(ToggleEntity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||||
if not preset_modes or preset_mode not in preset_modes:
|
if not preset_modes or preset_mode not in preset_modes:
|
||||||
preset_modes_str: str = ", ".join(preset_modes or [])
|
preset_modes_str: str = ", ".join(preset_modes or [])
|
||||||
raise NotValidPresetModeError(
|
raise NotValidPresetModeError(
|
||||||
f"The preset_mode {preset_mode} is not a valid preset_mode:"
|
|
||||||
f" {preset_modes}",
|
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
"preset_mode": preset_mode,
|
"preset_mode": preset_mode,
|
||||||
"preset_modes": preset_modes_str,
|
"preset_modes": preset_modes_str,
|
||||||
|
|
|
@ -282,7 +282,6 @@ async def async_setup_platform(
|
||||||
scene = platform.entities.get(entity_id)
|
scene = platform.entities.get(entity_id)
|
||||||
if scene is None:
|
if scene is None:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"{entity_id} is not a valid scene entity_id",
|
|
||||||
translation_domain=SCENE_DOMAIN,
|
translation_domain=SCENE_DOMAIN,
|
||||||
translation_key="entity_not_scene",
|
translation_key="entity_not_scene",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
@ -292,7 +291,6 @@ async def async_setup_platform(
|
||||||
assert isinstance(scene, HomeAssistantScene)
|
assert isinstance(scene, HomeAssistantScene)
|
||||||
if not scene.from_service:
|
if not scene.from_service:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"The scene {entity_id} is not created with service `scene.create`",
|
|
||||||
translation_domain=SCENE_DOMAIN,
|
translation_domain=SCENE_DOMAIN,
|
||||||
translation_key="entity_not_dynamically_created",
|
translation_key="entity_not_dynamically_created",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
|
|
@ -156,7 +156,6 @@ class LockEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
assert self.code_format
|
assert self.code_format
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"The code for {self.entity_id} doesn't match pattern {self.code_format}",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="add_default_code",
|
translation_key="add_default_code",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
|
|
@ -331,8 +331,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
except vol.Invalid as err:
|
except vol.Invalid as err:
|
||||||
err_str = str(err)
|
err_str = str(err)
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Unable to publish: topic template '{msg_topic_template}' produced an "
|
|
||||||
f"invalid topic '{rendered_topic}' after rendering ({err_str})",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_publish_topic",
|
translation_key="invalid_publish_topic",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
@ -405,7 +403,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
)
|
)
|
||||||
except ConfigValidationError as ex:
|
except ConfigValidationError as ex:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
str(ex),
|
|
||||||
translation_domain=ex.translation_domain,
|
translation_domain=ex.translation_domain,
|
||||||
translation_key=ex.translation_key,
|
translation_key=ex.translation_key,
|
||||||
translation_placeholders=ex.translation_placeholders,
|
translation_placeholders=ex.translation_placeholders,
|
||||||
|
|
|
@ -179,7 +179,6 @@ class SelectEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||||
if not options or option not in options:
|
if not options or option not in options:
|
||||||
friendly_options: str = ", ".join(options or [])
|
friendly_options: str = ", ".join(options or [])
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Option {option} is not valid for {self.entity_id}",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="not_valid_option",
|
translation_key="not_valid_option",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
|
|
@ -264,10 +264,6 @@ def _attach_file(hass, atch_name, content_id=""):
|
||||||
file_name = os.path.basename(atch_name)
|
file_name = os.path.basename(atch_name)
|
||||||
url = "https://www.home-assistant.io/docs/configuration/basic/"
|
url = "https://www.home-assistant.io/docs/configuration/basic/"
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Cannot send email with attachment '{file_name}' "
|
|
||||||
f"from directory '{file_path}' which is not secure to load data from. "
|
|
||||||
f"Only folders added to `{allow_list}` are accessible. "
|
|
||||||
f"See {url} for more information.",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="remote_path_not_allowed",
|
translation_key="remote_path_not_allowed",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
|
|
@ -112,7 +112,6 @@ class TessieCableLockEntity(TessieEntity, LockEntity):
|
||||||
async def async_lock(self, **kwargs: Any) -> None:
|
async def async_lock(self, **kwargs: Any) -> None:
|
||||||
"""Charge cable Lock cannot be manually locked."""
|
"""Charge cable Lock cannot be manually locked."""
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
"Insert cable to lock",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="no_cable",
|
translation_key="no_cable",
|
||||||
)
|
)
|
||||||
|
|
|
@ -107,7 +107,6 @@ def _validate_supported_features(
|
||||||
continue
|
continue
|
||||||
if not supported_features or not supported_features & desc.required_feature:
|
if not supported_features or not supported_features & desc.required_feature:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Entity does not support setting field '{desc.service_field}'",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="update_field_not_supported",
|
translation_key="update_field_not_supported",
|
||||||
translation_placeholders={"service_field": desc.service_field},
|
translation_placeholders={"service_field": desc.service_field},
|
||||||
|
@ -485,7 +484,6 @@ async def _async_update_todo_item(entity: TodoListEntity, call: ServiceCall) ->
|
||||||
found = _find_by_uid_or_summary(item, entity.todo_items)
|
found = _find_by_uid_or_summary(item, entity.todo_items)
|
||||||
if not found:
|
if not found:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Unable to find To-do item '{item}'",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="item_not_found",
|
translation_key="item_not_found",
|
||||||
translation_placeholders={"item": item},
|
translation_placeholders={"item": item},
|
||||||
|
@ -518,7 +516,6 @@ async def _async_remove_todo_items(entity: TodoListEntity, call: ServiceCall) ->
|
||||||
found = _find_by_uid_or_summary(item, entity.todo_items)
|
found = _find_by_uid_or_summary(item, entity.todo_items)
|
||||||
if not found or not found.uid:
|
if not found or not found.uid:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Unable to find To-do item '{item}'",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="item_not_found",
|
translation_key="item_not_found",
|
||||||
translation_placeholders={"item": item},
|
translation_placeholders={"item": item},
|
||||||
|
|
|
@ -368,8 +368,6 @@ class WaterHeaterEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||||
"""Handle a set target operation mode service call."""
|
"""Handle a set target operation mode service call."""
|
||||||
if self.operation_list is None:
|
if self.operation_list is None:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Operation mode {operation_mode} not valid for "
|
|
||||||
f"entity {self.entity_id}. The operation list is not defined",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="operation_list_not_defined",
|
translation_key="operation_list_not_defined",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
@ -380,9 +378,6 @@ class WaterHeaterEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
||||||
if operation_mode not in self.operation_list:
|
if operation_mode not in self.operation_list:
|
||||||
operation_list = ", ".join(self.operation_list)
|
operation_list = ", ".join(self.operation_list)
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
f"Operation mode {operation_mode} not valid for "
|
|
||||||
f"entity {self.entity_id}. Valid "
|
|
||||||
f"operation modes are: {operation_list}",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="not_valid_operation_mode",
|
translation_key="not_valid_operation_mode",
|
||||||
translation_placeholders={
|
translation_placeholders={
|
||||||
|
|
|
@ -36,7 +36,6 @@ def async_register_services(hass: HomeAssistant) -> None:
|
||||||
break
|
break
|
||||||
if entry is None or entry.state == ConfigEntryState.NOT_LOADED:
|
if entry is None or entry.state == ConfigEntryState.NOT_LOADED:
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
"Config entry not found or not loaded!",
|
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_config_entry",
|
translation_key="invalid_config_entry",
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
"""Tests for the services provided by the EnergyZero integration."""
|
"""Tests for the services provided by the EnergyZero integration."""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
@ -101,7 +103,7 @@ def config_entry_data(
|
||||||
"start": "incorrect date",
|
"start": "incorrect date",
|
||||||
},
|
},
|
||||||
ServiceValidationError,
|
ServiceValidationError,
|
||||||
"Invalid datetime provided.",
|
"Invalid date provided. Got incorrect date",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{"config_entry": True},
|
{"config_entry": True},
|
||||||
|
@ -110,7 +112,7 @@ def config_entry_data(
|
||||||
"end": "incorrect date",
|
"end": "incorrect date",
|
||||||
},
|
},
|
||||||
ServiceValidationError,
|
ServiceValidationError,
|
||||||
"Invalid datetime provided.",
|
"Invalid date provided. Got incorrect date",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
indirect=["config_entry_data"],
|
indirect=["config_entry_data"],
|
||||||
|
@ -125,7 +127,7 @@ async def test_service_validation(
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the EnergyZero Service validation."""
|
"""Test the EnergyZero Service validation."""
|
||||||
|
|
||||||
with pytest.raises(error, match=error_message):
|
with pytest.raises(error) as exc:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
service,
|
service,
|
||||||
|
@ -133,6 +135,7 @@ async def test_service_validation(
|
||||||
blocking=True,
|
blocking=True,
|
||||||
return_response=True,
|
return_response=True,
|
||||||
)
|
)
|
||||||
|
assert re.match(error_message, str(exc.value))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_integration")
|
@pytest.mark.usefixtures("init_integration")
|
||||||
|
|
|
@ -550,8 +550,8 @@ async def test_service_call_with_template_topic_renders_invalid_topic(
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
assert str(exc.value) == (
|
assert str(exc.value) == (
|
||||||
"Unable to publish: topic template 'test/{{ '+' if True else 'topic' }}/topic' "
|
"Unable to publish: topic template `test/{{ '+' if True else 'topic' }}/topic` "
|
||||||
"produced an invalid topic 'test/+/topic' after rendering "
|
"produced an invalid topic `test/+/topic` after rendering "
|
||||||
"(Wildcards cannot be used in topic names)"
|
"(Wildcards cannot be used in topic names)"
|
||||||
)
|
)
|
||||||
assert not mqtt_mock.async_publish.called
|
assert not mqtt_mock.async_publish.called
|
||||||
|
|
|
@ -348,12 +348,12 @@ async def test_add_item_service_raises(
|
||||||
(
|
(
|
||||||
{"item": "Submit forms", "description": "Submit tax forms"},
|
{"item": "Submit forms", "description": "Submit tax forms"},
|
||||||
ServiceValidationError,
|
ServiceValidationError,
|
||||||
"does not support setting field 'description'",
|
"does not support setting field: description",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{"item": "Submit forms", "due_date": "2023-11-17"},
|
{"item": "Submit forms", "due_date": "2023-11-17"},
|
||||||
ServiceValidationError,
|
ServiceValidationError,
|
||||||
"does not support setting field 'due_date'",
|
"does not support setting field: due_date",
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
@ -361,7 +361,7 @@ async def test_add_item_service_raises(
|
||||||
"due_datetime": f"2023-11-17T17:00:00{TEST_OFFSET}",
|
"due_datetime": f"2023-11-17T17:00:00{TEST_OFFSET}",
|
||||||
},
|
},
|
||||||
ServiceValidationError,
|
ServiceValidationError,
|
||||||
"does not support setting field 'due_datetime'",
|
"does not support setting field: due_datetime",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -376,7 +376,7 @@ async def test_add_item_service_invalid_input(
|
||||||
|
|
||||||
await create_mock_platform(hass, [test_entity])
|
await create_mock_platform(hass, [test_entity])
|
||||||
|
|
||||||
with pytest.raises(expected_exception, match=expected_error):
|
with pytest.raises(expected_exception) as exc:
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
"add_item",
|
"add_item",
|
||||||
|
@ -385,6 +385,8 @@ async def test_add_item_service_invalid_input(
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
assert expected_error in str(exc.value)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("supported_entity_feature", "item_data", "expected_item"),
|
("supported_entity_feature", "item_data", "expected_item"),
|
||||||
|
|
|
@ -175,7 +175,7 @@ async def test_operation_mode_validation(
|
||||||
DOMAIN, SERVICE_SET_OPERATION_MODE, data, blocking=True
|
DOMAIN, SERVICE_SET_OPERATION_MODE, data, blocking=True
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
str(exc.value) == "Operation mode test not valid for entity water_heater.test. "
|
str(exc.value) == "Operation mode test is not valid for water_heater.test. "
|
||||||
"The operation list is not defined"
|
"The operation list is not defined"
|
||||||
)
|
)
|
||||||
assert exc.value.translation_domain == DOMAIN
|
assert exc.value.translation_domain == DOMAIN
|
||||||
|
@ -191,7 +191,7 @@ async def test_operation_mode_validation(
|
||||||
DOMAIN, SERVICE_SET_OPERATION_MODE, data, blocking=True
|
DOMAIN, SERVICE_SET_OPERATION_MODE, data, blocking=True
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
str(exc.value) == "Operation mode test not valid for entity water_heater.test. "
|
str(exc.value) == "Operation mode test is not valid for water_heater.test. "
|
||||||
"Valid operation modes are: gas, eco"
|
"Valid operation modes are: gas, eco"
|
||||||
)
|
)
|
||||||
assert exc.value.translation_domain == DOMAIN
|
assert exc.value.translation_domain == DOMAIN
|
||||||
|
|
Loading…
Add table
Reference in a new issue