"""Model-provider selection + the null-provider fail-loud behavior. No network: we only assert which provider the factory returns and that the null providers raise a clear error. (Live LLM/embedding calls aren't unit-tested.) """ import pytest from app.api.deps import get_embedding_provider, get_llm_provider from app.core.config import get_settings from app.integrations.models.anthropic_provider import AnthropicLLMProvider from app.integrations.models.base import ModelProviderNotConfigured from app.integrations.models.null import NullEmbeddingProvider, NullLLMProvider async def test_default_llm_is_null_and_fails_loud(monkeypatch): monkeypatch.setattr(get_settings(), "model_provider", "null") provider = get_llm_provider() assert isinstance(provider, NullLLMProvider) with pytest.raises(ModelProviderNotConfigured): await provider.complete(prompt="hello") async def test_anthropic_selected_when_configured(monkeypatch): s = get_settings() monkeypatch.setattr(s, "model_provider", "anthropic") monkeypatch.setattr(s, "anthropic_api_key", "sk-ant-test-key") monkeypatch.setattr(s, "llm_model", "claude-opus-4-8") assert isinstance(get_llm_provider(), AnthropicLLMProvider) # no network call async def test_anthropic_without_key_falls_back_to_null(monkeypatch): s = get_settings() monkeypatch.setattr(s, "model_provider", "anthropic") monkeypatch.setattr(s, "anthropic_api_key", None) assert isinstance(get_llm_provider(), NullLLMProvider) async def test_embedding_default_is_null_and_fails_loud(): provider = get_embedding_provider() assert isinstance(provider, NullEmbeddingProvider) with pytest.raises(ModelProviderNotConfigured): await provider.embed(["text"])