mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Base entity ids on English for languages not using Latin script (#91357)
This commit is contained in:
parent
fe28067481
commit
071d3a474f
@ -3,6 +3,8 @@
|
|||||||
To update, run python3 -m script.languages [frontend_tag]
|
To update, run python3 -m script.languages [frontend_tag]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
DEFAULT_LANGUAGE = "en"
|
||||||
|
|
||||||
LANGUAGES = {
|
LANGUAGES = {
|
||||||
"af",
|
"af",
|
||||||
"ar",
|
"ar",
|
||||||
@ -66,3 +68,46 @@ LANGUAGES = {
|
|||||||
"zh-Hans",
|
"zh-Hans",
|
||||||
"zh-Hant",
|
"zh-Hant",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NATIVE_ENTITY_IDS = {
|
||||||
|
"af",
|
||||||
|
"bs",
|
||||||
|
"ca",
|
||||||
|
"cs",
|
||||||
|
"cy",
|
||||||
|
"da",
|
||||||
|
"de",
|
||||||
|
"en",
|
||||||
|
"en-GB",
|
||||||
|
"eo",
|
||||||
|
"es",
|
||||||
|
"es-419",
|
||||||
|
"et",
|
||||||
|
"eu",
|
||||||
|
"fi",
|
||||||
|
"fr",
|
||||||
|
"fy",
|
||||||
|
"gl",
|
||||||
|
"gsw",
|
||||||
|
"hr",
|
||||||
|
"hu",
|
||||||
|
"id",
|
||||||
|
"is",
|
||||||
|
"it",
|
||||||
|
"ka",
|
||||||
|
"lb",
|
||||||
|
"lt",
|
||||||
|
"lv",
|
||||||
|
"nb",
|
||||||
|
"nl",
|
||||||
|
"nn",
|
||||||
|
"pl",
|
||||||
|
"pt",
|
||||||
|
"pt-BR",
|
||||||
|
"ro",
|
||||||
|
"sk",
|
||||||
|
"sl",
|
||||||
|
"sr-Latn",
|
||||||
|
"sv",
|
||||||
|
"tr",
|
||||||
|
}
|
||||||
|
@ -381,17 +381,31 @@ class Entity(ABC):
|
|||||||
return self.entity_description.has_entity_name
|
return self.entity_description.has_entity_name
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@cached_property
|
def _device_class_name_helper(
|
||||||
def _device_class_name(self) -> str | None:
|
self,
|
||||||
|
component_translations: dict[str, Any],
|
||||||
|
) -> str | None:
|
||||||
"""Return a translated name of the entity based on its device class."""
|
"""Return a translated name of the entity based on its device class."""
|
||||||
if not self.has_entity_name:
|
if not self.has_entity_name:
|
||||||
return None
|
return None
|
||||||
device_class_key = self.device_class or "_"
|
device_class_key = self.device_class or "_"
|
||||||
platform = self.platform
|
platform = self.platform
|
||||||
name_translation_key = (
|
name_translation_key = (
|
||||||
f"component.{platform.domain}.entity_component." f"{device_class_key}.name"
|
f"component.{platform.domain}.entity_component.{device_class_key}.name"
|
||||||
)
|
)
|
||||||
return platform.component_translations.get(name_translation_key)
|
return component_translations.get(name_translation_key)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def _object_id_device_class_name(self) -> str | None:
|
||||||
|
"""Return a translated name of the entity based on its device class."""
|
||||||
|
return self._device_class_name_helper(
|
||||||
|
self.platform.object_id_component_translations
|
||||||
|
)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def _device_class_name(self) -> str | None:
|
||||||
|
"""Return a translated name of the entity based on its device class."""
|
||||||
|
return self._device_class_name_helper(self.platform.component_translations)
|
||||||
|
|
||||||
def _default_to_device_class_name(self) -> bool:
|
def _default_to_device_class_name(self) -> bool:
|
||||||
"""Return True if an unnamed entity should be named by its device class."""
|
"""Return True if an unnamed entity should be named by its device class."""
|
||||||
@ -408,15 +422,18 @@ class Entity(ABC):
|
|||||||
f".{self.translation_key}.name"
|
f".{self.translation_key}.name"
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
def _name_internal(
|
||||||
def name(self) -> str | UndefinedType | None:
|
self,
|
||||||
|
device_class_name: str | None,
|
||||||
|
platform_translations: dict[str, Any],
|
||||||
|
) -> str | UndefinedType | None:
|
||||||
"""Return the name of the entity."""
|
"""Return the name of the entity."""
|
||||||
if hasattr(self, "_attr_name"):
|
if hasattr(self, "_attr_name"):
|
||||||
return self._attr_name
|
return self._attr_name
|
||||||
if (
|
if (
|
||||||
self.has_entity_name
|
self.has_entity_name
|
||||||
and (name_translation_key := self._name_translation_key)
|
and (name_translation_key := self._name_translation_key)
|
||||||
and (name := self.platform.platform_translations.get(name_translation_key))
|
and (name := platform_translations.get(name_translation_key))
|
||||||
):
|
):
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
assert isinstance(name, str)
|
assert isinstance(name, str)
|
||||||
@ -424,15 +441,42 @@ class Entity(ABC):
|
|||||||
if hasattr(self, "entity_description"):
|
if hasattr(self, "entity_description"):
|
||||||
description_name = self.entity_description.name
|
description_name = self.entity_description.name
|
||||||
if description_name is UNDEFINED and self._default_to_device_class_name():
|
if description_name is UNDEFINED and self._default_to_device_class_name():
|
||||||
return self._device_class_name
|
return device_class_name
|
||||||
return description_name
|
return description_name
|
||||||
|
|
||||||
# The entity has no name set by _attr_name, translation_key or entity_description
|
# The entity has no name set by _attr_name, translation_key or entity_description
|
||||||
# Check if the entity should be named by its device class
|
# Check if the entity should be named by its device class
|
||||||
if self._default_to_device_class_name():
|
if self._default_to_device_class_name():
|
||||||
return self._device_class_name
|
return device_class_name
|
||||||
return UNDEFINED
|
return UNDEFINED
|
||||||
|
|
||||||
|
@property
|
||||||
|
def suggested_object_id(self) -> str | None:
|
||||||
|
"""Return input for object id."""
|
||||||
|
# The check for self.platform guards against integrations not using an
|
||||||
|
# EntityComponent and can be removed in HA Core 2024.1
|
||||||
|
# mypy doesn't know about fget: https://github.com/python/mypy/issues/6185
|
||||||
|
if self.__class__.name.fget is Entity.name.fget and self.platform: # type: ignore[attr-defined]
|
||||||
|
name = self._name_internal(
|
||||||
|
self._object_id_device_class_name,
|
||||||
|
self.platform.object_id_platform_translations,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
name = self.name
|
||||||
|
return None if name is UNDEFINED else name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str | UndefinedType | None:
|
||||||
|
"""Return the name of the entity."""
|
||||||
|
# The check for self.platform guards against integrations not using an
|
||||||
|
# EntityComponent and can be removed in HA Core 2024.1
|
||||||
|
if not self.platform:
|
||||||
|
return self._name_internal(None, {})
|
||||||
|
return self._name_internal(
|
||||||
|
self._device_class_name,
|
||||||
|
self.platform.platform_translations,
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self) -> StateType:
|
def state(self) -> StateType:
|
||||||
"""Return the state of the entity."""
|
"""Return the state of the entity."""
|
||||||
|
@ -31,6 +31,7 @@ from homeassistant.exceptions import (
|
|||||||
PlatformNotReady,
|
PlatformNotReady,
|
||||||
RequiredParameterMissing,
|
RequiredParameterMissing,
|
||||||
)
|
)
|
||||||
|
from homeassistant.generated import languages
|
||||||
from homeassistant.setup import async_start_setup
|
from homeassistant.setup import async_start_setup
|
||||||
from homeassistant.util.async_ import run_callback_threadsafe
|
from homeassistant.util.async_ import run_callback_threadsafe
|
||||||
|
|
||||||
@ -128,6 +129,8 @@ class EntityPlatform:
|
|||||||
self.entities: dict[str, Entity] = {}
|
self.entities: dict[str, Entity] = {}
|
||||||
self.component_translations: dict[str, Any] = {}
|
self.component_translations: dict[str, Any] = {}
|
||||||
self.platform_translations: dict[str, Any] = {}
|
self.platform_translations: dict[str, Any] = {}
|
||||||
|
self.object_id_component_translations: dict[str, Any] = {}
|
||||||
|
self.object_id_platform_translations: dict[str, Any] = {}
|
||||||
self._tasks: list[asyncio.Task[None]] = []
|
self._tasks: list[asyncio.Task[None]] = []
|
||||||
# Stop tracking tasks after setup is completed
|
# Stop tracking tasks after setup is completed
|
||||||
self._setup_complete = False
|
self._setup_complete = False
|
||||||
@ -294,22 +297,43 @@ class EntityPlatform:
|
|||||||
logger = self.logger
|
logger = self.logger
|
||||||
hass = self.hass
|
hass = self.hass
|
||||||
full_name = f"{self.domain}.{self.platform_name}"
|
full_name = f"{self.domain}.{self.platform_name}"
|
||||||
|
object_id_language = (
|
||||||
|
hass.config.language
|
||||||
|
if hass.config.language in languages.NATIVE_ENTITY_IDS
|
||||||
|
else languages.DEFAULT_LANGUAGE
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
async def get_translations(
|
||||||
self.component_translations = await translation.async_get_translations(
|
language: str, category: str, integration: str
|
||||||
hass, hass.config.language, "entity_component", {self.domain}
|
) -> dict[str, Any]:
|
||||||
|
"""Get entity translations."""
|
||||||
|
try:
|
||||||
|
return await translation.async_get_translations(
|
||||||
|
hass, language, category, {integration}
|
||||||
|
)
|
||||||
|
except Exception as err: # pylint: disable=broad-exception-caught
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Could not load translations for %s",
|
||||||
|
integration,
|
||||||
|
exc_info=err,
|
||||||
|
)
|
||||||
|
return {}
|
||||||
|
|
||||||
|
self.component_translations = await get_translations(
|
||||||
|
hass.config.language, "entity_component", self.domain
|
||||||
|
)
|
||||||
|
self.platform_translations = await get_translations(
|
||||||
|
hass.config.language, "entity", self.platform_name
|
||||||
|
)
|
||||||
|
if object_id_language == hass.config.language:
|
||||||
|
self.object_id_component_translations = self.component_translations
|
||||||
|
self.object_id_platform_translations = self.platform_translations
|
||||||
|
else:
|
||||||
|
self.object_id_component_translations = await get_translations(
|
||||||
|
object_id_language, "entity_component", self.domain
|
||||||
)
|
)
|
||||||
except Exception as err: # pylint: disable=broad-exception-caught
|
self.object_id_platform_translations = await get_translations(
|
||||||
_LOGGER.debug(
|
object_id_language, "entity", self.platform_name
|
||||||
"Could not load translations for %s", self.domain, exc_info=err
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
self.platform_translations = await translation.async_get_translations(
|
|
||||||
hass, hass.config.language, "entity", {self.platform_name}
|
|
||||||
)
|
|
||||||
except Exception as err: # pylint: disable=broad-exception-caught
|
|
||||||
_LOGGER.debug(
|
|
||||||
"Could not load translations for %s", self.platform_name, exc_info=err
|
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info("Setting up %s", full_name)
|
logger.info("Setting up %s", full_name)
|
||||||
@ -652,9 +676,11 @@ class EntityPlatform:
|
|||||||
if entity.use_device_name:
|
if entity.use_device_name:
|
||||||
suggested_object_id = device_name
|
suggested_object_id = device_name
|
||||||
else:
|
else:
|
||||||
suggested_object_id = f"{device_name} {entity_name}"
|
suggested_object_id = (
|
||||||
|
f"{device_name} {entity.suggested_object_id}"
|
||||||
|
)
|
||||||
if not suggested_object_id:
|
if not suggested_object_id:
|
||||||
suggested_object_id = entity_name
|
suggested_object_id = entity.suggested_object_id
|
||||||
|
|
||||||
if self.entity_namespace is not None:
|
if self.entity_namespace is not None:
|
||||||
suggested_object_id = f"{self.entity_namespace} {suggested_object_id}"
|
suggested_object_id = f"{self.entity_namespace} {suggested_object_id}"
|
||||||
@ -709,7 +735,7 @@ class EntityPlatform:
|
|||||||
# Generate entity ID
|
# Generate entity ID
|
||||||
if entity.entity_id is None or generate_new_entity_id:
|
if entity.entity_id is None or generate_new_entity_id:
|
||||||
suggested_object_id = (
|
suggested_object_id = (
|
||||||
suggested_object_id or entity_name or DEVICE_DEFAULT_NAME
|
suggested_object_id or entity.suggested_object_id or DEVICE_DEFAULT_NAME
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.entity_namespace is not None:
|
if self.entity_namespace is not None:
|
||||||
|
@ -15,10 +15,61 @@ req = requests.get(
|
|||||||
data = json.loads(req.content)
|
data = json.loads(req.content)
|
||||||
languages = set(data.keys())
|
languages = set(data.keys())
|
||||||
|
|
||||||
|
# Languages which can be used for entity IDs.
|
||||||
|
# Languages in the set are those which use a writing system based on the Latin
|
||||||
|
# script. Languages not in this set will instead base the entity ID on English.
|
||||||
|
|
||||||
|
# Note: Although vietnamese writing is based on the Latin script, it's too ambiguous
|
||||||
|
# after accents and diacritics have been removed by slugify
|
||||||
|
NATIVE_ENTITY_IDS = {
|
||||||
|
"af", # Afrikaans
|
||||||
|
"bs", # Bosanski
|
||||||
|
"ca", # Català
|
||||||
|
"cs", # Čeština
|
||||||
|
"cy", # Cymraeg
|
||||||
|
"da", # Dansk
|
||||||
|
"de", # Deutsch
|
||||||
|
"en", # English
|
||||||
|
"en-GB", # English (GB)
|
||||||
|
"eo", # Esperanto
|
||||||
|
"es", # Español
|
||||||
|
"es-419", # Español (Latin America)
|
||||||
|
"et", # Eesti
|
||||||
|
"eu", # Euskara
|
||||||
|
"fi", # Suomi
|
||||||
|
"fr", # Français
|
||||||
|
"fy", # Frysk
|
||||||
|
"gl", # Galego
|
||||||
|
"gsw", # Schwiizerdütsch
|
||||||
|
"hr", # Hrvatski
|
||||||
|
"hu", # Magyar
|
||||||
|
"id", # Indonesia
|
||||||
|
"is", # Íslenska
|
||||||
|
"it", # Italiano
|
||||||
|
"ka", # Kartuli
|
||||||
|
"lb", # Lëtzebuergesch
|
||||||
|
"lt", # Lietuvių
|
||||||
|
"lv", # Latviešu
|
||||||
|
"nb", # Nederlands
|
||||||
|
"nl", # Norsk Bokmål
|
||||||
|
"nn", # Norsk Nynorsk"
|
||||||
|
"pl", # Polski
|
||||||
|
"pt", # Português
|
||||||
|
"pt-BR", # Português (BR)
|
||||||
|
"ro", # Română
|
||||||
|
"sk", # Slovenčina
|
||||||
|
"sl", # Slovenščina
|
||||||
|
"sr-Latn", # Srpski
|
||||||
|
"sv", # Svenska
|
||||||
|
"tr", # Türkçe
|
||||||
|
}
|
||||||
|
|
||||||
Path("homeassistant/generated/languages.py").write_text(
|
Path("homeassistant/generated/languages.py").write_text(
|
||||||
format_python_namespace(
|
format_python_namespace(
|
||||||
{
|
{
|
||||||
|
"DEFAULT_LANGUAGE": "en",
|
||||||
"LANGUAGES": languages,
|
"LANGUAGES": languages,
|
||||||
|
"NATIVE_ENTITY_IDS": NATIVE_ENTITY_IDS,
|
||||||
},
|
},
|
||||||
generator="script.languages [frontend_tag]",
|
generator="script.languages [frontend_tag]",
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
"""Tests for the EntityPlatform helper."""
|
"""Tests for the EntityPlatform helper."""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from collections.abc import Iterable
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@ -18,6 +19,7 @@ from homeassistant.helpers import (
|
|||||||
)
|
)
|
||||||
from homeassistant.helpers.entity import (
|
from homeassistant.helpers.entity import (
|
||||||
DeviceInfo,
|
DeviceInfo,
|
||||||
|
Entity,
|
||||||
EntityCategory,
|
EntityCategory,
|
||||||
async_generate_entity_id,
|
async_generate_entity_id,
|
||||||
)
|
)
|
||||||
@ -1669,3 +1671,159 @@ async def test_entity_name_influences_entity_id(
|
|||||||
|
|
||||||
assert len(hass.states.async_entity_ids()) == 1
|
assert len(hass.states.async_entity_ids()) == 1
|
||||||
assert registry.async_get(expected_entity_id) is not None
|
assert registry.async_get(expected_entity_id) is not None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("language", "has_entity_name", "expected_entity_id"),
|
||||||
|
(
|
||||||
|
("en", False, "test_domain.test_qwer"), # Set to <platform>_<unique_id>
|
||||||
|
("en", True, "test_domain.device_bla_english_name"),
|
||||||
|
("sv", True, "test_domain.device_bla_swedish_name"),
|
||||||
|
# Chinese uses english for entity_id
|
||||||
|
("cn", True, "test_domain.device_bla_english_name"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
async def test_translated_entity_name_influences_entity_id(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
language: str,
|
||||||
|
has_entity_name: bool,
|
||||||
|
expected_entity_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test entity_id is influenced by translated entity name."""
|
||||||
|
|
||||||
|
class TranslatedEntity(Entity):
|
||||||
|
_attr_unique_id = "qwer"
|
||||||
|
_attr_device_info = {
|
||||||
|
"identifiers": {("hue", "1234")},
|
||||||
|
"connections": {(dr.CONNECTION_NETWORK_MAC, "abcd")},
|
||||||
|
"name": "Device Bla",
|
||||||
|
}
|
||||||
|
|
||||||
|
_attr_translation_key = "test"
|
||||||
|
|
||||||
|
def __init__(self, has_entity_name: bool) -> None:
|
||||||
|
"""Initialize."""
|
||||||
|
self._attr_has_entity_name = has_entity_name
|
||||||
|
|
||||||
|
registry = er.async_get(hass)
|
||||||
|
|
||||||
|
translations = {
|
||||||
|
"en": {"component.test.entity.test_domain.test.name": "English name"},
|
||||||
|
"sv": {"component.test.entity.test_domain.test.name": "Swedish name"},
|
||||||
|
"cn": {"component.test.entity.test_domain.test.name": "Chinese name"},
|
||||||
|
}
|
||||||
|
hass.config.language = language
|
||||||
|
|
||||||
|
async def async_get_translations(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
language: str,
|
||||||
|
category: str,
|
||||||
|
integrations: Iterable[str] | None = None,
|
||||||
|
config_flow: bool | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Return all backend translations."""
|
||||||
|
return translations[language]
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
|
"""Mock setup entry method."""
|
||||||
|
async_add_entities([TranslatedEntity(has_entity_name)])
|
||||||
|
return True
|
||||||
|
|
||||||
|
platform = MockPlatform(async_setup_entry=async_setup_entry)
|
||||||
|
config_entry = MockConfigEntry(entry_id="super-mock-id")
|
||||||
|
entity_platform = MockEntityPlatform(
|
||||||
|
hass, platform_name=config_entry.domain, platform=platform
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.helpers.entity_platform.translation.async_get_translations",
|
||||||
|
side_effect=async_get_translations,
|
||||||
|
):
|
||||||
|
assert await entity_platform.async_setup_entry(config_entry)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert len(hass.states.async_entity_ids()) == 1
|
||||||
|
assert registry.async_get(expected_entity_id) is not None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("language", "has_entity_name", "device_class", "expected_entity_id"),
|
||||||
|
(
|
||||||
|
("en", False, None, "test_domain.test_qwer"), # Set to <platform>_<unique_id>
|
||||||
|
(
|
||||||
|
"en",
|
||||||
|
False,
|
||||||
|
"test_class",
|
||||||
|
"test_domain.test_qwer",
|
||||||
|
), # Set to <platform>_<unique_id>
|
||||||
|
("en", True, "test_class", "test_domain.device_bla_english_cls"),
|
||||||
|
("sv", True, "test_class", "test_domain.device_bla_swedish_cls"),
|
||||||
|
# Chinese uses english for entity_id
|
||||||
|
("cn", True, "test_class", "test_domain.device_bla_english_cls"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
async def test_translated_device_class_name_influences_entity_id(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
language: str,
|
||||||
|
has_entity_name: bool,
|
||||||
|
device_class: str | None,
|
||||||
|
expected_entity_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test entity_id is influenced by translated entity name."""
|
||||||
|
|
||||||
|
class TranslatedDeviceClassEntity(Entity):
|
||||||
|
_attr_unique_id = "qwer"
|
||||||
|
_attr_device_info = {
|
||||||
|
"identifiers": {("hue", "1234")},
|
||||||
|
"connections": {(dr.CONNECTION_NETWORK_MAC, "abcd")},
|
||||||
|
"name": "Device Bla",
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, device_class: str | None, has_entity_name: bool) -> None:
|
||||||
|
"""Initialize."""
|
||||||
|
self._attr_device_class = device_class
|
||||||
|
self._attr_has_entity_name = has_entity_name
|
||||||
|
|
||||||
|
def _default_to_device_class_name(self) -> bool:
|
||||||
|
"""Return True if an unnamed entity should be named by its device class."""
|
||||||
|
return self.device_class is not None
|
||||||
|
|
||||||
|
registry = er.async_get(hass)
|
||||||
|
|
||||||
|
translations = {
|
||||||
|
"en": {"component.test_domain.entity_component.test_class.name": "English cls"},
|
||||||
|
"sv": {"component.test_domain.entity_component.test_class.name": "Swedish cls"},
|
||||||
|
"cn": {"component.test_domain.entity_component.test_class.name": "Chinese cls"},
|
||||||
|
}
|
||||||
|
hass.config.language = language
|
||||||
|
|
||||||
|
async def async_get_translations(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
language: str,
|
||||||
|
category: str,
|
||||||
|
integrations: Iterable[str] | None = None,
|
||||||
|
config_flow: bool | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Return all backend translations."""
|
||||||
|
return translations[language]
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
|
"""Mock setup entry method."""
|
||||||
|
async_add_entities([TranslatedDeviceClassEntity(device_class, has_entity_name)])
|
||||||
|
return True
|
||||||
|
|
||||||
|
platform = MockPlatform(async_setup_entry=async_setup_entry)
|
||||||
|
config_entry = MockConfigEntry(entry_id="super-mock-id")
|
||||||
|
entity_platform = MockEntityPlatform(
|
||||||
|
hass, platform_name=config_entry.domain, platform=platform
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.helpers.entity_platform.translation.async_get_translations",
|
||||||
|
side_effect=async_get_translations,
|
||||||
|
):
|
||||||
|
assert await entity_platform.async_setup_entry(config_entry)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert len(hass.states.async_entity_ids()) == 1
|
||||||
|
assert registry.async_get(expected_entity_id) is not None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user