7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
687 lines
26 KiB
Python
687 lines
26 KiB
Python
"""
|
|
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}"
|
|
)
|