"""Test environment variable auto-generation and external variables.""" import os import sys from unittest.mock import patch import pytest from local_deep_research.settings.env_settings import ( BooleanSetting, StringSetting, IntegerSetting, PathSetting, SecretSetting, EnumSetting, ) class TestEnvVarAutoGeneration: """Test that environment variable names are auto-generated correctly.""" def test_simple_key_generation(self): """Test basic key to env var conversion.""" test_cases = [ ("testing.test_mode", "LDR_TESTING_TEST_MODE"), ("bootstrap.data_dir", "LDR_BOOTSTRAP_DATA_DIR"), ("db_config.cache_size", "LDR_DB_CONFIG_CACHE_SIZE"), ("app.debug", "LDR_APP_DEBUG"), ("search.max_results", "LDR_SEARCH_MAX_RESULTS"), ] for key, expected_env_var in test_cases: setting = StringSetting(key, "Test description") assert setting.env_var == expected_env_var, f"Failed for key: {key}" def test_all_setting_types_generate_correctly(self): """Test that all setting types auto-generate env vars.""" settings = [ BooleanSetting("test.bool", "Bool setting"), StringSetting("test.string", "String setting"), IntegerSetting("test.int", "Int setting"), PathSetting("test.path", "Path setting"), SecretSetting("test.secret", "Secret setting"), EnumSetting("test.enum", "Enum setting", allowed_values={"A", "B"}), ] for setting in settings: assert setting.env_var.startswith("LDR_TEST_") assert ( setting.env_var == f"LDR_TEST_{setting.key.split('.')[-1].upper()}" ) def test_no_duplicate_env_vars_in_registry(self): """Test that all registered settings have unique env vars.""" from local_deep_research.settings.env_registry import registry all_env_vars = [] for key in registry.list_all_settings(): env_var = registry.get_env_var(key) if env_var: all_env_vars.append(env_var) # Check for duplicates assert len(all_env_vars) == len(set(all_env_vars)), ( "Duplicate env vars found!" ) def test_env_var_reading(self): """Test that settings correctly read from environment.""" test_env_var = "LDR_TEST_SETTING" test_value = "test_value_123" with patch.dict(os.environ, {test_env_var: test_value}): setting = StringSetting("test.setting", "Test") assert setting.get_value() == test_value def test_boolean_conversion(self): """Test boolean environment variable conversion.""" setting = BooleanSetting("test.flag", "Test flag") test_cases = [ ("true", True), ("True", True), ("TRUE", True), ("1", True), ("yes", True), ("false", False), ("False", False), ("0", False), ("no", False), ("", False), ] for env_value, expected in test_cases: with patch.dict(os.environ, {"LDR_TEST_FLAG": env_value}): assert setting.get_value() == expected, ( f"Failed for value: {env_value}" ) @pytest.fixture def restore_testing_env_module(): """Put back the pre-test env_definitions.testing module. The external-vars tests delete the module and re-import it under a patched environment; without a restore, the module (and its CI/GITHUB_ACTIONS/TESTING constants) would stay baked with the last test's patched values for the rest of the process. """ name = "local_deep_research.settings.env_definitions.testing" saved = sys.modules.get(name) yield sys.modules.pop(name, None) parent = sys.modules.get("local_deep_research.settings.env_definitions") if saved is not None: sys.modules[name] = saved if parent is not None: parent.testing = saved elif parent is not None and hasattr(parent, "testing"): delattr(parent, "testing") class TestExternalEnvVars: """Test external environment variables (CI, GITHUB_ACTIONS, etc.).""" def test_external_vars_are_booleans(self): """Test that external vars are properly converted to booleans.""" from local_deep_research.settings.env_definitions.testing import ( CI, GITHUB_ACTIONS, TESTING, ) # They should be booleans assert isinstance(CI, bool) assert isinstance(GITHUB_ACTIONS, bool) assert isinstance(TESTING, bool) def test_external_vars_respond_to_environment( self, restore_testing_env_module ): """Test that external vars read from environment correctly.""" # We need to reimport the module after changing env vars with patch.dict( os.environ, {"CI": "true", "GITHUB_ACTIONS": "1", "TESTING": "yes"} ): # Clear the module from cache and reimport if ( "local_deep_research.settings.env_definitions.testing" in sys.modules ): del sys.modules[ "local_deep_research.settings.env_definitions.testing" ] from local_deep_research.settings.env_definitions.testing import ( CI, GITHUB_ACTIONS, TESTING, ) assert CI is True assert GITHUB_ACTIONS is True assert TESTING is True def test_external_vars_default_to_false(self, restore_testing_env_module): """Test that external vars default to False when not set.""" with patch.dict(os.environ, {}, clear=True): # Clear and reimport if ( "local_deep_research.settings.env_definitions.testing" in sys.modules ): del sys.modules[ "local_deep_research.settings.env_definitions.testing" ] from local_deep_research.settings.env_definitions.testing import ( CI, GITHUB_ACTIONS, TESTING, ) assert CI is False assert GITHUB_ACTIONS is False assert TESTING is False class TestBackwardCompatibility: """Test that the refactoring maintains backward compatibility.""" def test_expected_env_var_names(self): """Test that common env vars still map to expected names.""" from local_deep_research.settings.env_registry import registry # These are the env vars that existing code might depend on expected_mappings = [ ("testing.test_mode", "LDR_TESTING_TEST_MODE"), ("bootstrap.encryption_key", "LDR_BOOTSTRAP_ENCRYPTION_KEY"), ("bootstrap.database_url", "LDR_BOOTSTRAP_DATABASE_URL"), ("bootstrap.data_dir", "LDR_BOOTSTRAP_DATA_DIR"), ("db_config.cache_size_mb", "LDR_DB_CONFIG_CACHE_SIZE_MB"), ] for key, expected_env_var in expected_mappings: actual = registry.get_env_var(key) assert actual == expected_env_var, ( f"Backward compatibility broken for {key}" )