Add comprehensive unit test suite

- Add 111 unit tests covering all client classes and exceptions
- Test BaseClientMixin: initialization, validation, retry logic
- Test FastGPTClient: HTTP requests, streaming, error handling, context manager
- Test ChatClient: all chat operations (completion, histories, records, feedback)
- Test AppClient: app analytics and logs
- Test all exception classes with various configurations
- Add shared pytest fixtures in conftest.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Xin Wang
2026-01-06 16:17:43 +08:00
parent 017bdc4b53
commit b322ef1d7a
6 changed files with 1938 additions and 0 deletions

168
tests/conftest.py Normal file
View File

@@ -0,0 +1,168 @@
"""Pytest configuration and fixtures for FastGPT client tests."""
import pytest
from unittest.mock import Mock, MagicMock
import httpx
@pytest.fixture
def api_key():
"""Test API key."""
return "fastgpt-test-key-12345"
@pytest.fixture
def base_url():
"""Test base URL."""
return "http://localhost:3000"
@pytest.fixture
def mock_response():
"""Create a mock httpx.Response object."""
response = Mock(spec=httpx.Response)
response.status_code = 200
response.headers = {}
response._content = b'{"data": "test"}'
response.request = Mock()
response.request.method = "GET"
response.request.url = "http://test.com"
return response
@pytest.fixture
def mock_stream_response():
"""Create a mock streaming httpx.Response object."""
response = Mock(spec=httpx.Response)
response.status_code = 200
response.headers = {}
response._content = b'data: {"content": "test"}\n\n'
response.request = Mock()
response.request.method = "POST"
response.request.url = "http://test.com/stream"
response.iter_lines = Mock(return_value=[b'data: {"content": "test"}\n\n'])
return response
@pytest.fixture
def mock_httpx_client():
"""Create a mock httpx.Client."""
client = Mock(spec=httpx.Client)
client.is_closed = False
return client
@pytest.fixture
def sample_chat_response():
"""Sample chat completion response data."""
return {
"id": "chatcmpl-123",
"object": "chat.completion",
"created": 1234567890,
"model": "gpt-3.5-turbo",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 20,
"total_tokens": 30
}
}
@pytest.fixture
def sample_chat_histories_response():
"""Sample chat histories response data."""
return {
"data": [
{
"chatId": "chat-123",
"customTitle": "Test Chat",
"time": 1234567890,
"top": False
}
],
"total": 1
}
@pytest.fixture
def sample_chat_records_response():
"""Sample chat records response data."""
return {
"data": [
{
"dataId": "msg-123",
"content": {
"text": "Hello!"
},
"time": 1234567890,
"feedback": {
"userGoodFeedback": "Great!",
"userBadFeedback": None
}
}
]
}
@pytest.fixture
def sample_app_logs_response():
"""Sample app logs chart response data."""
return {
"data": {
"users": {
"day": [
{"time": "2024-01-01", "count": 10},
{"time": "2024-01-02", "count": 15}
]
},
"chats": {
"day": [
{"time": "2024-01-01", "count": 25},
{"time": "2024-01-02", "count": 30}
]
},
"app": {
"day": [
{"time": "2024-01-01", "count": 100},
{"time": "2024-01-02", "count": 120}
]
}
}
}
@pytest.fixture
def error_responses():
"""Sample error response data."""
return {
"authentication_error": {
"code": "invalid_api_key",
"message": "Invalid API key",
"status": 401
},
"rate_limit_error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded",
"status": 429
},
"validation_error": {
"code": "invalid_parameters",
"message": "Invalid parameters",
"status": 422
},
"server_error": {
"code": "internal_error",
"message": "Internal server error",
"status": 500
}
}