Skip to content

Commit 1b24299

Browse files
committed
将多个API方法的返回类型从Task<HttpResponseMessage>更改为ITask<HttpResponseMessage>,以支持异步操作的改进。同时,更新CreateByText类中的文档语言注释,添加详细的错误信息处理,并在测试中增加日志记录功能。
1 parent d02fa4a commit 1b24299

6 files changed

Lines changed: 240 additions & 63 deletions

File tree

DifySharp.Test/Apis/ChatApiTest/ChatMessageApiTest.cs

Lines changed: 170 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
using DifySharp.Extensions;
44
using JetBrains.Annotations;
55
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.Logging;
7+
using System.Text;
8+
using System.Text.Json;
69

710
namespace DifySharp.Test.Apis.ChatApiTest;
811

@@ -17,12 +20,17 @@ public ChatMessageApiTestFixture()
1720
}
1821

1922
[TestSubject(typeof(IChatApi))]
20-
public class ChatMessageApiTest(ChatMessageApiTestFixture fixture) : IClassFixture<ChatMessageApiTestFixture>
23+
public class ChatMessageApiTest(ChatMessageApiTestFixture fixture, ILogger<ChatMessageApiTest> logger) : IClassFixture<ChatMessageApiTestFixture>
2124
{
2225
private ChatClient Client => fixture.Client;
2326

27+
private static JsonSerializerOptions JsonSerializerOptions = new()
28+
{
29+
WriteIndented = true
30+
};
31+
2432
[Fact]
25-
public async Task TestChatMessage_shouldHaveMessage()
33+
public async Task TestChatMessage_ShouldHaveMessage()
2634
{
2735
var responseBody = await Client.PostChatMessageBlocking(new ChatMessage.RequestBody
2836
{
@@ -32,6 +40,166 @@ public async Task TestChatMessage_shouldHaveMessage()
3240

3341
Assert.NotNull(responseBody);
3442
Assert.NotNull(responseBody.Answer);
43+
44+
logger.LogInformation("TestChatMessage_shouldHaveMessage: {info}",
45+
System.Text.Json.JsonSerializer.Serialize(responseBody, JsonSerializerOptions));
46+
}
47+
48+
[Fact]
49+
public async Task TestGetInfo_ShouldReturnApplicationInfo()
50+
{
51+
var result = await Client.GetInfo();
52+
53+
Assert.NotNull(result);
54+
logger.LogInformation("GetInfo result: {info}",
55+
JsonSerializer.Serialize(result, JsonSerializerOptions));
3556
}
3657

58+
[Fact]
59+
public async Task TestGetParameters_ShouldReturnParameters()
60+
{
61+
var result = await Client.GetParameters();
62+
63+
Assert.NotNull(result);
64+
logger.LogInformation("GetParameters result: {info}",
65+
JsonSerializer.Serialize(result, JsonSerializerOptions));
66+
}
67+
68+
[Fact]
69+
public async Task TestGetMeta_ShouldReturnMeta()
70+
{
71+
var result = await Client.GetMeta();
72+
73+
Assert.NotNull(result);
74+
logger.LogInformation("GetMeta result: {info}",
75+
JsonSerializer.Serialize(result, JsonSerializerOptions));
76+
}
77+
78+
[Fact]
79+
public async Task TestChatMessageStreaming_ShouldReceiveStreamingResponse()
80+
{
81+
var requestBody = new ChatMessage.RequestBody
82+
{
83+
Query = "请简短介绍一下人工智能",
84+
User = Guid.NewGuid().ToString("N") + "-- streaming test"
85+
};
86+
87+
var chunks = new List<string>();
88+
89+
await foreach (var chunk in Client.PostChatMessageStreaming(requestBody))
90+
{
91+
Assert.NotNull(chunk);
92+
93+
// 根据不同的事件类型处理Answer属性
94+
switch (chunk)
95+
{
96+
case MessageEvent messageEvent:
97+
if (!string.IsNullOrEmpty(messageEvent.Answer))
98+
{
99+
chunks.Add(messageEvent.Answer);
100+
}
101+
break;
102+
case AgentMessageEvent agentMessageEvent:
103+
if (!string.IsNullOrEmpty(agentMessageEvent.Answer))
104+
{
105+
chunks.Add(agentMessageEvent.Answer);
106+
}
107+
break;
108+
case MessageReplaceEvent messageReplaceEvent:
109+
if (!string.IsNullOrEmpty(messageReplaceEvent.Answer))
110+
{
111+
chunks.Add(messageReplaceEvent.Answer);
112+
}
113+
break;
114+
}
115+
116+
logger.LogInformation("Received chunk ({eventType}): {chunk}",
117+
chunk.Event,
118+
JsonSerializer.Serialize(chunk, JsonSerializerOptions));
119+
}
120+
121+
Assert.NotEmpty(chunks);
122+
logger.LogInformation("Total chunks received: {count}", chunks.Count);
123+
}
124+
125+
[Fact]
126+
public async Task TestGetConversations_ShouldReturnConversationsList()
127+
{
128+
var user = Guid.NewGuid().ToString("N") + "-- conversations test";
129+
130+
// 先发送一条消息创建对话
131+
await Client.PostChatMessageBlocking(new ChatMessage.RequestBody
132+
{
133+
Query = "Hello, this is a test conversation",
134+
User = user
135+
});
136+
137+
// 获取对话列表
138+
var result = await Client.GetConversations(user, limit: 10);
139+
140+
Assert.NotNull(result);
141+
logger.LogInformation("GetConversations result: {info}",
142+
JsonSerializer.Serialize(result, JsonSerializerOptions));
143+
}
144+
145+
[Fact]
146+
public async Task TestChatMessageWithConversationId_ShouldContinueConversation()
147+
{
148+
var user = Guid.NewGuid().ToString("N") + "-- conversation test";
149+
150+
// 第一条消息
151+
var firstResponse = await Client.PostChatMessageBlocking(new ChatMessage.RequestBody
152+
{
153+
Query = "我的名字叫小明",
154+
User = user
155+
});
156+
157+
Assert.NotNull(firstResponse);
158+
Assert.NotNull(firstResponse.ConversationId);
159+
160+
// 第二条消息,使用相同的对话ID
161+
var secondResponse = await Client.PostChatMessageBlocking(new ChatMessage.RequestBody
162+
{
163+
Query = "我的名字是什么?",
164+
User = user,
165+
ConversationId = firstResponse.ConversationId
166+
});
167+
168+
Assert.NotNull(secondResponse);
169+
Assert.Equal(firstResponse.ConversationId, secondResponse.ConversationId);
170+
171+
logger.LogInformation("First response: {first}",
172+
JsonSerializer.Serialize(firstResponse, JsonSerializerOptions));
173+
logger.LogInformation("Second response: {second}",
174+
JsonSerializer.Serialize(secondResponse, JsonSerializerOptions));
175+
}
176+
177+
[Fact]
178+
public async Task TestChatMessageWithEmptyQuery_ShouldThrowException()
179+
{
180+
await Assert.ThrowsAsync<HttpRequestException>(async () =>
181+
{
182+
await Client.PostChatMessageBlocking(new ChatMessage.RequestBody
183+
{
184+
Query = "",
185+
User = Guid.NewGuid().ToString("N") + "-- empty query test"
186+
});
187+
});
188+
}
189+
190+
[Fact]
191+
public async Task TestChatMessageWithInvalidUser_ShouldHandleGracefully()
192+
{
193+
// 测试用空字符串作为用户
194+
var exception = await Assert.ThrowsAsync<HttpRequestException>(async () =>
195+
{
196+
await Client.PostChatMessageBlocking(new ChatMessage.RequestBody
197+
{
198+
Query = "Test query",
199+
User = ""
200+
});
201+
});
202+
203+
logger.LogInformation("Expected exception for invalid user: {exception}", exception.Message);
204+
}
37205
}

DifySharp.Test/Startup.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Text.Json;
22
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Options;
34
using Xunit.DependencyInjection.Logging;
45

56
// using Xunit.DependencyInjection.Logging;
@@ -24,6 +25,8 @@ public void ConfigureServices(IServiceCollection services)
2425
new DifyApiSecret(workflowApiTestKey!, "workflow", DifyApiType.WORKFLOW),
2526
new DifyApiSecret(chatApiKey, "chat", DifyApiType.CHAT)
2627
];
28+
29+
option.EnableLogging = true;
2730
});
2831
services.AddLogging(lb => lb.AddXunitOutput());
2932

