test: add comprehensive test suite with 89% coverage
- Add tests for all backend modules: config, database, models, services, routes, middleware, and providers - Separate dev dependencies using dependency-groups - Update CLAUDE.md with test commands and project structure - Add .coverage and .pytest_cache to gitignore 88 tests covering: - Authentication and authorization - Model routing and key selection - Async logging with batch processing - All API endpoints (chat, openai, anthropic, health) - LiteLLM wrapper (mocked external calls) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
118
backend/tests/test_models.py
Normal file
118
backend/tests/test_models.py
Normal file
@@ -0,0 +1,118 @@
|
||||
"""Tests for data models."""
|
||||
import pytest
|
||||
from app.models import ClientKey, Provider, ProviderKey, RequestLog
|
||||
|
||||
|
||||
class TestClientKey:
|
||||
"""Test ClientKey model."""
|
||||
|
||||
def test_create_client_key(self):
|
||||
"""Test creating a ClientKey instance."""
|
||||
key = ClientKey(
|
||||
id=1,
|
||||
key="test-key",
|
||||
name="test-client",
|
||||
is_active=True,
|
||||
created_at="2024-01-01"
|
||||
)
|
||||
assert key.id == 1
|
||||
assert key.key == "test-key"
|
||||
assert key.name == "test-client"
|
||||
assert key.is_active is True
|
||||
|
||||
def test_client_key_with_null_name(self):
|
||||
"""Test ClientKey with null name."""
|
||||
key = ClientKey(
|
||||
id=1,
|
||||
key="test-key",
|
||||
name=None,
|
||||
is_active=True,
|
||||
created_at="2024-01-01"
|
||||
)
|
||||
assert key.name is None
|
||||
|
||||
|
||||
class TestProvider:
|
||||
"""Test Provider model."""
|
||||
|
||||
def test_create_provider(self):
|
||||
"""Test creating a Provider instance."""
|
||||
provider = Provider(
|
||||
id=1,
|
||||
name="openai",
|
||||
base_url="https://api.openai.com/v1",
|
||||
api_type="openai",
|
||||
is_active=True
|
||||
)
|
||||
assert provider.id == 1
|
||||
assert provider.name == "openai"
|
||||
assert provider.api_type == "openai"
|
||||
|
||||
def test_provider_anthropic(self):
|
||||
"""Test creating an Anthropic provider."""
|
||||
provider = Provider(
|
||||
id=2,
|
||||
name="anthropic",
|
||||
base_url="https://api.anthropic.com/v1",
|
||||
api_type="anthropic",
|
||||
is_active=True
|
||||
)
|
||||
assert provider.name == "anthropic"
|
||||
assert provider.api_type == "anthropic"
|
||||
|
||||
|
||||
class TestProviderKey:
|
||||
"""Test ProviderKey model."""
|
||||
|
||||
def test_create_provider_key(self):
|
||||
"""Test creating a ProviderKey instance."""
|
||||
key = ProviderKey(
|
||||
id=1,
|
||||
provider_id=1,
|
||||
key="sk-test",
|
||||
is_active=True,
|
||||
created_at="2024-01-01"
|
||||
)
|
||||
assert key.id == 1
|
||||
assert key.provider_id == 1
|
||||
assert key.key == "sk-test"
|
||||
|
||||
|
||||
class TestRequestLog:
|
||||
"""Test RequestLog model."""
|
||||
|
||||
def test_create_request_log(self):
|
||||
"""Test creating a RequestLog instance."""
|
||||
log = RequestLog(
|
||||
id=1,
|
||||
client_key_id=1,
|
||||
provider_id=1,
|
||||
model="gpt-4o",
|
||||
prompt_tokens=10,
|
||||
completion_tokens=20,
|
||||
latency_ms=100,
|
||||
success=True,
|
||||
error_message=None,
|
||||
created_at="2024-01-01"
|
||||
)
|
||||
assert log.model == "gpt-4o"
|
||||
assert log.success is True
|
||||
assert log.error_message is None
|
||||
|
||||
def test_request_log_with_error(self):
|
||||
"""Test RequestLog with error."""
|
||||
log = RequestLog(
|
||||
id=None,
|
||||
client_key_id=1,
|
||||
provider_id=1,
|
||||
model="gpt-4o",
|
||||
prompt_tokens=None,
|
||||
completion_tokens=None,
|
||||
latency_ms=100,
|
||||
success=False,
|
||||
error_message="Rate limit exceeded",
|
||||
created_at=None
|
||||
)
|
||||
assert log.id is None
|
||||
assert log.success is False
|
||||
assert log.error_message == "Rate limit exceeded"
|
||||
Reference in New Issue
Block a user