diff --git a/src/netcheck/exporter.py b/src/netcheck/exporter.py index 80ee9d7..67a22d9 100644 --- a/src/netcheck/exporter.py +++ b/src/netcheck/exporter.py @@ -114,6 +114,20 @@ def _t(lang: str, en: str, ru: str) -> str: return en if lang == "en" else ru +_WARNING_RU = { + "no ASN was resolved for this target": "для этой цели не удалось определить ASN", + "no egress IP to check": "нет внешнего IP для проверки", + "ABUSEIPDB_API_KEY not set — abuse score skipped": "ABUSEIPDB_API_KEY не задан — оценка abuse пропущена", + "speedtest skipped: --quick": "speedtest пропущен: --quick", + "speedtest skipped in target mode": "speedtest пропущен в режиме цели", + "no throughput measured": "пропускная способность не измерена", +} + + +def _warning(lang: str, text: str) -> str: + return text if lang == "en" else _WARNING_RU.get(text, text) + + def sparkline(values: list[float | None]) -> str: numbers = [v for v in values if v is not None] if not numbers: @@ -260,7 +274,7 @@ def unavailable(report: dict[str, Any], section: str, lang: str = "en") -> str | return None detail = "; ".join(f"{e.get('source')}: {e.get('message')}" for e in module.get("errors") or []) if not detail: - detail = "; ".join(module.get("warnings") or []) + detail = "; ".join(_warning(lang, w) for w in module.get("warnings") or []) if not detail: detail = _t(lang, "no data was collected for this section", "для этого раздела не собраны данные") status_word = _module_status_word(module.get("status", "skipped"), lang) @@ -641,7 +655,7 @@ def _diagnostics(report: dict, lang: str = "en") -> list[str]: lang, ) if warnings: - lines += [""] + [f"- {w}" for w in warnings] + lines += [""] + [f"- {_warning(lang, w)}" for w in warnings] return lines + [""] diff --git a/tests/test_exporter.py b/tests/test_exporter.py index d8bab03..f1672b1 100644 --- a/tests/test_exporter.py +++ b/tests/test_exporter.py @@ -589,6 +589,34 @@ def test_unavailable_surfaces_the_skip_reason_from_warnings(): assert "speedtest skipped in target mode" in note +def test_unavailable_translates_the_skip_reason_into_russian(): + report = build_report( + meta(), + {"speed": ModuleResult(name="speed", status="skipped", warnings=["speedtest skipped: --quick"])}, + [], + {}, + ) + note = unavailable(report, "speed", lang="ru") + assert note is not None + assert "speedtest skipped: --quick" not in note + assert "speedtest пропущен: --quick" in note + + +def test_diagnostics_translates_module_warnings_into_russian(): + from netcheck.exporter import _diagnostics + + report = build_report( + meta(), + {"reputation": ModuleResult(name="reputation", status="partial", warnings=["ABUSEIPDB_API_KEY not set — abuse score skipped"])}, + [], + {}, + ) + lines = _diagnostics(report, lang="ru") + text = "\n".join(lines) + assert "ABUSEIPDB_API_KEY not set — abuse score skipped" not in text + assert "ABUSEIPDB_API_KEY не задан" in text + + def test_an_all_modules_failed_run_still_renders_every_section(): text = render_markdown(dead_report()) headings = [line for line in text.splitlines() if line.startswith("## ")]