Files
fastgpt-python-sdk/tests/test_chat_client.py
2026-01-08 17:36:04 +08:00

627 lines
22 KiB
Python

"""Tests for ChatClient."""
from unittest.mock import Mock, patch
import pytest
import httpx
from fastgpt_client.client import ChatClient
from fastgpt_client.exceptions import ValidationError
class TestChatClientCreateChatCompletion:
"""Test suite for ChatClient.create_chat_completion method."""
def test_create_chat_completion_basic(self, api_key, sample_chat_response):
"""Test basic chat completion creation."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
mock_response.json = Mock(return_value=sample_chat_response)
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
stream=False
)
assert response.status_code == 200
mock_send.assert_called_once()
call_args = mock_send.call_args
assert call_args[0][0] == "POST"
assert call_args[0][1] == "/api/v1/chat/completions"
assert call_args[1]['json']['messages'] == [{"role": "user", "content": "Hello"}]
assert call_args[1]['stream'] is False
def test_create_chat_completion_with_chat_id(self, api_key):
"""Test chat completion with chatId parameter."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
chatId="chat-123"
)
assert response.status_code == 200
assert mock_send.call_args[1]['json']['chatId'] == "chat-123"
def test_create_chat_completion_with_variables(self, api_key):
"""Test chat completion with variables parameter."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
variables={"name": "John", "city": "NYC"}
)
assert response.status_code == 200
assert mock_send.call_args[1]['json']['variables'] == {"name": "John", "city": "NYC"}
def test_create_chat_completion_with_detail(self, api_key):
"""Test chat completion with detail enabled."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
detail=True
)
assert response.status_code == 200
assert mock_send.call_args[1]['json']['detail'] is True
def test_create_chat_completion_with_response_chat_item_id(self, api_key):
"""Test chat completion with custom responseChatItemId."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
responseChatItemId="custom-id-123"
)
assert response.status_code == 200
assert mock_send.call_args[1]['json']['responseChatItemId'] == "custom-id-123"
def test_create_chat_completion_streaming(self, api_key, mock_stream_response):
"""Test streaming chat completion."""
client = ChatClient(api_key)
with patch.object(client, '_send_request', return_value=mock_stream_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
stream=True
)
assert response.status_code == 200
assert mock_send.call_args[1]['stream'] is True
def test_create_chat_completion_all_parameters(self, api_key):
"""Test chat completion with all parameters."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
stream=True,
chatId="chat-123",
detail=True,
variables={"key": "value"},
responseChatItemId="custom-id"
)
assert response.status_code == 200
json_data = mock_send.call_args[1]['json']
assert json_data['chatId'] == "chat-123"
assert json_data['detail'] is True
assert json_data['variables'] == {"key": "value"}
assert json_data['responseChatItemId'] == "custom-id"
def test_create_chat_completion_parameter_validation(self, api_key):
"""Test that parameter validation works for known fields."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
# Test with valid chatId (should pass validation)
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.create_chat_completion(
messages=[{"role": "user", "content": "Hello"}],
chatId="valid-chat-id"
)
# Verify the request was sent successfully
assert response.status_code == 200
mock_send.assert_called_once()
class TestChatClientGetChatHistories:
"""Test suite for ChatClient.get_chat_histories method."""
def test_get_chat_histories_basic(self, api_key, sample_chat_histories_response):
"""Test getting chat histories with basic parameters."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
mock_response.json = Mock(return_value=sample_chat_histories_response)
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_histories(appId="app-123")
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "POST"
assert call_args[0][1] == "/api/core/chat/getHistories"
assert call_args[1]['json']['appId'] == "app-123"
def test_get_chat_histories_with_pagination(self, api_key):
"""Test getting chat histories with pagination."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_histories(
appId="app-123",
offset=10,
pageSize=50
)
json_data = mock_send.call_args[1]['json']
assert json_data['offset'] == 10
assert json_data['pageSize'] == 50
def test_get_chat_histories_with_source(self, api_key):
"""Test getting chat histories with source filter."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_histories(
appId="app-123",
source="online"
)
assert mock_send.call_args[1]['json']['source'] == "online"
def test_get_chat_histories_all_parameters(self, api_key):
"""Test getting chat histories with all parameters."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_histories(
appId="app-123",
offset=5,
pageSize=25,
source="share"
)
json_data = mock_send.call_args[1]['json']
assert json_data == {
"appId": "app-123",
"offset": 5,
"pageSize": 25,
"source": "share"
}
class TestChatClientGetChatInit:
"""Test suite for ChatClient.get_chat_init method."""
def test_get_chat_init(self, api_key):
"""Test getting chat initialization."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_init(appId="app-123", chatId="chat-123")
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "GET"
assert call_args[0][1] == "/api/core/chat/init"
assert call_args[1]['params'] == {"appId": "app-123", "chatId": "chat-123"}
class TestChatClientGetChatRecords:
"""Test suite for ChatClient.get_chat_records method."""
def test_get_chat_records_basic(self, api_key, sample_chat_records_response):
"""Test getting chat records with basic parameters."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
mock_response.json = Mock(return_value=sample_chat_records_response)
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_records(appId="app-123", chatId="chat-123")
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "POST"
assert call_args[0][1] == "/api/core/chat/getPaginationRecords"
json_data = call_args[1]['json']
assert json_data['appId'] == "app-123"
assert json_data['chatId'] == "chat-123"
def test_get_chat_records_with_pagination(self, api_key):
"""Test getting chat records with pagination."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_records(
appId="app-123",
chatId="chat-123",
offset=20,
pageSize=30
)
json_data = mock_send.call_args[1]['json']
assert json_data['offset'] == 20
assert json_data['pageSize'] == 30
def test_get_chat_records_with_custom_feedbacks(self, api_key):
"""Test getting chat records with custom feedbacks loaded."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_records(
appId="app-123",
chatId="chat-123",
loadCustomFeedbacks=True
)
assert mock_send.call_args[1]['json']['loadCustomFeedbacks'] is True
def test_get_chat_records_all_parameters(self, api_key):
"""Test getting chat records with all parameters."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_chat_records(
appId="app-123",
chatId="chat-123",
offset=10,
pageSize=20,
loadCustomFeedbacks=True
)
json_data = mock_send.call_args[1]['json']
assert json_data == {
"appId": "app-123",
"chatId": "chat-123",
"offset": 10,
"pageSize": 20,
"loadCustomFeedbacks": True
}
class TestChatClientGetRecordDetail:
"""Test suite for ChatClient.get_record_detail method."""
def test_get_record_detail(self, api_key):
"""Test getting record detail."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_record_detail(
appId="app-123",
chatId="chat-123",
dataId="data-123"
)
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "GET"
assert call_args[0][1] == "/api/core/chat/getResData"
assert call_args[1]['params'] == {
"appId": "app-123",
"chatId": "chat-123",
"dataId": "data-123"
}
class TestChatClientUpdateChatHistory:
"""Test suite for ChatClient.update_chat_history method."""
def test_update_chat_history_title(self, api_key):
"""Test updating chat history title."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.update_chat_history(
appId="app-123",
chatId="chat-123",
customTitle="New Title"
)
assert response.status_code == 200
json_data = mock_send.call_args[1]['json']
assert json_data['appId'] == "app-123"
assert json_data['chatId'] == "chat-123"
assert json_data['customTitle'] == "New Title"
assert 'top' not in json_data
def test_update_chat_history_pin(self, api_key):
"""Test pinning chat history."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.update_chat_history(
appId="app-123",
chatId="chat-123",
top=True
)
json_data = mock_send.call_args[1]['json']
assert json_data['top'] is True
assert 'customTitle' not in json_data
def test_update_chat_history_both_parameters(self, api_key):
"""Test updating both title and pin status."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.update_chat_history(
appId="app-123",
chatId="chat-123",
customTitle="Important Chat",
top=True
)
json_data = mock_send.call_args[1]['json']
assert json_data['customTitle'] == "Important Chat"
assert json_data['top'] is True
class TestChatClientDeleteChatHistory:
"""Test suite for ChatClient.delete_chat_history method."""
def test_delete_chat_history(self, api_key):
"""Test deleting a chat history."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.delete_chat_history(appId="app-123", chatId="chat-123")
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "DELETE"
assert call_args[0][1] == "/api/core/chat/delHistory"
assert call_args[1]['params'] == {"appId": "app-123", "chatId": "chat-123"}
class TestChatClientClearChatHistories:
"""Test suite for ChatClient.clear_chat_histories method."""
def test_clear_chat_histories(self, api_key):
"""Test clearing all chat histories."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.clear_chat_histories(appId="app-123")
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "DELETE"
assert call_args[0][1] == "/api/core/chat/clearHistories"
assert call_args[1]['params'] == {"appId": "app-123"}
class TestChatClientDeleteChatRecord:
"""Test suite for ChatClient.delete_chat_record method."""
def test_delete_chat_record(self, api_key):
"""Test deleting a single chat record."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.delete_chat_record(
appId="app-123",
chatId="chat-123",
contentId="content-123"
)
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "DELETE"
assert call_args[0][1] == "/api/core/chat/item/delete"
assert call_args[1]['json'] == {
"appId": "app-123",
"chatId": "chat-123",
"contentId": "content-123"
}
class TestChatClientSendFeedback:
"""Test suite for ChatClient.send_feedback method."""
def test_send_feedback_good(self, api_key):
"""Test sending positive feedback."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.send_feedback(
appId="app-123",
chatId="chat-123",
dataId="data-123",
userGoodFeedback="Great response!"
)
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "POST"
assert call_args[0][1] == "/api/core/chat/feedback/updateUserFeedback"
json_data = call_args[1]['json']
assert json_data['userGoodFeedback'] == "Great response!"
assert 'userBadFeedback' not in json_data
def test_send_feedback_bad(self, api_key):
"""Test sending negative feedback."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.send_feedback(
appId="app-123",
chatId="chat-123",
dataId="data-123",
userBadFeedback="Not helpful"
)
json_data = mock_send.call_args[1]['json']
assert json_data['userBadFeedback'] == "Not helpful"
assert 'userGoodFeedback' not in json_data
def test_send_feedback_cancel_good(self, api_key):
"""Test canceling positive feedback by passing empty string."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.send_feedback(
appId="app-123",
chatId="chat-123",
dataId="data-123",
userGoodFeedback=""
)
# Empty string is still sent (to cancel the feedback)
json_data = mock_send.call_args[1]['json']
assert 'userGoodFeedback' in json_data
def test_send_feedback_only_required_params(self, api_key):
"""Test sending feedback with only required parameters."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.send_feedback(
appId="app-123",
chatId="chat-123",
dataId="data-123"
)
json_data = mock_send.call_args[1]['json']
assert json_data == {
"appId": "app-123",
"chatId": "chat-123",
"dataId": "data-123"
}
class TestChatClientGetSuggestedQuestions:
"""Test suite for ChatClient.get_suggested_questions method."""
def test_get_suggested_questions_basic(self, api_key):
"""Test getting suggested questions."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_suggested_questions(
appId="app-123",
chatId="chat-123"
)
assert response.status_code == 200
call_args = mock_send.call_args
assert call_args[0][0] == "POST"
assert call_args[0][1] == "/api/core/ai/agent/v2/createQuestionGuide"
json_data = call_args[1]['json']
assert json_data['appId'] == "app-123"
assert json_data['chatId'] == "chat-123"
assert 'questionGuide' not in json_data
def test_get_suggested_questions_with_guide(self, api_key):
"""Test getting suggested questions with custom question guide."""
client = ChatClient(api_key)
mock_response = Mock(spec=httpx.Response)
mock_response.status_code = 200
question_guide = {
"maxQuestions": 5,
"contextWindow": 10
}
with patch.object(client, '_send_request', return_value=mock_response) as mock_send:
response = client.get_suggested_questions(
appId="app-123",
chatId="chat-123",
questionGuide=question_guide
)
json_data = mock_send.call_args[1]['json']
assert json_data['questionGuide'] == question_guide