"""High-value tests for utilities/llm_utils.py - LLM URL Resolution.""" from unittest.mock import patch from local_deep_research.utilities.llm_utils import ( get_ollama_base_url, get_server_url, ) # --------------------------------------------------------------------------- # get_ollama_base_url() # --------------------------------------------------------------------------- class TestGetOllamaBaseUrl: """Ollama base URL fallback chain.""" @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") @patch( "local_deep_research.utilities.url_utils.normalize_url", side_effect=lambda x: x, ) def test_embeddings_url_takes_priority(self, mock_normalize, mock_get): mock_get.side_effect = ( lambda key, default=None, settings_snapshot=None: ( "http://ollama-embed:11434" if key == "embeddings.ollama.url" else default ) ) result = get_ollama_base_url() assert result == "http://ollama-embed:11434" @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") @patch( "local_deep_research.utilities.url_utils.normalize_url", side_effect=lambda x: x, ) def test_llm_url_fallback(self, mock_normalize, mock_get): def side_effect(key, default=None, settings_snapshot=None): if key == "embeddings.ollama.url": return default # not set if key == "llm.ollama.url": return "http://ollama-llm:11434" return default mock_get.side_effect = side_effect result = get_ollama_base_url() assert result == "http://ollama-llm:11434" @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") @patch( "local_deep_research.utilities.url_utils.normalize_url", side_effect=lambda x: x, ) def test_default_localhost(self, mock_normalize, mock_get): mock_get.side_effect = ( lambda key, default=None, settings_snapshot=None: default ) result = get_ollama_base_url() assert result == "http://localhost:11434" @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") @patch( "local_deep_research.utilities.url_utils.normalize_url", side_effect=lambda x: x, ) def test_settings_snapshot_passed_through(self, mock_normalize, mock_get): snapshot = {"embeddings": {"ollama": {"url": "http://custom:1234"}}} mock_get.side_effect = ( lambda key, default=None, settings_snapshot=None: default ) get_ollama_base_url(settings_snapshot=snapshot) # Verify snapshot is passed to every get_setting_from_snapshot call for call in mock_get.call_args_list: assert call.kwargs.get("settings_snapshot") == snapshot @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") @patch( "local_deep_research.utilities.url_utils.normalize_url", side_effect=lambda x: x, ) def test_normalize_url_called(self, mock_normalize, mock_get): mock_get.side_effect = ( lambda key, default=None, settings_snapshot=None: ( "http://host:1234/" if key == "embeddings.ollama.url" else default ) ) get_ollama_base_url() mock_normalize.assert_called_once_with("http://host:1234/") @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") def test_none_url_returns_default(self, mock_get): """If the resolved URL is None/empty, fall back to localhost.""" mock_get.side_effect = ( lambda key, default=None, settings_snapshot=None: None ) result = get_ollama_base_url() assert result == "http://localhost:11434" # --------------------------------------------------------------------------- # get_server_url() # --------------------------------------------------------------------------- class TestGetServerUrl: """Server URL multi-source fallback chain.""" def test_no_snapshot_returns_default(self): result = get_server_url(settings_snapshot=None) assert result == "http://127.0.0.1:5000/" def test_direct_server_url_in_snapshot(self): snapshot = {"server_url": "https://myserver.com:8080/"} result = get_server_url(settings_snapshot=snapshot) assert result == "https://myserver.com:8080/" def test_system_server_url_fallback(self): snapshot = {"system": {"server_url": "https://system-server.com/"}} result = get_server_url(settings_snapshot=snapshot) assert result == "https://system-server.com/" @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") def test_construct_from_host_port_https(self, mock_get): def side_effect(key, default_val=None, default=None): mapping = { "web.host": "192.168.1.100", "web.port": 8443, "web.use_https": True, } return mapping.get(key, default) mock_get.side_effect = side_effect snapshot = {"other": "stuff"} # no server_url, no system.server_url result = get_server_url(settings_snapshot=snapshot) assert "192.168.1.100" in result assert "8443" in result assert result.startswith("https://") @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") def test_construct_http_when_not_https(self, mock_get): def side_effect(key, default_val=None, default=None): mapping = { "web.host": "myhost", "web.port": 3000, "web.use_https": False, } return mapping.get(key, default) mock_get.side_effect = side_effect snapshot = {"other": "stuff"} result = get_server_url(settings_snapshot=snapshot) assert result.startswith("http://") @patch("local_deep_research.utilities.llm_utils.get_setting_from_snapshot") def test_0000_replaced_with_127001(self, mock_get): def side_effect(key, default_val=None, default=None): mapping = { "web.host": "0.0.0.0", "web.port": 5000, "web.use_https": True, } return mapping.get(key, default) mock_get.side_effect = side_effect snapshot = {"other": "stuff"} result = get_server_url(settings_snapshot=snapshot) assert "127.0.0.1" in result assert "0.0.0.0" not in result def test_direct_server_url_preferred_over_system(self): snapshot = { "server_url": "https://direct.com/", "system": {"server_url": "https://system.com/"}, } result = get_server_url(settings_snapshot=snapshot) assert result == "https://direct.com/" def test_empty_snapshot(self): result = get_server_url(settings_snapshot={}) # Should construct from defaults or fall back assert result is not None assert len(result) > 0 def test_empty_string_server_url_falls_through(self): snapshot = {"server_url": "", "system": {"server_url": ""}} result = get_server_url(settings_snapshot=snapshot) # Empty strings are falsy, should fall through to construction assert result is not None