Files
wehub-resource-sync 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
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

343 lines
13 KiB
Python

"""Tests for API settings utilities."""
from unittest.mock import patch
from local_deep_research.api.settings_utils import (
InMemorySettingsManager,
get_default_settings_snapshot,
create_settings_snapshot,
extract_setting_value,
)
class TestInMemorySettingsManager:
"""Tests for InMemorySettingsManager class."""
def test_init_loads_defaults(self):
"""Test that initialization loads default settings."""
with patch.object(
InMemorySettingsManager, "_load_defaults"
) as mock_load:
InMemorySettingsManager()
mock_load.assert_called_once()
def test_get_setting_existing_key(self):
"""Test getting an existing setting."""
manager = InMemorySettingsManager()
# llm.provider should be in defaults
value = manager.get_setting("llm.provider")
assert value is not None
def test_get_setting_missing_key_returns_default(self):
"""Test getting a missing setting returns the default."""
manager = InMemorySettingsManager()
value = manager.get_setting("nonexistent.key", default="default_value")
assert value == "default_value"
def test_get_setting_none_default(self):
"""Test getting a missing setting with None default."""
manager = InMemorySettingsManager()
value = manager.get_setting("nonexistent.key")
assert value is None
def test_set_setting_existing_key(self):
"""Test setting an existing key."""
manager = InMemorySettingsManager()
result = manager.set_setting("llm.provider", "openai")
assert result is True
assert manager.get_setting("llm.provider") == "openai"
def test_set_setting_nonexistent_key(self):
"""Test setting a nonexistent key returns False."""
manager = InMemorySettingsManager()
result = manager.set_setting("nonexistent.key", "value")
assert result is False
def test_get_all_settings_returns_dict(self):
"""Test get_all_settings returns a dictionary."""
manager = InMemorySettingsManager()
settings = manager.get_all_settings()
assert isinstance(settings, dict)
assert len(settings) > 0
def test_get_all_settings_returns_copy(self):
"""Test get_all_settings returns a deep copy."""
manager = InMemorySettingsManager()
settings1 = manager.get_all_settings()
settings2 = manager.get_all_settings()
assert settings1 is not settings2
def test_create_or_update_setting_with_dict(self):
"""Test creating a setting from a dict."""
manager = InMemorySettingsManager()
setting = {
"key": "new.setting",
"value": "test_value",
"ui_element": "text",
}
result = manager.create_or_update_setting(setting)
assert result is not None
assert manager.get_setting("new.setting") == "test_value"
def test_create_or_update_setting_without_key(self):
"""Test creating a setting without key returns None."""
manager = InMemorySettingsManager()
result = manager.create_or_update_setting({"value": "test"})
assert result is None
def test_delete_setting_existing(self):
"""Test deleting an existing setting."""
manager = InMemorySettingsManager()
# First ensure it exists
manager.create_or_update_setting(
{"key": "temp.setting", "value": "temp", "ui_element": "text"}
)
assert manager.get_setting("temp.setting") == "temp"
result = manager.delete_setting("temp.setting")
assert result is True
assert manager.get_setting("temp.setting") is None
def test_delete_setting_nonexistent(self):
"""Test deleting a nonexistent setting returns False."""
manager = InMemorySettingsManager()
result = manager.delete_setting("nonexistent.key")
assert result is False
def test_import_settings_basic(self):
"""Test importing settings."""
manager = InMemorySettingsManager()
new_settings = {
"imported.setting": {
"value": "imported_value",
"ui_element": "text",
},
}
manager.import_settings(new_settings)
assert manager.get_setting("imported.setting") == "imported_value"
def test_import_settings_with_delete_extra(self):
"""Test importing with delete_extra clears existing settings."""
manager = InMemorySettingsManager()
original_count = len(manager.get_all_settings())
assert original_count > 0
manager.import_settings(
{"only.setting": {"value": "only", "ui_element": "text"}},
delete_extra=True,
)
settings = manager.get_all_settings()
assert len(settings) == 1
assert "only.setting" in settings
def test_import_settings_no_overwrite(self):
"""Test importing without overwriting existing settings."""
manager = InMemorySettingsManager()
manager.create_or_update_setting(
{"key": "existing", "value": "original", "ui_element": "text"}
)
manager.import_settings(
{"existing": {"value": "new_value", "ui_element": "text"}},
overwrite=False,
)
assert manager.get_setting("existing") == "original"
def test_get_typed_value_checkbox(self):
"""Test type conversion for checkbox."""
manager = InMemorySettingsManager()
setting_data = {"ui_element": "checkbox"}
assert manager._get_typed_value(setting_data, "true") is True
assert manager._get_typed_value(setting_data, "false") is False
assert manager._get_typed_value(setting_data, "1") is True
assert manager._get_typed_value(setting_data, "yes") is True
def test_get_typed_value_number(self):
"""Test type conversion for number."""
manager = InMemorySettingsManager()
setting_data = {"ui_element": "number"}
assert manager._get_typed_value(setting_data, "42") == 42.0
assert manager._get_typed_value(setting_data, "3.14") == 3.14
def test_get_typed_value_text(self):
"""Test type conversion for text."""
manager = InMemorySettingsManager()
setting_data = {"ui_element": "text"}
assert manager._get_typed_value(setting_data, 123) == "123"
assert manager._get_typed_value(setting_data, "hello") == "hello"
def test_get_typed_value_unknown_type(self):
"""Test type conversion for unknown ui_element returns as-is."""
manager = InMemorySettingsManager()
setting_data = {"ui_element": "unknown_type"}
result = manager._get_typed_value(setting_data, "value")
assert result == "value"
def test_load_from_defaults_file(self):
"""Test that load_from_defaults_file reloads defaults."""
manager = InMemorySettingsManager()
# Modify a setting
manager.set_setting("llm.provider", "modified")
assert manager.get_setting("llm.provider") == "modified"
# Reload defaults
manager.load_from_defaults_file()
# Should be back to default
# (exact value depends on defaults file)
def test_env_var_override(self, monkeypatch):
"""Test that environment variables override defaults."""
monkeypatch.setenv("LDR_LLM_PROVIDER", "env_provider")
InMemorySettingsManager()
# Check if env var was applied (depends on implementation)
class TestGetDefaultSettingsSnapshot:
"""Tests for get_default_settings_snapshot function."""
def test_returns_dict(self):
"""Test that function returns a dictionary."""
snapshot = get_default_settings_snapshot()
assert isinstance(snapshot, dict)
def test_contains_core_settings(self):
"""Test that snapshot contains core settings."""
snapshot = get_default_settings_snapshot()
# Check for some expected keys
assert "llm.provider" in snapshot
assert "llm.temperature" in snapshot or "llm.model" in snapshot
def test_settings_have_value_key(self):
"""Test that settings have a 'value' key."""
snapshot = get_default_settings_snapshot()
for key, setting in snapshot.items():
if isinstance(setting, dict):
assert "value" in setting, f"Setting {key} missing 'value' key"
class TestCreateSettingsSnapshot:
"""Tests for create_settings_snapshot function."""
def test_returns_dict(self):
"""Test that function returns a dictionary."""
snapshot = create_settings_snapshot()
assert isinstance(snapshot, dict)
def test_without_overrides(self):
"""Test creating snapshot without overrides uses defaults."""
snapshot = create_settings_snapshot()
assert len(snapshot) > 0
def test_with_overrides_dict(self):
"""Test creating snapshot with overrides dict."""
snapshot = create_settings_snapshot(
overrides={"llm.provider": "openai"}
)
assert snapshot["llm.provider"]["value"] == "openai"
def test_with_overrides_as_first_arg(self):
"""Test creating snapshot with overrides as first positional arg."""
snapshot = create_settings_snapshot({"llm.provider": "anthropic"})
assert snapshot["llm.provider"]["value"] == "anthropic"
def test_with_custom_base_settings(self):
"""Test creating snapshot with custom base settings."""
base = {"custom.setting": {"value": "base_value", "ui_element": "text"}}
snapshot = create_settings_snapshot(base_settings=base)
assert "custom.setting" in snapshot
assert snapshot["custom.setting"]["value"] == "base_value"
def test_override_unknown_key(self):
"""Test overriding with unknown key creates new entry."""
snapshot = create_settings_snapshot(
overrides={"new.unknown.key": "new_value"}
)
assert "new.unknown.key" in snapshot
assert snapshot["new.unknown.key"]["value"] == "new_value"
def test_provider_kwarg(self):
"""Test provider kwarg shortcut."""
snapshot = create_settings_snapshot(provider="openai")
assert snapshot["llm.provider"]["value"] == "openai"
def test_provider_with_api_key_kwarg(self):
"""Test provider and api_key kwargs together."""
snapshot = create_settings_snapshot(
provider="openai", api_key="sk-test-key"
)
assert snapshot["llm.provider"]["value"] == "openai"
assert "llm.openai.api_key" in snapshot
assert snapshot["llm.openai.api_key"]["value"] == "sk-test-key"
def test_temperature_kwarg(self):
"""Test temperature kwarg shortcut."""
snapshot = create_settings_snapshot(temperature=0.5)
assert snapshot["llm.temperature"]["value"] == 0.5
def test_max_search_results_kwarg(self):
"""Test max_search_results kwarg shortcut."""
snapshot = create_settings_snapshot(max_search_results=50)
assert snapshot["search.max_results"]["value"] == 50
def test_infer_ui_element_bool(self):
"""Test ui_element inference for boolean values."""
snapshot = create_settings_snapshot(overrides={"new.bool": True})
assert snapshot["new.bool"]["ui_element"] == "checkbox"
def test_infer_ui_element_number(self):
"""Test ui_element inference for numeric values."""
snapshot = create_settings_snapshot(overrides={"new.number": 42})
assert snapshot["new.number"]["ui_element"] == "number"
def test_infer_ui_element_dict(self):
"""Test ui_element inference for dict values."""
snapshot = create_settings_snapshot(
overrides={"new.dict": {"nested": "value"}}
)
assert snapshot["new.dict"]["ui_element"] == "json"
class TestExtractSettingValue:
"""Tests for extract_setting_value function."""
def test_extract_with_value_key(self):
"""Test extracting value from dict with 'value' key."""
snapshot = {"test.key": {"value": "test_value"}}
result = extract_setting_value(snapshot, "test.key")
assert result == "test_value"
def test_extract_direct_value(self):
"""Test extracting direct value (not dict)."""
snapshot = {"test.key": "direct_value"}
result = extract_setting_value(snapshot, "test.key")
assert result == "direct_value"
def test_extract_missing_key(self):
"""Test extracting missing key returns default."""
snapshot = {"other.key": {"value": "value"}}
result = extract_setting_value(
snapshot, "missing.key", default="default"
)
assert result == "default"
def test_extract_from_none_snapshot(self):
"""Test extracting from None snapshot returns default."""
result = extract_setting_value(None, "any.key", default="default")
assert result == "default"
def test_extract_default_none(self):
"""Test default value is None when not specified."""
snapshot = {}
result = extract_setting_value(snapshot, "missing.key")
assert result is None
def test_extract_nested_dict_value(self):
"""Test extracting value that is itself a dict."""
snapshot = {"complex.key": {"value": {"nested": "data"}}}
result = extract_setting_value(snapshot, "complex.key")
assert result == {"nested": "data"}