""" Comprehensive tests for boolean centralization feature. This module tests the centralized boolean handling functionality: 1. to_bool() utility function from settings_utils.py 2. extract_bool_setting() from settings_utils.py 3. get_bool_setting_from_snapshot() from thread_settings.py 4. get_bool_setting() method on SettingsManager """ import pytest from unittest.mock import patch from local_deep_research.api.settings_utils import ( to_bool, extract_bool_setting, ) from local_deep_research.config.thread_settings import ( get_bool_setting_from_snapshot, ) from local_deep_research.settings.manager import ( SettingsManager, ) class TestToBoolUtility: """Test the to_bool() utility function.""" def test_boolean_true_passthrough(self): """Test that boolean True passes through unchanged.""" assert to_bool(True) is True def test_boolean_false_passthrough(self): """Test that boolean False passes through unchanged.""" assert to_bool(False) is False def test_none_with_default_false(self): """Test that None returns default value (False).""" assert to_bool(None) is False def test_none_with_default_true(self): """Test that None returns custom default value (True).""" assert to_bool(None, default=True) is True # Truthy string values @pytest.mark.parametrize( "value", [ "true", "True", "TRUE", "TrUe", # Mixed case "1", "yes", "Yes", "YES", "YeS", # Mixed case "on", "On", "ON", "enabled", "Enabled", "ENABLED", "EnAbLeD", # Mixed case ], ) def test_truthy_strings(self, value): """Test various truthy string representations return True.""" assert to_bool(value) is True # Falsy string values @pytest.mark.parametrize( "value", [ "false", "False", "FALSE", "0", "no", "No", "NO", "off", "Off", "OFF", "disabled", "", # Empty string "random", # Random string not in truthy list "2", # Not "1" "truth", # Not exactly "true" "enabled_partially", # Contains "enabled" but not exact ], ) def test_falsy_strings(self, value): """Test various falsy string representations return False.""" assert to_bool(value) is False # Whitespace handling def test_empty_string_is_false(self): """Test that empty string returns False.""" assert to_bool("") is False def test_whitespace_only_string_is_false(self): """Test that whitespace-only strings return False.""" # Note: The implementation doesn't strip whitespace, # so these should be False (not in truthy list) assert to_bool(" ") is False assert to_bool("\t") is False assert to_bool("\n") is False def test_string_with_leading_whitespace_is_true(self): """Test that strings with leading/trailing whitespace still match.""" # to_bool strips whitespace before matching (handles env var quirks) assert to_bool(" true") is True assert to_bool("true ") is True assert to_bool(" yes ") is True # Numeric values def test_integer_zero_is_false(self): """Test that integer 0 returns False.""" assert to_bool(0) is False def test_integer_one_is_true(self): """Test that integer 1 returns True.""" assert to_bool(1) is True def test_positive_integer_is_true(self): """Test that positive integers return True.""" assert to_bool(42) is True assert to_bool(1000) is True def test_negative_integer_is_true(self): """Test that negative integers return True.""" assert to_bool(-1) is True assert to_bool(-42) is True def test_float_zero_is_false(self): """Test that float 0.0 returns False.""" assert to_bool(0.0) is False def test_nonzero_float_is_true(self): """Test that non-zero floats return True.""" assert to_bool(3.14) is True assert to_bool(-2.71) is True # Collection types def test_empty_list_is_false(self): """Test that empty list returns False.""" assert to_bool([]) is False def test_nonempty_list_is_true(self): """Test that non-empty list returns True.""" assert to_bool([1, 2, 3]) is True assert to_bool(["false"]) is True def test_empty_dict_is_false(self): """Test that empty dict returns False.""" assert to_bool({}) is False def test_nonempty_dict_is_true(self): """Test that non-empty dict returns True.""" assert to_bool({"key": "value"}) is True def test_empty_tuple_is_false(self): """Test that empty tuple returns False.""" assert to_bool(()) is False def test_nonempty_tuple_is_true(self): """Test that non-empty tuple returns True.""" assert to_bool((1, 2)) is True # Edge cases def test_returns_actual_bool_not_truthy(self): """Test that return value is actual bool, not just truthy.""" result = to_bool("true") assert result is True assert isinstance(result, bool) result = to_bool("false") assert result is False assert isinstance(result, bool) def test_case_sensitivity(self): """Test that string comparison is case-insensitive via .lower().""" # These should all return True assert to_bool("TRUE") is True assert to_bool("TrUe") is True assert to_bool("YES") is True assert to_bool("YeS") is True def test_default_parameter_default_value(self): """Test that default parameter defaults to False.""" # When value is None and no default specified assert to_bool(None) is False class TestExtractBoolSetting: """Test the extract_bool_setting() function.""" def test_extract_from_dict_with_value_key(self): """Test extracting boolean from dict with 'value' key.""" snapshot = {"setting.key": {"value": "true"}} assert extract_bool_setting(snapshot, "setting.key") is True def test_extract_from_dict_with_direct_value(self): """Test extracting boolean from dict with direct value.""" snapshot = {"setting.key": "yes"} assert extract_bool_setting(snapshot, "setting.key") is True def test_extract_from_dict_with_boolean_value(self): """Test extracting boolean that's already a bool.""" snapshot = {"setting.key": {"value": True}} assert extract_bool_setting(snapshot, "setting.key") is True def test_extract_missing_key_uses_default_false(self): """Test that missing key returns default (False).""" snapshot = {"other.key": "true"} assert extract_bool_setting(snapshot, "missing.key") is False def test_extract_missing_key_uses_custom_default(self): """Test that missing key returns custom default value.""" snapshot = {"other.key": "true"} assert ( extract_bool_setting(snapshot, "missing.key", default=True) is True ) def test_extract_none_snapshot(self): """Test extracting from None snapshot returns default.""" assert extract_bool_setting(None, "any.key") is False assert extract_bool_setting(None, "any.key", default=True) is True def test_extract_empty_snapshot(self): """Test extracting from empty snapshot returns default.""" assert extract_bool_setting({}, "any.key") is False def test_extract_truthy_string_values(self): """Test extracting various truthy string values.""" snapshot = { "setting1": {"value": "true"}, "setting2": {"value": "1"}, "setting3": {"value": "yes"}, "setting4": {"value": "on"}, "setting5": {"value": "enabled"}, } assert extract_bool_setting(snapshot, "setting1") is True assert extract_bool_setting(snapshot, "setting2") is True assert extract_bool_setting(snapshot, "setting3") is True assert extract_bool_setting(snapshot, "setting4") is True assert extract_bool_setting(snapshot, "setting5") is True def test_extract_falsy_string_values(self): """Test extracting various falsy string values.""" snapshot = { "setting1": {"value": "false"}, "setting2": {"value": "0"}, "setting3": {"value": "no"}, "setting4": {"value": ""}, "setting5": {"value": "random"}, } assert extract_bool_setting(snapshot, "setting1") is False assert extract_bool_setting(snapshot, "setting2") is False assert extract_bool_setting(snapshot, "setting3") is False assert extract_bool_setting(snapshot, "setting4") is False assert extract_bool_setting(snapshot, "setting5") is False def test_extract_with_numeric_values(self): """Test extracting numeric values.""" snapshot = { "zero": {"value": 0}, "one": {"value": 1}, "positive": {"value": 42}, } assert extract_bool_setting(snapshot, "zero") is False assert extract_bool_setting(snapshot, "one") is True assert extract_bool_setting(snapshot, "positive") is True class TestGetBoolSettingFromSnapshot: """Test the get_bool_setting_from_snapshot() function.""" def test_get_from_snapshot_with_value_key(self): """Test getting boolean from snapshot with 'value' key.""" snapshot = {"test.setting": {"value": "true"}} result = get_bool_setting_from_snapshot( "test.setting", settings_snapshot=snapshot ) assert result is True def test_get_from_snapshot_with_direct_value(self): """Test getting boolean from snapshot with direct value.""" snapshot = {"test.setting": "yes"} result = get_bool_setting_from_snapshot( "test.setting", settings_snapshot=snapshot ) assert result is True def test_get_from_snapshot_with_boolean_value(self): """Test getting boolean that's already a bool.""" snapshot = {"test.setting": True} result = get_bool_setting_from_snapshot( "test.setting", settings_snapshot=snapshot ) assert result is True def test_get_missing_key_uses_default_false(self): """Test that missing key returns default (False).""" snapshot = {"other.setting": "true"} result = get_bool_setting_from_snapshot( "missing.key", settings_snapshot=snapshot ) assert result is False def test_get_missing_key_uses_custom_default(self): """Test that missing key returns custom default value.""" snapshot = {"other.setting": "true"} result = get_bool_setting_from_snapshot( "missing.key", default=True, settings_snapshot=snapshot ) assert result is True def test_get_with_none_snapshot_uses_default(self): """Test that None snapshot with default doesn't raise error.""" # When settings_snapshot is None and default is provided result = get_bool_setting_from_snapshot( "any.key", default=True, settings_snapshot=None ) assert result is True def test_get_truthy_string_values(self): """Test getting various truthy string values.""" snapshot = { "s1": "true", "s2": "1", "s3": "yes", "s4": "on", "s5": "enabled", } assert ( get_bool_setting_from_snapshot("s1", settings_snapshot=snapshot) is True ) assert ( get_bool_setting_from_snapshot("s2", settings_snapshot=snapshot) is True ) assert ( get_bool_setting_from_snapshot("s3", settings_snapshot=snapshot) is True ) assert ( get_bool_setting_from_snapshot("s4", settings_snapshot=snapshot) is True ) assert ( get_bool_setting_from_snapshot("s5", settings_snapshot=snapshot) is True ) def test_get_falsy_string_values(self): """Test getting various falsy string values.""" snapshot = { "s1": "false", "s2": "0", "s3": "no", "s4": "off", "s5": "", } assert ( get_bool_setting_from_snapshot("s1", settings_snapshot=snapshot) is False ) assert ( get_bool_setting_from_snapshot("s2", settings_snapshot=snapshot) is False ) assert ( get_bool_setting_from_snapshot("s3", settings_snapshot=snapshot) is False ) assert ( get_bool_setting_from_snapshot("s4", settings_snapshot=snapshot) is False ) assert ( get_bool_setting_from_snapshot("s5", settings_snapshot=snapshot) is False ) def test_get_with_none_value_uses_default(self): """Test that None value returns default.""" snapshot = {"test.setting": None} result = get_bool_setting_from_snapshot( "test.setting", default=True, settings_snapshot=snapshot ) assert result is True def test_get_with_numeric_values(self): """Test getting numeric values.""" snapshot = {"zero": 0, "one": 1, "positive": 42} assert ( get_bool_setting_from_snapshot("zero", settings_snapshot=snapshot) is False ) assert ( get_bool_setting_from_snapshot("one", settings_snapshot=snapshot) is True ) assert ( get_bool_setting_from_snapshot( "positive", settings_snapshot=snapshot ) is True ) def test_backward_compatibility_username_parameter(self): """Test that username parameter is accepted (for backward compatibility).""" snapshot = {"test.setting": "true"} # Should not raise an error even though username is unused result = get_bool_setting_from_snapshot( "test.setting", username="testuser", settings_snapshot=snapshot ) assert result is True class TestSettingsManagerGetBoolSetting: """Test the get_bool_setting() method on SettingsManager.""" def test_get_bool_setting_with_boolean_true(self): """Test getting a setting that's already boolean True.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=True): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_with_boolean_false(self): """Test getting a setting that's already boolean False.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=False): result = manager.get_bool_setting("test.key") assert result is False def test_get_bool_setting_with_string_true(self): """Test getting a setting with string 'true'.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="true"): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_with_string_false(self): """Test getting a setting with string 'false'.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="false"): result = manager.get_bool_setting("test.key") assert result is False def test_get_bool_setting_with_string_yes(self): """Test getting a setting with string 'yes'.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="yes"): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_with_string_one(self): """Test getting a setting with string '1'.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="1"): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_with_string_on(self): """Test getting a setting with string 'on'.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="on"): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_with_string_enabled(self): """Test getting a setting with string 'enabled'.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="enabled"): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_with_none_uses_default_false(self): """Test that None value returns default (False).""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=None): result = manager.get_bool_setting("test.key") assert result is False def test_get_bool_setting_with_none_uses_custom_default(self): """Test that None value returns custom default.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=None): result = manager.get_bool_setting("test.key", default=True) assert result is True def test_get_bool_setting_with_integer_zero(self): """Test getting a setting with integer 0.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=0): result = manager.get_bool_setting("test.key") assert result is False def test_get_bool_setting_with_integer_one(self): """Test getting a setting with integer 1.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=1): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_with_positive_integer(self): """Test getting a setting with positive integer.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=42): result = manager.get_bool_setting("test.key") assert result is True def test_get_bool_setting_passes_check_env_true(self): """Test that check_env=True is passed to get_setting.""" manager = SettingsManager(db_session=None) with patch.object( manager, "get_setting", return_value=True ) as mock_get: manager.get_bool_setting("test.key", check_env=True) mock_get.assert_called_once_with("test.key", False, True) def test_get_bool_setting_passes_check_env_false(self): """Test that check_env=False is passed to get_setting.""" manager = SettingsManager(db_session=None) with patch.object( manager, "get_setting", return_value=True ) as mock_get: manager.get_bool_setting("test.key", check_env=False) mock_get.assert_called_once_with("test.key", False, False) def test_get_bool_setting_passes_custom_default(self): """Test that custom default is passed to get_setting.""" manager = SettingsManager(db_session=None) with patch.object( manager, "get_setting", return_value=None ) as mock_get: manager.get_bool_setting("test.key", default=True) mock_get.assert_called_once_with("test.key", True, True) def test_get_bool_setting_with_empty_string(self): """Test getting a setting with empty string.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=""): result = manager.get_bool_setting("test.key") assert result is False def test_get_bool_setting_with_random_string(self): """Test getting a setting with random string (not in truthy list).""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="random"): result = manager.get_bool_setting("test.key") assert result is False def test_get_bool_setting_case_insensitive(self): """Test that string comparison is case-insensitive.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="TRUE"): assert manager.get_bool_setting("test.key") is True with patch.object(manager, "get_setting", return_value="YES"): assert manager.get_bool_setting("test.key") is True with patch.object(manager, "get_setting", return_value="ON"): assert manager.get_bool_setting("test.key") is True def test_get_bool_setting_with_list(self): """Test getting a setting with list value.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=[]): assert manager.get_bool_setting("test.key") is False with patch.object(manager, "get_setting", return_value=[1, 2, 3]): assert manager.get_bool_setting("test.key") is True def test_get_bool_setting_with_dict(self): """Test getting a setting with dict value.""" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value={}): assert manager.get_bool_setting("test.key") is False with patch.object( manager, "get_setting", return_value={"key": "value"} ): assert manager.get_bool_setting("test.key") is True class TestBooleanCentralizationIntegration: """Integration tests for the boolean centralization feature.""" def test_consistency_across_all_methods(self): """Test that all boolean methods return consistent results.""" # Test with string "true" assert to_bool("true") is True assert extract_bool_setting({"key": "true"}, "key") is True assert ( get_bool_setting_from_snapshot( "key", settings_snapshot={"key": "true"} ) is True ) manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value="true"): assert manager.get_bool_setting("key") is True def test_consistency_with_boolean_values(self): """Test consistency when passing actual boolean values.""" assert to_bool(True) is True assert extract_bool_setting({"key": True}, "key") is True assert ( get_bool_setting_from_snapshot( "key", settings_snapshot={"key": True} ) is True ) manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=True): assert manager.get_bool_setting("key") is True def test_consistency_with_none_and_defaults(self): """Test consistency when handling None with defaults.""" assert to_bool(None, default=True) is True assert extract_bool_setting({"key": None}, "key", default=True) is True assert ( get_bool_setting_from_snapshot( "key", default=True, settings_snapshot={"key": None} ) is True ) manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=None): assert manager.get_bool_setting("key", default=True) is True def test_all_truthy_strings_consistent(self): """Test that all truthy strings work consistently across methods.""" truthy_values = ["true", "1", "yes", "on", "enabled"] for value in truthy_values: assert to_bool(value) is True, f"to_bool failed for {value}" assert extract_bool_setting({"k": value}, "k") is True, ( f"extract_bool_setting failed for {value}" ) assert ( get_bool_setting_from_snapshot( "k", settings_snapshot={"k": value} ) is True ), f"get_bool_setting_from_snapshot failed for {value}" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=value): assert manager.get_bool_setting("k") is True, ( f"get_bool_setting failed for {value}" ) def test_all_falsy_strings_consistent(self): """Test that all falsy strings work consistently across methods.""" falsy_values = ["false", "0", "no", "off", ""] for value in falsy_values: assert to_bool(value) is False, f"to_bool failed for {value}" assert extract_bool_setting({"k": value}, "k") is False, ( f"extract_bool_setting failed for {value}" ) assert ( get_bool_setting_from_snapshot( "k", settings_snapshot={"k": value} ) is False ), f"get_bool_setting_from_snapshot failed for {value}" manager = SettingsManager(db_session=None) with patch.object(manager, "get_setting", return_value=value): assert manager.get_bool_setting("k") is False, ( f"get_bool_setting failed for {value}" )