DifySharp/Apis/ChatApi.cs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using DifySharp.Chat.ChatMessages;
44
using DifySharp.Chat.Conversations;
55
using DifySharp.Chat.Messages;
6+
using WebApiClientCore;
67
using WebApiClientCore.Attributes;
78

89
namespace DifySharp.Apis
@@ -23,7 +24,7 @@ public interface IChatApi : IApplicationApi, IConversationApi, IChatMessageApi,
2324
/// <param name="file"></param>
2425
/// <returns></returns>
2526
[HttpPost("files/upload")]
26-
public Task<HttpResponseMessage> PostFilesUpload(
27+
public ITask<HttpResponseMessage> PostFilesUpload(
2728
[FormDataContent] string user,
2829
FileInfo file
2930
);
@@ -37,7 +38,7 @@ FileInfo file
3738
/// <param name="user">User identifier, defined by the developer's rules, must be unique within the application.</param>
3839
/// <returns></returns>
3940
[HttpPost("/v1/audio-to-text")]
40-
public Task<HttpResponseMessage> PostAudioToText(
41+
public ITask<HttpResponseMessage> PostAudioToText(
4142
FileInfo file,
4243
[FormDataContent] string user
4344
);
@@ -48,7 +49,7 @@ [FormDataContent] string user
4849
/// <param name="requestBody"></param>
4950
/// <returns></returns>
5051
[HttpPost("/v1/text-to-audio")]
51-
public Task<HttpResponseMessage> PostTextToAudio(
52+
public ITask<HttpResponseMessage> PostTextToAudio(
5253
[JsonContent] object requestBody
5354
);
5455
}
@@ -65,7 +66,7 @@ public interface IChatMessageApi
6566
/// <param name="requestBody"></param>
6667
/// <returns></returns>
6768
[HttpPost("/v1/chat-messages")]
68-
public Task<HttpResponseMessage> PostChatMessages(
69+
public ITask<HttpResponseMessage> PostChatMessages(
6970
[JsonContent] ChatMessage.RequestBody requestBody
7071
);
7172

@@ -78,7 +79,7 @@ [JsonContent] ChatMessage.RequestBody requestBody
7879
/// <param name="requestBody">request body</param>
7980
/// <returns></returns>
8081
[HttpPost("/v1/chat-messages/{taskId}/stop")]
81-
public Task<Stop.ResponseBody> PostChatMessagesStop(
82+
public ITask<Stop.ResponseBody> PostChatMessagesStop(
8283
string taskId,
8384
Stop.RequestBody requestBody
8485
);
@@ -97,7 +98,7 @@ public interface IMessagesApi
9798
/// <param name="requestBody"></param>
9899
/// <returns></returns>
99100
[HttpPost("/v1/messages/{messageId}/feedbacks")]
100-
public Task<PostFeedback.ResponseBody> PostMessagesFeedbacks(
101+
public ITask<PostFeedback.ResponseBody> PostMessagesFeedbacks(
101102
string messageId,
102103
[JsonContent] PostFeedback.RequestBody requestBody
103104
);
@@ -111,7 +112,7 @@ [JsonContent] PostFeedback.RequestBody requestBody
111112
/// <param name="user"></param>
112113
/// <returns></returns>
113114
[HttpGet("/v1/messages/{messageId}/suggested")]
114-
public Task<GetSuggested.ResponseBody> GetMessagesSuggested(
115+
public ITask<GetSuggested.ResponseBody> GetMessagesSuggested(
115116
string messageId,
116117
[PathQuery] string user
117118
);
@@ -128,7 +129,7 @@ [PathQuery] string user
128129
/// <param name="limit"></param>
129130
/// <returns></returns>
130131
[HttpGet("/v1/messages")]
131-
public Task<Get.ResponseBody> GetMessages(
132+
public ITask<Get.ResponseBody> GetMessages(
132133
[PathQuery] string conversation_id,
133134
[PathQuery] string user,
134135
[PathQuery] string first_id,
@@ -169,7 +170,7 @@ public interface IConversationApi
169170
/// </param>
170171
/// <returns></returns>
171172
[HttpGet("/v1/conversations")]
172-
public Task<Get.ResponseBody> GetConversations(
173+
public ITask<Get.ResponseBody> GetConversations(
173174
[PathQuery] string user,
174175
[PathQuery] string? last_id = null,
175176
[PathQuery] int? limit = null,
@@ -184,7 +185,7 @@ public interface IConversationApi
184185
/// <param name="requestBody"></param>
185186
/// <returns></returns>
186187
[HttpDelete("/v1/conversations/{conversationId}")]
187-
public Task<Delete.RequestBody> DeleteConversations(
188+
public ITask<Delete.RequestBody> DeleteConversations(
188189
string conversationId,
189190
Delete.RequestBody requestBody
190191
);
@@ -197,7 +198,7 @@ Delete.RequestBody requestBody
197198
/// <param name="requestBody"></param>
198199
/// <returns></returns>
199200
[HttpPost("/v1/conversations/{conversationId}/name")]
200-
public Task<Conversation> PostRenameConversation(
201+
public ITask<Conversation> PostRenameConversation(
201202
string conversationId,
202203
[JsonContent] Rename.RequestBody requestBody
203204
);
@@ -214,22 +215,22 @@ public interface IApplicationApi
214215
/// </summary>
215216
/// <returns></returns>
216217
[HttpGet("/v1/info")]
217-
public Task<Basic.ResponseBody> GetInfo();
218+
public ITask<Basic.ResponseBody> GetInfo();
218219

219220
/// <summary>
220221
/// # Get Application Parameters Information
221222
/// <para>Used at the start of entering the page to obtain information such as features, input parameter names, types, and default values.</para>
222223
/// </summary>
223224
/// <returns></returns>
224225
[HttpGet("/v1/parameters")]
225-
public Task<Parameters.ResponseBody> GetParameters();
226+
public ITask<Parameters.ResponseBody> GetParameters();
226227

227228
/// <summary>
228229
/// Get Application Meta Information
229230
/// <para>Used to get icons of tools in this application</para>
230231
/// </summary>
231232
/// <returns></returns>
232233
[HttpGet("/v1/meta")]
233-
public Task<Meta.ResponseBody> GetMeta();
234+
public ITask<Meta.ResponseBody> GetMeta();
234235
}
235236
}

DifySharp/DTOs/KnowledgeBase/Document/CreateByText.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public record CreateByText
1313
/// <param name="DocMetadata">Document metadata (required if doc_type is provided)</param>
1414
/// <param name="IndexingTechnique">Indexing technique</param>
1515
/// <param name="DocForm">Format of indexed content</param>
16-
/// <param name="DocLanguage">Document language for Q&A mode</param>
16+
/// <param name="DocLanguage">Document language for Q and A mode</param>
1717
/// <param name="ProcessRule">Processing rules</param>
1818
/// <param name="RetrievalModel">Retrieval model (required when knowledge base has no parameters set for first upload)</param>
1919
/// <param name="EmbeddingModel">Embedding model name</param>

0 commit comments

Comments
 (0)