using CryptoExchange.Net.Objects; using CryptoExchange.Net.Testing; using CryptoExchange.Net.UnitTests.Implementations; using CryptoExchange.Net.UnitTests.TestImplementations; using NUnit.Framework; using System; using System.Linq; using System.Text.Json; using System.Threading; using System.Threading.Tasks; namespace CryptoExchange.Net.UnitTests { [TestFixture] public class SocketClientTests { [TestCase] public void SettingOptions_Should_ResultInOptionsSet() { //arrange //act var client = new TestSocketClient(options => { options.ExchangeOptions.MaxSocketConnections = 1; }); //assert Assert.That(1 == client.ApiClient1.ApiOptions.MaxSocketConnections); } [TestCase(true)] [TestCase(false)] public async Task ConnectSocket_Should_ReturnConnectionResult(bool canConnect) { //arrange var client = new TestSocketClient(); var socket = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); socket.CanConnect = canConnect; //act var connectResult = await client.ApiClient1.SubscribeToUpdatesAsync(x => { }, false, default); //assert Assert.That(connectResult.Success == canConnect); } [TestCase] public async Task SocketMessages_Should_BeProcessedInDataHandlers() { var client = new TestSocketClient(); var socket = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); var expected = new TestObject() { DecimalData = 1.23M, IntData = 10, StringData = "Some data" }; var strData = JsonSerializer.Serialize(expected, new JsonSerializerOptions { TypeInfoResolver = new TestSerializerContext() }); TestObject? received = null; var resetEvent = new AsyncResetEvent(false); await client.ApiClient1.SubscribeToUpdatesAsync(x => { received = x.Data; resetEvent.Set(); }, false, default); socket.InvokeMessage(strData); await resetEvent.WaitAsync(TimeSpan.FromSeconds(1)); Assert.That(received != null); } [TestCase(false)] [TestCase(true)] public async Task SocketMessages_Should_ContainOriginalDataIfEnabled(bool enabled) { // arrange var client = new TestSocketClient(options => { options.ReconnectInterval = TimeSpan.Zero; options.ExchangeOptions.OutputOriginalData = enabled; }); var socket = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); var expected = new TestObject() { DecimalData = 1.23M, IntData = 10, StringData = "Some data" }; var strData = JsonSerializer.Serialize(expected, new JsonSerializerOptions { TypeInfoResolver = new TestSerializerContext() }); string? originalData = null; var resetEvent = new AsyncResetEvent(false); await client.ApiClient1.SubscribeToUpdatesAsync(x => { originalData = x.OriginalData; resetEvent.Set(); }, false, default); socket.InvokeMessage(strData); await resetEvent.WaitAsync(TimeSpan.FromSeconds(1)); // assert Assert.That(originalData == (enabled ? strData : null)); } [TestCase()] public async Task UnsubscribingStream_Should_CloseTheSocket() { // arrange var client = new TestSocketClient(options => { options.ReconnectInterval = TimeSpan.Zero; }); var socket = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); var result = await client.ApiClient1.SubscribeToUpdatesAsync(x => {}, false, default); // act await client.UnsubscribeAsync(result.Data); // assert Assert.That(socket.Connected == false); } [TestCase()] public async Task UnsubscribingAll_Should_CloseAllSockets() { // arrange var client = new TestSocketClient(options => { options.ReconnectInterval = TimeSpan.Zero; }); var socket = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); var result = await client.ApiClient1.SubscribeToUpdatesAsync(x => { }, false, default); var socket2 = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); var result2 = await client.ApiClient1.SubscribeToUpdatesAsync(x => { }, false, default); // act await client.UnsubscribeAllAsync(); // assert Assert.That(socket.Connected == false); Assert.That(socket2.Connected == false); } [TestCase()] public async Task ErrorResponse_ShouldNot_ConfirmSubscription() { // arrange var client = new TestSocketClient(opt => { opt.OutputOriginalData = true; }); var socket = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); var subTask = client.ApiClient1.SubscribeToUpdatesAsync(x => { }, true, default); socket.InvokeMessage(JsonSerializer.Serialize(new TestSocketMessage { Id = 1, Data = "ErrorWithSub" })); var result = await subTask; // assert Assert.That(result.Success == false); Assert.That(result.Error!.Message!.Contains("ErrorWithSub")); } [TestCase()] public async Task SuccessResponse_Should_ConfirmSubscription() { var client = new TestSocketClient(); var socket = TestHelpers.ConfigureSocketClient(client, "wss://localhost"); var subTask = client.ApiClient1.SubscribeToUpdatesAsync(x => { }, true, default); socket.InvokeMessage(JsonSerializer.Serialize(new TestSocketMessage { Id = 1, Data = "OK" })); var result = await subTask; var subscription = client.ApiClient1._socketConnections.Single().Value.Subscriptions.Single(); Assert.That(subscription.Status == SubscriptionStatus.Subscribed); } } }