From 8b579d83ce32859fb054013254645571ba3c9461 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Fri, 13 Dec 2024 09:50:10 +0100 Subject: [PATCH] Add data/data_description translation checks (#131705) --- tests/components/conftest.py | 38 ++++++++++++++++++++++ tests/components/onkyo/test_config_flow.py | 9 +++++ 2 files changed, 47 insertions(+) diff --git a/tests/components/conftest.py b/tests/components/conftest.py index 71c3b14050d..ac30d105299 100644 --- a/tests/components/conftest.py +++ b/tests/components/conftest.py @@ -4,6 +4,7 @@ from __future__ import annotations import asyncio from collections.abc import AsyncGenerator, Callable, Generator +from functools import lru_cache from importlib.util import find_spec from pathlib import Path import string @@ -37,6 +38,7 @@ from homeassistant.data_entry_flow import ( from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import issue_registry as ir from homeassistant.helpers.translation import async_get_translations +from homeassistant.util import yaml if TYPE_CHECKING: from homeassistant.components.hassio import AddonManager @@ -619,6 +621,26 @@ def ignore_translations() -> str | list[str]: return [] +@lru_cache +def _get_integration_quality_scale(integration: str) -> dict[str, Any]: + """Get the quality scale for an integration.""" + try: + return yaml.load_yaml_dict( + f"homeassistant/components/{integration}/quality_scale.yaml" + ).get("rules", {}) + except FileNotFoundError: + return {} + + +def _get_integration_quality_scale_rule(integration: str, rule: str) -> str: + """Get the quality scale for an integration.""" + quality_scale = _get_integration_quality_scale(integration) + if not quality_scale or rule not in quality_scale: + return "todo" + status = quality_scale[rule] + return status if isinstance(status, str) else status["status"] + + async def _check_config_flow_result_translations( manager: FlowManager, flow: FlowHandler, @@ -650,6 +672,9 @@ async def _check_config_flow_result_translations( setattr(flow, "__flow_seen_before", hasattr(flow, "__flow_seen_before")) if result["type"] is FlowResultType.FORM: + iqs_config_flow = _get_integration_quality_scale_rule( + integration, "config-flow" + ) if step_id := result.get("step_id"): # neither title nor description are required # - title defaults to integration name @@ -664,6 +689,19 @@ async def _check_config_flow_result_translations( result["description_placeholders"], translation_required=False, ) + if iqs_config_flow == "done" and (data_schema := result["data_schema"]): + # data and data_description are compulsory + for data_key in data_schema.schema: + for header in ("data", "data_description"): + await _validate_translation( + flow.hass, + translation_errors, + category, + integration, + f"{key_prefix}step.{step_id}.{header}.{data_key}", + result["description_placeholders"], + ) + if errors := result.get("errors"): for error in errors.values(): await _validate_translation( diff --git a/tests/components/onkyo/test_config_flow.py b/tests/components/onkyo/test_config_flow.py index f230ab124bd..a9d6f072559 100644 --- a/tests/components/onkyo/test_config_flow.py +++ b/tests/components/onkyo/test_config_flow.py @@ -503,6 +503,15 @@ async def test_import_success( } +@pytest.mark.parametrize( + "ignore_translations", + [ + [ # The schema is dynamically created from input sources + "component.onkyo.options.step.init.data.TV", + "component.onkyo.options.step.init.data_description.TV", + ] + ], +) async def test_options_flow(hass: HomeAssistant, config_entry: MockConfigEntry) -> None: """Test options flow."""