Skip to content

Commit be1eb9d

Browse files
committed
test: add socket test snapshots
1 parent 1f83e23 commit be1eb9d

20 files changed

+322
-5
lines changed

src/Cnblogs.DashScope.Core/DashScopeClientWebSocket.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void ResetOutput()
107107
public Task SendMessageAsync<TInput, TParameter>(
108108
DashScopeWebSocketRequest<TInput, TParameter> request,
109109
CancellationToken cancellationToken = default)
110-
where TInput : class
110+
where TInput : class, new()
111111
where TParameter : class
112112
{
113113
if (State == DashScopeWebSocketState.Closed)
@@ -222,6 +222,10 @@ public async Task CloseAsync(CancellationToken cancellationToken = default)
222222
{
223223
await _socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", cancellationToken);
224224
State = DashScopeWebSocketState.Closed;
225+
if (_receiveTask != null)
226+
{
227+
await _receiveTask;
228+
}
225229
}
226230

227231
private void Dispose(bool disposing)

src/Cnblogs.DashScope.Core/DashScopeClientWebSocketPool.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ public DashScopeClientWebSocketPool(DashScopeOptions options)
2020
_options = options;
2121
}
2222

23+
internal DashScopeClientWebSocketPool(IEnumerable<DashScopeClientWebSocket> sockets)
24+
{
25+
_options = new DashScopeOptions();
26+
foreach (var socket in sockets)
27+
{
28+
_available.Add(socket);
29+
}
30+
}
31+
2332
internal void ReturnSocketAsync(DashScopeClientWebSocket socket)
2433
{
2534
if (socket.State != DashScopeWebSocketState.Ready)

src/Cnblogs.DashScope.Core/DashScopeClientWebSocketWrapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public sealed record DashScopeClientWebSocketWrapper(DashScopeClientWebSocket So
3737
public Task SendMessageAsync<TInput, TParameter>(
3838
DashScopeWebSocketRequest<TInput, TParameter> request,
3939
CancellationToken cancellationToken = default)
40-
where TInput : class
40+
where TInput : class, new()
4141
where TParameter : class
4242
=> Socket.SendMessageAsync(request, cancellationToken);
4343

src/Cnblogs.DashScope.Core/DashScopeWebSocketRequest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/// <typeparam name="TInput">Type of the input.</typeparam>
77
/// <typeparam name="TParameter">Type of the parameter.</typeparam>
88
public class DashScopeWebSocketRequest<TInput, TParameter>
9-
where TInput : class
9+
where TInput : class, new()
1010
where TParameter : class
1111
{
1212
/// <summary>

src/Cnblogs.DashScope.Core/DashScopeWebSocketRequestPayload.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
/// <typeparam name="TInput">Type of the input.</typeparam>
77
/// <typeparam name="TParameter">Type of the parameter.</typeparam>
88
public class DashScopeWebSocketRequestPayload<TInput, TParameter>
9-
where TInput : class
9+
where TInput : class, new() // Input's default value must be empty object(not null or omitted).
1010
where TParameter : class
1111
{
1212
/// <summary>
@@ -37,5 +37,5 @@ public class DashScopeWebSocketRequestPayload<TInput, TParameter>
3737
/// <summary>
3838
/// The input of the request.
3939
/// </summary>
40-
public TInput Input { get; set; } = null!;
40+
public TInput Input { get; set; } = new();
4141
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System.Runtime.CompilerServices;
22

33
[assembly: InternalsVisibleTo("Cnblogs.DashScope.Sdk.UnitTests")]
4+
[assembly: InternalsVisibleTo("Cnblogs.DashScope.Tests.Shared")]
45
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

src/Cnblogs.DashScope.Core/SpeechSynthesizerParameters.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@ public class SpeechSynthesizerParameters
3939
/// Pitch of the voice, range between 0.5~2, defaults to 1.0.
4040
/// </summary>
4141
public float? Pitch { get; set; }
42+
43+
/// <summary>
44+
/// Enable SSML, you can only send text once if enabled.
45+
/// </summary>
46+
public bool? EnableSsml { get; set; }
4247
}

test/Cnblogs.DashScope.Sdk.UnitTests/DashScopeClientWebSocketTests.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Reflection;
44
using Cnblogs.DashScope.Core;
55
using Cnblogs.DashScope.Core.Internals;
6+
using Cnblogs.DashScope.Tests.Shared.Utils;
67
using NSubstitute;
78

89
namespace Cnblogs.DashScope.Sdk.UnitTests;
@@ -102,6 +103,56 @@ public async Task ResetOutput_WithInitialOutput_CompleteThenCreateNewOutputAsync
102103
Assert.NotSame(oldSignal, client.TaskStarted);
103104
}
104105

106+
[Fact]
107+
public async Task SendMessageAsync_SocketClosed_ThrowAsync()
108+
{
109+
// Arrange
110+
var socket = Substitute.For<IClientWebSocket>();
111+
var client = new DashScopeClientWebSocket(socket);
112+
var snapshot = Snapshots.SpeechSynthesizer.RunTask;
113+
await client.CloseAsync();
114+
115+
// Act
116+
var act = () => client.SendMessageAsync(snapshot.Message);
117+
118+
// Assert
119+
await Assert.ThrowsAsync<InvalidOperationException>(act);
120+
}
121+
122+
[Fact]
123+
public async Task SendMessageAsync_Connected_SendAsync()
124+
{
125+
// Arrange
126+
var socket = Substitute.For<IClientWebSocket>();
127+
var client = new DashScopeClientWebSocket(socket);
128+
var snapshot = Snapshots.SpeechSynthesizer.RunTask;
129+
130+
// Act
131+
await client.ConnectAsync<SpeechSynthesizerOutput>(new Uri(DashScopeDefaults.WebsocketApiBaseAddress));
132+
await client.SendMessageAsync(snapshot.Message);
133+
134+
// Assert
135+
await socket.Received().SendAsync(
136+
Arg.Is<ArraySegment<byte>>(s => Checkers.IsJsonEquivalent(s, snapshot.GetRequestJson())),
137+
WebSocketMessageType.Text,
138+
true,
139+
Arg.Any<CancellationToken>());
140+
}
141+
142+
[Fact]
143+
public async Task ReceiveMessageAsync_ServerClosed_CloseAsync()
144+
{
145+
// Arrange
146+
var (_, dashScopeClientWebSocket, server) = await Sut.GetSocketTestClientAsync<SpeechSynthesizerOutput>();
147+
148+
// Act
149+
await server.WriteServerCloseAsync();
150+
151+
// Assert
152+
Assert.Equal(DashScopeWebSocketState.Closed, dashScopeClientWebSocket.State);
153+
Assert.Equal(WebSocketCloseStatus.NormalClosure, server.CloseStatus);
154+
}
155+
105156
private static WebHeaderCollection ExtractHeaders(DashScopeClientWebSocket socket)
106157
{
107158
var obj = InnerSocketInfo.GetValue(socket);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
using System.Runtime.CompilerServices;
2+
3+
[assembly: InternalsVisibleTo("Cnblogs.DashScope.Sdk.UnitTests")]
4+
[assembly: InternalsVisibleTo("Cnblogs.DashScope.AI.UnitTests")]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"header": {
3+
"action": "continue-task",
4+
"task_id": "439e0616-2f5b-44e0-8872-0002a066a49c"
5+
},
6+
"payload": {
7+
"input": {
8+
"text": "代码改变世界"
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)