diff --git a/homeassistant/helpers/translation.py b/homeassistant/helpers/translation.py index c2caecaa184..ca79ec443ab 100644 --- a/homeassistant/helpers/translation.py +++ b/homeassistant/helpers/translation.py @@ -165,20 +165,21 @@ async def _async_get_component_strings( for language in languages: files_to_load: dict[str, str] = {} files_to_load_by_language[language] = files_to_load - - loaded_translations: dict[str, Any] = {} - translations_by_language[language] = loaded_translations + translations_by_language[language] = {} for loaded in components: - domain = loaded.partition(".")[0] + domain, _, platform = loaded.partition(".") if not (integration := integrations.get(domain)): continue - path = component_translation_path(loaded, language, integration) - # No translation available - if path is None: - loaded_translations[loaded] = {} - else: + if platform and integration.is_built_in: + # Legacy state translations are no longer used for built-in integrations + # and we avoid trying to load them. This is a temporary measure to allow + # them to keep working for custom integrations until we can fully remove + # them. + continue + + if path := component_translation_path(loaded, language, integration): files_to_load[loaded] = path if not files_to_load: diff --git a/tests/helpers/test_translation.py b/tests/helpers/test_translation.py index 210378c5812..69d7ef274ae 100644 --- a/tests/helpers/test_translation.py +++ b/tests/helpers/test_translation.py @@ -335,20 +335,57 @@ async def test_get_translation_categories(hass: HomeAssistant) -> None: assert "component.light.device_automation.action_type.turn_on" in translations -async def test_translation_merging( +async def test_legacy_platform_translations_not_used_built_in_integrations( hass: HomeAssistant, caplog: pytest.LogCaptureFixture ) -> None: - """Test we merge translations of two integrations.""" + """Test legacy platform translations are not used for built-in integrations.""" hass.config.components.add("moon.sensor") hass.config.components.add("sensor") + load_requests = [] + + def mock_load_translations_files_by_language(files): + load_requests.append(files) + return {} + + with patch( + "homeassistant.helpers.translation._load_translations_files_by_language", + mock_load_translations_files_by_language, + ): + await translation.async_get_translations(hass, "en", "state") + + assert len(load_requests) == 1 + to_load = load_requests[0] + assert len(to_load) == 1 + en_load = to_load["en"] + assert len(en_load) == 1 + assert "sensor" in en_load + assert "moon.sensor" not in en_load + + +async def test_translation_merging_custom_components( + hass: HomeAssistant, + caplog: pytest.LogCaptureFixture, + enable_custom_integrations: None, +) -> None: + """Test we merge translations of two integrations. + + Legacy state translations only used for custom integrations. + """ + hass.config.components.add("test_legacy_state_translations.sensor") + hass.config.components.add("sensor") + orig_load_translations = translation._load_translations_files_by_language def mock_load_translations_files(files): """Mock loading.""" result = orig_load_translations(files) - result["en"]["moon.sensor"] = { - "state": {"moon__phase": {"first_quarter": "First Quarter"}} + result["en"]["test_legacy_state_translations.sensor"] = { + "state": { + "test_legacy_state_translations__phase": { + "first_quarter": "First Quarter" + } + } } return result @@ -358,15 +395,20 @@ async def test_translation_merging( ): translations = await translation.async_get_translations(hass, "en", "state") - assert "component.sensor.state.moon__phase.first_quarter" in translations + assert ( + "component.sensor.state.test_legacy_state_translations__phase.first_quarter" + in translations + ) - hass.config.components.add("season.sensor") + hass.config.components.add("test_legacy_state_translations_bad_data.sensor") # Patch in some bad translation data def mock_load_bad_translations_files(files): """Mock loading.""" result = orig_load_translations(files) - result["en"]["season.sensor"] = {"state": "bad data"} + result["en"]["test_legacy_state_translations_bad_data.sensor"] = { + "state": "bad data" + } return result with patch( @@ -375,7 +417,10 @@ async def test_translation_merging( ): translations = await translation.async_get_translations(hass, "en", "state") - assert "component.sensor.state.moon__phase.first_quarter" in translations + assert ( + "component.sensor.state.test_legacy_state_translations__phase.first_quarter" + in translations + ) assert ( "An integration providing translations for sensor provided invalid data:" @@ -383,17 +428,26 @@ async def test_translation_merging( ) in caplog.text -async def test_translation_merging_loaded_apart( - hass: HomeAssistant, caplog: pytest.LogCaptureFixture +async def test_translation_merging_loaded_apart_custom_integrations( + hass: HomeAssistant, + caplog: pytest.LogCaptureFixture, + enable_custom_integrations: None, ) -> None: - """Test we merge translations of two integrations when they are not loaded at the same time.""" + """Test we merge translations of two integrations when they are not loaded at the same time. + + Legacy state translations only used for custom integrations. + """ orig_load_translations = translation._load_translations_files_by_language def mock_load_translations_files(files): """Mock loading.""" result = orig_load_translations(files) - result["en"]["moon.sensor"] = { - "state": {"moon__phase": {"first_quarter": "First Quarter"}} + result["en"]["test_legacy_state_translations.sensor"] = { + "state": { + "test_legacy_state_translations__phase": { + "first_quarter": "First Quarter" + } + } } return result @@ -405,9 +459,12 @@ async def test_translation_merging_loaded_apart( ): translations = await translation.async_get_translations(hass, "en", "state") - assert "component.sensor.state.moon__phase.first_quarter" not in translations + assert ( + "component.sensor.state.test_legacy_state_translations__phase.first_quarter" + not in translations + ) - hass.config.components.add("moon.sensor") + hass.config.components.add("test_legacy_state_translations.sensor") with patch( "homeassistant.helpers.translation._load_translations_files_by_language", @@ -415,7 +472,10 @@ async def test_translation_merging_loaded_apart( ): translations = await translation.async_get_translations(hass, "en", "state") - assert "component.sensor.state.moon__phase.first_quarter" in translations + assert ( + "component.sensor.state.test_legacy_state_translations__phase.first_quarter" + in translations + ) with patch( "homeassistant.helpers.translation._load_translations_files_by_language", @@ -425,7 +485,10 @@ async def test_translation_merging_loaded_apart( hass, "en", "state", integrations={"sensor"} ) - assert "component.sensor.state.moon__phase.first_quarter" in translations + assert ( + "component.sensor.state.test_legacy_state_translations__phase.first_quarter" + in translations + ) async def test_translation_merging_loaded_together( diff --git a/tests/testing_config/custom_components/test_legacy_state_translations/__init__.py b/tests/testing_config/custom_components/test_legacy_state_translations/__init__.py new file mode 100644 index 00000000000..e3bf8f02952 --- /dev/null +++ b/tests/testing_config/custom_components/test_legacy_state_translations/__init__.py @@ -0,0 +1 @@ +"""Provide a mock package component.""" diff --git a/tests/testing_config/custom_components/test_legacy_state_translations/manifest.json b/tests/testing_config/custom_components/test_legacy_state_translations/manifest.json new file mode 100644 index 00000000000..6f5c8837eb7 --- /dev/null +++ b/tests/testing_config/custom_components/test_legacy_state_translations/manifest.json @@ -0,0 +1,7 @@ +{ + "domain": "test_legacy_state_translations", + "name": "Test package for legacy state translations", + "documentation": "http://test-package.io", + "config_flow": true, + "version": "1.2.3" +} diff --git a/tests/testing_config/custom_components/test_legacy_state_translations_bad_data/__init__.py b/tests/testing_config/custom_components/test_legacy_state_translations_bad_data/__init__.py new file mode 100644 index 00000000000..e3bf8f02952 --- /dev/null +++ b/tests/testing_config/custom_components/test_legacy_state_translations_bad_data/__init__.py @@ -0,0 +1 @@ +"""Provide a mock package component.""" diff --git a/tests/testing_config/custom_components/test_legacy_state_translations_bad_data/manifest.json b/tests/testing_config/custom_components/test_legacy_state_translations_bad_data/manifest.json new file mode 100644 index 00000000000..d5d7fc7b1b1 --- /dev/null +++ b/tests/testing_config/custom_components/test_legacy_state_translations_bad_data/manifest.json @@ -0,0 +1,7 @@ +{ + "domain": "test_legacy_state_translations_bad_data", + "name": "Test package for legacy state translations", + "documentation": "http://test-package.io", + "config_flow": true, + "version": "1.2.3" +}