Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion homeassistant/components/frontend/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,7 @@ def websocket_get_themes(
vol.Required("language"): str,
vol.Required("category"): str,
vol.Optional("integration"): str,
vol.Optional("integrations"): [str],
Comment thread
bdraco marked this conversation as resolved.
Outdated
vol.Optional("config_flow"): bool,
}
)
Expand All @@ -676,11 +677,17 @@ async def websocket_get_translations(
hass: HomeAssistant, connection: ActiveConnection, msg: dict
) -> None:
"""Handle get translations command."""
integrations = None
if "integration" in msg:
integrations = {msg["integration"]}
elif "integrations" in msg:
integrations = set(msg["integrations"])

resources = await async_get_translations(
hass,
msg["language"],
msg["category"],
msg.get("integration"),
integrations,
msg.get("config_flow"),
)
connection.send_message(
Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/onboarding/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from homeassistant.components.http.view import HomeAssistantView
from homeassistant.core import callback
from homeassistant.helpers.system_info import async_get_system_info
from homeassistant.helpers.translation import async_get_translations

from .const import (
DEFAULT_AREAS,
Expand Down Expand Up @@ -147,8 +148,8 @@ async def post(self, request, data):
await person.async_create_person(hass, data["name"], user_id=user.id)

# Create default areas using the users supplied language.
translations = await hass.helpers.translation.async_get_translations(
data["language"], "area", DOMAIN
translations = await async_get_translations(
hass, data["language"], "area", {DOMAIN}
)

area_registry = await hass.helpers.area_registry.async_get_registry()
Expand Down
11 changes: 7 additions & 4 deletions homeassistant/helpers/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ async def async_get_translations(
hass: HomeAssistant,
language: str,
category: str,
integration: str | None = None,
integrations: set[str] | None = None,
config_flow: bool | None = None,
) -> dict[str, Any]:
"""Return all backend translations.
Expand All @@ -297,8 +297,8 @@ async def async_get_translations(
"""
lock = hass.data.setdefault(TRANSLATION_LOAD_LOCK, asyncio.Lock())

if integration is not None:
components = {integration}
if integrations is not None:
components = integrations
elif config_flow:
components = (await async_get_config_flows(hass)) - hass.config.components
elif category == "state":
Expand All @@ -310,7 +310,10 @@ async def async_get_translations(
}

async with lock:
cache = hass.data.setdefault(TRANSLATION_FLATTEN_CACHE, _TranslationCache(hass))
if TRANSLATION_FLATTEN_CACHE in hass.data:
cache = hass.data[TRANSLATION_FLATTEN_CACHE]
else:
cache = hass.data[TRANSLATION_FLATTEN_CACHE] = _TranslationCache(hass)
cached = await cache.async_fetch(language, category, components)

return dict(ChainMap(*cached))
54 changes: 53 additions & 1 deletion tests/components/frontend/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ async def test_get_translations(hass, ws_client):
"""Test get_translations command."""
with patch(
"homeassistant.components.frontend.async_get_translations",
side_effect=lambda hass, lang, category, integration, config_flow: {
side_effect=lambda hass, lang, category, integrations, config_flow: {
"lang": lang
},
):
Expand All @@ -444,6 +444,58 @@ async def test_get_translations(hass, ws_client):
assert msg["result"] == {"resources": {"lang": "nl"}}


async def test_get_translations_for_integrations(hass, ws_client):
"""Test get_translations for integrations command."""
with patch(
"homeassistant.components.frontend.async_get_translations",
side_effect=lambda hass, lang, category, integrations, config_flow: {
"lang": lang,
"integrations": integrations,
},
):
await ws_client.send_json(
{
"id": 5,
"type": "frontend/get_translations",
"integrations": ["frontend", "http"],
"language": "nl",
"category": "lang",
}
)
msg = await ws_client.receive_json()

assert msg["id"] == 5
assert msg["type"] == TYPE_RESULT
assert msg["success"]
assert set(msg["result"]["resources"]["integrations"]) == {"frontend", "http"}


async def test_get_translations_for_single_integration(hass, ws_client):
"""Test get_translations for integration command."""
with patch(
"homeassistant.components.frontend.async_get_translations",
side_effect=lambda hass, lang, category, integrations, config_flow: {
"lang": lang,
"integration": integrations,
},
):
await ws_client.send_json(
{
"id": 5,
"type": "frontend/get_translations",
"integration": "http",
"language": "nl",
"category": "lang",
}
)
msg = await ws_client.receive_json()

assert msg["id"] == 5
assert msg["type"] == TYPE_RESULT
assert msg["success"]
assert msg["result"] == {"resources": {"lang": "nl", "integration": ["http"]}}


async def test_auth_load(hass):
"""Test auth component loaded by default."""
frontend = await async_get_integration(hass, "frontend")
Expand Down
29 changes: 23 additions & 6 deletions tests/helpers/test_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,29 @@ async def test_translation_merging_loaded_apart(hass, caplog):
assert "component.sensor.state.moon__phase.first_quarter" in translations

translations = await translation.async_get_translations(
hass, "en", "state", integration="sensor"
hass, "en", "state", integrations={"sensor"}
)

assert "component.sensor.state.moon__phase.first_quarter" in translations


async def test_translation_merging_loaded_together(hass, caplog):
"""Test we merge translations of two integrations when they are loaded at the same time."""
hass.config.components.add("hue")
hass.config.components.add("homekit")
hue_translations = await translation.async_get_translations(
hass, "en", "config", integrations={"hue"}
)
homekit_translations = await translation.async_get_translations(
hass, "en", "config", integrations={"homekit"}
)

translations = await translation.async_get_translations(
hass, "en", "config", integrations={"hue", "homekit"}
)
assert translations == hue_translations | homekit_translations


async def test_caching(hass):
"""Test we cache data."""
hass.config.components.add("sensor")
Expand All @@ -320,14 +337,14 @@ async def test_caching(hass):
)

load_sensor_only = await translation.async_get_translations(
hass, "en", "state", integration="sensor"
hass, "en", "state", integrations={"sensor"}
)
assert load_sensor_only
for key in load_sensor_only:
assert key.startswith("component.sensor.state.")

load_light_only = await translation.async_get_translations(
hass, "en", "state", integration="light"
hass, "en", "state", integrations={"light"}
)
assert load_light_only
for key in load_light_only:
Expand All @@ -341,20 +358,20 @@ async def test_caching(hass):
side_effect=translation._build_resources,
) as mock_build:
load_sensor_only = await translation.async_get_translations(
hass, "en", "title", integration="sensor"
hass, "en", "title", integrations={"sensor"}
)
assert load_sensor_only
for key in load_sensor_only:
assert key == "component.sensor.title"
assert len(mock_build.mock_calls) == 0

assert await translation.async_get_translations(
hass, "en", "title", integration="sensor"
hass, "en", "title", integrations={"sensor"}
)
assert len(mock_build.mock_calls) == 0

load_light_only = await translation.async_get_translations(
hass, "en", "title", integration="media_player"
hass, "en", "title", integrations={"media_player"}
)
assert load_light_only
for key in load_light_only:
Expand Down