core/tests/helpers/test_translation.py

242 lines
8.3 KiB
Python
Raw Normal View History

"""Test the translation helper."""
import asyncio
from os import path
import pathlib
from asynctest import Mock, patch
import pytest
from homeassistant.generated import config_flows
import homeassistant.helpers.translation as translation
from homeassistant.loader import async_get_integration
from homeassistant.setup import async_setup_component
@pytest.fixture
def mock_config_flows():
"""Mock the config flows."""
flows = []
2019-07-31 19:25:30 +00:00
with patch.object(config_flows, "FLOWS", flows):
yield flows
def test_flatten():
"""Test the flatten function."""
2019-07-31 19:25:30 +00:00
data = {"parent1": {"child1": "data1", "child2": "data2"}, "parent2": "data3"}
flattened = translation.flatten(data)
assert flattened == {
"parent1.child1": "data1",
"parent1.child2": "data2",
"parent2": "data3",
}
async def test_component_translation_path(hass):
"""Test the component translation file function."""
2019-07-31 19:25:30 +00:00
assert await async_setup_component(
hass,
"switch",
{"switch": [{"platform": "test"}, {"platform": "test_embedded"}]},
)
assert await async_setup_component(hass, "test_standalone", {"test_standalone"})
assert await async_setup_component(hass, "test_package", {"test_package"})
(
int_test,
int_test_embedded,
int_test_standalone,
int_test_package,
) = await asyncio.gather(
async_get_integration(hass, "test"),
async_get_integration(hass, "test_embedded"),
async_get_integration(hass, "test_standalone"),
async_get_integration(hass, "test_package"),
)
2019-07-31 19:25:30 +00:00
assert path.normpath(
translation.component_translation_path("switch.test", "en", int_test)
2019-07-31 19:25:30 +00:00
) == path.normpath(
hass.config.path("custom_components", "test", ".translations", "switch.en.json")
)
assert path.normpath(
translation.component_translation_path(
"switch.test_embedded", "en", int_test_embedded
)
2019-07-31 19:25:30 +00:00
) == path.normpath(
hass.config.path(
"custom_components", "test_embedded", ".translations", "switch.en.json"
)
)
assert (
translation.component_translation_path(
"test_standalone", "en", int_test_standalone
)
2019-07-31 19:25:30 +00:00
is None
)
assert path.normpath(
translation.component_translation_path("test_package", "en", int_test_package)
2019-07-31 19:25:30 +00:00
) == path.normpath(
hass.config.path(
"custom_components", "test_package", ".translations", "en.json"
)
)
def test_load_translations_files(hass):
"""Test the load translation files function."""
# Test one valid and one invalid file
file1 = hass.config.path(
2019-07-31 19:25:30 +00:00
"custom_components", "test", ".translations", "switch.en.json"
)
file2 = hass.config.path(
2019-07-31 19:25:30 +00:00
"custom_components", "test", ".translations", "invalid.json"
)
assert translation.load_translations_files(
{"switch.test": file1, "invalid": file2}
) == {
"switch.test": {
"state": {"string1": "Value 1", "string2": "Value 2"},
"something": "else",
},
2019-07-31 19:25:30 +00:00
"invalid": {},
}
async def test_get_translations(hass, mock_config_flows):
"""Test the get translations helper."""
translations = await translation.async_get_translations(hass, "en", "state")
assert translations == {}
2019-07-31 19:25:30 +00:00
assert await async_setup_component(hass, "switch", {"switch": {"platform": "test"}})
translations = await translation.async_get_translations(hass, "en", "state")
2019-09-10 20:07:55 +00:00
assert translations["component.switch.state.string1"] == "Value 1"
assert translations["component.switch.state.string2"] == "Value 2"
translations = await translation.async_get_translations(hass, "de", "state")
assert "component.switch.something" not in translations
2019-09-10 20:07:55 +00:00
assert translations["component.switch.state.string1"] == "German Value 1"
assert translations["component.switch.state.string2"] == "German Value 2"
# Test a partial translation
translations = await translation.async_get_translations(hass, "es", "state")
2019-09-10 20:07:55 +00:00
assert translations["component.switch.state.string1"] == "Spanish Value 1"
assert translations["component.switch.state.string2"] == "Value 2"
# Test that an untranslated language falls back to English.
translations = await translation.async_get_translations(
hass, "invalid-language", "state"
)
2019-09-10 20:07:55 +00:00
assert translations["component.switch.state.string1"] == "Value 1"
assert translations["component.switch.state.string2"] == "Value 2"
async def test_get_translations_loads_config_flows(hass, mock_config_flows):
"""Test the get translations helper loads config flow translations."""
2019-07-31 19:25:30 +00:00
mock_config_flows.append("component1")
integration = Mock(file_path=pathlib.Path(__file__))
integration.name = "Component 1"
2019-07-31 19:25:30 +00:00
with patch.object(
translation, "component_translation_path", return_value="bla.json"
2019-07-31 19:25:30 +00:00
), patch.object(
translation,
"load_translations_files",
return_value={"component1": {"hello": "world"}},
), patch(
"homeassistant.helpers.translation.async_get_integration",
return_value=integration,
):
translations = await translation.async_get_translations(
hass, "en", "hello", config_flow=True
)
assert translations == {
"component.component1.hello": "world",
}
assert "component1" not in hass.config.components
async def test_get_translations_while_loading_components(hass):
"""Test the get translations helper loads config flow translations."""
integration = Mock(file_path=pathlib.Path(__file__))
integration.name = "Component 1"
hass.config.components.add("component1")
async def mock_load_translation_files(files):
"""Mock load translation files."""
# Mimic race condition by loading a component during setup
await async_setup_component(hass, "persistent_notification", {})
return {"component1": {"hello": "world"}}
with patch.object(
translation, "component_translation_path", return_value="bla.json"
), patch.object(
translation, "load_translations_files", side_effect=mock_load_translation_files,
), patch(
"homeassistant.helpers.translation.async_get_integration",
return_value=integration,
2019-07-31 19:25:30 +00:00
):
translations = await translation.async_get_translations(hass, "en", "hello")
assert translations == {
"component.component1.hello": "world",
}
async def test_get_translation_categories(hass):
"""Test the get translations helper loads config flow translations."""
with patch.object(translation, "async_get_config_flows", return_value={"light"}):
translations = await translation.async_get_translations(
hass, "en", "title", None, True
)
assert "component.light.title" in translations
translations = await translation.async_get_translations(
hass, "en", "device_automation", None, True
)
assert "component.light.device_automation.action_type.turn_on" in translations
async def test_translation_merging(hass, caplog):
"""Test we merge translations of two integrations."""
hass.config.components.add("sensor.moon")
hass.config.components.add("sensor.season")
hass.config.components.add("sensor")
translations = await translation.async_get_translations(hass, "en", "state")
assert "component.sensor.state.moon__phase.first_quarter" in translations
assert "component.sensor.state.season__season.summer" in translations
# Merge in some bad translation data
integration = Mock(file_path=pathlib.Path(__file__))
hass.config.components.add("sensor.bad_translations")
with patch.object(
translation, "component_translation_path", return_value="bla.json"
), patch.object(
translation,
"load_translations_files",
return_value={"sensor.bad_translations": {"state": "bad data"}},
), patch(
"homeassistant.helpers.translation.async_get_integration",
return_value=integration,
):
translations = await translation.async_get_translations(hass, "en", "state")
assert "component.sensor.state.moon__phase.first_quarter" in translations
assert "component.sensor.state.season__season.summer" in translations
assert (
"An integration providing translations for sensor provided invalid data: bad data"
in caplog.text
)