Skip to content

Commit

Permalink
Websocket refactoring (#103)
Browse files Browse the repository at this point in the history
Websocket refactoring
  • Loading branch information
JKorf authored Feb 24, 2024
1 parent ce2a5fa commit ff38021
Show file tree
Hide file tree
Showing 59 changed files with 1,166 additions and 1,381 deletions.
7 changes: 2 additions & 5 deletions Huobi.Net.UnitTests/HuobiClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@
using Newtonsoft.Json;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using CryptoExchange.Net.Authentication;
using System.Threading.Tasks;
using Huobi.Net.Enums;
using System.Reflection;
using System.Diagnostics;
using CryptoExchange.Net.Objects;
using CryptoExchange.Net.Sockets;
using Huobi.Net.Clients;
using Huobi.Net.Clients.SpotApi;
using Huobi.Net.ExtensionMethods;
using CryptoExchange.Net.Objects.Sockets;

namespace Huobi.Net.UnitTests
{
Expand Down
110 changes: 55 additions & 55 deletions Huobi.Net.UnitTests/HuobiSocketClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CryptoExchange.Net;
using Huobi.Net.Enums;
using Huobi.Net.Objects;
Expand All @@ -18,7 +19,7 @@ namespace Huobi.Net.UnitTests
public class HuobiSocketClientTests
{
[Test]
public void SubscribeV1_Should_SucceedIfSubbedResponse()
public async Task SubscribeV1_Should_SucceedIfSubbedResponse()
{
// arrange
var socket = new TestSocket();
Expand All @@ -28,15 +29,15 @@ public void SubscribeV1_Should_SucceedIfSubbedResponse()
// act
var subTask = client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => { });
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\":\"{id}\", \"status\": \"ok\"}}");
await socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\":\"{id}\", \"status\": \"ok\"}}");
var subResult = subTask.Result;

// assert
Assert.IsTrue(subResult.Success);
}

[Test]
public void SubscribeV1_Should_FailIfNoResponse()
public async Task SubscribeV1_Should_FailIfNoResponse()
{
// arrange
var socket = new TestSocket();
Expand All @@ -47,15 +48,14 @@ public void SubscribeV1_Should_FailIfNoResponse()
});

// act
var subTask = client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => { });
var subResult = subTask.Result;
var subResult = await client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => { });

// assert
Assert.IsFalse(subResult.Success);
}

[Test]
public void SubscribeV1_Should_FailIfErrorResponse()
public async Task SubscribeV1_Should_FailIfErrorResponse()
{
// arrange
var socket = new TestSocket();
Expand All @@ -65,15 +65,15 @@ public void SubscribeV1_Should_FailIfErrorResponse()
// act
var subTask = client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => { });
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"status\": \"error\", \"id\": \"{id}\", \"err-code\": \"Fail\", \"err-msg\": \"failed\"}}");
await socket.InvokeMessage($"{{\"status\": \"error\", \"id\": \"{id}\", \"err-code\": \"Fail\", \"err-msg\": \"failed\"}}");
var subResult = subTask.Result;

// assert
Assert.IsFalse(subResult.Success);
}

[Test]
public void SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate()
public async Task SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate()
{
// arrange
var socket = new TestSocket();
Expand All @@ -83,7 +83,7 @@ public void SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate()
HuobiOrderBook result = null;
var subTask = client.SpotApi.SubscribeToPartialOrderBookUpdates1SecondAsync("ETHBTC", 1, test => result = test.Data);
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"status\": \"ok\", \"id\": \"{id}\"}}");
await socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"status\": \"ok\", \"id\": \"{id}\"}}");
var subResult = subTask.Result;

var expected = new HuobiOrderBook()
Expand All @@ -99,7 +99,7 @@ public void SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate()
};

// act
socket.InvokeMessage(SerializeExpected("market.ethbtc.depth.step1", expected));
await socket.InvokeMessage(SerializeExpected("market.ethbtc.depth.step1", expected));

// assert
Assert.IsTrue(subResult.Success);
Expand All @@ -108,17 +108,17 @@ public void SubscribeToDepthUpdates_Should_TriggerWithDepthUpdate()
}

[Test]
public void SubscribeToDetailUpdates_Should_TriggerWithDetailUpdate()
public async Task SubscribeToDetailUpdates_Should_TriggerWithDetailUpdate()
{
// arrange
var socket = new TestSocket();
socket.CanConnect = true;
var client = TestHelpers.CreateSocketClient(socket);

HuobiSymbolData result = null;
HuobiSymbolDetails result = null;
var subTask = client.SpotApi.SubscribeToSymbolDetailUpdatesAsync("ETHBTC", test => result = test.Data);
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}");
await socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}");
var subResult = subTask.Result;

