""" Coverage tests for local_deep_research/llm/providers/auto_discovery.py Focuses on paths not covered by tests/llm_providers/test_auto_discovery.py: - ProviderInfo.__init__ with and without optional class attributes - ProviderInfo._generate_display_name() for cloud=True, cloud=False - ProviderInfo.to_dict() shape - ProviderDiscovery singleton behaviour - ProviderDiscovery.get_provider_info() triggers discover_providers if not done - ProviderDiscovery.get_provider_class() returns None for unknown key - ProviderDiscovery.get_provider_options() sorts by label - get_available_discovered_provider_options() filters unavailable providers - Module-level convenience functions delegate correctly """ from unittest.mock import MagicMock from local_deep_research.llm.providers.auto_discovery import ( ProviderInfo, ProviderDiscovery, discover_providers, get_discovered_provider_options, get_available_discovered_provider_options, get_provider_class, ) # --------------------------------------------------------------------------- # Minimal provider class stubs # --------------------------------------------------------------------------- def _make_provider_class( provider_name="TestProv", provider_key="TESTPROV", company_name=None, is_cloud=True, requires_auth=True, ): cls = MagicMock() cls.__name__ = f"{provider_name}Provider" cls.provider_name = provider_name cls.provider_key = provider_key if company_name is not None: cls.company_name = company_name else: del cls.company_name # force AttributeError → getattr default cls.is_cloud = is_cloud cls.requires_auth_for_models = MagicMock(return_value=requires_auth) cls.is_available = MagicMock(return_value=True) return cls # --------------------------------------------------------------------------- # ProviderInfo # --------------------------------------------------------------------------- class TestProviderInfo: def test_basic_attributes_set(self): cls = _make_provider_class( provider_name="Alpha", provider_key="ALPHA", is_cloud=True ) info = ProviderInfo(cls) assert info.provider_name == "Alpha" assert info.provider_key == "ALPHA" assert info.is_cloud is True def test_display_name_cloud(self): cls = _make_provider_class(is_cloud=True) info = ProviderInfo(cls) assert "Cloud" in info.display_name or "☁️" in info.display_name def test_display_name_local(self): cls = _make_provider_class(is_cloud=False) info = ProviderInfo(cls) assert "Local" in info.display_name or "💻" in info.display_name def test_to_dict_shape(self): cls = _make_provider_class( provider_name="Beta", provider_key="BETA", is_cloud=True ) info = ProviderInfo(cls) d = info.to_dict() assert "value" in d assert "label" in d assert "is_cloud" in d assert d["value"] == "BETA" def test_provider_key_falls_back_to_class_name(self): """When provider_key is not an attribute, falls back to class name.""" cls = MagicMock(spec=[]) cls.provider_name = "Gamma" cls.__name__ = "GammaProvider" cls.is_cloud = True cls.requires_auth_for_models = MagicMock(return_value=True) info = ProviderInfo(cls) assert info.provider_key # must be some non-empty string # --------------------------------------------------------------------------- # ProviderDiscovery singleton # --------------------------------------------------------------------------- class TestProviderDiscoverySingleton: def test_same_instance_returned(self): d1 = ProviderDiscovery() d2 = ProviderDiscovery() assert d1 is d2 # --------------------------------------------------------------------------- # get_provider_info # --------------------------------------------------------------------------- class TestGetProviderInfo: def test_unknown_key_returns_none(self): discovery = ProviderDiscovery() # Force providers to be discovered first discovery.discover_providers() result = discovery.get_provider_info("NONEXISTENT_PROVIDER_XYZ") assert result is None def test_triggers_discover_if_not_done(self): """get_provider_info() discovers providers if not already done.""" discovery = ProviderDiscovery() discovery._discovered = False # Just verifying it runs without error result = discovery.get_provider_info("NONEXISTENT_XYZ") assert result is None # not found, but no crash # --------------------------------------------------------------------------- # get_provider_class # --------------------------------------------------------------------------- class TestGetProviderClass: def test_unknown_key_returns_none(self): result = get_provider_class("TOTALLY_NONEXISTENT_KEY_ZZZ") assert result is None # --------------------------------------------------------------------------- # get_provider_options sorting # --------------------------------------------------------------------------- class TestGetProviderOptions: def test_options_sorted_by_label(self): discovery = ProviderDiscovery() # Inject two fake providers with known labels cls_z = _make_provider_class(provider_name="Zebra", provider_key="Z") cls_a = _make_provider_class(provider_name="Apple", provider_key="A") info_z = ProviderInfo(cls_z) info_a = ProviderInfo(cls_a) original = dict(discovery._providers) discovery._providers = {"Z": info_z, "A": info_a} discovery._discovered = True try: options = discovery.get_provider_options() labels = [o["label"] for o in options] assert labels == sorted(labels) finally: discovery._providers = original # --------------------------------------------------------------------------- # get_available_provider_options – filters unavailable # --------------------------------------------------------------------------- class TestGetAvailableProviderOptions: def test_unavailable_providers_filtered_out(self): discovery = ProviderDiscovery() cls_ok = _make_provider_class(provider_name="OK", provider_key="OK") cls_ok.is_available = MagicMock(return_value=True) cls_bad = _make_provider_class(provider_name="BAD", provider_key="BAD") cls_bad.is_available = MagicMock(return_value=False) info_ok = ProviderInfo(cls_ok) info_ok.provider_class = cls_ok info_bad = ProviderInfo(cls_bad) info_bad.provider_class = cls_bad original = dict(discovery._providers) original_disc = discovery._discovered discovery._providers = {"OK": info_ok, "BAD": info_bad} discovery._discovered = True try: options = discovery.get_available_provider_options() values = [o["value"] for o in options] assert "OK" in values assert "BAD" not in values finally: discovery._providers = original discovery._discovered = original_disc # --------------------------------------------------------------------------- # Module-level convenience functions # --------------------------------------------------------------------------- class TestModuleLevelFunctions: def test_discover_providers_returns_dict(self): result = discover_providers() assert isinstance(result, dict) def test_get_discovered_provider_options_returns_list(self): result = get_discovered_provider_options() assert isinstance(result, list) def test_get_available_discovered_provider_options_returns_list(self): result = get_available_discovered_provider_options() assert isinstance(result, list)