""" Tests for InMemorySettingsManager.get_settings_snapshot() and import_settings() in api/settings_utils.py. Tests cover: - get_settings_snapshot: full format extraction, simplified format passthrough, mixed - import_settings: overwrite=True, overwrite=False, delete_extra, type handling, empty """ from unittest.mock import patch, MagicMock def _make_manager_with_settings(settings_dict): """Create an InMemorySettingsManager with pre-loaded settings (no disk I/O).""" with patch( "local_deep_research.api.settings_utils.InMemorySettingsManager.__init__", lambda self: None, ): from local_deep_research.api.settings_utils import ( InMemorySettingsManager, ) mgr = InMemorySettingsManager() mgr._settings = settings_dict.copy() mgr._base_manager = MagicMock() return mgr class TestGetSettingsSnapshot: """Tests for get_settings_snapshot().""" def test_full_format_extracts_value(self): """Dict-with-value entries → snapshot has just the value.""" mgr = _make_manager_with_settings( {"key1": {"value": 42, "ui_element": "number"}} ) snapshot = mgr.get_settings_snapshot() assert snapshot["key1"] == 42 def test_simplified_format_passthrough(self): """Non-dict or dict-without-value entries pass through as-is.""" mgr = _make_manager_with_settings({"key1": "simple_value"}) snapshot = mgr.get_settings_snapshot() assert snapshot["key1"] == "simple_value" def test_mixed_formats(self): """Mix of full and simplified formats in one snapshot.""" mgr = _make_manager_with_settings( { "full_key": {"value": True, "ui_element": "checkbox"}, "simple_key": 100, "dict_no_value": {"other": "data"}, } ) snapshot = mgr.get_settings_snapshot() assert snapshot["full_key"] is True assert snapshot["simple_key"] == 100 assert snapshot["dict_no_value"] == {"other": "data"} def test_empty_settings(self): """Empty settings → empty snapshot.""" mgr = _make_manager_with_settings({}) assert mgr.get_settings_snapshot() == {} def test_none_value_in_full_format(self): """Full format with value=None → snapshot has None.""" mgr = _make_manager_with_settings( {"key": {"value": None, "ui_element": "text"}} ) snapshot = mgr.get_settings_snapshot() assert snapshot["key"] is None def test_snapshot_is_independent_copy(self): """Modifying snapshot doesn't affect internal settings.""" mgr = _make_manager_with_settings( {"key": {"value": "original", "ui_element": "text"}} ) snapshot = mgr.get_settings_snapshot() snapshot["key"] = "modified" # Internal still has original value assert mgr._settings["key"]["value"] == "original" def test_list_value(self): """Full format with list value → snapshot has the list.""" mgr = _make_manager_with_settings( {"key": {"value": [1, 2, 3], "ui_element": "text"}} ) snapshot = mgr.get_settings_snapshot() assert snapshot["key"] == [1, 2, 3] class TestImportSettings: """Tests for import_settings().""" def test_import_overwrites_existing(self): """overwrite=True replaces existing settings.""" mgr = _make_manager_with_settings({"key1": "old_value"}) mgr.import_settings({"key1": "new_value"}, overwrite=True) assert mgr._settings["key1"] == "new_value" def test_import_no_overwrite_skips_existing(self): """overwrite=False skips keys that already exist.""" mgr = _make_manager_with_settings({"key1": "original"}) mgr.import_settings({"key1": "ignored", "key2": "new"}, overwrite=False) assert mgr._settings["key1"] == "original" assert mgr._settings["key2"] == "new" def test_import_adds_new_keys(self): """New keys are always added regardless of overwrite flag.""" mgr = _make_manager_with_settings({}) mgr.import_settings({"new_key": "value"}, overwrite=False) assert mgr._settings["new_key"] == "value" def test_delete_extra_clears_first(self): """delete_extra=True clears existing settings before importing.""" mgr = _make_manager_with_settings({"old_key": "old_value"}) mgr.import_settings({"new_key": "new_value"}, delete_extra=True) assert "old_key" not in mgr._settings assert mgr._settings["new_key"] == "new_value" def test_delete_extra_false_preserves(self): """delete_extra=False preserves existing settings.""" mgr = _make_manager_with_settings({"old_key": "old_value"}) mgr.import_settings({"new_key": "new_value"}, delete_extra=False) assert "old_key" in mgr._settings assert "new_key" in mgr._settings def test_import_full_format_with_type_conversion(self): """Full format dicts get _get_typed_value applied.""" mgr = _make_manager_with_settings({}) mgr._get_typed_value = MagicMock(return_value=42) mgr.import_settings( {"key": {"value": "42", "ui_element": "number"}}, overwrite=True ) mgr._get_typed_value.assert_called() # Value should be the typed result assert mgr._settings["key"]["value"] == 42 def test_import_simple_value_no_type_conversion(self): """Simple (non-dict) values are stored as-is without type conversion.""" mgr = _make_manager_with_settings({}) mgr._get_typed_value = MagicMock() mgr.import_settings({"key": "plain_string"}, overwrite=True) mgr._get_typed_value.assert_not_called() assert mgr._settings["key"] == "plain_string" def test_import_empty_dict(self): """Importing empty dict changes nothing.""" mgr = _make_manager_with_settings({"existing": "value"}) mgr.import_settings({}) assert mgr._settings["existing"] == "value"