var expected = new HuobiSymbolData()
Expand All @@ -133,15 +133,15 @@ public void SubscribeToDetailUpdates_Should_TriggerWithDetailUpdate()
};

// act
socket.InvokeMessage(SerializeExpected("market.ethbtc.detail", expected));
await socket.InvokeMessage(SerializeExpected("market.ethbtc.detail", expected));

// assert
Assert.IsTrue(subResult.Success);
Assert.IsTrue(TestHelpers.AreEqual(expected, result));
}

[Test]
public void SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate()
public async Task SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate()
{
// arrange
var socket = new TestSocket();
Expand All @@ -151,7 +151,7 @@ public void SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate()
HuobiSymbolData result = null;
var subTask = client.SpotApi.SubscribeToKlineUpdatesAsync("ETHBTC", KlineInterval.FiveMinutes, test => result = test.Data);
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}");
await socket.InvokeMessage($"{{\"subbed\": \"ethbtc\", \"id\": \"{id}\", \"status\": \"ok\"}}");
var subResult = subTask.Result;

var expected = new HuobiSymbolData()
Expand All @@ -166,30 +166,30 @@ public void SubscribeToKlineUpdates_Should_TriggerWithKlineUpdate()
};

// act
socket.InvokeMessage(SerializeExpected("market.ethbtc.kline.5min", expected));
await socket.InvokeMessage(SerializeExpected("market.ethbtc.kline.5min", expected));

// assert
Assert.IsTrue(subResult.Success);
Assert.IsTrue(TestHelpers.AreEqual(expected, result));
}

[Test]
public void SubscribeToTickerUpdates_Should_TriggerWithTickerUpdate()
public async Task SubscribeToTickerUpdates_Should_TriggerWithTickerUpdate()
{
// arrange
var socket = new TestSocket();
socket.CanConnect = true;
var client = TestHelpers.CreateSocketClient(socket);

HuobiSymbolDatas result = null;
IEnumerable<HuobiSymbolTicker> result = null;
var subTask = client.SpotApi.SubscribeToTickerUpdatesAsync((test => result = test.Data));
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}");
await socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}");
var subResult = subTask.Result;

var expected = new List<HuobiSymbolData>
var expected = new List<HuobiSymbolTicker>
{
new HuobiSymbolData()
new HuobiSymbolTicker()
{
QuoteVolume = 0.1m,
ClosePrice = 0.2m,
Expand All @@ -202,15 +202,15 @@ public void SubscribeToTickerUpdates_Should_TriggerWithTickerUpdate()
};

// act
socket.InvokeMessage(SerializeExpected("market.tickers", expected));
await socket.InvokeMessage(SerializeExpected("market.tickers", expected));

// assert
Assert.IsTrue(subResult.Success);
Assert.IsTrue(TestHelpers.AreEqual(expected[0], result.Ticks.ToList()[0]));
Assert.IsTrue(TestHelpers.AreEqual(expected[0], result.First()));
}

[Test]
public void SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate()
public async Task SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate()
{
// arrange
var socket = new TestSocket();
Expand All @@ -220,7 +220,7 @@ public void SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate()
HuobiSymbolTrade result = null;
var subTask = client.SpotApi.SubscribeToTradeUpdatesAsync("ethusdt", test => result = test.Data);
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}");
await socket.InvokeMessage($"{{\"subbed\": \"test\", \"id\": \"{id}\", \"status\": \"ok\"}}");
var subResult = subTask.Result;

var expected =
Expand All @@ -242,7 +242,7 @@ public void SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate()
};

// act
socket.InvokeMessage(SerializeExpected("market.ethusdt.trade.detail", expected));
await socket.InvokeMessage(SerializeExpected("market.ethusdt.trade.detail", expected));

// assert
Assert.IsTrue(subResult.Success);
Expand All @@ -251,7 +251,7 @@ public void SubscribeToTradeUpdates_Should_TriggerWithTradeUpdate()
}

