1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-11 16:32:57 +00:00

Refactor clients/options

This commit is contained in:
Jkorf
2021-12-01 13:31:54 +01:00
parent 49de7e89cc
commit 3c3b5639f5
19 changed files with 572 additions and 217 deletions
@@ -11,27 +11,12 @@ 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 RestSubClientOptions() { ApiCredentials = new ApiCredentials(key, secret) });
}
[TestCase]
public void SettingLogOutput_Should_RedirectLogOutput()
{
// arrange
var logger = new TestStringLogger();
var client = new TestBaseClient(new RestClientOptions()
var client = new TestBaseClient(new BaseRestClientOptions()
{
LogWriters = new List<ILogger> { logger }
});
@@ -71,7 +56,7 @@ namespace CryptoExchange.Net.UnitTests
{
// arrange
var logger = new TestStringLogger();
var options = new RestClientOptions()
var options = new BaseRestClientOptions()
{
LogWriters = new List<ILogger> { logger }
};
@@ -0,0 +1,300 @@
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.UnitTests.TestImplementations;
using Microsoft.Extensions.Logging;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CryptoExchange.Net.UnitTests
{
[TestFixture()]
public class OptionsTests
{
[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 RestApiClientOptions() { ApiCredentials = new ApiCredentials(key, secret) });
}
[Test]
public void TestBasicOptionsAreSet()
{
// arrange, act
var options = new TestClientOptions
{
ApiCredentials = new ApiCredentials("123", "456"),
ReceiveWindow = TimeSpan.FromSeconds(10)
};
// assert
Assert.AreEqual(options.ReceiveWindow, TimeSpan.FromSeconds(10));
Assert.AreEqual(options.ApiCredentials.Key.GetString(), "123");
Assert.AreEqual(options.ApiCredentials.Secret.GetString(), "456");
}
[Test]
public void TestApiOptionsAreSet()
{
// arrange, act
var options = new TestClientOptions
{
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("123", "456"),
BaseAddress = "http://test1.com"
},
Api2Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("789", "101"),
BaseAddress = "http://test2.com"
}
};
// assert
Assert.AreEqual(options.Api1Options.ApiCredentials.Key.GetString(), "123");
Assert.AreEqual(options.Api1Options.ApiCredentials.Secret.GetString(), "456");
Assert.AreEqual(options.Api1Options.BaseAddress, "http://test1.com");
Assert.AreEqual(options.Api2Options.ApiCredentials.Key.GetString(), "789");
Assert.AreEqual(options.Api2Options.ApiCredentials.Secret.GetString(), "101");
Assert.AreEqual(options.Api2Options.BaseAddress, "http://test2.com");
}
[Test]
public void TestNotOverridenApiOptionsAreStillDefault()
{
// arrange, act
var options = new TestClientOptions
{
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("123", "456"),
}
};
// assert
Assert.AreEqual(options.Api1Options.RateLimitingBehaviour, RateLimitingBehaviour.Wait);
Assert.AreEqual(options.Api1Options.BaseAddress, "https://api1.test.com/");
Assert.AreEqual(options.Api2Options.BaseAddress, "https://api2.test.com/");
}
[Test]
public void TestSettingDefaultBaseOptionsAreRespected()
{
// arrange
TestClientOptions.Default = new TestClientOptions
{
ApiCredentials = new ApiCredentials("123", "456"),
LogLevel = LogLevel.Trace
};
// act
var options = new TestClientOptions();
// assert
Assert.AreEqual(options.LogLevel, LogLevel.Trace);
Assert.AreEqual(options.ApiCredentials.Key.GetString(), "123");
Assert.AreEqual(options.ApiCredentials.Secret.GetString(), "456");
}
[Test]
public void TestSettingDefaultApiOptionsAreRespected()
{
// arrange
TestClientOptions.Default = new TestClientOptions
{
ApiCredentials = new ApiCredentials("123", "456"),
LogLevel = LogLevel.Trace,
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("456", "789")
}
};
// act
var options = new TestClientOptions();
// assert
Assert.AreEqual(options.ApiCredentials.Key.GetString(), "123");
Assert.AreEqual(options.ApiCredentials.Secret.GetString(), "456");
Assert.AreEqual(options.Api1Options.BaseAddress, "https://api1.test.com/");
Assert.AreEqual(options.Api1Options.ApiCredentials.Key.GetString(), "456");
Assert.AreEqual(options.Api1Options.ApiCredentials.Secret.GetString(), "789");
}
[Test]
public void TestSettingDefaultApiOptionsWithSomeOverriddenAreRespected()
{
// arrange
TestClientOptions.Default = new TestClientOptions
{
ApiCredentials = new ApiCredentials("123", "456"),
LogLevel = LogLevel.Trace,
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("456", "789")
},
Api2Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("111", "222")
}
};
// act
var options = new TestClientOptions
{
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("333", "444")
}
};
// assert
Assert.AreEqual(options.ApiCredentials.Key.GetString(), "123");
Assert.AreEqual(options.ApiCredentials.Secret.GetString(), "456");
Assert.AreEqual(options.Api1Options.ApiCredentials.Key.GetString(), "333");
Assert.AreEqual(options.Api1Options.ApiCredentials.Secret.GetString(), "444");
Assert.AreEqual(options.Api2Options.ApiCredentials.Key.GetString(), "111");
Assert.AreEqual(options.Api2Options.ApiCredentials.Secret.GetString(), "222");
}
[Test]
public void TestClientUsesCorrectOptions()
{
var client = new TestRestClient(new TestClientOptions()
{
ApiCredentials = new ApiCredentials("123", "456"),
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("111", "222")
}
});
Assert.AreEqual(client.Api1.AuthenticationProvider.Credentials.Key.GetString(), "111");
Assert.AreEqual(client.Api1.AuthenticationProvider.Credentials.Secret.GetString(), "222");
Assert.AreEqual(client.Api2.AuthenticationProvider.Credentials.Key.GetString(), "123");
Assert.AreEqual(client.Api2.AuthenticationProvider.Credentials.Secret.GetString(), "456");
}
[Test]
public void TestClientUsesCorrectOptionsWithDefault()
{
TestClientOptions.Default = new TestClientOptions()
{
ApiCredentials = new ApiCredentials("123", "456"),
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("111", "222")
}
};
var client = new TestRestClient();
Assert.AreEqual(client.Api1.AuthenticationProvider.Credentials.Key.GetString(), "111");
Assert.AreEqual(client.Api1.AuthenticationProvider.Credentials.Secret.GetString(), "222");
Assert.AreEqual(client.Api2.AuthenticationProvider.Credentials.Key.GetString(), "123");
Assert.AreEqual(client.Api2.AuthenticationProvider.Credentials.Secret.GetString(), "456");
}
[Test]
public void TestClientUsesCorrectOptionsWithOverridingDefault()
{
TestClientOptions.Default = new TestClientOptions()
{
ApiCredentials = new ApiCredentials("123", "456"),
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("111", "222")
}
};
var client = new TestRestClient(new TestClientOptions
{
Api1Options = new RestApiClientOptions
{
ApiCredentials = new ApiCredentials("333", "444")
},
Api2Options = new RestApiClientOptions()
{
BaseAddress = "http://test.com"
}
});
Assert.AreEqual(client.Api1.AuthenticationProvider.Credentials.Key.GetString(), "333");
Assert.AreEqual(client.Api1.AuthenticationProvider.Credentials.Secret.GetString(), "444");
Assert.AreEqual(client.Api2.AuthenticationProvider.Credentials.Key.GetString(), "123");
Assert.AreEqual(client.Api2.AuthenticationProvider.Credentials.Secret.GetString(), "456");
Assert.AreEqual(client.Api2.BaseAddress, "http://test.com");
}
}
public class TestClientOptions: BaseRestClientOptions
{
/// <summary>
/// Default options for the futures client
/// </summary>
public static TestClientOptions Default { get; set; } = new TestClientOptions()
{
Api1Options = new RestApiClientOptions(),
Api2Options = new RestApiClientOptions()
};
/// <summary>
/// The default receive window for requests
/// </summary>
public TimeSpan ReceiveWindow { get; set; } = TimeSpan.FromSeconds(5);
private RestApiClientOptions _api1Options = new RestApiClientOptions("https://api1.test.com/");
public RestApiClientOptions Api1Options
{
get => _api1Options;
set => _api1Options.Copy(_api1Options, value);
}
private RestApiClientOptions _api2Options = new RestApiClientOptions("https://api2.test.com/");
public RestApiClientOptions Api2Options
{
get => _api2Options;
set => _api2Options.Copy(_api2Options, value);
}
/// <summary>
/// ctor
/// </summary>
public TestClientOptions()
{
if (Default == null)
return;
Copy(this, Default);
}
/// <summary>
/// Copy the values of the def to the input
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="input"></param>
/// <param name="def"></param>
public new void Copy<T>(T input, T def) where T : TestClientOptions
{
base.Copy(input, def);
input.ReceiveWindow = def.ReceiveWindow;
input.Api1Options = new RestApiClientOptions(def.Api1Options);
input.Api2Options = new RestApiClientOptions(def.Api2Options);
}
}
}
@@ -106,9 +106,9 @@ namespace CryptoExchange.Net.UnitTests
{
// arrange
// act
var client = new TestRestClient(new TestRestClientOptions()
var client = new TestRestClient(new TestClientOptions()
{
SubOptions = new RestSubClientOptions
Api1Options = new RestApiClientOptions
{
BaseAddress = "http://test.address.com",
RateLimiters = new List<IRateLimiter> { new RateLimiter() },
@@ -119,9 +119,9 @@ namespace CryptoExchange.Net.UnitTests
// assert
Assert.IsTrue(((TestRestClientOptions)client.ClientOptions).SubOptions.BaseAddress == "http://test.address.com");
Assert.IsTrue(((TestRestClientOptions)client.ClientOptions).SubOptions.RateLimiters.Count == 1);
Assert.IsTrue(((TestRestClientOptions)client.ClientOptions).SubOptions.RateLimitingBehaviour == RateLimitingBehaviour.Fail);
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));
}
@@ -136,9 +136,9 @@ namespace CryptoExchange.Net.UnitTests
{
// arrange
// act
var client = new TestRestClient(new TestRestClientOptions()
var client = new TestRestClient(new TestClientOptions()
{
SubOptions = new RestSubClientOptions
Api1Options = new RestApiClientOptions
{
BaseAddress = "http://test.address.com"
}
@@ -19,7 +19,7 @@ namespace CryptoExchange.Net.UnitTests
//act
var client = new TestSocketClient(new TestOptions()
{
SubOptions = new SubClientOptions
SubOptions = new RestApiClientOptions
{
BaseAddress = "http://test.address.com"
},
@@ -8,11 +8,11 @@ namespace CryptoExchange.Net.UnitTests
{
public class TestBaseClient: BaseClient
{
public TestBaseClient(): base("Test", new RestClientOptions())
public TestBaseClient(): base("Test", new BaseClientOptions())
{
}
public TestBaseClient(RestClientOptions exchangeOptions) : base("Test", exchangeOptions)
public TestBaseClient(BaseRestClientOptions exchangeOptions) : base("Test", exchangeOptions)
{
}
@@ -15,17 +15,19 @@ using System.Collections.Generic;
namespace CryptoExchange.Net.UnitTests.TestImplementations
{
public class TestRestClient: RestClient
public class TestRestClient: BaseRestClient
{
public TestRestSubClient SubClient { get; }
public TestRestApi1Client Api1 { get; }
public TestRestApi2Client Api2 { get; }
public TestRestClient() : this(new TestRestClientOptions())
public TestRestClient() : this(new TestClientOptions())
{
}
public TestRestClient(TestRestClientOptions exchangeOptions) : base("Test", exchangeOptions)
public TestRestClient(TestClientOptions exchangeOptions) : base("Test", exchangeOptions)
{
SubClient = new TestRestSubClient(exchangeOptions);
Api1 = new TestRestApi1Client(exchangeOptions);
Api2 = new TestRestApi2Client(exchangeOptions);
RequestFactory = new Mock<IRequestFactory>().Object;
}
@@ -103,26 +105,35 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
public async Task<CallResult<T>> Request<T>(CancellationToken ct = default) where T:class
{
return await SendRequestAsync<T>(SubClient, new Uri("http://www.test.com"), HttpMethod.Get, ct);
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>(SubClient, new Uri("http://www.test.com"), method, default, parameters, additionalHeaders: headers);
return await SendRequestAsync<T>(Api1, new Uri("http://www.test.com"), method, default, parameters, additionalHeaders: headers);
}
}
public class TestRestSubClient: RestSubClient
public class TestRestApi1Client : RestApiClient
{
public TestRestSubClient(TestRestClientOptions options): base(options.SubOptions, null)
public TestRestApi1Client(TestClientOptions options): base(options, options.Api1Options)
{
}
public override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials)
=> new TestAuthProvider(credentials);
}
public class TestRestClientOptions: RestClientOptions
public class TestRestApi2Client : RestApiClient
{
public RestSubClientOptions SubOptions { get; set; } = new RestSubClientOptions();
public TestRestApi2Client(TestClientOptions options) : base(options, options.Api2Options)
{
}
public override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials)
=> new TestAuthProvider(credentials);
}
public class TestAuthProvider : AuthenticationProvider
@@ -135,7 +146,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
public class ParseErrorTestRestClient: TestRestClient
{
public ParseErrorTestRestClient() { }
public ParseErrorTestRestClient(TestRestClientOptions exchangeOptions) : base(exchangeOptions) { }
public ParseErrorTestRestClient(TestClientOptions exchangeOptions) : base(exchangeOptions) { }
protected override Error ParseErrorResponse(JToken error)
{
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Logging;
using CryptoExchange.Net.Objects;
@@ -9,7 +10,7 @@ using Newtonsoft.Json.Linq;
namespace CryptoExchange.Net.UnitTests.TestImplementations
{
public class TestSocketClient: SocketClient
public class TestSocketClient: BaseSocketClient
{
public TestSubSocketClient SubClient { get; }
@@ -19,7 +20,7 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
public TestSocketClient(TestOptions exchangeOptions) : base("test", exchangeOptions)
{
SubClient = new TestSubSocketClient(exchangeOptions.SubOptions);
SubClient = new TestSubSocketClient(exchangeOptions, exchangeOptions.SubOptions);
SocketFactory = new Mock<IWebsocketFactory>().Object;
Mock.Get(SocketFactory).Setup(f => f.CreateWebsocket(It.IsAny<Log>(), It.IsAny<string>())).Returns(new TestSocket());
}
@@ -67,17 +68,20 @@ namespace CryptoExchange.Net.UnitTests.TestImplementations
}
}
public class TestOptions: SocketClientOptions
public class TestOptions: BaseSocketClientOptions
{
public SubClientOptions SubOptions { get; set; } = new SubClientOptions();
public ApiClientOptions SubOptions { get; set; } = new ApiClientOptions();
}
public class TestSubSocketClient : SocketSubClient
public class TestSubSocketClient : SocketApiClient
{
public TestSubSocketClient(SubClientOptions options): base(options, options.ApiCredentials == null ? null: new TestAuthProvider(options.ApiCredentials))
public TestSubSocketClient(BaseClientOptions options, ApiClientOptions apiOptions): base(options, apiOptions)
{
}
public override AuthenticationProvider CreateAuthenticationProvider(ApiCredentials credentials)
=> new TestAuthProvider(credentials);
}
}