# ABOUTME: Tests for locale detection and string lookup. # ABOUTME: Verifies DE/EN selection based on system locale. from pathlib import Path import pytest from moongreet.i18n import detect_locale, load_strings, Strings class TestDetectLocale: """Tests for system locale detection.""" def test_reads_lang_env(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("LANG", "de_DE.UTF-8") result = detect_locale() assert result == "de" def test_reads_lang_without_region(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("LANG", "en_US.UTF-8") result = detect_locale() assert result == "en" def test_falls_back_to_locale_conf(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.delenv("LANG", raising=False) locale_conf = tmp_path / "locale.conf" locale_conf.write_text("LANG=de_AT.UTF-8\n") result = detect_locale(locale_conf_path=locale_conf) assert result == "de" def test_defaults_to_english(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.delenv("LANG", raising=False) missing = tmp_path / "nonexistent" result = detect_locale(locale_conf_path=missing) assert result == "en" def test_handles_bare_language_code(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("LANG", "de") result = detect_locale() assert result == "de" def test_handles_c_locale(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("LANG", "C") result = detect_locale() assert result == "en" def test_handles_posix_locale(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("LANG", "POSIX") result = detect_locale() assert result == "en" def test_rejects_non_alpha_lang(self, monkeypatch: pytest.MonkeyPatch) -> None: monkeypatch.setenv("LANG", "../../etc") result = detect_locale() assert result == "en" class TestLoadStrings: """Tests for loading the correct string table.""" def test_loads_german_strings(self) -> None: strings = load_strings("de") assert strings.password_placeholder == "Passwort" assert strings.reboot_tooltip == "Neustart" assert strings.shutdown_tooltip == "Herunterfahren" def test_loads_english_strings(self) -> None: strings = load_strings("en") assert strings.password_placeholder == "Password" assert strings.reboot_tooltip == "Reboot" assert strings.shutdown_tooltip == "Shut down" def test_unknown_locale_falls_back_to_english(self) -> None: strings = load_strings("fr") assert strings.password_placeholder == "Password" def test_returns_strings_dataclass(self) -> None: strings = load_strings("de") assert isinstance(strings, Strings) def test_error_messages_are_present(self) -> None: strings = load_strings("en") assert strings.wrong_password assert strings.auth_failed assert strings.reboot_failed assert strings.shutdown_failed assert strings.no_session_selected assert strings.multi_stage_unsupported assert strings.invalid_session_command assert strings.session_start_failed assert strings.faillock_locked def test_faillock_warning_template(self) -> None: strings = load_strings("de") # Template should accept an int for remaining attempts result = strings.faillock_attempts_remaining.format(n=1) assert "1" in result def test_connection_error_is_generic(self) -> None: strings = load_strings("en") # Error messages should not contain format placeholders (no info leakage) assert "{" not in strings.connection_error assert "{" not in strings.socket_error