[Test]
public void SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate()
public async Task SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate()
{
// arrange
var socket = new TestSocket();
Expand All @@ -260,9 +260,9 @@ public void SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate()

HuobiAccountUpdate result = null;
var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => result = test.Data);
socket.InvokeMessage("{\"ch\": \"auth\", \"code\": 200, \"action\": \"req\"}");
await socket.InvokeMessage("{\"ch\": \"auth\", \"code\": 200, \"action\": \"req\"}");
Thread.Sleep(100);
socket.InvokeMessage($"{{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}}");
await socket.InvokeMessage($"{{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}}");
var subResult = subTask.Result;

var expected = new HuobiAccountUpdate()
Expand All @@ -277,15 +277,15 @@ public void SubscribeToAccountUpdates_Should_TriggerWithAccountUpdate()
};

// act
socket.InvokeMessage(SerializeExpectedAuth("accounts.update#1", expected));
await socket.InvokeMessage(SerializeExpectedAuth("accounts.update#1", expected));

// assert
Assert.IsTrue(subResult.Success);
Assert.IsTrue(TestHelpers.AreEqual(expected, result));
}

[Test]
public void SubscribeV2_Should_SucceedIfSubbedResponse()
public async Task SubscribeV2_Should_SucceedIfSubbedResponse()
{
// arrange
var socket = new TestSocket();
Expand All @@ -294,17 +294,17 @@ public void SubscribeV2_Should_SucceedIfSubbedResponse()

// act
var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => { });
socket.InvokeMessage("{\"action\": \"req\", \"code\": 200, \"ch\": \"auth\"}");
await socket.InvokeMessage("{\"action\": \"req\", \"code\": 200, \"ch\": \"auth\"}");
Thread.Sleep(10);
socket.InvokeMessage("{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}");
await socket.InvokeMessage("{\"action\": \"sub\", \"code\": 200, \"ch\": \"accounts.update#1\"}");
var subResult = subTask.Result;

// assert
Assert.IsTrue(subResult.Success);
}

[Test]
public void SubscribeV2_Should_FailIfAuthErrorResponse()
public async Task SubscribeV2_Should_FailIfAuthErrorResponse()
{
// arrange
var socket = new TestSocket();
Expand All @@ -313,32 +313,32 @@ public void SubscribeV2_Should_FailIfAuthErrorResponse()

// act
var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => { });
socket.InvokeMessage("{ \"action\": \"req\", \"ch\": \"auth\", \"code\": 400}");
await socket.InvokeMessage("{ \"action\": \"req\", \"ch\": \"auth\", \"code\": 400}");
var subResult = subTask.Result;

// assert
Assert.IsFalse(subResult.Success);
}

[Test]
public void SubscribeV2_Should_FailIfErrorResponse()
{
// arrange
var socket = new TestSocket();
socket.CanConnect = true;
var client = TestHelpers.CreateSocketClient(socket);

// act
var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => { });
socket.InvokeMessage("{\"op\": \"auth\"}");
Thread.Sleep(10);
var id = JToken.Parse(socket.LastSendMessage)["id"];
socket.InvokeMessage($"{{\"op\": \"sub\", \"cid\": \"{id}\", \"status\": \"error\", \"err-code\": 1, \"err-msg\": \"failed\"}}");
var subResult = subTask.Result;

// assert
Assert.IsFalse(subResult.Success);
}
//[Test]
//public async Task SubscribeV2_Should_FailIfErrorResponse()
//{
// // arrange
// var socket = new TestSocket();
// socket.CanConnect = true;
// var client = TestHelpers.CreateSocketClient(socket);

// // act
// var subTask = client.SpotApi.SubscribeToAccountUpdatesAsync(test => { });
// await socket.InvokeMessage("{\"op\": \"auth\"}");
// Thread.Sleep(10);
// var id = JToken.Parse(socket.LastSendMessage)["id"];
// await socket.InvokeMessage($"{{\"op\": \"sub\", \"cid\": \"{id}\", \"status\": \"error\", \"err-code\": 1, \"err-msg\": \"failed\"}}");
// var subResult = subTask.Result;

// // assert
// Assert.IsFalse(subResult.Success);
//}

[Test]
public void SubscribeV2_Should_FailIfNoResponse()
Expand Down
1 change: 1 addition & 0 deletions Huobi.Net.UnitTests/TestImplementations/TestHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using CryptoExchange.Net;
using CryptoExchange.Net.Authentication;
using CryptoExchange.Net.Interfaces;
using CryptoExchange.Net.Objects.Sockets;
using CryptoExchange.Net.Sockets;
using Huobi.Net.Clients;
using Huobi.Net.Enums;
Expand Down
Loading

0 comments on commit ff38021

Please sign in to comment.