""" 测试Knowledge API不再默认使用MockEmbedder - 无OpenAI Key时API返回503+明确错误信息 - 有OpenAI Key时使用OpenAIEmbedder - MockEmbedder不再作为默认选择 """ import pytest from unittest.mock import patch, MagicMock from app.services.knowledge.embedder import MockEmbedder, OpenAIEmbedder from app.services.knowledge.rag_service import RAGService from app.services.api_key_manager import APIKeyManager class TestKnowledgeAPINoMockEmbedder: """验证knowledge.py不再默认使用MockEmbedder""" def test_get_rag_service_raises_without_openai_key(self): """无OpenAI Key时_get_rag_service必须抛出HTTPException""" from app.api.knowledge import _get_rag_service from fastapi import HTTPException key_manager = APIKeyManager() with patch("app.api.knowledge._key_manager", key_manager): with pytest.raises(HTTPException) as exc_info: _get_rag_service() assert exc_info.value.status_code == 503 assert "OpenAI API Key" in exc_info.value.detail def test_get_rag_service_returns_openai_embedder_with_key(self): """有OpenAI Key时_get_rag_service必须返回使用OpenAIEmbedder的RAGService""" from app.api.knowledge import _get_rag_service key_manager = APIKeyManager() key_manager.add_key("chatgpt", "sk-test-key-1234567890", source="system") with patch("app.api.knowledge._key_manager", key_manager): rag_service = _get_rag_service() assert isinstance(rag_service, RAGService) assert isinstance(rag_service.embedder, OpenAIEmbedder) def test_get_rag_service_never_returns_mock_embedder(self): """_get_rag_service绝不能返回MockEmbedder""" from app.api.knowledge import _get_rag_service from fastapi import HTTPException key_manager = APIKeyManager() with patch("app.api.knowledge._key_manager", key_manager): with pytest.raises(HTTPException): _get_rag_service() key_manager_with_key = APIKeyManager() key_manager_with_key.add_key("chatgpt", "sk-test-key-1234567890", source="system") with patch("app.api.knowledge._key_manager", key_manager_with_key): rag_service = _get_rag_service() assert not isinstance(rag_service.embedder, MockEmbedder) def test_no_module_level_mock_rag_service(self): """模块级别不再存在使用MockEmbedder的_rag_service变量""" import app.api.knowledge as knowledge_module assert not hasattr(knowledge_module, "_rag_service"), ( "_rag_service模块级变量仍然存在,必须删除" ) def test_error_message_contains_configuration_guidance(self): """503错误信息必须包含配置指引""" from app.api.knowledge import _get_rag_service from fastapi import HTTPException key_manager = APIKeyManager() with patch("app.api.knowledge._key_manager", key_manager): with pytest.raises(HTTPException) as exc_info: _get_rag_service() detail = exc_info.value.detail assert "OpenAI API Key" in detail assert "设置" in detail or "配置" in detail def test_mock_embedder_class_still_exists(self): """MockEmbedder类必须保留(仅用于测试)""" assert MockEmbedder is not None embedder = MockEmbedder() assert isinstance(embedder, MockEmbedder) def test_get_rag_service_uses_api_key_manager(self): """_get_rag_service必须使用APIKeyManager获取Key""" from app.api.knowledge import _get_rag_service mock_km = MagicMock(spec=APIKeyManager) mock_km.get_key.return_value = "sk-test-key-1234567890" with patch("app.api.knowledge._key_manager", mock_km): rag_service = _get_rag_service() mock_km.get_key.assert_called_once_with("chatgpt") assert isinstance(rag_service.embedder, OpenAIEmbedder)