""" test_nvidia_chat.py - NvidiaProvider.chat() 測試 2026-03-29 ogt: 模組化重構 - 測試移至 NvidiaProvider 符合 feedback_lewooogo_modular_enforcement.md 規範 測試策略 (遵循 feedback_no_mock_testing.md): - 使用真實 NVIDIA API (需 NVIDIA_API_KEY) - 跳過條件: 無 API Key 時跳過 """ import json import os import pytest from src.core.config import get_settings from src.services.nvidia_provider import NvidiaProvider, get_nvidia_provider settings = get_settings() @pytest.fixture def nvidia_provider(): """建立 NvidiaProvider 實例""" return NvidiaProvider() @pytest.mark.asyncio @pytest.mark.skipif( not os.getenv("NVIDIA_API_KEY") and not settings.NVIDIA_API_KEY, reason="NVIDIA_API_KEY not configured", ) async def test_chat_success(nvidia_provider): """ 測試 chat() 成功回應 驗證: - 回應格式正確 (4-tuple) - success = True - total_tokens > 0 - cost_usd = 0 (免費 tier) """ prompt = """你是一個 JSON 產生器。請回傳以下格式: {"status": "ok", "message": "test"} 只回傳 JSON,不要其他內容。""" response, success, total_tokens, cost_usd = await nvidia_provider.chat(prompt) assert success is True, f"Expected success, got error: {response}" assert isinstance(response, str) assert len(response) > 0 assert total_tokens > 0, "Expected token count > 0" assert cost_usd == 0.0, "Expected $0 for free tier" @pytest.mark.asyncio async def test_chat_no_api_key(): """ 測試無 API Key 時的處理 驗證: - success = False - 回傳適當錯誤訊息 """ # 建立沒有 API Key 的 provider provider = NvidiaProvider(api_key=None) response, success, total_tokens, cost_usd = await provider.chat("test") assert success is False assert "not configured" in response.lower() assert total_tokens == 0 assert cost_usd == 0.0 @pytest.mark.asyncio @pytest.mark.skipif( not os.getenv("NVIDIA_API_KEY") and not settings.NVIDIA_API_KEY, reason="NVIDIA_API_KEY not configured", ) async def test_chat_json_response(nvidia_provider): """ 測試 JSON 格式回應 驗證: - 回應是有效 JSON """ prompt = """回傳一個 JSON 物件,包含: - action: "NO_ACTION" - reason: "測試" 只回傳 JSON。""" response, success, _, _ = await nvidia_provider.chat(prompt) assert success is True # 驗證是有效 JSON try: data = json.loads(response) assert isinstance(data, dict) except json.JSONDecodeError: pytest.fail(f"Response is not valid JSON: {response[:200]}") @pytest.mark.asyncio @pytest.mark.skipif( not os.getenv("NVIDIA_API_KEY") and not settings.NVIDIA_API_KEY, reason="NVIDIA_API_KEY not configured", ) async def test_chat_uses_model_registry(nvidia_provider): """ 測試使用 ModelRegistry 取得模型 驗證: - 使用 models.json 中定義的 rca 模型 """ from src.services.model_registry import get_model_registry registry = get_model_registry() expected_model = registry.get_model("nvidia", "rca") # 模型應該是 llama-3.1-nemotron-70b-instruct assert "nemotron" in expected_model.lower() assert "70b" in expected_model or "mini" in expected_model @pytest.mark.asyncio def test_get_nvidia_provider_singleton(): """ 測試單例模式 驗證: - get_nvidia_provider() 返回同一實例 """ provider1 = get_nvidia_provider() provider2 = get_nvidia_provider() assert provider1 is provider2 @pytest.mark.asyncio @pytest.mark.skipif( not os.getenv("NVIDIA_API_KEY") and not settings.NVIDIA_API_KEY, reason="NVIDIA_API_KEY not configured", ) async def test_chat_includes_otel_tracing(nvidia_provider): """ 測試 OTEL 追蹤整合 驗證: - chat() 執行時有 OTEL span """ # 這個測試主要驗證代碼不會拋出異常 prompt = '{"test": true}' response, success, _, _ = await nvidia_provider.chat(prompt) # 只要沒有拋出異常就算通過 assert isinstance(response, str)