"""Tests for OpenAI native routes.""" import pytest from unittest.mock import MagicMock from fastapi.testclient import TestClient from app.main import app from app.models import ClientKey, Provider @pytest.fixture def mock_client_key(): """Return a valid client key for testing.""" return ClientKey( id=1, key="test-api-key", name="test-client", is_active=True, created_at="2024-01-01" ) @pytest.fixture def mock_openai_provider(): """Return a mock OpenAI provider.""" return Provider( id=1, name="openai", base_url="https://api.openai.com/v1", api_type="openai", is_active=True ) class TestOpenAIChat: """Test /v1/openai/chat/completions endpoint.""" def test_openai_chat_unauthorized(self): """Test OpenAI chat without auth.""" client = TestClient(app) response = client.post( "/v1/openai/chat/completions", json={"model": "gpt-4o", "messages": [{"role": "user", "content": "hi"}]} ) assert response.status_code == 401 def test_openai_chat_success(self, mock_client_key, mock_openai_provider): """Test successful OpenAI chat.""" from app.middleware.auth import get_current_client from app.services.router import ModelRouter from app.services.key_selector import key_selector from app.services.logger import async_logger from app.providers.litellm_wrapper import LiteLLMWrapper app.dependency_overrides[get_current_client] = lambda: mock_client_key mock_response = MagicMock() mock_response.model_dump.return_value = { "id": "chatcmpl-test", "choices": [{"message": {"content": "Hello!"}}] } original_get_provider = ModelRouter.get_provider original_get_key = key_selector.get_next_key original_chat = LiteLLMWrapper.chat_completion original_log = async_logger.log async def mock_get_provider(name): return mock_openai_provider async def mock_get_key(provider_id): return MagicMock(key="sk-test") async def mock_chat(*args, **kwargs): return (mock_response, 10, 20) async def mock_log(entry): pass ModelRouter.get_provider = staticmethod(lambda name: mock_get_provider(name)) key_selector.get_next_key = mock_get_key LiteLLMWrapper.chat_completion = staticmethod(lambda *a, **k: mock_chat(*a, **k)) async_logger.log = mock_log try: client = TestClient(app) response = client.post( "/v1/openai/chat/completions", json={"model": "gpt-4o", "messages": [{"role": "user", "content": "hi"}]}, headers={"Authorization": "Bearer test-api-key"} ) assert response.status_code == 200 finally: ModelRouter.get_provider = original_get_provider key_selector.get_next_key = original_get_key LiteLLMWrapper.chat_completion = original_chat async_logger.log = original_log app.dependency_overrides.clear() class TestOpenAIModels: """Test /v1/openai/models endpoint.""" def test_openai_models_success(self, mock_client_key): """Test list OpenAI models.""" from app.middleware.auth import get_current_client app.dependency_overrides[get_current_client] = lambda: mock_client_key try: client = TestClient(app) response = client.get( "/v1/openai/models", headers={"Authorization": "Bearer test-api-key"} ) assert response.status_code == 200 data = response.json() assert data["object"] == "list" for model in data["data"]: assert model["owned_by"] == "openai" finally: app.dependency_overrides.clear()