Bloom_Ware / tests /test_ai_client.py
LawrenceBai's picture
feat: overhaul MCP architecture with structured tool schemas, comprehensive care-mode skill definitions, and enhanced test coverage for pipelines and service integration.
79df050
Raw
History Blame Contribute Delete
3.8 kB
"""
測試 core/ai_client.py OpenAI 客戶端管理
"""
import pytest
from unittest.mock import patch, MagicMock
class TestAIClient:
"""測試 AI 客戶端模組"""
def test_get_openai_client_no_api_key(self):
"""測試無 API Key 時返回 None"""
from core import ai_client
ai_client.reset_client()
with patch.object(ai_client, 'settings') as mock_settings:
mock_settings.OPENAI_API_KEY = ""
mock_settings.OPENAI_BASE_URL = ""
mock_settings.OPENAI_TIMEOUT = 30
client = ai_client.get_openai_client()
# 無 API Key 應返回 None
assert client is None
def test_reset_client(self):
"""測試重置客戶端"""
from core import ai_client
ai_client.reset_client()
assert ai_client._initialized is False
assert ai_client._openai_client is None
def test_is_available_false(self):
"""測試服務不可用"""
from core import ai_client
ai_client.reset_client()
with patch.object(ai_client, 'settings') as mock_settings:
mock_settings.OPENAI_API_KEY = ""
mock_settings.OPENAI_BASE_URL = ""
mock_settings.OPENAI_TIMEOUT = 30
assert ai_client.is_available() is False
def test_get_openai_client_passes_base_url(self):
"""測試有設定 base_url 時會傳入 OpenAI client"""
from core import ai_client
ai_client.reset_client()
fake_client = MagicMock()
with patch.object(ai_client, 'settings') as mock_settings:
mock_settings.OPENAI_API_KEY = "sk-test"
mock_settings.OPENAI_BASE_URL = "https://sub2api.flowatelier.com/v1"
mock_settings.OPENAI_TIMEOUT = 30
with patch("openai.OpenAI", return_value=fake_client) as mock_openai:
client = ai_client.get_openai_client()
assert client is fake_client
mock_openai.assert_called_once_with(
api_key="sk-test",
base_url="https://sub2api.flowatelier.com/v1",
timeout=30.0,
max_retries=3,
)
def test_get_openai_client_normalizes_base_url_without_v1(self):
"""測試 base_url 可用裸網域設定,client factory 會補 /v1"""
from core import ai_client
ai_client.reset_client()
fake_client = MagicMock()
with patch.object(ai_client, 'settings') as mock_settings:
mock_settings.OPENAI_API_KEY = "sk-test"
mock_settings.OPENAI_BASE_URL = "https://sub2api.flowatelier.com"
mock_settings.OPENAI_TIMEOUT = 30
with patch("openai.OpenAI", return_value=fake_client) as mock_openai:
client = ai_client.get_openai_client()
assert client is fake_client
mock_openai.assert_called_once_with(
api_key="sk-test",
base_url="https://sub2api.flowatelier.com/v1",
timeout=30.0,
max_retries=3,
)
def test_get_openai_client_omits_base_url_when_unset(self):
"""測試未設定 base_url 時沿用 SDK 預設 OpenAI endpoint"""
from core import ai_client
ai_client.reset_client()
fake_client = MagicMock()
with patch.object(ai_client, 'settings') as mock_settings:
mock_settings.OPENAI_API_KEY = "sk-test"
mock_settings.OPENAI_BASE_URL = ""
mock_settings.OPENAI_TIMEOUT = 30
with patch("openai.OpenAI", return_value=fake_client) as mock_openai:
client = ai_client.get_openai_client()
assert client is fake_client
mock_openai.assert_called_once_with(
api_key="sk-test",
timeout=30.0,
max_retries=3,
)