mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2025-06-10 09:26:22 +00:00
Initial unit test
This commit is contained in:
parent
3641293fd6
commit
6a0c7c417b
123
CryptoExchange.Net.UnitTests/BaseClientTests.cs
Normal file
123
CryptoExchange.Net.UnitTests/BaseClientTests.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using CryptoExchange.Net.Logging;
|
||||
using CryptoExchange.Net.Objects;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
[TestFixture()]
|
||||
public class BaseClientTests
|
||||
{
|
||||
[TestCase(null, null)]
|
||||
[TestCase("", "")]
|
||||
[TestCase("test", null)]
|
||||
[TestCase("test", "")]
|
||||
[TestCase(null, "test")]
|
||||
[TestCase("", "test")]
|
||||
public void SettingEmptyValuesForAPICredentials_Should_ThrowException(string key, string secret)
|
||||
{
|
||||
// arrange
|
||||
// act
|
||||
// assert
|
||||
Assert.Throws(typeof(ArgumentException), () => new TestBaseClient(new ClientOptions() { ApiCredentials = new ApiCredentials(key, secret) }));
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void SettingLogOutput_Should_RedirectLogOutput()
|
||||
{
|
||||
// arrange
|
||||
var stringBuilder = new StringBuilder();
|
||||
var client = new TestBaseClient(new ClientOptions()
|
||||
{
|
||||
LogWriters = new List<TextWriter> { new StringWriter(stringBuilder) }
|
||||
});
|
||||
|
||||
// act
|
||||
client.Log(LogVerbosity.Info, "Test");
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(string.IsNullOrEmpty(stringBuilder.ToString()));
|
||||
}
|
||||
|
||||
[TestCase(LogVerbosity.None, LogVerbosity.Error, false)]
|
||||
[TestCase(LogVerbosity.None, LogVerbosity.Warning, false)]
|
||||
[TestCase(LogVerbosity.None, LogVerbosity.Info, false)]
|
||||
[TestCase(LogVerbosity.None, LogVerbosity.Debug, false)]
|
||||
[TestCase(LogVerbosity.Error, LogVerbosity.Error, true)]
|
||||
[TestCase(LogVerbosity.Error, LogVerbosity.Warning, false)]
|
||||
[TestCase(LogVerbosity.Error, LogVerbosity.Info, false)]
|
||||
[TestCase(LogVerbosity.Error, LogVerbosity.Debug, false)]
|
||||
[TestCase(LogVerbosity.Warning, LogVerbosity.Error, true)]
|
||||
[TestCase(LogVerbosity.Warning, LogVerbosity.Warning, true)]
|
||||
[TestCase(LogVerbosity.Warning, LogVerbosity.Info, false)]
|
||||
[TestCase(LogVerbosity.Warning, LogVerbosity.Debug, false)]
|
||||
[TestCase(LogVerbosity.Info, LogVerbosity.Error, true)]
|
||||
[TestCase(LogVerbosity.Info, LogVerbosity.Warning, true)]
|
||||
[TestCase(LogVerbosity.Info, LogVerbosity.Info, true)]
|
||||
[TestCase(LogVerbosity.Info, LogVerbosity.Debug, false)]
|
||||
[TestCase(LogVerbosity.Debug, LogVerbosity.Error, true)]
|
||||
[TestCase(LogVerbosity.Debug, LogVerbosity.Warning, true)]
|
||||
[TestCase(LogVerbosity.Debug, LogVerbosity.Info, true)]
|
||||
[TestCase(LogVerbosity.Debug, LogVerbosity.Debug, true)]
|
||||
public void SettingLogVerbosity_Should_RestrictLogging(LogVerbosity verbosity, LogVerbosity testVerbosity, bool expected)
|
||||
{
|
||||
// arrange
|
||||
var stringBuilder = new StringBuilder();
|
||||
var client = new TestBaseClient(new ClientOptions()
|
||||
{
|
||||
LogWriters = new List<TextWriter> { new StringWriter(stringBuilder) },
|
||||
LogVerbosity = verbosity
|
||||
});
|
||||
|
||||
// act
|
||||
client.Log(testVerbosity, "Test");
|
||||
|
||||
// assert
|
||||
Assert.AreEqual(!string.IsNullOrEmpty(stringBuilder.ToString()), expected);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void DeserializingValidJson_Should_GiveSuccessfulResult()
|
||||
{
|
||||
// arrange
|
||||
var client = new TestBaseClient();
|
||||
|
||||
// act
|
||||
var result = client.Deserialize<object>("{\"testProperty\": 123}");
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(result.Success);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void DeserializingInvalidJson_Should_GiveErrorResult()
|
||||
{
|
||||
// arrange
|
||||
var client = new TestBaseClient();
|
||||
|
||||
// act
|
||||
var result = client.Deserialize<object>("{\"testProperty\": 123");
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.IsTrue(result.Error != null);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void FillingPathParameters_Should_ResultInValidUrl()
|
||||
{
|
||||
// arrange
|
||||
var client = new TestBaseClient();
|
||||
|
||||
// act
|
||||
var result = client.FillParameters("http://test.api/{}/path/{}", "1", "test");
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(result == "http://test.api/1/path/test");
|
||||
}
|
||||
}
|
||||
}
|
@ -21,207 +21,207 @@ namespace CryptoExchange.Net.UnitTests
|
||||
[TestFixture()]
|
||||
public class ExchangeClientTests
|
||||
{
|
||||
[TestCase(null, null)]
|
||||
[TestCase("", "")]
|
||||
[TestCase("test", null)]
|
||||
[TestCase("test", "")]
|
||||
[TestCase(null, "test")]
|
||||
[TestCase("", "test")]
|
||||
public void SettingEmptyValuesForAPICredentials_Should_ThrowException(string key, string secret)
|
||||
{
|
||||
// arrange
|
||||
var client = PrepareClient("");
|
||||
//[TestCase(null, null)]
|
||||
//[TestCase("", "")]
|
||||
//[TestCase("test", null)]
|
||||
//[TestCase("test", "")]
|
||||
//[TestCase(null, "test")]
|
||||
//[TestCase("", "test")]
|
||||
//public void SettingEmptyValuesForAPICredentials_Should_ThrowException(string key, string secret)
|
||||
//{
|
||||
// // arrange
|
||||
// var client = PrepareClient("");
|
||||
|
||||
// act
|
||||
// assert
|
||||
Assert.Throws(typeof(ArgumentException), () => client.SetApiCredentails(key, secret));
|
||||
}
|
||||
// // act
|
||||
// // assert
|
||||
// Assert.Throws(typeof(ArgumentException), () => client.SetApiCredentails(key, secret));
|
||||
//}
|
||||
|
||||
[TestCase()]
|
||||
public void SettingLogOutput_Should_RedirectLogOutput()
|
||||
{
|
||||
// arrange
|
||||
var stringBuilder = new StringBuilder();
|
||||
var client = PrepareClient("{}", true, LogVerbosity.Debug, new StringWriter(stringBuilder));
|
||||
//[TestCase()]
|
||||
//public void SettingLogOutput_Should_RedirectLogOutput()
|
||||
//{
|
||||
// // arrange
|
||||
// var stringBuilder = new StringBuilder();
|
||||
// var client = PrepareClient("{}", true, LogVerbosity.Debug, new StringWriter(stringBuilder));
|
||||
|
||||
// act
|
||||
client.TestCall();
|
||||
// // act
|
||||
// client.TestCall();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(string.IsNullOrEmpty(stringBuilder.ToString()));
|
||||
}
|
||||
// // assert
|
||||
// Assert.IsFalse(string.IsNullOrEmpty(stringBuilder.ToString()));
|
||||
//}
|
||||
|
||||
[TestCase()]
|
||||
public void ObjectDeserializationFail_Should_GiveFailedResult()
|
||||
{
|
||||
// arrange
|
||||
var errorMessage = "TestErrorMessage";
|
||||
var client = PrepareClient(JsonConvert.SerializeObject(errorMessage));
|
||||
//[TestCase()]
|
||||
//public void ObjectDeserializationFail_Should_GiveFailedResult()
|
||||
//{
|
||||
// // arrange
|
||||
// var errorMessage = "TestErrorMessage";
|
||||
// var client = PrepareClient(JsonConvert.SerializeObject(errorMessage));
|
||||
|
||||
// act
|
||||
var result = client.TestCall();
|
||||
// // act
|
||||
// var result = client.TestCall();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreNotEqual(0, result.Error.Code);
|
||||
Assert.IsTrue(result.Error.Message.Contains(errorMessage));
|
||||
}
|
||||
// // assert
|
||||
// Assert.IsFalse(result.Success);
|
||||
// Assert.AreNotEqual(0, result.Error.Code);
|
||||
// Assert.IsTrue(result.Error.Message.Contains(errorMessage));
|
||||
//}
|
||||
|
||||
[TestCase()]
|
||||
public void InvalidJson_Should_GiveFailedResult()
|
||||
{
|
||||
// arrange
|
||||
var errorMessage = "TestErrorMessage";
|
||||
var client = PrepareClient(JsonConvert.SerializeObject(errorMessage));
|
||||
//[TestCase()]
|
||||
//public void InvalidJson_Should_GiveFailedResult()
|
||||
//{
|
||||
// // arrange
|
||||
// var errorMessage = "TestErrorMessage";
|
||||
// var client = PrepareClient(JsonConvert.SerializeObject(errorMessage));
|
||||
|
||||
// act
|
||||
var result = client.TestCall();
|
||||
// // act
|
||||
// var result = client.TestCall();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.AreNotEqual(0, result.Error.Code);
|
||||
Assert.IsTrue(result.Error.Message.Contains(errorMessage));
|
||||
}
|
||||
// // assert
|
||||
// Assert.IsFalse(result.Success);
|
||||
// Assert.AreNotEqual(0, result.Error.Code);
|
||||
// Assert.IsTrue(result.Error.Message.Contains(errorMessage));
|
||||
//}
|
||||
|
||||
[TestCase()]
|
||||
public void WhenUsingRateLimiterTotalRequests_Should_BeDelayed()
|
||||
{
|
||||
// arrange
|
||||
var client = PrepareClient(JsonConvert.SerializeObject(new TestObject()));
|
||||
client.AddRateLimiter(new RateLimiterTotal(1, TimeSpan.FromSeconds(5)));
|
||||
//[TestCase()]
|
||||
//public void WhenUsingRateLimiterTotalRequests_Should_BeDelayed()
|
||||
//{
|
||||
// // arrange
|
||||
// var client = PrepareClient(JsonConvert.SerializeObject(new TestObject()));
|
||||
// client.AddRateLimiter(new RateLimiterTotal(1, TimeSpan.FromSeconds(5)));
|
||||
|
||||
// act
|
||||
var sw = Stopwatch.StartNew();
|
||||
client.TestCall();
|
||||
client.TestCall();
|
||||
client.TestCall();
|
||||
sw.Stop();
|
||||
// // act
|
||||
// var sw = Stopwatch.StartNew();
|
||||
// client.TestCall();
|
||||
// client.TestCall();
|
||||
// client.TestCall();
|
||||
// sw.Stop();
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(sw.ElapsedMilliseconds > 9000);
|
||||
}
|
||||
// // assert
|
||||
// Assert.IsTrue(sw.ElapsedMilliseconds > 9000);
|
||||
//}
|
||||
|
||||
[TestCase()]
|
||||
public void WhenUsingRateLimiterPerEndpointRequests_Should_BeDelayed()
|
||||
{
|
||||
// arrange
|
||||
var client = PrepareClient(JsonConvert.SerializeObject(new TestObject()));
|
||||
client.AddRateLimiter(new RateLimiterTotal(1, TimeSpan.FromSeconds(5)));
|
||||
//[TestCase()]
|
||||
//public void WhenUsingRateLimiterPerEndpointRequests_Should_BeDelayed()
|
||||
//{
|
||||
// // arrange
|
||||
// var client = PrepareClient(JsonConvert.SerializeObject(new TestObject()));
|
||||
// client.AddRateLimiter(new RateLimiterTotal(1, TimeSpan.FromSeconds(5)));
|
||||
|
||||
// act
|
||||
var sw = Stopwatch.StartNew();
|
||||
client.TestCall();
|
||||
client.TestCall();
|
||||
client.TestCall();
|
||||
sw.Stop();
|
||||
// // act
|
||||
// var sw = Stopwatch.StartNew();
|
||||
// client.TestCall();
|
||||
// client.TestCall();
|
||||
// client.TestCall();
|
||||
// sw.Stop();
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(sw.ElapsedMilliseconds > 9000);
|
||||
}
|
||||
// // assert
|
||||
// Assert.IsTrue(sw.ElapsedMilliseconds > 9000);
|
||||
//}
|
||||
|
||||
[TestCase()]
|
||||
public void WhenRemovingRateLimiterRequest_Should_NoLongerBeDelayed()
|
||||
{
|
||||
// arrange
|
||||
var client = PrepareClient(JsonConvert.SerializeObject(new TestObject()));
|
||||
client.AddRateLimiter(new RateLimiterTotal(1, TimeSpan.FromSeconds(5)));
|
||||
client.RemoveRateLimiters();
|
||||
//[TestCase()]
|
||||
//public void WhenRemovingRateLimiterRequest_Should_NoLongerBeDelayed()
|
||||
//{
|
||||
// // arrange
|
||||
// var client = PrepareClient(JsonConvert.SerializeObject(new TestObject()));
|
||||
// client.AddRateLimiter(new RateLimiterTotal(1, TimeSpan.FromSeconds(5)));
|
||||
// client.RemoveRateLimiters();
|
||||
|
||||
// act
|
||||
var sw = Stopwatch.StartNew();
|
||||
client.TestCall();
|
||||
client.TestCall();
|
||||
client.TestCall();
|
||||
sw.Stop();
|
||||
// // act
|
||||
// var sw = Stopwatch.StartNew();
|
||||
// client.TestCall();
|
||||
// client.TestCall();
|
||||
// client.TestCall();
|
||||
// sw.Stop();
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(sw.ElapsedMilliseconds < 5000);
|
||||
}
|
||||
// // assert
|
||||
// Assert.IsTrue(sw.ElapsedMilliseconds < 5000);
|
||||
//}
|
||||
|
||||
[TestCase()]
|
||||
public void ReceivingErrorStatusCode_Should_NotSuccess()
|
||||
{
|
||||
// arrange
|
||||
var client = PrepareExceptionClient(JsonConvert.SerializeObject(new TestObject()), "InvalidStatusCodeResponse", 203);
|
||||
//[TestCase()]
|
||||
//public void ReceivingErrorStatusCode_Should_NotSuccess()
|
||||
//{
|
||||
// // arrange
|
||||
// var client = PrepareExceptionClient(JsonConvert.SerializeObject(new TestObject()), "InvalidStatusCodeResponse", 203);
|
||||
|
||||
// act
|
||||
var result = client.TestCall();
|
||||
// // act
|
||||
// var result = client.TestCall();
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.IsNotNull(result.Error);
|
||||
Assert.IsTrue(result.Error.Message.Contains("InvalidStatusCodeResponse"));
|
||||
}
|
||||
// // assert
|
||||
// Assert.IsFalse(result.Success);
|
||||
// Assert.IsNotNull(result.Error);
|
||||
// Assert.IsTrue(result.Error.Message.Contains("InvalidStatusCodeResponse"));
|
||||
//}
|
||||
|
||||
private TestImplementation PrepareClient(string responseData, bool withOptions = true, LogVerbosity verbosity = LogVerbosity.Warning, TextWriter tw = null)
|
||||
{
|
||||
var expectedBytes = Encoding.UTF8.GetBytes(responseData);
|
||||
var responseStream = new MemoryStream();
|
||||
responseStream.Write(expectedBytes, 0, expectedBytes.Length);
|
||||
responseStream.Seek(0, SeekOrigin.Begin);
|
||||
//private TestRestClient PrepareClient(string responseData, bool withOptions = true, LogVerbosity verbosity = LogVerbosity.Warning, TextWriter tw = null)
|
||||
//{
|
||||
// var expectedBytes = Encoding.UTF8.GetBytes(responseData);
|
||||
// var responseStream = new MemoryStream();
|
||||
// responseStream.Write(expectedBytes, 0, expectedBytes.Length);
|
||||
// responseStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var response = new Mock<IResponse>();
|
||||
response.Setup(c => c.GetResponseStream()).Returns(responseStream);
|
||||
// var response = new Mock<IResponse>();
|
||||
// response.Setup(c => c.GetResponseStream()).Returns(responseStream);
|
||||
|
||||
var request = new Mock<IRequest>();
|
||||
request.Setup(c => c.Headers).Returns(new WebHeaderCollection());
|
||||
request.Setup(c => c.Uri).Returns(new Uri("http://www.test.com"));
|
||||
request.Setup(c => c.GetResponse()).Returns(Task.FromResult(response.Object));
|
||||
// var request = new Mock<IRequest>();
|
||||
// request.Setup(c => c.Headers).Returns(new WebHeaderCollection());
|
||||
// request.Setup(c => c.Uri).Returns(new Uri("http://www.test.com"));
|
||||
// request.Setup(c => c.GetResponse()).Returns(Task.FromResult(response.Object));
|
||||
|
||||
var factory = new Mock<IRequestFactory>();
|
||||
factory.Setup(c => c.Create(It.IsAny<string>()))
|
||||
.Returns(request.Object);
|
||||
TestImplementation client;
|
||||
if (withOptions)
|
||||
{
|
||||
var options = new ClientOptions()
|
||||
{
|
||||
ApiCredentials = new ApiCredentials("Test", "Test2"),
|
||||
LogVerbosity = verbosity
|
||||
};
|
||||
if (tw != null)
|
||||
options.LogWriters = new List<TextWriter>() { tw };
|
||||
// var factory = new Mock<IRequestFactory>();
|
||||
// factory.Setup(c => c.Create(It.IsAny<string>()))
|
||||
// .Returns(request.Object);
|
||||
// TestRestClient client;
|
||||
// if (withOptions)
|
||||
// {
|
||||
// var options = new ClientOptions()
|
||||
// {
|
||||
// ApiCredentials = new ApiCredentials("Test", "Test2"),
|
||||
// LogVerbosity = verbosity
|
||||
// };
|
||||
// if (tw != null)
|
||||
// options.LogWriters = new List<TextWriter>() { tw };
|
||||
|
||||
client = new TestImplementation(options);
|
||||
}
|
||||
else
|
||||
{
|
||||
client = new TestImplementation();
|
||||
}
|
||||
client.RequestFactory = factory.Object;
|
||||
return client;
|
||||
}
|
||||
// client = new TestRestClient(options);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// client = new TestRestClient();
|
||||
// }
|
||||
// client.RequestFactory = factory.Object;
|
||||
// return client;
|
||||
//}
|
||||
|
||||
private TestImplementation PrepareExceptionClient(string responseData, string exceptionMessage, int statusCode, bool credentials = true)
|
||||
{
|
||||
var expectedBytes = Encoding.UTF8.GetBytes(responseData);
|
||||
var responseStream = new MemoryStream();
|
||||
responseStream.Write(expectedBytes, 0, expectedBytes.Length);
|
||||
responseStream.Seek(0, SeekOrigin.Begin);
|
||||
//private TestRestClient PrepareExceptionClient(string responseData, string exceptionMessage, int statusCode, bool credentials = true)
|
||||
//{
|
||||
// var expectedBytes = Encoding.UTF8.GetBytes(responseData);
|
||||
// var responseStream = new MemoryStream();
|
||||
// responseStream.Write(expectedBytes, 0, expectedBytes.Length);
|
||||
// responseStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var we = new WebException();
|
||||
var r = new HttpWebResponse();
|
||||
var re = new HttpResponseMessage();
|
||||
// var we = new WebException();
|
||||
// var r = new HttpWebResponse();
|
||||
// var re = new HttpResponseMessage();
|
||||
|
||||
typeof(HttpResponseMessage).GetField("_statusCode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(re, (HttpStatusCode)statusCode);
|
||||
typeof(HttpWebResponse).GetField("_httpResponseMessage", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(r, re);
|
||||
typeof(WebException).GetField("_message", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, exceptionMessage);
|
||||
typeof(WebException).GetField("_response", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, r);
|
||||
// typeof(HttpResponseMessage).GetField("_statusCode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(re, (HttpStatusCode)statusCode);
|
||||
// typeof(HttpWebResponse).GetField("_httpResponseMessage", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(r, re);
|
||||
// typeof(WebException).GetField("_message", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, exceptionMessage);
|
||||
// typeof(WebException).GetField("_response", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, r);
|
||||
|
||||
var response = new Mock<IResponse>();
|
||||
response.Setup(c => c.GetResponseStream()).Throws(we);
|
||||
// var response = new Mock<IResponse>();
|
||||
// response.Setup(c => c.GetResponseStream()).Throws(we);
|
||||
|
||||
var request = new Mock<IRequest>();
|
||||
request.Setup(c => c.Headers).Returns(new WebHeaderCollection());
|
||||
request.Setup(c => c.GetResponse()).Returns(Task.FromResult(response.Object));
|
||||
// var request = new Mock<IRequest>();
|
||||
// request.Setup(c => c.Headers).Returns(new WebHeaderCollection());
|
||||
// request.Setup(c => c.GetResponse()).Returns(Task.FromResult(response.Object));
|
||||
|
||||
var factory = new Mock<IRequestFactory>();
|
||||
factory.Setup(c => c.Create(It.IsAny<string>()))
|
||||
.Returns(request.Object);
|
||||
// var factory = new Mock<IRequestFactory>();
|
||||
// factory.Setup(c => c.Create(It.IsAny<string>()))
|
||||
// .Returns(request.Object);
|
||||
|
||||
TestImplementation client = credentials ? new TestImplementation(new ClientOptions() { ApiCredentials = new ApiCredentials("Test", "Test2") }) : new TestImplementation();
|
||||
client.RequestFactory = factory.Object;
|
||||
return client;
|
||||
}
|
||||
// TestRestClient client = credentials ? new TestRestClient(new ClientOptions() { ApiCredentials = new ApiCredentials("Test", "Test2") }) : new TestRestClient();
|
||||
// client.RequestFactory = factory.Object;
|
||||
// return client;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
81
CryptoExchange.Net.UnitTests/RestClientTests.cs
Normal file
81
CryptoExchange.Net.UnitTests/RestClientTests.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using CryptoExchange.Net.Logging;
|
||||
using CryptoExchange.Net.Objects;
|
||||
using CryptoExchange.Net.UnitTests.TestImplementations;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
[TestFixture()]
|
||||
public class RestClientTests
|
||||
{
|
||||
[TestCase]
|
||||
public void RequestingData_Should_ResultInData()
|
||||
{
|
||||
// arrange
|
||||
var client = new TestRestClient();
|
||||
var expected = new TestObject() { DecimalData = 1.23M, IntData = 10, StringData = "Some data" };
|
||||
client.SetResponse(JsonConvert.SerializeObject(expected));
|
||||
|
||||
// act
|
||||
var result = client.Request<TestObject>().Result;
|
||||
|
||||
// assert
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.IsTrue(TestHelpers.AreEqual(expected, result.Data));
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void ReceivingInvalidData_Should_ResultInError()
|
||||
{
|
||||
// arrange
|
||||
var client = new TestRestClient();
|
||||
client.SetResponse("{\"property\": 123");
|
||||
|
||||
// act
|
||||
var result = client.Request<TestObject>().Result;
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.IsTrue(result.Error != null);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void ReceivingErrorCode_Should_ResultInError()
|
||||
{
|
||||
// arrange
|
||||
var client = new TestRestClient();
|
||||
client.SetErrorWithoutResponse(System.Net.HttpStatusCode.BadRequest, "Invalid request");
|
||||
|
||||
// act
|
||||
var result = client.Request<TestObject>().Result;
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.IsTrue(result.Error != null);
|
||||
}
|
||||
|
||||
[TestCase]
|
||||
public void ReceivingErrorAndParsingError_Should_ResultInParsedError()
|
||||
{
|
||||
// arrange
|
||||
var client = new ParseErrorTestRestClient();
|
||||
client.SetErrorWithResponse("{\"errorMessage\": \"Invalid request\", \"errorCode\": 123}", System.Net.HttpStatusCode.BadRequest);
|
||||
|
||||
// act
|
||||
var result = client.Request<TestObject>().Result;
|
||||
|
||||
// assert
|
||||
Assert.IsFalse(result.Success);
|
||||
Assert.IsTrue(result.Error != null);
|
||||
Assert.IsTrue(result.Error is ServerError);
|
||||
Assert.IsTrue(result.Error.Code == 123);
|
||||
Assert.IsTrue(result.Error.Message == "Invalid request");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using CryptoExchange.Net.Authentication;
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
using CryptoExchange.Net.Logging;
|
||||
using CryptoExchange.Net.Objects;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests
|
||||
{
|
||||
public class TestImplementation: RestClient
|
||||
{
|
||||
public TestImplementation(): base(new ClientOptions(), null) { }
|
||||
|
||||
public TestImplementation(ClientOptions exchangeOptions) : base(exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
|
||||
public class TestBaseClient: BaseClient
|
||||
{
|
||||
public TestBaseClient(): base(new ClientOptions(), null)
|
||||
{
|
||||
}
|
||||
|
||||
public void SetApiCredentails(string key, string secret)
|
||||
public TestBaseClient(ClientOptions exchangeOptions) : base(exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
|
||||
{
|
||||
SetAuthenticationProvider(new TestAuthProvider(new ApiCredentials(key, secret)));
|
||||
}
|
||||
|
||||
public CallResult<TestObject> TestCall()
|
||||
public void Log(LogVerbosity verbosity, string data)
|
||||
{
|
||||
return ExecuteRequest<TestObject>(new Uri("http://www.test.com")).Result;
|
||||
log.Write(verbosity, data);
|
||||
}
|
||||
|
||||
public CallResult<T> Deserialize<T>(string data)
|
||||
{
|
||||
return Deserialize<T>(data, false);
|
||||
}
|
||||
|
||||
public string FillParameters(string path, params string[] values)
|
||||
{
|
||||
return FillPathParameter(path, values);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,10 +52,4 @@ namespace CryptoExchange.Net.UnitTests
|
||||
return toSign;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestObject
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public List<string> Data { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests.TestImplementations
|
||||
{
|
||||
public class TestHelpers
|
||||
{
|
||||
[ExcludeFromCodeCoverage]
|
||||
public static bool AreEqual<T>(T self, T to, params string[] ignore) where T : class
|
||||
{
|
||||
if (self != null && to != null)
|
||||
{
|
||||
var type = self.GetType();
|
||||
var ignoreList = new List<string>(ignore);
|
||||
foreach (var pi in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (ignoreList.Contains(pi.Name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var selfValue = type.GetProperty(pi.Name).GetValue(self, null);
|
||||
var toValue = type.GetProperty(pi.Name).GetValue(to, null);
|
||||
|
||||
if (pi.PropertyType.IsClass && !pi.PropertyType.Module.ScopeName.Equals("System.Private.CoreLib.dll"))
|
||||
{
|
||||
// Check of "CommonLanguageRuntimeLibrary" is needed because string is also a class
|
||||
if (AreEqual(selfValue, toValue, ignore))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return self == to;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests.TestImplementations
|
||||
{
|
||||
public class TestObject
|
||||
{
|
||||
[JsonProperty("other")]
|
||||
public string StringData { get; set; }
|
||||
public int IntData { get; set; }
|
||||
public decimal DecimalData { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
using CryptoExchange.Net.Interfaces;
|
||||
using CryptoExchange.Net.Objects;
|
||||
using Moq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CryptoExchange.Net.UnitTests.TestImplementations
|
||||
{
|
||||
public class TestRestClient: RestClient
|
||||
{
|
||||
public TestRestClient() : base(new ClientOptions(), null)
|
||||
{
|
||||
RequestFactory = new Mock<IRequestFactory>().Object;
|
||||
}
|
||||
|
||||
public TestRestClient(ClientOptions exchangeOptions) : base(exchangeOptions, exchangeOptions.ApiCredentials == null ? null : new TestAuthProvider(exchangeOptions.ApiCredentials))
|
||||
{
|
||||
}
|
||||
|
||||
public void SetResponse(string responseData)
|
||||
{
|
||||
var expectedBytes = Encoding.UTF8.GetBytes(responseData);
|
||||
var responseStream = new MemoryStream();
|
||||
responseStream.Write(expectedBytes, 0, expectedBytes.Length);
|
||||
responseStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var response = new Mock<IResponse>();
|
||||
response.Setup(c => c.GetResponseStream()).Returns(responseStream);
|
||||
|
||||
var request = new Mock<IRequest>();
|
||||
request.Setup(c => c.Headers).Returns(new WebHeaderCollection());
|
||||
request.Setup(c => c.Uri).Returns(new Uri("http://www.test.com"));
|
||||
request.Setup(c => c.GetResponse()).Returns(Task.FromResult(response.Object));
|
||||
|
||||
var factory = Mock.Get(RequestFactory);
|
||||
factory.Setup(c => c.Create(It.IsAny<string>()))
|
||||
.Returns(request.Object);
|
||||
}
|
||||
|
||||
public void SetErrorWithoutResponse(HttpStatusCode code, string message)
|
||||
{
|
||||
var we = new WebException();
|
||||
var r = new HttpWebResponse();
|
||||
var re = new HttpResponseMessage();
|
||||
|
||||
typeof(HttpResponseMessage).GetField("_statusCode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(re, code);
|
||||
typeof(HttpWebResponse).GetField("_httpResponseMessage", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(r, re);
|
||||
typeof(WebException).GetField("_message", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, message);
|
||||
typeof(WebException).GetField("_response", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, r);
|
||||
|
||||
var response = new Mock<IResponse>();
|
||||
response.Setup(c => c.GetResponseStream()).Throws(we);
|
||||
|
||||
var request = new Mock<IRequest>();
|
||||
request.Setup(c => c.Headers).Returns(new WebHeaderCollection());
|
||||
request.Setup(c => c.GetResponse()).Returns(Task.FromResult(response.Object));
|
||||
|
||||
var factory = Mock.Get(RequestFactory);
|
||||
factory.Setup(c => c.Create(It.IsAny<string>()))
|
||||
.Returns(request.Object);
|
||||
}
|
||||
|
||||
public void SetErrorWithResponse(string responseData, HttpStatusCode code)
|
||||
{
|
||||
var expectedBytes = Encoding.UTF8.GetBytes(responseData);
|
||||
var responseStream = new MemoryStream();
|
||||
responseStream.Write(expectedBytes, 0, expectedBytes.Length);
|
||||
responseStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var we = new WebException();
|
||||
var r = new HttpWebResponse();
|
||||
var re = new HttpResponseMessage();
|
||||
|
||||
typeof(HttpResponseMessage).GetField("_statusCode", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(re, code);
|
||||
typeof(HttpWebResponse).GetField("_httpResponseMessage", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(r, re);
|
||||
typeof(WebException).GetField("_message", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, "");
|
||||
typeof(WebException).GetField("_response", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).SetValue(we, r);
|
||||
|
||||
var response = new Mock<IResponse>();
|
||||
response.Setup(c => c.GetResponseStream()).Returns(responseStream);
|
||||
|
||||
var request = new Mock<IRequest>();
|
||||
request.Setup(c => c.Headers).Returns(new WebHeaderCollection());
|
||||
request.Setup(c => c.GetResponse()).Returns(Task.FromResult(response.Object));
|
||||
|
||||
var factory = Mock.Get(RequestFactory);
|
||||
factory.Setup(c => c.Create(It.IsAny<string>()))
|
||||
.Returns(request.Object);
|
||||
}
|
||||
|
||||
public async Task<CallResult<T>> Request<T>() where T:class
|
||||
{
|
||||
return await ExecuteRequest<T>(new Uri("http://www.test.com"));
|
||||
}
|
||||
}
|
||||
|
||||
public class ParseErrorTestRestClient: TestRestClient
|
||||
{
|
||||
public ParseErrorTestRestClient() { }
|
||||
public ParseErrorTestRestClient(ClientOptions exchangeOptions) : base(exchangeOptions) { }
|
||||
|
||||
protected override Error ParseErrorResponse(string error)
|
||||
{
|
||||
var data = JToken.Parse(error);
|
||||
return new ServerError((int)data["errorCode"], (string)data["errorMessage"]);
|
||||
}
|
||||
}
|
||||
}
|
@ -70,7 +70,28 @@ namespace CryptoExchange.Net
|
||||
/// <returns></returns>
|
||||
protected CallResult<T> Deserialize<T>(string data, bool checkObject = true, JsonSerializer serializer = null)
|
||||
{
|
||||
return Deserialize<T>(JToken.Parse(data), checkObject, serializer);
|
||||
try
|
||||
{
|
||||
return Deserialize<T>(JToken.Parse(data), checkObject, serializer);
|
||||
}
|
||||
catch (JsonReaderException jre)
|
||||
{
|
||||
var info = $"Deserialize JsonReaderException: {jre.Message}, Path: {jre.Path}, LineNumber: {jre.LineNumber}, LinePosition: {jre.LinePosition}. Data: {data}";
|
||||
log.Write(LogVerbosity.Error, info);
|
||||
return new CallResult<T>(default(T), new DeserializeError(info));
|
||||
}
|
||||
catch (JsonSerializationException jse)
|
||||
{
|
||||
var info = $"Deserialize JsonSerializationException: {jse.Message}. Data: {data}";
|
||||
log.Write(LogVerbosity.Error, info);
|
||||
return new CallResult<T>(default(T), new DeserializeError(info));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var info = $"Deserialize Unknown Exception: {ex.Message}. Data: {data}";
|
||||
log.Write(LogVerbosity.Error, info);
|
||||
return new CallResult<T>(default(T), new DeserializeError(info));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -17,11 +17,8 @@ namespace CryptoExchange.Net.Logging
|
||||
get => level;
|
||||
set
|
||||
{
|
||||
if (level != value)
|
||||
{
|
||||
Write(LogVerbosity.Info, "Loglevel set to " + value);
|
||||
level = value;
|
||||
}
|
||||
if (level != value)
|
||||
level = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user