1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-16 19:03:01 +00:00

Updated tests

This commit is contained in:
JKorf
2022-11-13 15:31:28 +01:00
parent 66ac2972d6
commit 3365837338
13 changed files with 288 additions and 166 deletions
@@ -16,7 +16,7 @@ namespace CryptoExchange.Net.UnitTests
{
// arrange
var logger = new TestStringLogger();
var client = new TestBaseClient(new BaseRestClientOptions()
var client = new TestBaseClient(new TestOptions()
{
LogWriters = new List<ILogger> { logger }
});
@@ -56,7 +56,7 @@ namespace CryptoExchange.Net.UnitTests
{
// arrange
var logger = new TestStringLogger();
var options = new BaseRestClientOptions()
var options = new TestOptions()
{
LogWriters = new List<ILogger> { logger }
};
@@ -78,7 +78,7 @@ namespace CryptoExchange.Net.UnitTests
var client = new TestBaseClient();
// act
var result = client.Deserialize<object>("{\"testProperty\": 123}");
var result = client.SubClient.Deserialize<object>("{\"testProperty\": 123}");
// assert
Assert.IsTrue(result.Success);
@@ -91,7 +91,7 @@ namespace CryptoExchange.Net.UnitTests
var client = new TestBaseClient();
// act
var result = client.Deserialize<object>("{\"testProperty\": 123");
var result = client.SubClient.Deserialize<object>("{\"testProperty\": 123");
// assert
Assert.IsFalse(result.Success);
+1 -1
View File
@@ -248,7 +248,7 @@ namespace CryptoExchange.Net.UnitTests
}
}
public class TestClientOptions: BaseRestClientOptions
public class TestClientOptions: ClientOptions
{
/// <summary>
/// Default options for the futures client
+10 -10
View File
@@ -28,7 +28,7 @@ namespace CryptoExchange.Net.UnitTests
client.SetResponse(JsonConvert.SerializeObject(expected), out _);
// act
var result = client.Request<TestObject>().Result;
var result = client.Api1.Request<TestObject>().Result;
// assert
Assert.IsTrue(result.Success);
@@ -43,7 +43,7 @@ namespace CryptoExchange.Net.UnitTests
client.SetResponse("{\"property\": 123", out _);
// act
var result = client.Request<TestObject>().Result;
var result = client.Api1.Request<TestObject>().Result;
// assert
Assert.IsFalse(result.Success);
@@ -58,7 +58,7 @@ namespace CryptoExchange.Net.UnitTests
client.SetErrorWithoutResponse(System.Net.HttpStatusCode.BadRequest, "Invalid request");
// act
var result = await client.Request<TestObject>();
var result = await client.Api1.Request<TestObject>();
// assert
Assert.IsFalse(result.Success);
@@ -73,7 +73,7 @@ namespace CryptoExchange.Net.UnitTests
client.SetErrorWithResponse("{\"errorMessage\": \"Invalid request\", \"errorCode\": 123}", System.Net.HttpStatusCode.BadRequest);
// act
var result = await client.Request<TestObject>();
var result = await client.Api1.Request<TestObject>();
// assert
Assert.IsFalse(result.Success);
@@ -91,7 +91,7 @@ namespace CryptoExchange.Net.UnitTests
client.SetErrorWithResponse("{\"errorMessage\": \"Invalid request\", \"errorCode\": 123}", System.Net.HttpStatusCode.BadRequest);
// act
var result = await client.Request<TestObject>();
var result = await client.Api2.Request<TestObject>();
// assert
Assert.IsFalse(result.Success);
@@ -112,9 +112,9 @@ namespace CryptoExchange.Net.UnitTests
{
BaseAddress = "http://test.address.com",
RateLimiters = new List<IRateLimiter> { new RateLimiter() },
RateLimitingBehaviour = RateLimitingBehaviour.Fail
},
RequestTimeout = TimeSpan.FromMinutes(1)
RateLimitingBehaviour = RateLimitingBehaviour.Fail,
RequestTimeout = TimeSpan.FromMinutes(1)
}
});
@@ -122,7 +122,7 @@ namespace CryptoExchange.Net.UnitTests
Assert.IsTrue(((TestClientOptions)client.ClientOptions).Api1Options.BaseAddress == "http://test.address.com");
Assert.IsTrue(((TestClientOptions)client.ClientOptions).Api1Options.RateLimiters.Count == 1);
Assert.IsTrue(((TestClientOptions)client.ClientOptions).Api1Options.RateLimitingBehaviour == RateLimitingBehaviour.Fail);
Assert.IsTrue(client.ClientOptions.RequestTimeout == TimeSpan.FromMinutes(1));
Assert.IsTrue(((TestClientOptions)client.ClientOptions).Api1Options.RequestTimeout == TimeSpan.FromMinutes(1));
}
[TestCase("GET", HttpMethodParameterPosition.InUri)] // No need to test InBody for GET since thats not valid
@@ -148,7 +148,7 @@ namespace CryptoExchange.Net.UnitTests
client.SetResponse("{}", out var request);
await client.RequestWithParams<TestObject>(new HttpMethod(method), new Dictionary<string, object>
await client.Api1.RequestWithParams<TestObject>(new HttpMethod(method), new Dictionary<string, object>
{
{ "TestParam1", "Value1" },
{ "TestParam2", 2 },
@@ -1,5 +1,6 @@
using System;
using System.Threading;
using CryptoExchange.Net.Logging;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Sockets;
using CryptoExchange.Net.UnitTests.TestImplementations;
@@ -19,17 +20,17 @@ namespace CryptoExchange.Net.UnitTests
//act
var client = new TestSocketClient(new TestOptions()
{
SubOptions = new RestApiClientOptions
SubOptions = new SocketApiClientOptions
{
BaseAddress = "http://test.address.com"
},
ReconnectInterval = TimeSpan.FromSeconds(6)
BaseAddress = "http://test.address.com",
ReconnectInterval = TimeSpan.FromSeconds(6)
}
});
//assert
Assert.IsTrue(client.SubClient.Options.BaseAddress == "http://test.address.com");
Assert.IsTrue(client.ClientOptions.ReconnectInterval.TotalSeconds == 6);
Assert.IsTrue(client.SubClient.Options.ReconnectInterval.TotalSeconds == 6);
}
[TestCase(true)]
@@ -42,7 +43,7 @@ namespace CryptoExchange.Net.UnitTests
socket.CanConnect = canConnect;
//act
var connectResult = client.ConnectSocketSub(new SocketConnection(client, null, socket, null));
var connectResult = client.SubClient.ConnectSocketSub(new SocketConnection(new Log(""), client.SubClient, socket, null));
//assert
Assert.IsTrue(connectResult.Success == canConnect);
@@ -52,12 +53,18 @@ namespace CryptoExchange.Net.UnitTests
public void SocketMessages_Should_BeProcessedInDataHandlers()
{
// arrange
var client = new TestSocketClient(new TestOptions() { ReconnectInterval = TimeSpan.Zero, LogLevel = LogLevel.Debug });
var client = new TestSocketClient(new TestOptions() {
SubOptions = new SocketApiClientOptions
{
ReconnectInterval = TimeSpan.Zero,
},
LogLevel = LogLevel.Debug
});
var socket = client.CreateSocket();
socket.ShouldReconnect = true;
socket.CanConnect = true;
socket.DisconnectTime = DateTime.UtcNow;
var sub = new SocketConnection(client, null, socket, null);
var sub = new SocketConnection(new Log(""), client.SubClient, socket, null);
var rstEvent = new ManualResetEvent(false);
JToken result = null;
sub.AddSubscription(SocketSubscription.CreateForIdentifier(10, "TestHandler", true, false, (messageEvent) =>
@@ -65,7 +72,7 @@ namespace CryptoExchange.Net.UnitTests
result = messageEvent.JsonData;
rstEvent.Set();
}));
client.ConnectSocketSub(sub);
client.SubClient.ConnectSocketSub(sub);
// act
socket.InvokeMessage("{\"property\": 123}");
@@ -80,12 +87,19 @@ namespace CryptoExchange.Net.UnitTests
public void SocketMessages_Should_ContainOriginalDataIfEnabled(bool enabled)
{
// arrange
var client = new TestSocketClient(new TestOptions() { ReconnectInterval = TimeSpan.Zero, LogLevel = LogLevel.Debug, OutputOriginalData = enabled });
var client = new TestSocketClient(new TestOptions() {
SubOptions = new SocketApiClientOptions
{
ReconnectInterval = TimeSpan.Zero,
OutputOriginalData = enabled
},
LogLevel = LogLevel.Debug,
});
var socket = client.CreateSocket();
socket.ShouldReconnect = true;
socket.CanConnect = true;
socket.DisconnectTime = DateTime.UtcNow;
var sub = new SocketConnection(client, null, socket, null);
var sub = new SocketConnection(new Log(""), client.SubClient, socket, null);
var rstEvent = new ManualResetEvent(false);
string original = null;
sub.AddSubscription(SocketSubscription.CreateForIdentifier(10, "TestHandler", true, false, (messageEvent) =>
@@ -93,7 +107,7 @@ namespace CryptoExchange.Net.UnitTests
original = messageEvent.OriginalData;
rstEvent.Set();
}));
client.ConnectSocketSub(sub);
client.SubClient.ConnectSocketSub(sub);
// act
socket.InvokeMessage("{\"property\": 123}");
@@ -107,11 +121,18 @@ namespace CryptoExchange.Net.UnitTests
public void UnsubscribingStream_Should_CloseTheSocket()
{
// arrange
var client = new TestSocketClient(new TestOptions() { ReconnectInterval = TimeSpan.Zero, LogLevel = LogLevel.Debug });
var client = new TestSocketClient(new TestOptions()
{
SubOptions = new SocketApiClientOptions
{
ReconnectInterval = TimeSpan.Zero,
},
LogLevel = LogLevel.Debug
});
var socket = client.CreateSocket();
socket.CanConnect = true;
var sub = new SocketConnection(client, null, socket, null);
client.ConnectSocketSub(sub);
var sub = new SocketConnection(new Log(""), client.SubClient, socket, null);
client.SubClient.ConnectSocketSub(sub);
var us = SocketSubscription.CreateForIdentifier(10, "Test", true, false, (e) => { });
var ups = new UpdateSubscription(sub, us);
sub.AddSubscription(us);
@@ -127,15 +148,22 @@ namespace CryptoExchange.Net.UnitTests
public void UnsubscribingAll_Should_CloseAllSockets()
{
// arrange
var client = new TestSocketClient(new TestOptions() { ReconnectInterval = TimeSpan.Zero, LogLevel = LogLevel.Debug });
var client = new TestSocketClient(new TestOptions()
{
SubOptions = new SocketApiClientOptions
{
ReconnectInterval = TimeSpan.Zero,
},
LogLevel = LogLevel.Debug
});
var socket1 = client.CreateSocket();
var socket2 = client.CreateSocket();
socket1.CanConnect = true;
socket2.CanConnect = true;
var sub1 = new SocketConnection(client, null, socket1, null);
var sub2 = new SocketConnection(client, null, socket2, null);
client.ConnectSocketSub(sub1);
client.ConnectSocketSub(sub2);
var sub1 = new SocketConnection(new Log(""), client.SubClient, socket1, null);
var sub2 = new SocketConnection(new Log(""), client.SubClient, socket2, null);
client.SubClient.ConnectSocketSub(sub1);
client.SubClient.ConnectSocketSub(sub2);
// act
client.UnsubscribeAllAsync().Wait();
@@ -149,13 +177,20 @@ namespace CryptoExchange.Net.UnitTests
public void FailingToConnectSocket_Should_ReturnError()
{
// arrange
var client = new TestSocketClient(new TestOptions() { ReconnectInterval = TimeSpan.Zero, LogLevel = LogLevel.Debug });
var client = new TestSocketClient(new TestOptions()
{
SubOptions = new SocketApiClientOptions
{
ReconnectInterval = TimeSpan.Zero,
},
LogLevel = LogLevel.Debug
});
var socket = client.CreateSocket();
socket.CanConnect = false;
var sub = new SocketConnection(client, null, socket, null);
var sub1 = new SocketConnection(new Log(""), client.SubClient, socket, null);
// act
var connectResult = client.ConnectSocketSub(sub);
var connectResult = client.SubClient.ConnectSocketSub(sub1);
// assert
Assert.IsFalse(connectResult.Success);
@@ -1,19 +1,25 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Logging;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.UnitTests.TestImplementations;
using Microsoft.Extensions.Logging;
namespace CryptoExchange.Net.UnitTests
{
public class TestBaseClient: BaseClient
{
public TestBaseClient(): base("Test", new BaseClientOptions())
public TestSubClient SubClient { get; }
public TestBaseClient(): base("Test", new TestOptions())
{
SubClient = AddApiClient(new TestSubClient(new TestOptions(), new RestApiClientOptions()));
}
public TestBaseClient(BaseRestClientOptions exchangeOptions) : base("Test", exchangeOptions)
public TestBaseClient(ClientOptions exchangeOptions) : base("Test", exchangeOptions)
{
}
@@ -21,11 +27,20 @@ namespace CryptoExchange.Net.UnitTests
{
log.Write(verbosity, data);
}
}
public CallResult<T> Deserialize<T>(string data)
public class TestSubClient : RestApiClient
{
public TestSubClient(ClientOptions options, RestApiClientOptions apiOptions) : base(new Log(""), options, apiOptions)
{
return Deserialize<T>(data, null, null);
}
public CallResult<T> Deserialize<T>(string data) => Deserialize<T>(data, null, null);
public override TimeSpan GetTimeOffset() => throw new NotImplementedException();
public override TimeSyncInfo GetTimeSyncInfo() => throw new NotImplementedException();
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials) => throw new NotImplementedException();
protected override Task<WebCallResult<DateTime>> GetServerTimestampAsync() => throw new NotImplementedException();
}
public class TestAuthProvider : AuthenticationProvider
@@ -12,6 +12,7 @@ using System.Threading;
using System.Threading.Tasks;
using CryptoExchange.Net.Authentication;
using System.Collections.Generic;
using CryptoExchange.Net.Logging;
namespace CryptoExchange.Net.UnitTests.TestImplementations
{
@@ -28,7 +29,6 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
{
Api1 = new TestRestApi1Client(exchangeOptions);
Api2 = new TestRestApi2Client(exchangeOptions);
RequestFactory = new Mock<IRequestFactory>().Object;
}
public void SetResponse(string responseData, out IRequest requestObj)
@@ -50,7 +50,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
request.Setup(c => c.AddHeader(It.IsAny<string>(), It.IsAny<string>())).Callback<string, string>((key, val) => headers.Add(key, new List<string> { val }));
request.Setup(c => c.GetHeaders()).Returns(() => headers);
var factory = Mock.Get(RequestFactory);
var factory = Mock.Get(Api1.RequestFactory);
factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<Uri>(), It.IsAny<int>()))
.Callback<HttpMethod, Uri, int>((method, uri, id) =>
{
@@ -58,6 +58,15 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
request.Setup(a => a.Method).Returns(method);
})
.Returns(request.Object);
factory = Mock.Get(Api2.RequestFactory);
factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<Uri>(), It.IsAny<int>()))
.Callback<HttpMethod, Uri, int>((method, uri, id) =>
{
request.Setup(a => a.Uri).Returns(uri);
request.Setup(a => a.Method).Returns(method);
})
.Returns(request.Object);
requestObj = request.Object;
}
@@ -71,7 +80,12 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
request.Setup(c => c.GetHeaders()).Returns(new Dictionary<string, IEnumerable<string>>());
request.Setup(c => c.GetResponseAsync(It.IsAny<CancellationToken>())).Throws(we);
var factory = Mock.Get(RequestFactory);
var factory = Mock.Get(Api1.RequestFactory);
factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<Uri>(), It.IsAny<int>()))
.Returns(request.Object);
factory = Mock.Get(Api2.RequestFactory);
factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<Uri>(), It.IsAny<int>()))
.Returns(request.Object);
}
@@ -94,27 +108,33 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
request.Setup(c => c.AddHeader(It.IsAny<string>(), It.IsAny<string>())).Callback<string, string>((key, val) => headers.Add(key, new List<string> { val }));
request.Setup(c => c.GetHeaders()).Returns(headers);
var factory = Mock.Get(RequestFactory);
var factory = Mock.Get(Api1.RequestFactory);
factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<Uri>(), It.IsAny<int>()))
.Callback<HttpMethod, Uri, int>((method, uri, id) => request.Setup(a => a.Uri).Returns(uri))
.Returns(request.Object);
}
public async Task<CallResult<T>> Request<T>(CancellationToken ct = default) where T:class
{
return await SendRequestAsync<T>(Api1, new Uri("http://www.test.com"), HttpMethod.Get, ct);
}
public async Task<CallResult<T>> RequestWithParams<T>(HttpMethod method, Dictionary<string, object> parameters, Dictionary<string, string> headers) where T : class
{
return await SendRequestAsync<T>(Api1, new Uri("http://www.test.com"), method, default, parameters, additionalHeaders: headers);
factory = Mock.Get(Api2.RequestFactory);
factory.Setup(c => c.Create(It.IsAny<HttpMethod>(), It.IsAny<Uri>(), It.IsAny<int>()))
.Callback<HttpMethod, Uri, int>((method, uri, id) => request.Setup(a => a.Uri).Returns(uri))
.Returns(request.Object);
}
}
public class TestRestApi1Client : RestApiClient
{
public TestRestApi1Client(TestClientOptions options): base(options, options.Api1Options)
public TestRestApi1Client(TestClientOptions options): base(new Log(""), options, options.Api1Options)
{
RequestFactory = new Mock<IRequestFactory>().Object;
}
public async Task<CallResult<T>> Request<T>(CancellationToken ct = default) where T : class
{
return await SendRequestAsync<T>(new Uri("http://www.test.com"), HttpMethod.Get, ct);
}
public async Task<CallResult<T>> RequestWithParams<T>(HttpMethod method, Dictionary<string, object> parameters, Dictionary<string, string> headers) where T : class
{
return await SendRequestAsync<T>(new Uri("http://www.test.com"), method, default, parameters, additionalHeaders: headers);
}
public void SetParameterPosition(HttpMethod method, HttpMethodParameterPosition position)
@@ -143,9 +163,19 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
public class TestRestApi2Client : RestApiClient
{
public TestRestApi2Client(TestClientOptions options) : base(options, options.Api2Options)
public TestRestApi2Client(TestClientOptions options) : base(new Log(""), options, options.Api2Options)
{
RequestFactory = new Mock<IRequestFactory>().Object;
}
public async Task<CallResult<T>> Request<T>(CancellationToken ct = default) where T : class
{
return await SendRequestAsync<T>(new Uri("http://www.test.com"), HttpMethod.Get, ct);
}
protected override Error ParseErrorResponse(JToken error)
{
return new ServerError((int)error["errorCode"], (string)error["errorMessage"]);
}
public override TimeSpan GetTimeOffset()
@@ -186,9 +216,5 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
public ParseErrorTestRestClient() { }
public ParseErrorTestRestClient(TestClientOptions exchangeOptions) : base(exchangeOptions) { }
protected override Error ParseErrorResponse(JToken error)
{
return new ServerError((int)error["errorCode"], (string)error["errorMessage"]);
}
}
}
@@ -20,16 +20,39 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
public TestSocketClient(TestOptions exchangeOptions) : base("test", exchangeOptions)
{
SubClient = new TestSubSocketClient(exchangeOptions, exchangeOptions.SubOptions);
SocketFactory = new Mock<IWebsocketFactory>().Object;
Mock.Get(SocketFactory).Setup(f => f.CreateWebsocket(It.IsAny<Log>(), It.IsAny<WebSocketParameters>())).Returns(new TestSocket());
SubClient = AddApiClient(new TestSubSocketClient(exchangeOptions, exchangeOptions.SubOptions));
SubClient.SocketFactory = new Mock<IWebsocketFactory>().Object;
Mock.Get(SubClient.SocketFactory).Setup(f => f.CreateWebsocket(It.IsAny<Log>(), It.IsAny<WebSocketParameters>())).Returns(new TestSocket());
}
public TestSocket CreateSocket()
{
Mock.Get(SocketFactory).Setup(f => f.CreateWebsocket(It.IsAny<Log>(), It.IsAny<WebSocketParameters>())).Returns(new TestSocket());
return (TestSocket)CreateSocket("https://localhost:123/");
Mock.Get(SubClient.SocketFactory).Setup(f => f.CreateWebsocket(It.IsAny<Log>(), It.IsAny<WebSocketParameters>())).Returns(new TestSocket());
return (TestSocket)SubClient.CreateSocketInternal("https://localhost:123/");
}
}
public class TestOptions: ClientOptions
{
public SocketApiClientOptions SubOptions { get; set; } = new SocketApiClientOptions();
}
public class TestSubSocketClient : SocketApiClient
{
public TestSubSocketClient(ClientOptions options, SocketApiClientOptions apiOptions): base(new Log(""), options, apiOptions)
{
}
internal IWebsocket CreateSocketInternal(string address)
{
return CreateSocket(address);
}
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials)
=> new TestAuthProvider(credentials);
public CallResult<bool> ConnectSocketSub(SocketConnection sub)
{
@@ -67,21 +90,4 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
throw new NotImplementedException();
}
}
public class TestOptions: BaseSocketClientOptions
{
public ApiClientOptions SubOptions { get; set; } = new ApiClientOptions();
}
public class TestSubSocketClient : SocketApiClient
{
public TestSubSocketClient(BaseClientOptions options, ApiClientOptions apiOptions): base(options, apiOptions)
{
}
protected override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials)
=> new TestAuthProvider(credentials);
}
}