Skip to content

Commit 7a51439

Browse files
committed
Initial implementation of unit tests
1 parent c07e253 commit 7a51439

3 files changed

Lines changed: 114 additions & 27 deletions

File tree

SteamQueryNet/SteamQueryNet.Tests/ServerQueryTests.cs

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,52 @@
1-
using System;
2-
1+
using Moq;
2+
using System;
3+
using System.Net;
4+
using System.Net.Sockets;
35
using Xunit;
46

57
namespace SteamQueryNet.Tests
68
{
79
public class ServerQueryTests
810
{
9-
private const string IP_ADDRESS = "54.37.111.216";
10-
private const int PORT = 27015;
11+
private const string IP_ADDRESS = "127.0.0.1";
12+
private const string HOST_NAME = "localhost";
13+
private const ushort PORT = 27015;
14+
private readonly string IP_AND_PORT_COLON = $"{IP_ADDRESS}:{PORT}";
15+
private readonly string IP_AND_PORT_COMMA = $"{IP_ADDRESS},{PORT}";
16+
private readonly string HOST_NAME_AND_PORT_COLON = $"{HOST_NAME}:{PORT}";
17+
private readonly string HOST_NAME_AND_PORT_COMMA = $"{HOST_NAME},{PORT}";
1118

1219
[Theory]
1320
[InlineData(IP_ADDRESS)]
21+
[InlineData(HOST_NAME)]
1422
public void ShouldInitializeWithProperHost(string host)
1523
{
16-
var squery = new ServerQuery(host, PORT);
17-
var t = squery.GetPlayers();
24+
var client = new Mock<UdpClient>();
25+
client.Setup(x => x.Connect(It.IsAny<IPEndPoint>()));
26+
new ServerQuery(client.Object, It.IsAny<IPEndPoint>()).Connect(host, PORT);
27+
}
28+
29+
// Please don't hate me but i think ClassDataAttribute sucks for many reasons.
30+
[Fact]
31+
public void ShouldInitializeWithProperHostAndPort()
32+
{
33+
new ServerQuery(IP_AND_PORT_COLON);
34+
new ServerQuery(IP_AND_PORT_COMMA);
35+
new ServerQuery(HOST_NAME_AND_PORT_COLON);
36+
new ServerQuery(HOST_NAME_AND_PORT_COMMA);
1837
}
1938

2039
[Theory]
2140
[InlineData("256.256.256.256")]
2241
[InlineData("invalidHost")]
42+
[InlineData("invalidHost:-1")]
43+
[InlineData("invalidHost,-1")]
44+
[InlineData("invalidHost:65536")]
45+
[InlineData("invalidHost,65536")]
46+
[InlineData("256.256.256.256:-1")]
47+
[InlineData("256.256.256.256,-1")]
48+
[InlineData("256.256.256.256:65536")]
49+
[InlineData("256.256.256.256,65536")]
2350
public void ShouldNotInitializeWithAnInvalidHost(string invalidHost)
2451
{
2552
Assert.Throws<ArgumentException>(() =>

SteamQueryNet/SteamQueryNet.Tests/SteamQueryNet.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
<ItemGroup>
1010
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0" />
11+
<PackageReference Include="Moq" Version="4.13.1" />
1112
<PackageReference Include="xunit" Version="2.3.1" />
1213
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
1314
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />

SteamQueryNet/SteamQueryNet/ServerQuery.cs

Lines changed: 80 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
using SteamQueryNet.Models;
2-
using SteamQueryNet.Attributes;
2+
using SteamQueryNet.Utils;
3+
34
using System;
45
using System.Collections.Generic;
5-
using System.Globalization;
66
using System.Linq;
77
using System.Net;
88
using System.Net.NetworkInformation;
99
using System.Net.Sockets;
10-
using System.Reflection;
11-
using System.Runtime.InteropServices;
1210
using System.Text;
13-
using System.Threading;
1411
using System.Threading.Tasks;
15-
using SteamQueryNet.Utils;
1612

13+
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("SteamQueryNet.Tests")]
1714
namespace SteamQueryNet
1815
{
1916
// This is not really required but imma be a good guy and create this for them people that wants to mock the ServerQuery.
@@ -39,6 +36,30 @@ public interface IServerQuery
3936
/// <returns>Connected instance of ServerQuery.</returns>
4037
IServerQuery Connect(string serverAddress, ushort port);
4138

39+
/// <summary>
40+
/// Configures and Connects the created instance of SteamQuery UDP socket for Steam Server Query Operations.
41+
/// </summary>
42+
/// <param name="serverAddressAndPort">IPAddress or HostName of the server and port separated by a colon(:) or a comma(,).</param>
43+
/// <returns>Connected instance of ServerQuery.</returns>
44+
IServerQuery Connect(string serverAddressAndPort);
45+
46+
/// <summary>
47+
/// Configures and Connects the created instance of SteamQuery UDP socket for Steam Server Query Operations.
48+
/// </summary>
49+
/// <param name="customLocalIPEndpoint">Desired local IPEndpoint to bound.</param>
50+
/// <param name="serverAddressAndPort">IPAddress or HostName of the server and port separated by a colon(:) or a comma(,).</param>
51+
/// <returns>Connected instance of ServerQuery.</returns>
52+
IServerQuery Connect(IPEndPoint customLocalIPEndpoint, string serverAddressAndPort);
53+
54+
/// <summary>
55+
/// Configures and Connects the created instance of SteamQuery UDP socket for Steam Server Query Operations.
56+
/// </summary>
57+
/// <param name="customLocalIPEndpoint">Desired local IPEndpoint to bound.</param>
58+
/// <param name="serverAddress">IPAddress or HostName of the server that queries will be sent.</param>
59+
/// <param name="port">Port of the server that queries will be sent.</param>
60+
/// <returns>Connected instance of ServerQuery.</returns>
61+
IServerQuery Connect(IPEndPoint customLocalIPEndpoint, string serverAddress, ushort port);
62+
4263
/// <summary>
4364
/// Requests and serializes the server information.
4465
/// </summary>
@@ -82,20 +103,21 @@ public interface IServerQuery
82103

83104
public class ServerQuery : IServerQuery, IDisposable
84105
{
85-
private IPEndPoint _ipEndpoint;
86-
private readonly UdpClient _client = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
106+
private IPEndPoint _remoteIpEndpoint;
87107

88108
private ushort _port;
89109
private int _currentChallenge;
90110

111+
internal virtual UdpClient UdpClient { get; private set; }
112+
91113
/// <summary>
92114
/// Reflects the udp client connection state.
93115
/// </summary>
94116
public bool IsConnected
95117
{
96118
get
97119
{
98-
return _client.Client.Connected;
120+
return UdpClient.Client.Connected;
99121
}
100122
}
101123

@@ -109,6 +131,17 @@ public bool IsConnected
109131
/// </summary>
110132
public int ReceiveTimeout { get; set; }
111133

134+
/// <summary>
135+
/// Creates a new instance of ServerQuery with given UDPClient and remote endpoint.
136+
/// </summary>
137+
/// <param name="udpClient">UdpClient to communicate.</param>
138+
/// <param name="remoteEndpoint">Remote server endpoint.</param>
139+
public ServerQuery(UdpClient udpClient, IPEndPoint remoteEndpoint)
140+
{
141+
UdpClient = udpClient;
142+
_remoteIpEndpoint = remoteEndpoint;
143+
}
144+
112145
/// <summary>
113146
/// Creates a new instance of ServerQuery without UDP socket connection.
114147
/// </summary>
@@ -141,7 +174,7 @@ public ServerQuery(string serverAddressAndPort)
141174
/// <param name="serverAddressAndPort">IPAddress or HostName of the server and port separated by a colon(:) or a comma(,).</param>
142175
public ServerQuery(IPEndPoint customLocalIPEndpoint, string serverAddressAndPort)
143176
{
144-
_client = new UdpClient(customLocalIPEndpoint);
177+
UdpClient = new UdpClient(customLocalIPEndpoint);
145178
(string serverAddress, ushort port) = Helpers.ResolveIPAndPortFromString(serverAddressAndPort);
146179
PrepareAndConnect(serverAddress, port);
147180
}
@@ -154,7 +187,7 @@ public ServerQuery(IPEndPoint customLocalIPEndpoint, string serverAddressAndPort
154187
/// <param name="port">Port of the server that queries will be sent.</param>
155188
public ServerQuery(IPEndPoint customLocalIPEndpoint, string serverAddress, ushort port)
156189
{
157-
_client = new UdpClient(customLocalIPEndpoint);
190+
UdpClient = new UdpClient(customLocalIPEndpoint);
158191
PrepareAndConnect(serverAddress, port);
159192
}
160193

@@ -165,13 +198,38 @@ public IServerQuery Connect(string serverAddress, ushort port)
165198
return this;
166199
}
167200

201+
/// <inheritdoc/>
202+
public IServerQuery Connect(string serverAddressAndPort)
203+
{
204+
(string serverAddress, ushort port) = Helpers.ResolveIPAndPortFromString(serverAddressAndPort);
205+
PrepareAndConnect(serverAddress, port);
206+
return this;
207+
}
208+
209+
/// <inheritdoc/>
210+
public IServerQuery Connect(IPEndPoint customLocalIPEndpoint, string serverAddressAndPort)
211+
{
212+
UdpClient = new UdpClient(customLocalIPEndpoint);
213+
(string serverAddress, ushort port) = Helpers.ResolveIPAndPortFromString(serverAddressAndPort);
214+
PrepareAndConnect(serverAddress, port);
215+
return this;
216+
}
217+
218+
/// <inheritdoc/>
219+
public IServerQuery Connect(IPEndPoint customLocalIPEndpoint, string serverAddress, ushort port)
220+
{
221+
UdpClient = new UdpClient(customLocalIPEndpoint);
222+
PrepareAndConnect(serverAddress, port);
223+
return this;
224+
}
225+
168226
/// <inheritdoc/>
169227
public async Task<ServerInfo> GetServerInfoAsync()
170228
{
171229
const string requestPayload = "Source Engine Query\0";
172230
var sInfo = new ServerInfo
173231
{
174-
Ping = new Ping().Send(_ipEndpoint.Address).RoundtripTime
232+
Ping = new Ping().Send(_remoteIpEndpoint.Address).RoundtripTime
175233
};
176234

177235
byte[] response = await SendRequestAsync(RequestHeaders.A2S_INFO, Encoding.UTF8.GetBytes(requestPayload));
@@ -262,8 +320,8 @@ public List<Rule> GetRules()
262320
/// </summary>
263321
public void Dispose()
264322
{
265-
_client.Close();
266-
_client.Dispose();
323+
UdpClient.Close();
324+
UdpClient.Dispose();
267325
}
268326

269327
private void PrepareAndConnect(string serverAddress, ushort port)
@@ -274,7 +332,7 @@ private void PrepareAndConnect(string serverAddress, ushort port)
274332
if (IPAddress.TryParse(serverAddress, out IPAddress parsedIpAddress))
275333
{
276334
// Yep its an IP.
277-
_ipEndpoint = new IPEndPoint(parsedIpAddress, _port);
335+
_remoteIpEndpoint = new IPEndPoint(parsedIpAddress, _port);
278336
}
279337
else
280338
{
@@ -285,7 +343,7 @@ private void PrepareAndConnect(string serverAddress, ushort port)
285343
if (addresslist.Length > 0)
286344
{
287345
// We get the first address.
288-
_ipEndpoint = new IPEndPoint(addresslist[0], _port);
346+
_remoteIpEndpoint = new IPEndPoint(addresslist[0], _port);
289347
}
290348
else
291349
{
@@ -298,16 +356,17 @@ private void PrepareAndConnect(string serverAddress, ushort port)
298356
}
299357
}
300358

301-
_client.Client.SendTimeout = SendTimeout;
302-
_client.Client.ReceiveTimeout = ReceiveTimeout;
303-
_client.Connect(_ipEndpoint);
359+
UdpClient = UdpClient ?? new UdpClient(new IPEndPoint(IPAddress.Any, 0));
360+
UdpClient.Client.SendTimeout = SendTimeout;
361+
UdpClient.Client.ReceiveTimeout = ReceiveTimeout;
362+
UdpClient.Connect(_remoteIpEndpoint);
304363
}
305364

306365
private async Task<byte[]> SendRequestAsync(byte requestHeader, byte[] payload = null)
307366
{
308367
var request = BuildRequest(requestHeader, payload);
309-
await _client.SendAsync(request, request.Length);
310-
UdpReceiveResult result = await _client.ReceiveAsync();
368+
await UdpClient.SendAsync(request, request.Length);
369+
UdpReceiveResult result = await UdpClient.ReceiveAsync();
311370
return result.Buffer;
312371
}
313372

0 commit comments

Comments
 (0)