""" Behavioral tests for settings/env_registry module. Tests convenience functions for CI detection, test mode, and rate limiting. """ import os from unittest.mock import patch import pytest class TestRegistry: """Tests for the global registry instance.""" def test_registry_is_settings_registry(self): """Registry is a SettingsRegistry instance.""" from local_deep_research.settings.env_registry import registry from local_deep_research.settings.env_settings import SettingsRegistry assert isinstance(registry, SettingsRegistry) def test_registry_has_categories(self): """Registry has registered categories.""" from local_deep_research.settings.env_registry import registry # Should have at least some categories from ALL_SETTINGS all_vars = registry.get_all_env_vars() assert len(all_vars) > 0 class TestGetEnvSetting: """Tests for get_env_setting function.""" def test_returns_default_for_unknown_key(self): """Returns default for unknown setting key.""" from local_deep_research.settings.env_registry import get_env_setting result = get_env_setting( "completely.unknown.key.xyz", default="fallback" ) assert result == "fallback" def test_returns_none_default(self): """Returns None when no default specified and key not found.""" from local_deep_research.settings.env_registry import get_env_setting result = get_env_setting("completely.unknown.key.xyz") assert result is None class TestIsTestMode: """Tests for is_test_mode function.""" def test_returns_bool(self): """Returns a boolean.""" from local_deep_research.settings.env_registry import is_test_mode result = is_test_mode() assert isinstance(result, bool) def test_callable_without_args(self): """Callable without arguments.""" from local_deep_research.settings.env_registry import is_test_mode # Should not raise is_test_mode() class TestIsCiEnvironment: """Tests for is_ci_environment function.""" def test_returns_bool(self): """Returns a boolean.""" from local_deep_research.settings.env_registry import is_ci_environment result = is_ci_environment() assert isinstance(result, bool) def test_true_when_ci_set(self): """Returns True when CI env var is 'true'.""" from local_deep_research.settings.env_registry import is_ci_environment with patch.dict(os.environ, {"CI": "true"}): assert is_ci_environment() is True def test_true_when_ci_is_1(self): """Returns True when CI env var is '1'.""" from local_deep_research.settings.env_registry import is_ci_environment with patch.dict(os.environ, {"CI": "1"}): assert is_ci_environment() is True def test_true_when_ci_is_yes(self): """Returns True when CI env var is 'yes'.""" from local_deep_research.settings.env_registry import is_ci_environment with patch.dict(os.environ, {"CI": "yes"}): assert is_ci_environment() is True def test_false_when_ci_is_false(self): """Returns False when CI env var is 'false'.""" from local_deep_research.settings.env_registry import is_ci_environment with patch.dict(os.environ, {"CI": "false"}): assert is_ci_environment() is False def test_false_when_ci_not_set(self): """Returns False when CI env var is not set.""" from local_deep_research.settings.env_registry import is_ci_environment env = os.environ.copy() env.pop("CI", None) with patch.dict(os.environ, env, clear=True): assert is_ci_environment() is False def test_case_insensitive(self): """CI check is case-insensitive.""" from local_deep_research.settings.env_registry import is_ci_environment with patch.dict(os.environ, {"CI": "TRUE"}): assert is_ci_environment() is True with patch.dict(os.environ, {"CI": "True"}): assert is_ci_environment() is True class TestIsGithubActions: """Tests for is_github_actions function.""" def test_returns_bool(self): """Returns a boolean.""" from local_deep_research.settings.env_registry import is_github_actions result = is_github_actions() assert isinstance(result, bool) def test_true_when_set(self): """Returns True when GITHUB_ACTIONS is 'true'.""" from local_deep_research.settings.env_registry import is_github_actions with patch.dict(os.environ, {"GITHUB_ACTIONS": "true"}): assert is_github_actions() is True def test_false_when_not_set(self): """Returns False when GITHUB_ACTIONS is not set.""" from local_deep_research.settings.env_registry import is_github_actions env = os.environ.copy() env.pop("GITHUB_ACTIONS", None) with patch.dict(os.environ, env, clear=True): assert is_github_actions() is False def test_false_when_false(self): """Returns False when GITHUB_ACTIONS is 'false'.""" from local_deep_research.settings.env_registry import is_github_actions with patch.dict(os.environ, {"GITHUB_ACTIONS": "false"}): assert is_github_actions() is False class TestIsRateLimitingEnabled: """Tests for is_rate_limiting_enabled function.""" @pytest.fixture(autouse=True) def clean_env(self): """Strip both env-var forms before each test. CI exports `LDR_DISABLE_RATE_LIMITING=true`, and `patch.dict` does not clear pre-existing keys — it only adds/overrides the keys it is given. Without this fixture, the canonical var bleeds in from the outer process, short-circuits before the legacy code path, and silently breaks any test that exercises the legacy form. """ from local_deep_research.settings.env_registry import ( _reset_legacy_warning_flag_for_tests, ) env_vars = ("DISABLE_RATE_LIMITING", "LDR_DISABLE_RATE_LIMITING") original_env = {k: os.environ[k] for k in env_vars if k in os.environ} for k in env_vars: os.environ.pop(k, None) _reset_legacy_warning_flag_for_tests() yield for k in env_vars: os.environ.pop(k, None) for key, value in original_env.items(): os.environ[key] = value _reset_legacy_warning_flag_for_tests() def test_returns_bool(self): """Returns a boolean.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, ) result = is_rate_limiting_enabled() assert isinstance(result, bool) def test_enabled_by_default(self): """Rate limiting is enabled by default.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, ) env = os.environ.copy() env.pop("DISABLE_RATE_LIMITING", None) env.pop("LDR_DISABLE_RATE_LIMITING", None) with patch.dict(os.environ, env, clear=True): assert is_rate_limiting_enabled() is True def test_disabled_when_flag_true(self): """Rate limiting disabled when DISABLE_RATE_LIMITING=true.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, ) with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "true"}): assert is_rate_limiting_enabled() is False def test_disabled_when_flag_1(self): """Rate limiting disabled when DISABLE_RATE_LIMITING=1.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, ) with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "1"}): assert is_rate_limiting_enabled() is False def test_disabled_when_flag_yes(self): """Rate limiting disabled when DISABLE_RATE_LIMITING=yes.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, ) with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "yes"}): assert is_rate_limiting_enabled() is False def test_enabled_when_flag_false(self): """Rate limiting stays enabled when DISABLE_RATE_LIMITING=false.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, ) with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "false"}): assert is_rate_limiting_enabled() is True def test_case_insensitive(self): """DISABLE_RATE_LIMITING check is case-insensitive.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, ) with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "TRUE"}): assert is_rate_limiting_enabled() is False def test_legacy_form_emits_deprecation_warning_once(self, loguru_caplog): """Legacy DISABLE_RATE_LIMITING=true emits warning exactly once per process.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, _reset_legacy_warning_flag_for_tests, ) _reset_legacy_warning_flag_for_tests() try: with patch.dict(os.environ, {"DISABLE_RATE_LIMITING": "true"}): with loguru_caplog.at_level("WARNING"): is_rate_limiting_enabled() first_warnings = [ r for r in loguru_caplog.records if "DISABLE_RATE_LIMITING is deprecated" in r.getMessage() ] assert len(first_warnings) == 1, ( "Legacy form should emit deprecation warning on first call" ) loguru_caplog.clear() with loguru_caplog.at_level("WARNING"): is_rate_limiting_enabled() is_rate_limiting_enabled() repeat_warnings = [ r for r in loguru_caplog.records if "DISABLE_RATE_LIMITING is deprecated" in r.getMessage() ] assert repeat_warnings == [], ( "Deprecation warning should not re-fire after first call" ) finally: _reset_legacy_warning_flag_for_tests() def test_canonical_form_does_not_emit_deprecation_warning( self, loguru_caplog ): """LDR_DISABLE_RATE_LIMITING does not emit deprecation warning.""" from local_deep_research.settings.env_registry import ( is_rate_limiting_enabled, _reset_legacy_warning_flag_for_tests, ) _reset_legacy_warning_flag_for_tests() try: env_clean = { k: v for k, v in os.environ.items() if k != "DISABLE_RATE_LIMITING" } env_clean["LDR_DISABLE_RATE_LIMITING"] = "true" with patch.dict(os.environ, env_clean, clear=True): with loguru_caplog.at_level("WARNING"): assert is_rate_limiting_enabled() is False warnings = [ r for r in loguru_caplog.records if "deprecated" in r.getMessage() ] assert warnings == [], ( "Canonical form should not emit deprecation warning" ) finally: _reset_legacy_warning_flag_for_tests() class TestModuleExports: """Tests for module __all__ exports.""" def test_exports_registry(self): """Exports registry.""" from local_deep_research.settings.env_registry import __all__ assert "registry" in __all__ def test_exports_get_env_setting(self): """Exports get_env_setting.""" from local_deep_research.settings.env_registry import __all__ assert "get_env_setting" in __all__ def test_exports_is_test_mode(self): """Exports is_test_mode.""" from local_deep_research.settings.env_registry import __all__ assert "is_test_mode" in __all__ def test_exports_is_ci_environment(self): """Exports is_ci_environment.""" from local_deep_research.settings.env_registry import __all__ assert "is_ci_environment" in __all__ def test_exports_is_rate_limiting_enabled(self): """Exports is_rate_limiting_enabled.""" from local_deep_research.settings.env_registry import __all__ assert "is_rate_limiting_enabled" in __all__