diff --git a/CryptoPulse.BianceApi/Attributes/AuthKeyRequiredAttribute.cs b/CryptoPulse.BianceApi/Attributes/AuthKeyRequiredAttribute.cs new file mode 100644 index 0000000..af3160b --- /dev/null +++ b/CryptoPulse.BianceApi/Attributes/AuthKeyRequiredAttribute.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CryptoPulse.BianceApi.Attributes; +[AttributeUsage(AttributeTargets.Method, Inherited = false)] +public sealed class AuthKeyRequiredAttribute: Attribute +{ +} diff --git a/CryptoPulse.BianceApi/CryptoPulse.BianceApi.csproj b/CryptoPulse.BianceApi/CryptoPulse.BianceApi.csproj index 1176935..ab59708 100644 --- a/CryptoPulse.BianceApi/CryptoPulse.BianceApi.csproj +++ b/CryptoPulse.BianceApi/CryptoPulse.BianceApi.csproj @@ -1,4 +1,4 @@ - + net9.0;net9.0-android;net9.0-windows10.0.19041.0; diff --git a/CryptoPulse.BianceApi/Services/BinanceApiClient.cs b/CryptoPulse.BianceApi/Services/BinanceApiClient.cs index ed615bf..898dd78 100644 --- a/CryptoPulse.BianceApi/Services/BinanceApiClient.cs +++ b/CryptoPulse.BianceApi/Services/BinanceApiClient.cs @@ -1,4 +1,5 @@ -using CryptoPulse.BianceApi.DTOs; +using CryptoPulse.BianceApi.Attributes; +using CryptoPulse.BianceApi.DTOs; using CryptoPulse.BianceApi.Services.Interfaces; using CryptoPulse.Infrastructure.Exceptions; using CryptoPulse.Infrastructure.Services.Interfaces; @@ -10,7 +11,7 @@ public class BinanceApiClient : IBinanceApiClient { private string _apiKey { get; set; } = string.Empty; - private string _apiSecret { get; set; } = string.Empty; + private string _privateKey { get; set; } = string.Empty; private HttpClient _httpClient; private HttpClient _httpClientNoAuth; private readonly long _recvWindow = 50000; @@ -38,13 +39,20 @@ private string CreateSignature(string queryString) if (!_hasValidKeys) GetCashedKeys(); - using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_apiSecret)); + using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_privateKey)); var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(queryString)); return BitConverter.ToString(hash).Replace("-", "").ToLower(); } - + #region Authorization required // Fetch transaction history for a given pair - public async Task> GetAccountTradeLis(string symbol) + /// + /// Fetch transaction history for a given pair + /// + /// + /// + /// + [AuthKeyRequired] + public async Task> GetAccountTradeLisAsync(string symbol) { var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); var starttime = DateTimeOffset.UtcNow.AddDays(-30).ToUnixTimeMilliseconds(); @@ -63,13 +71,34 @@ public async Task> GetAccountTradeLis(string symbol) return JsonConvert.DeserializeObject>(json) ?? throw new Exception("Response is empty"); } + [AuthKeyRequired] + public async Task GetAccountTradeLastPairOperationAsync(string symbol) + { + var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + var queryString = $"symbol={symbol}&limit=1×tamp={timestamp}&recvWindow={_recvWindow}"; + var signature = CreateSignature(queryString); + var url = $"/api/v3/myTrades?{queryString}&signature={signature}"; - public async Task GetSymbolCurrentPrice(string symbol, CancellationTokenSource token) + var response = await _httpClient.GetAsync(url); + if (response.IsSuccessStatusCode) + { + var json = await response.Content.ReadAsStringAsync(); + return JsonConvert.DeserializeObject>(json)?.FirstOrDefault() ?? throw new Exception("Response is empty"); + } + else + { + throw new Exception($"API call failed: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}"); + } + } + #endregion + + #region No authorization methods + public async Task GetSymbolCurrentPriceAsync(string symbol) { var queryString = $"symbol={symbol}"; var url = $"/api/v3/ticker/price?{queryString}"; - var response = await _httpClientNoAuth.GetAsync(url,token.Token); + var response = await _httpClientNoAuth.GetAsync(url); if (!response.IsSuccessStatusCode) { throw new Exception($"API call failed: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}"); @@ -79,7 +108,7 @@ public async Task GetSymbolCurrentPrice(string symbol, Cance return JsonConvert.DeserializeObject(json) ?? throw new Exception("Response is empty"); } - public async Task GetSymbolAvgPrice(string symbol) + public async Task GetSymbolAvgPriceAsync(string symbol) { var queryString = $"symbol={symbol}"; var url = $"/api/v3/avgPrice?{queryString}"; @@ -89,29 +118,10 @@ public async Task GetSymbolAvgPrice(string symbol) { throw new Exception($"API call failed: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}"); } - var json = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(json) ?? throw new Exception("Response is empty"); } - public async Task GetAccountTradeLastPairOperation(string symbol) - { - var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); - var queryString = $"symbol={symbol}&limit=1×tamp={timestamp}&recvWindow={_recvWindow}"; - var signature = CreateSignature(queryString); - var url = $"/api/v3/myTrades?{queryString}&signature={signature}"; - - var response = await _httpClient.GetAsync(url); - if (response.IsSuccessStatusCode) - { - var json = await response.Content.ReadAsStringAsync(); - return JsonConvert.DeserializeObject>(json)?.FirstOrDefault() ?? throw new Exception("Response is empty"); - } - else - { - throw new Exception($"API call failed: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}"); - } - } public async Task> GetHistoricalDataAsync(string symbol, string interval, int limit) { @@ -155,14 +165,15 @@ public async Task> GetHistoricalDataAsync(string symbol, stri throw new Exception($"API call failed: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}"); } } + #endregion #region Keys operation private void GetCashedKeys() { _apiKey = _secureStorage.GetApiKeyCashed() ?? string.Empty; - _apiSecret = _secureStorage.GetApiPrivateKeyCashed() ?? string.Empty; + _privateKey = _secureStorage.GetApiPrivateKeyCashed() ?? string.Empty; - if (!(string.IsNullOrEmpty(_apiKey) || string.IsNullOrEmpty(_apiSecret))) + if (!(string.IsNullOrEmpty(_apiKey) || string.IsNullOrEmpty(_privateKey))) { _httpClient = new HttpClient { @@ -174,40 +185,24 @@ private void GetCashedKeys() else { _hasValidKeys = false; - throw new NoAuthKeyExeption(); + throw new NoAuthKeyException(); } } - public void SetNewKeyApiValue(string apiKey) - { - _apiKey = apiKey; - _httpClient = new HttpClient - { - BaseAddress = new Uri("https://api.binance.com") - }; - _httpClient.DefaultRequestHeaders.Add("X-MBX-APIKEY", _apiKey); - } - - public void SetNewPrivateKeyValue(string privateKey) - { - _apiSecret = privateKey; - } - - public async Task InitializeAuthHttpClientAsync() { if (!_hasValidKeys) { _apiKey = await _secureStorage.GetApiKeyAsync() ?? string.Empty; - _apiSecret = await _secureStorage.GetApiPrivateKeyAsync() ?? string.Empty; + _privateKey = await _secureStorage.GetApiPrivateKeyAsync() ?? string.Empty; _httpClient = new HttpClient { BaseAddress = new Uri("https://api.binance.com") }; - if (!(string.IsNullOrEmpty(_apiKey) || string.IsNullOrEmpty(_apiSecret))) + if (!(string.IsNullOrEmpty(_apiKey) || string.IsNullOrEmpty(_privateKey))) { _httpClient.DefaultRequestHeaders.Add("X-MBX-APIKEY", _apiKey); _hasValidKeys = true; @@ -219,8 +214,9 @@ public async Task InitializeAuthHttpClientAsync() } } - public async Task GetUserKeysValidation(string apiKey, string privateKey) + public async Task ChceckUserKeysValidationAsync(string apiKey, string privateKey, bool applayNewKeys = false) { + HttpClient tempClient = new HttpClient { BaseAddress = new Uri("https://api.binance.com") @@ -236,6 +232,12 @@ public async Task GetUserKeysValidation(string apiKey, string privateKey) var url = $"/api/v3/account?{queryString}&signature={signature}"; var response = await tempClient.GetAsync(url); + var responseSuccess = response.IsSuccessStatusCode; + + if (applayNewKeys && responseSuccess) + { + SetNewKeyApiValueToHttpClient(apiKey, privateKey); + } return response.IsSuccessStatusCode; } @@ -244,5 +246,17 @@ public bool GetKeysValidationInfo() { return _hasValidKeys; } + + public void SetNewKeyApiValueToHttpClient(string apiKey, string privateKey) + { + _apiKey = apiKey; + _privateKey = privateKey; + _httpClient = new HttpClient + { + BaseAddress = new Uri("https://api.binance.com") + }; + + _httpClient.DefaultRequestHeaders.Add("X-MBX-APIKEY", _apiKey); + } #endregion } diff --git a/CryptoPulse.BianceApi/Services/Interfaces/IBinanceApiClient.cs b/CryptoPulse.BianceApi/Services/Interfaces/IBinanceApiClient.cs index 9f6ee44..85a4771 100644 --- a/CryptoPulse.BianceApi/Services/Interfaces/IBinanceApiClient.cs +++ b/CryptoPulse.BianceApi/Services/Interfaces/IBinanceApiClient.cs @@ -8,14 +8,12 @@ namespace CryptoPulse.BianceApi.Services.Interfaces; public interface IBinanceApiClient { - public Task> GetAccountTradeLis(string symbol); - public Task GetAccountTradeLastPairOperation(string symbol); - public void SetNewKeyApiValue(string apiKey); - public void SetNewPrivateKeyValue(string privateKey); - public Task GetSymbolCurrentPrice(string symbol, CancellationTokenSource token); - public Task GetSymbolAvgPrice(string symbol); + public Task InitializeAsync(); + public Task> GetAccountTradeLisAsync(string symbol); + public Task GetAccountTradeLastPairOperationAsync(string symbol); + public Task GetSymbolCurrentPriceAsync(string symbol); + public Task GetSymbolAvgPriceAsync(string symbol); public Task> GetHistoricalDataAsync(string symbol, string interval, int limit); - public Task GetUserKeysValidation(string apiKey, string privateKey); + public Task ChceckUserKeysValidationAsync(string apiKey, string privateKey, bool applayNewKeys = false); public bool GetKeysValidationInfo(); - public Task InitializeAsync(); } diff --git a/CryptoPulse.Infrastructure/Exceptions/NoAuthKeyExeption.cs b/CryptoPulse.Infrastructure/Exceptions/NoAuthKeyException.cs similarity index 72% rename from CryptoPulse.Infrastructure/Exceptions/NoAuthKeyExeption.cs rename to CryptoPulse.Infrastructure/Exceptions/NoAuthKeyException.cs index 146f6d2..4e44092 100644 --- a/CryptoPulse.Infrastructure/Exceptions/NoAuthKeyExeption.cs +++ b/CryptoPulse.Infrastructure/Exceptions/NoAuthKeyException.cs @@ -5,25 +5,25 @@ using System.Threading.Tasks; namespace CryptoPulse.Infrastructure.Exceptions; -public class NoAuthKeyExeption : Exception +public class NoAuthKeyException : Exception { // Optionally, add custom properties public int ErrorCode { get; set; } = 0; public string ErrorDetails { get; set; } = string.Empty; // Default constructor - public NoAuthKeyExeption() + public NoAuthKeyException() { } // Constructor with a message - public NoAuthKeyExeption(string message) + public NoAuthKeyException(string message) : base(message) { } // Constructor with a message and an inner exception - public NoAuthKeyExeption(string message, Exception innerException) + public NoAuthKeyException(string message, Exception innerException) : base(message, innerException) { } diff --git a/CryptoPulse.Tests/BaseTest.cs b/CryptoPulse.Tests/BaseTest.cs new file mode 100644 index 0000000..19859b3 --- /dev/null +++ b/CryptoPulse.Tests/BaseTest.cs @@ -0,0 +1,25 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CryptoPulse.Tests; +public class BaseTest +{ + private static string _projectDir = AppContext.BaseDirectory.Substring(0, AppContext.BaseDirectory.IndexOf("bin")); + private static string _bianceApiOutputTestFolder = Path.Combine(_projectDir, "BianceAPI", "OutputTestContent"); + private static string _bianceClientOutputTestFolder = Path.Combine(_projectDir, "BinanceClient", "OutputTestContent"); + + protected async Task GetBianceApiTestFileContent(string filename) + { + var ext = Path.GetExtension(filename); + if (string.IsNullOrEmpty(ext)) + { + filename = filename + ".json"; + } + var testDataPath = Path.Combine(_bianceApiOutputTestFolder, filename); + return await File.ReadAllTextAsync(testDataPath); + } +} diff --git a/CryptoPulse.Tests/BianceAPI/BinanceApiClientTests.cs b/CryptoPulse.Tests/BianceAPI/BinanceApiClientTests.cs index 083f702..7460b00 100644 --- a/CryptoPulse.Tests/BianceAPI/BinanceApiClientTests.cs +++ b/CryptoPulse.Tests/BianceAPI/BinanceApiClientTests.cs @@ -1,29 +1,33 @@ -using Moq; -using Moq.Protected; +using CryptoPulse.BianceApi.Attributes; using CryptoPulse.BianceApi.DTOs; -using CryptoPulse.Infrastructure.Services; +using CryptoPulse.BianceApi.Services.Interfaces; +using CryptoPulse.Infrastructure.Exceptions; using CryptoPulse.Infrastructure.Services.Interfaces; +using Moq; +using Moq.Protected; using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Linq; +using System.Globalization; using System.Net; using System.Text; -using System.Threading.Tasks; namespace CryptoPulse.Tests.BianceAPI; -public class BinanceApiClientTests +public class BinanceApiClientTests:BaseTest { private readonly Mock _mockSecureStorage; private readonly Mock _mockHttpMessageHandler; private readonly HttpClient _mockHttpClient; private readonly BinanceApiClient _binanceApiClient; + private readonly Mock _mockBinanceApiClient; + #region Constructor public BinanceApiClientTests() { _mockSecureStorage = new Mock(); _mockSecureStorage.Setup(x => x.GetApiKeyAsync()).ReturnsAsync("testApiKey"); _mockSecureStorage.Setup(x => x.GetApiPrivateKeyAsync()).ReturnsAsync("testApiSecret"); + _mockSecureStorage.Setup(x => x.GetApiKeyCashed()).Returns("testApiKey"); + _mockSecureStorage.Setup(x => x.GetApiPrivateKeyCashed()).Returns("testApiSecret"); + _mockHttpMessageHandler = new Mock(); _mockHttpClient = new HttpClient(_mockHttpMessageHandler.Object) { @@ -32,38 +36,50 @@ public BinanceApiClientTests() // Initialize the BinanceApiClient with the mocked dependencies _binanceApiClient = new BinanceApiClient(_mockSecureStorage.Object); + _binanceApiClient.GetType().GetField("_hasValidKeys", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(_binanceApiClient, true); + + _mockBinanceApiClient = new Mock(); } + #endregion [Fact] - public async Task GetSymbolCurrentPrice_ReturnsValidPrice() + public async Task GetDataWithRequiedAuthorization_ThrownNoAuthKeyExeption() { - // Arrange - var symbol = "BTCUSDT"; - var mockResponse = new PairPriceTickerDto { Symbol = symbol, Price = 50000.00m }; - var jsonResponse = JsonConvert.SerializeObject(mockResponse); - - _mockHttpMessageHandler.Protected() - .Setup>("SendAsync", - ItExpr.IsAny(), - ItExpr.IsAny()) - .ReturnsAsync(new HttpResponseMessage - { - StatusCode = HttpStatusCode.OK, - Content = new StringContent(jsonResponse, Encoding.UTF8, "application/json") - }); + //Arrange + var mockSecureStorage = new Mock(); + mockSecureStorage.Setup(x => x.GetApiKeyCashed()).Returns(string.Empty); + mockSecureStorage.Setup(x => x.GetApiPrivateKeyCashed()).Returns(string.Empty); - _binanceApiClient.GetType().GetField("_httpClientNoAuth", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) - ?.SetValue(_binanceApiClient, _mockHttpClient); + BinanceApiClient binanceApiClient = new BinanceApiClient(mockSecureStorage.Object); + binanceApiClient.GetType().GetField("_hasValidKeys", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(_binanceApiClient, false); - // Act - var result = await _binanceApiClient.GetSymbolCurrentPrice(symbol, new CancellationTokenSource()); + var methods = typeof(BinanceApiClient) + .GetMethods() + .Where(m => m.GetCustomAttributes(typeof(AuthKeyRequiredAttribute), false).Any()); - // Assert - Assert.NotNull(result); - Assert.Equal(symbol, result.Symbol); - Assert.Equal(50000.00m, result.Price); + // Act & Assert + foreach (var method in methods) + { + switch (method.Name) + { + case nameof(_binanceApiClient.GetAccountTradeLisAsync): + { + await Assert.ThrowsAsync(() => binanceApiClient.GetAccountTradeLisAsync("BTCUSDT")); + } + break; + case nameof(_binanceApiClient.GetAccountTradeLastPairOperationAsync): + { + await Assert.ThrowsAsync(() => binanceApiClient.GetAccountTradeLastPairOperationAsync("BTCUSDT")); + } + break; + default: + Assert.Fail($"Not all method's with AuthKeyRequired are tested!, missing Nethod: {method.Name}"); + break; + } + } } + #region GetAccountTradeLis [Fact] public async Task GetAccountTradeLis_ThrowsException_OnApiFailure() { @@ -85,7 +101,7 @@ public async Task GetAccountTradeLis_ThrowsException_OnApiFailure() ?.SetValue(_binanceApiClient, _mockHttpClient); // Act & Assert - await Assert.ThrowsAsync(() => _binanceApiClient.GetAccountTradeLis("BTCUSDT")); + await Assert.ThrowsAsync(() => _binanceApiClient.GetAccountTradeLisAsync("BTCUSDT")); } [Fact] @@ -108,25 +124,128 @@ public async Task GetAccountTradeLis_ReturnsValidTradeList() _binanceApiClient.GetType().GetField("_httpClient", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?.SetValue(_binanceApiClient, _mockHttpClient); - var Data = await _binanceApiClient.GetAccountTradeLis("XRPUSDT"); + var Data = await _binanceApiClient.GetAccountTradeLisAsync("XRPUSDT"); var jsonData = JsonConvert.DeserializeObject>(jsonResponse); // Act & Assert Assert.Equal(jsonData!.Count, Data.Count); Assert.Equal(jsonData[0].Id, Data[0].Id); } + #endregion + + #region GetAccountTradeLastPairOperation + [Fact] + public async Task GetAccountTradeLastPairOperation_ReturnsLastTradeInfo() + { + // Arrange + var jsonResponse = await GetBianceApiTestFileContent("GetAccountTradeLastPairOperationTestResult.json"); + + _mockHttpMessageHandler.Protected() + .Setup>("SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(jsonResponse, Encoding.UTF8, "application/json") + }); + + _binanceApiClient.GetType().GetField("_httpClient", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) + ?.SetValue(_binanceApiClient, _mockHttpClient); + + var Data = await _binanceApiClient.GetAccountTradeLastPairOperationAsync("XRPUSDT"); + + var jsonData = JsonConvert.DeserializeObject>(jsonResponse); + AccountTradeListDto element = jsonData!.First(); + // Act & Assert + Assert.Equivalent(element, Data); + } + #endregion + #region GetSymbolCurrentPrice + [Fact] + public async Task GetSymbolCurrentPrice_ReturnsValidPrice() + { + // Arrange + var symbol = "BTCUSDT"; + var jsonResponse = await GetBianceApiTestFileContent("GetSymbolCurrentPrice"); + var mockResponse = JsonConvert.DeserializeObject(jsonResponse); + + _mockHttpMessageHandler.Protected() + .Setup>("SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(jsonResponse, Encoding.UTF8, "application/json") + }); + + _binanceApiClient.GetType().GetField("_httpClientNoAuth", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) + ?.SetValue(_binanceApiClient, _mockHttpClient); + + // Act + var result = await _binanceApiClient.GetSymbolCurrentPriceAsync(symbol); + + // Assert + Assert.NotNull(result); + Assert.Equivalent(mockResponse, result); + } + + #endregion + + #region GetSymbolAvgPrice + [Fact] + public async Task GetSymbolAvgPrice_ReturnValidPrice() + { + // Arrange + var symbol = "BTCUSDT"; + var jsonResponse = await GetBianceApiTestFileContent("GetSymbolAvgPrice"); + var mockResponse = JsonConvert.DeserializeObject(jsonResponse); + + _mockHttpMessageHandler.Protected() + .Setup>("SendAsync", + ItExpr.IsAny(), + ItExpr.IsAny()) + .ReturnsAsync(new HttpResponseMessage + { + StatusCode = HttpStatusCode.OK, + Content = new StringContent(jsonResponse, Encoding.UTF8, "application/json") + }); + + _binanceApiClient.GetType().GetField("_httpClientNoAuth", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) + ?.SetValue(_binanceApiClient, _mockHttpClient); + + // Act + var result = await _binanceApiClient.GetSymbolAvgPriceAsync(symbol); + + // Assert + Assert.NotNull(result); + Assert.Equivalent(mockResponse, result); + } + #endregion + + #region GetHistoricalDataAsync [Fact] public async Task GetHistoricalDataAsync_ReturnsValidData() { // Arrange var symbol = "BTCUSDT"; - var interval = "1h"; - var limit = 10; - var mockResponse = new List> + var jsonResponse = await GetBianceApiTestFileContent("GetHistoricalDataAsync"); + + var mockResponse = JsonConvert.DeserializeObject>>(jsonResponse)!.Select(kline => new KlineDataDto { - new List { 1627484400000, "40000.00", "41000.00", "39000.00", "40500.00", "1000", 1627488000000, "100000", 10, "500", "50000" } - }; - var jsonResponse = JsonConvert.SerializeObject(mockResponse); + OpenTime = (long)Convert.ToDouble(kline[0], CultureInfo.InvariantCulture), + OpenPrice = Convert.ToDecimal(kline[1], CultureInfo.InvariantCulture), + HighPrice = Convert.ToDecimal(kline[2], CultureInfo.InvariantCulture), + LowPrice = Convert.ToDecimal(kline[3], CultureInfo.InvariantCulture), + ClosePrice = Convert.ToDecimal(kline[4], CultureInfo.InvariantCulture), + Volume = Convert.ToDouble(kline[5], CultureInfo.InvariantCulture), + CloseTime = (long)Convert.ToDouble(kline[6], CultureInfo.InvariantCulture), + QuoteAssetVolume = Convert.ToDouble(kline[7], CultureInfo.InvariantCulture), + NumberOfTrades = (long)Convert.ToDouble(kline[8], CultureInfo.InvariantCulture), + TakerBuyBaseAssetVolume = Convert.ToDecimal(kline[9], CultureInfo.InvariantCulture), + TakerBuyQuoteAssetVolume = Convert.ToDecimal(kline[10], CultureInfo.InvariantCulture) + }).ToList(); _mockHttpMessageHandler.Protected() .Setup>("SendAsync", @@ -142,12 +261,21 @@ public async Task GetHistoricalDataAsync_ReturnsValidData() ?.SetValue(_binanceApiClient, _mockHttpClient); // Act - var result = await _binanceApiClient.GetHistoricalDataAsync(symbol, interval, limit); + var result = await _binanceApiClient.GetHistoricalDataAsync("BTCUSDT","1h", 168); // Assert Assert.NotNull(result); - Assert.Single(result); - Assert.Equal(40500.00M, result[0].ClosePrice); + Assert.Equivalent(mockResponse, result); + } + #endregion + + #region InitializeAsync + [Fact] + public async Task InitializeAsync_GetKeysValidationInfo_ReturnTrue() + { + await _binanceApiClient.InitializeAsync(); + Assert.True(_binanceApiClient.GetKeysValidationInfo()); } + #endregion } diff --git a/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetAccountTradeLastPairOperationTestResult.json b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetAccountTradeLastPairOperationTestResult.json index 7b08f42..9e2518f 100644 --- a/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetAccountTradeLastPairOperationTestResult.json +++ b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetAccountTradeLastPairOperationTestResult.json @@ -1 +1,17 @@ -[{"symbol":"BTCUSDT","id":4397236319,"orderId":35079354236,"orderListId":-1,"price":"94337.46000000","qty":"0.00132000","quoteQty":"124.52544720","commission":"0.00000132","commissionAsset":"BTC","time":1736614973077,"isBuyer":true,"isMaker":false,"isBestMatch":true}] \ No newline at end of file +[ + { + "symbol": "BTCUSDT", + "id": 4397236319, + "orderId": 35079354236, + "orderListId": -1, + "price": "94337.46000000", + "qty": "0.00132000", + "quoteQty": "124.52544720", + "commission": "0.00000132", + "commissionAsset": "BTC", + "time": 1736614973077, + "isBuyer": true, + "isMaker": false, + "isBestMatch": true + } +] \ No newline at end of file diff --git a/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetHistoricalDataAsync.json b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetHistoricalDataAsync.json new file mode 100644 index 0000000..8ccedf5 --- /dev/null +++ b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetHistoricalDataAsync.json @@ -0,0 +1,2354 @@ +[ + [ + 1736632800000, + "94940.75000000", + "95005.00000000", + "94561.00000000", + "94593.80000000", + "532.69589000", + 1736636399999, + "50494588.98740880", + 61204, + "167.27985000", + "15851444.13102810", + "0" + ], + [ + 1736636400000, + "94593.80000000", + "94753.37000000", + "94541.66000000", + "94599.99000000", + "231.83722000", + 1736639999999, + "21939234.48920310", + 54156, + "119.82589000", + "11339464.36041050", + "0" + ], + [ + 1736640000000, + "94599.99000000", + "94655.22000000", + "94422.13000000", + "94452.07000000", + "320.75584000", + 1736643599999, + "30323567.27372450", + 71212, + "123.80544000", + "11704676.32258040", + "0" + ], + [ + 1736643600000, + "94452.08000000", + "94589.46000000", + "94296.99000000", + "94580.00000000", + "300.67295000", + 1736647199999, + "28391108.03606260", + 57063, + "130.75409000", + "12347810.59695320", + "0" + ], + [ + 1736647200000, + "94580.00000000", + "94670.00000000", + "94480.58000000", + "94625.25000000", + "152.15196000", + 1736650799999, + "14387817.88413700", + 34109, + "88.53161000", + "8371624.23210790", + "0" + ], + [ + 1736650800000, + "94625.25000000", + "94699.00000000", + "94418.56000000", + "94622.40000000", + "210.90464000", + 1736654399999, + "19942843.78598830", + 36046, + "124.99852000", + "11820279.83575200", + "0" + ], + [ + 1736654400000, + "94622.40000000", + "94650.00000000", + "94500.00000000", + "94587.99000000", + "132.27266000", + 1736657999999, + "12512438.29601230", + 27009, + "64.22828000", + "6075513.13600370", + "0" + ], + [ + 1736658000000, + "94587.99000000", + "94627.80000000", + "94500.00000000", + "94571.43000000", + "92.53877000", + 1736661599999, + "8751181.89750990", + 23665, + "36.98525000", + "3497792.37166950", + "0" + ], + [ + 1736661600000, + "94571.43000000", + "94616.00000000", + "94357.14000000", + "94381.78000000", + "163.50382000", + 1736665199999, + "15450421.27496440", + 35146, + "62.64977000", + "5920171.26935570", + "0" + ], + [ + 1736665200000, + "94381.78000000", + "94441.42000000", + "94274.01000000", + "94323.85000000", + "166.86151000", + 1736668799999, + "15744684.46446660", + 41102, + "60.78450000", + "5735551.43786300", + "0" + ], + [ + 1736668800000, + "94323.85000000", + "94393.57000000", + "94109.00000000", + "94170.01000000", + "255.91064000", + 1736672399999, + "24115498.95622970", + 48510, + "106.62236000", + "10046827.99443480", + "0" + ], + [ + 1736672400000, + "94170.01000000", + "94222.41000000", + "93711.19000000", + "93906.22000000", + "541.72205000", + 1736675999999, + "50908414.47423430", + 73557, + "190.07243000", + "17859096.91534120", + "0" + ], + [ + 1736676000000, + "93906.21000000", + "94056.04000000", + "93836.51000000", + "94015.16000000", + "438.14049000", + 1736679599999, + "41163287.69374720", + 53928, + "200.39696000", + "18827370.87300850", + "0" + ], + [ + 1736679600000, + "94015.17000000", + "94348.64000000", + "94015.16000000", + "94255.10000000", + "306.54770000", + 1736683199999, + "28880413.81654580", + 53043, + "159.56913000", + "15030132.49990800", + "0" + ], + [ + 1736683200000, + "94255.10000000", + "94600.00000000", + "94173.48000000", + "94328.20000000", + "414.09702000", + 1736686799999, + "39081233.61775030", + 68001, + "198.07103000", + "18699408.19891120", + "0" + ], + [ + 1736686800000, + "94328.21000000", + "94730.04000000", + "94303.03000000", + "94663.78000000", + "602.30540000", + 1736690399999, + "56965745.42690980", + 98183, + "321.84309000", + "30431485.41835870", + "0" + ], + [ + 1736690400000, + "94663.77000000", + "94994.49000000", + "94663.77000000", + "94811.00000000", + "444.18254000", + 1736693999999, + "42138132.58109260", + 106354, + "235.34842000", + "22328817.06441720", + "0" + ], + [ + 1736694000000, + "94811.00000000", + "95450.10000000", + "94675.54000000", + "95071.90000000", + "667.55246000", + 1736697599999, + "63508705.87536460", + 139442, + "351.25402000", + "33415927.83880290", + "0" + ], + [ + 1736697600000, + "95071.91000000", + "95131.05000000", + "94791.43000000", + "95046.76000000", + "269.91850000", + 1736701199999, + "25628215.00366580", + 79426, + "136.61557000", + "12973247.46259470", + "0" + ], + [ + 1736701200000, + "95046.76000000", + "95271.56000000", + "94984.36000000", + "95139.45000000", + "320.98582000", + 1736704799999, + "30534926.31232500", + 63629, + "192.96450000", + "18355749.54299160", + "0" + ], + [ + 1736704800000, + "95139.46000000", + "95314.12000000", + "94916.00000000", + "94992.64000000", + "222.20274000", + 1736708399999, + "21133316.26015710", + 66330, + "97.67667000", + "9291192.91698760", + "0" + ], + [ + 1736708400000, + "94992.65000000", + "95055.93000000", + "94578.54000000", + "94650.26000000", + "508.48683000", + 1736711999999, + "48203770.82211400", + 73930, + "122.29822000", + "11592794.63981610", + "0" + ], + [ + 1736712000000, + "94650.26000000", + "94800.00000000", + "94612.00000000", + "94687.69000000", + "183.55526000", + 1736715599999, + "17385394.93366110", + 67740, + "81.48305000", + "7717337.11625790", + "0" + ], + [ + 1736715600000, + "94687.69000000", + "94727.28000000", + "94302.90000000", + "94352.70000000", + "336.21071000", + 1736719199999, + "31765661.26016050", + 87757, + "131.98843000", + "12470664.62369070", + "0" + ], + [ + 1736719200000, + "94352.70000000", + "94362.92000000", + "93800.00000000", + "93962.91000000", + "831.05211000", + 1736722799999, + "78119040.42249500", + 128451, + "351.92293000", + "33080308.36841570", + "0" + ], + [ + 1736722800000, + "93962.91000000", + "94563.82000000", + "93946.96000000", + "94545.06000000", + "724.33380000", + 1736726399999, + "68243009.28907650", + 125230, + "457.46604000", + "43097989.24222050", + "0" + ], + [ + 1736726400000, + "94545.07000000", + "95940.00000000", + "94463.32000000", + "95325.43000000", + "1259.98460000", + 1736729999999, + "120236214.74014420", + 270941, + "689.86352000", + "65821543.29330590", + "0" + ], + [ + 1736730000000, + "95325.43000000", + "95400.00000000", + "94081.38000000", + "94218.01000000", + "1000.51032000", + 1736733599999, + "94821423.02765990", + 248346, + "490.96919000", + "46538227.84759890", + "0" + ], + [ + 1736733600000, + "94218.01000000", + "94500.00000000", + "93899.99000000", + "94217.43000000", + "622.98595000", + 1736737199999, + "58661332.27813440", + 153989, + "277.06170000", + "26089059.22404540", + "0" + ], + [ + 1736737200000, + "94217.43000000", + "94408.17000000", + "93972.54000000", + "94269.23000000", + "603.07676000", + 1736740799999, + "56795205.89898090", + 137624, + "358.03807000", + "33718219.49991330", + "0" + ], + [ + 1736740800000, + "94269.23000000", + "94913.03000000", + "94202.76000000", + "94503.34000000", + "505.10760000", + 1736744399999, + "47755855.97789410", + 124056, + "252.80023000", + "23895161.75947880", + "0" + ], + [ + 1736744400000, + "94503.34000000", + "94543.28000000", + "94045.45000000", + "94181.37000000", + "415.64412000", + 1736747999999, + "39169753.75884310", + 99839, + "222.10323000", + "20927044.75094130", + "0" + ], + [ + 1736748000000, + "94181.37000000", + "94327.35000000", + "93281.00000000", + "93637.37000000", + "1071.58867000", + 1736751599999, + "100421206.61624770", + 161793, + "414.28595000", + "38814130.51639770", + "0" + ], + [ + 1736751600000, + "93637.38000000", + "93947.30000000", + "93469.20000000", + "93590.24000000", + "659.49821000", + 1736755199999, + "61789256.35395620", + 112546, + "333.14985000", + "31221540.59217860", + "0" + ], + [ + 1736755200000, + "93590.24000000", + "93661.55000000", + "92904.35000000", + "93039.10000000", + "1106.31398000", + 1736758799999, + "103101118.60947930", + 168219, + "467.86819000", + "43598188.39556450", + "0" + ], + [ + 1736758800000, + "93039.11000000", + "93195.99000000", + "92644.11000000", + "92846.79000000", + "1308.31575000", + 1736762399999, + "121604374.76228020", + 280554, + "678.61644000", + "63084115.06998340", + "0" + ], + [ + 1736762400000, + "92846.79000000", + "92889.06000000", + "91372.17000000", + "91644.96000000", + "3461.57932000", + 1736765999999, + "318423524.88455020", + 381539, + "1379.19327000", + "126814681.97706460", + "0" + ], + [ + 1736766000000, + "91644.96000000", + "91776.04000000", + "90833.12000000", + "90851.22000000", + "4194.43530000", + 1736769599999, + "382960236.25351250", + 341718, + "1500.33583000", + "137003642.32181210", + "0" + ], + [ + 1736769600000, + "90851.23000000", + "91350.00000000", + "90300.00000000", + "90732.00000000", + "3847.56478000", + 1736773199999, + "349320105.60722850", + 350102, + "1525.43808000", + "138559016.09848700", + "0" + ], + [ + 1736773200000, + "90732.00000000", + "91780.00000000", + "90583.24000000", + "91131.41000000", + "2635.60842000", + 1736776799999, + "240534976.02195520", + 277986, + "1307.62997000", + "119353094.58817410", + "0" + ], + [ + 1736776800000, + "91131.41000000", + "92300.00000000", + "89256.69000000", + "91833.03000000", + "6291.93940000", + 1736780399999, + "571162387.12869280", + 497074, + "2864.64657000", + "260306763.03816620", + "0" + ], + [ + 1736780400000, + "91833.03000000", + "93100.00000000", + "91570.00000000", + "92123.75000000", + "2993.71459000", + 1736783999999, + "276551846.15416790", + 329980, + "1437.08115000", + "132767431.05028570", + "0" + ], + [ + 1736784000000, + "92123.75000000", + "92289.07000000", + "91250.00000000", + "91343.20000000", + "1967.47090000", + 1736787599999, + "180602380.19624250", + 283315, + "921.94582000", + "84629605.08057760", + "0" + ], + [ + 1736787600000, + "91343.21000000", + "92300.00000000", + "91250.00000000", + "91983.96000000", + "1292.83794000", + 1736791199999, + "118688266.06310490", + 249812, + "688.53560000", + "63210325.16415760", + "0" + ], + [ + 1736791200000, + "91983.96000000", + "92405.39000000", + "91593.85000000", + "92077.65000000", + "1146.24803000", + 1736794799999, + "105438557.94318650", + 262142, + "573.44974000", + "52752921.54159610", + "0" + ], + [ + 1736794800000, + "92077.65000000", + "92534.10000000", + "91600.00000000", + "92312.18000000", + "1190.57010000", + 1736798399999, + "109706613.70926770", + 253231, + "589.84923000", + "54349228.46077500", + "0" + ], + [ + 1736798400000, + "92312.18000000", + "93783.12000000", + "91908.20000000", + "93575.53000000", + "1763.26310000", + 1736801999999, + "163939465.85169970", + 273281, + "912.62189000", + "84847963.81381950", + "0" + ], + [ + 1736802000000, + "93575.53000000", + "94472.00000000", + "93401.84000000", + "94193.49000000", + "1762.73089000", + 1736805599999, + "165594588.66173890", + 247337, + "814.96802000", + "76551247.00791720", + "0" + ], + [ + 1736805600000, + "94193.49000000", + "94727.15000000", + "94152.00000000", + "94399.98000000", + "918.81918000", + 1736809199999, + "86777589.95275890", + 142362, + "495.06215000", + "46755316.05071040", + "0" + ], + [ + 1736809200000, + "94399.99000000", + "94612.70000000", + "94164.77000000", + "94536.10000000", + "599.75632000", + 1736812799999, + "56609853.89573120", + 93177, + "278.36673000", + "26279711.70665700", + "0" + ], + [ + 1736812800000, + "94536.11000000", + "94880.00000000", + "94346.22000000", + "94470.77000000", + "1089.79630000", + 1736816399999, + "103048988.94059700", + 133287, + "563.56025000", + "53295104.23570600", + "0" + ], + [ + 1736816400000, + "94470.76000000", + "95041.17000000", + "94462.59000000", + "94834.50000000", + "793.93418000", + 1736819999999, + "75272261.20846610", + 151323, + "415.88508000", + "39440575.37132130", + "0" + ], + [ + 1736820000000, + "94834.50000000", + "95280.80000000", + "94749.57000000", + "94882.65000000", + "861.15357000", + 1736823599999, + "81855019.78791200", + 135442, + "466.77054000", + "44370402.42830610", + "0" + ], + [ + 1736823600000, + "94882.65000000", + "95112.61000000", + "94828.46000000", + "94861.40000000", + "558.39973000", + 1736827199999, + "53015530.45169060", + 83811, + "232.06345000", + "22031270.45674180", + "0" + ], + [ + 1736827200000, + "94861.39000000", + "95149.32000000", + "94830.25000000", + "95119.19000000", + "552.62213000", + 1736830799999, + "52500121.37619050", + 73267, + "235.26030000", + "22347846.16743240", + "0" + ], + [ + 1736830800000, + "95119.18000000", + "95464.71000000", + "94861.39000000", + "94916.08000000", + "680.63696000", + 1736834399999, + "64819831.48276700", + 82599, + "292.17700000", + "27831600.47181690", + "0" + ], + [ + 1736834400000, + "94916.08000000", + "95031.94000000", + "94753.42000000", + "95031.94000000", + "528.83900000", + 1736837999999, + "50178231.02589120", + 82076, + "287.91225000", + "27323082.62346890", + "0" + ], + [ + 1736838000000, + "95031.93000000", + "95168.60000000", + "94838.56000000", + "94864.00000000", + "596.66211000", + 1736841599999, + "56685218.18654610", + 76210, + "236.11665000", + "22432385.04758450", + "0" + ], + [ + 1736841600000, + "94863.99000000", + "95819.70000000", + "94860.11000000", + "95488.50000000", + "1555.26872000", + 1736845199999, + "148486070.23419710", + 182327, + "914.60454000", + "87313609.72087580", + "0" + ], + [ + 1736845200000, + "95488.51000000", + "97371.00000000", + "95469.51000000", + "97159.44000000", + "2720.04616000", + 1736848799999, + "262340279.03826660", + 311153, + "1679.82053000", + "161907072.95783670", + "0" + ], + [ + 1736848800000, + "97159.43000000", + "97194.26000000", + "96579.31000000", + "96697.08000000", + "1394.49961000", + 1736852399999, + "134983343.23335130", + 202547, + "666.86491000", + "64545670.81759370", + "0" + ], + [ + 1736852400000, + "96686.09000000", + "96687.15000000", + "96336.92000000", + "96548.04000000", + "826.01262000", + 1736855999999, + "79733215.86489280", + 116024, + "372.78005000", + "35983418.58671290", + "0" + ], + [ + 1736856000000, + "96548.04000000", + "96700.00000000", + "95972.58000000", + "95988.00000000", + "1369.94574000", + 1736859599999, + "131895904.26801530", + 151318, + "496.84202000", + "47841894.88523360", + "0" + ], + [ + 1736859600000, + "95988.01000000", + "97263.02000000", + "95748.93000000", + "96336.00000000", + "2544.05682000", + 1736863199999, + "245671737.60551950", + 340691, + "1369.09204000", + "132267316.40299840", + "0" + ], + [ + 1736863200000, + "96336.00000000", + "97265.48000000", + "96029.73000000", + "96293.60000000", + "2135.64365000", + 1736866799999, + "206490157.41393660", + 392762, + "1152.38594000", + "111451395.98227840", + "0" + ], + [ + 1736866800000, + "96293.61000000", + "96974.82000000", + "96184.02000000", + "96471.65000000", + "2344.68602000", + 1736870399999, + "226574197.76113070", + 353659, + "1316.40536000", + "127215818.44235890", + "0" + ], + [ + 1736870400000, + "96471.65000000", + "96471.66000000", + "95351.76000000", + "95745.43000000", + "2219.24732000", + 1736873999999, + "212712227.78805080", + 431437, + "1115.10838000", + "106883963.97501820", + "0" + ], + [ + 1736874000000, + "95745.42000000", + "96550.46000000", + "95584.83000000", + "96527.96000000", + "1050.49264000", + 1736877599999, + "100870060.91189190", + 275542, + "523.12018000", + "50230152.38301310", + "0" + ], + [ + 1736877600000, + "96527.96000000", + "96958.97000000", + "96290.85000000", + "96777.80000000", + "996.63205000", + 1736881199999, + "96314693.81720440", + 240818, + "507.41044000", + "49032188.17090270", + "0" + ], + [ + 1736881200000, + "96777.79000000", + "97088.57000000", + "96466.03000000", + "96537.80000000", + "868.21053000", + 1736884799999, + "84073263.00186980", + 198314, + "390.39575000", + "37811983.85112270", + "0" + ], + [ + 1736884800000, + "96537.23000000", + "96921.13000000", + "96152.31000000", + "96505.04000000", + "1031.11214000", + 1736888399999, + "99543414.52839720", + 269457, + "506.99176000", + "48940839.81834160", + "0" + ], + [ + 1736888400000, + "96505.98000000", + "96678.18000000", + "96315.38000000", + "96486.09000000", + "561.54114000", + 1736891999999, + "54189007.96082250", + 104655, + "246.89276000", + "23826297.65788200", + "0" + ], + [ + 1736892000000, + "96486.10000000", + "96741.95000000", + "96450.00000000", + "96691.91000000", + "310.63288000", + 1736895599999, + "30006222.67649180", + 69640, + "141.56351000", + "13673288.98205240", + "0" + ], + [ + 1736895600000, + "96691.91000000", + "96780.02000000", + "96500.49000000", + "96560.86000000", + "256.54551000", + 1736899199999, + "24789471.79285160", + 74564, + "118.67247000", + "11466932.25689700", + "0" + ], + [ + 1736899200000, + "96560.85000000", + "97332.52000000", + "96500.00000000", + "96889.36000000", + "998.94002000", + 1736902799999, + "96885895.69818220", + 154266, + "528.28513000", + "51238156.87008150", + "0" + ], + [ + 1736902800000, + "96889.36000000", + "97554.63000000", + "96789.38000000", + "97349.62000000", + "1002.14317000", + 1736906399999, + "97399138.45205250", + 167015, + "545.84122000", + "53049236.16072430", + "0" + ], + [ + 1736906400000, + "97349.61000000", + "97464.80000000", + "96746.71000000", + "96824.06000000", + "647.36377000", + 1736909999999, + "62824728.50461540", + 113304, + "301.72400000", + "29285945.14049310", + "0" + ], + [ + 1736910000000, + "96824.06000000", + "97324.00000000", + "96751.47000000", + "97317.12000000", + "641.52255000", + 1736913599999, + "62237449.29544070", + 79066, + "250.16663000", + "24273647.32612110", + "0" + ], + [ + 1736913600000, + "97317.12000000", + "97724.96000000", + "97072.70000000", + "97189.71000000", + "1125.98732000", + 1736917199999, + "109649660.80135430", + 113644, + "471.35567000", + "45924109.74498330", + "0" + ], + [ + 1736917200000, + "97189.71000000", + "97242.29000000", + "96750.00000000", + "97029.97000000", + "809.66839000", + 1736920799999, + "78489495.52667830", + 75012, + "227.78745000", + "22081630.89777220", + "0" + ], + [ + 1736920800000, + "97029.97000000", + "97147.95000000", + "96851.50000000", + "97105.48000000", + "457.24837000", + 1736924399999, + "44344971.51680860", + 56516, + "216.43561000", + "20989595.14166080", + "0" + ], + [ + 1736924400000, + "97105.48000000", + "97600.31000000", + "97105.47000000", + "97301.35000000", + "666.95451000", + 1736927999999, + "64938494.61303430", + 102484, + "318.20875000", + "30983189.03314050", + "0" + ], + [ + 1736928000000, + "97301.35000000", + "97524.00000000", + "97153.48000000", + "97202.26000000", + "776.88371000", + 1736931599999, + "75624852.38991870", + 115608, + "250.56374000", + "24391825.69727090", + "0" + ], + [ + 1736931600000, + "97202.27000000", + "97366.11000000", + "96766.57000000", + "96816.47000000", + "775.71962000", + 1736935199999, + "75281032.02606280", + 123431, + "338.71231000", + "32881385.50543050", + "0" + ], + [ + 1736935200000, + "96816.47000000", + "97136.28000000", + "96721.39000000", + "96933.59000000", + "487.37338000", + 1736938799999, + "47252020.78136650", + 75338, + "219.77609000", + "21307562.07259180", + "0" + ], + [ + 1736938800000, + "96933.59000000", + "96942.37000000", + "96521.00000000", + "96762.18000000", + "622.72697000", + 1736942399999, + "60207426.86188120", + 93383, + "277.27696000", + "26807299.75157590", + "0" + ], + [ + 1736942400000, + "96762.19000000", + "97194.35000000", + "96539.77000000", + "96942.93000000", + "648.07612000", + 1736945999999, + "62742220.11254030", + 105907, + "334.64286000", + "32408326.06787670", + "0" + ], + [ + 1736946000000, + "96942.92000000", + "99073.39000000", + "96852.38000000", + "98964.00000000", + "4849.23407000", + 1736949599999, + "476875708.94306380", + 356935, + "3017.33001000", + "296704267.08117320", + "0" + ], + [ + 1736949600000, + "98963.99000000", + "99499.00000000", + "98613.99000000", + "99434.41000000", + "3178.76457000", + 1736953199999, + "314882689.93237280", + 346150, + "1752.39944000", + "173619654.89414320", + "0" + ], + [ + 1736953200000, + "99434.80000000", + "99799.98000000", + "98964.71000000", + "98992.42000000", + "2902.87621000", + 1736956799999, + "288660453.44357830", + 327648, + "1457.78587000", + "145004498.28797760", + "0" + ], + [ + 1736956800000, + "98992.42000000", + "99479.53000000", + "98888.98000000", + "98995.58000000", + "1407.98268000", + 1736960399999, + "139622249.03884250", + 200564, + "684.72687000", + "67898243.97931430", + "0" + ], + [ + 1736960400000, + "98995.58000000", + "99335.91000000", + "98602.05000000", + "98645.65000000", + "1091.04433000", + 1736963999999, + "108066398.90369800", + 135100, + "411.25355000", + "40739562.57707390", + "0" + ], + [ + 1736964000000, + "98645.65000000", + "99483.87000000", + "98645.65000000", + "99446.14000000", + "800.99381000", + 1736967599999, + "79393095.20094550", + 97249, + "430.47719000", + "42674280.71971620", + "0" + ], + [ + 1736967600000, + "99446.15000000", + "99990.00000000", + "99297.41000000", + "99844.90000000", + "1737.79895000", + 1736971199999, + "173045675.56921290", + 139826, + "992.16392000", + "98804365.80611640", + "0" + ], + [ + 1736971200000, + "99844.91000000", + "100681.94000000", + "99460.80000000", + "99566.40000000", + "2464.64680000", + 1736974799999, + "246584840.78523470", + 248035, + "1254.51846000", + "125545354.01389670", + "0" + ], + [ + 1736974800000, + "99566.34000000", + "99876.40000000", + "99476.16000000", + "99672.00000000", + "809.22859000", + 1736978399999, + "80676699.24519150", + 95841, + "379.20183000", + "37807443.71579770", + "0" + ], + [ + 1736978400000, + "99671.99000000", + "99838.28000000", + "99564.00000000", + "99713.46000000", + "534.55121000", + 1736981999999, + "53285269.15331910", + 54851, + "242.05297000", + "24125804.80856250", + "0" + ], + [ + 1736982000000, + "99713.45000000", + "100510.05000000", + "99632.73000000", + "100497.35000000", + "1072.26267000", + 1736985599999, + "107271916.09139970", + 110772, + "591.49220000", + "59182841.01483850", + "0" + ], + [ + 1736985600000, + "100497.35000000", + "100866.66000000", + "99658.78000000", + "99869.26000000", + "2043.88616000", + 1736989199999, + "204721134.99531960", + 283551, + "968.09747000", + "96986367.21438000", + "0" + ], + [ + 1736989200000, + "99869.26000000", + "100200.00000000", + "99814.91000000", + "100082.35000000", + "980.69271000", + 1736992799999, + "98084284.65784730", + 148293, + "513.74366000", + "51383565.11887510", + "0" + ], + [ + 1736992800000, + "100082.35000000", + "100112.00000000", + "99471.48000000", + "99637.77000000", + "872.45982000", + 1736996399999, + "87038002.10483500", + 116010, + "307.82228000", + "30705428.44863840", + "0" + ], + [ + 1736996400000, + "99637.78000000", + "99848.00000000", + "99170.00000000", + "99478.03000000", + "867.71480000", + 1736999999999, + "86329472.04184540", + 116500, + "344.42591000", + "34273813.34962490", + "0" + ], + [ + 1737000000000, + "99478.04000000", + "99698.70000000", + "99478.03000000", + "99610.00000000", + "463.39979000", + 1737003599999, + "46159035.48771100", + 48086, + "191.18503000", + "19042566.41903920", + "0" + ], + [ + 1737003600000, + "99610.00000000", + "99613.99000000", + "99355.23000000", + "99382.11000000", + "404.77978000", + 1737007199999, + "40265798.31028820", + 43716, + "138.59325000", + "13786450.05755310", + "0" + ], + [ + 1737007200000, + "99382.11000000", + "99921.86000000", + "99322.19000000", + "99801.23000000", + "700.10006000", + 1737010799999, + "69792078.42248160", + 63329, + "451.94026000", + "45055961.11471210", + "0" + ], + [ + 1737010800000, + "99801.22000000", + "99850.00000000", + "99650.33000000", + "99799.99000000", + "403.57875000", + 1737014399999, + "40250766.50111690", + 49227, + "201.08483000", + "20054355.74766690", + "0" + ], + [ + 1737014400000, + "99800.00000000", + "99820.00000000", + "98617.55000000", + "98955.80000000", + "1465.06662000", + 1737017999999, + "145204404.51665350", + 129878, + "589.68579000", + "58477904.56783520", + "0" + ], + [ + 1737018000000, + "98955.81000000", + "99315.00000000", + "98649.41000000", + "99152.93000000", + "1255.33253000", + 1737021599999, + "124172417.47902220", + 100316, + "673.03802000", + "66585978.37748080", + "0" + ], + [ + 1737021600000, + "99152.93000000", + "99405.74000000", + "99122.07000000", + "99214.25000000", + "459.21815000", + 1737025199999, + "45588772.61155980", + 55697, + "258.70285000", + "25683672.13916390", + "0" + ], + [ + 1737025200000, + "99214.26000000", + "99333.24000000", + "98699.99000000", + "99158.71000000", + "1044.87874000", + 1737028799999, + "103457591.35536840", + 131213, + "515.62451000", + "51051603.61052300", + "0" + ], + [ + 1737028800000, + "99158.70000000", + "99517.93000000", + "98886.95000000", + "99392.09000000", + "860.82336000", + 1737032399999, + "85467610.52241990", + 145860, + "472.93408000", + "46957262.37313880", + "0" + ], + [ + 1737032400000, + "99392.09000000", + "99461.93000000", + "98777.87000000", + "99084.04000000", + "1485.77569000", + 1737035999999, + "147230046.22985000", + 255326, + "746.40585000", + "73960362.17246810", + "0" + ], + [ + 1737036000000, + "99084.05000000", + "99424.96000000", + "97489.74000000", + "97618.89000000", + "3024.86460000", + 1737039599999, + "297263589.72033700", + 366598, + "1403.81873000", + "137986569.32869630", + "0" + ], + [ + 1737039600000, + "97618.88000000", + "99299.00000000", + "97335.13000000", + "99296.17000000", + "2581.46637000", + 1737043199999, + "253300259.36117440", + 386530, + "1432.55655000", + "140602372.90307810", + "0" + ], + [ + 1737043200000, + "99296.17000000", + "99873.37000000", + "99079.05000000", + "99346.39000000", + "2045.22890000", + 1737046799999, + "203483062.40373570", + 320473, + "1029.40060000", + "102436895.88477160", + "0" + ], + [ + 1737046800000, + "99346.39000000", + "100361.54000000", + "99178.30000000", + "99838.54000000", + "1379.66956000", + 1737050399999, + "137728663.12129280", + 246008, + "726.26499000", + "72486011.84087420", + "0" + ], + [ + 1737050400000, + "99838.55000000", + "100070.80000000", + "99260.45000000", + "99584.24000000", + "909.60548000", + 1737053999999, + "90606605.59873450", + 156432, + "424.02976000", + "42231662.22733530", + "0" + ], + [ + 1737054000000, + "99584.23000000", + "100448.72000000", + "99408.00000000", + "100417.20000000", + "1011.21215000", + 1737057599999, + "101124884.12898720", + 129711, + "504.44708000", + "50465359.62391390", + "0" + ], + [ + 1737057600000, + "100417.20000000", + "100641.99000000", + "100256.85000000", + "100343.99000000", + "1507.69777000", + 1737061199999, + "151486682.89631840", + 187514, + "705.71869000", + "70911512.78072900", + "0" + ], + [ + 1737061200000, + "100344.00000000", + "100399.33000000", + "99717.60000000", + "100156.98000000", + "861.92090000", + 1737064799999, + "86236997.14774160", + 113563, + "341.37723000", + "34155740.23977670", + "0" + ], + [ + 1737064800000, + "100156.98000000", + "100156.98000000", + "99377.00000000", + "99838.25000000", + "543.57901000", + 1737068399999, + "54208660.79397390", + 80578, + "215.12580000", + "21444844.66899450", + "0" + ], + [ + 1737068400000, + "99838.25000000", + "100115.87000000", + "99746.00000000", + "99987.30000000", + "659.90147000", + 1737071999999, + "65961220.23118480", + 88346, + "357.51385000", + "35736361.41805940", + "0" + ], + [ + 1737072000000, + "99987.30000000", + "100434.96000000", + "99950.77000000", + "100120.58000000", + "733.49266000", + 1737075599999, + "73481316.85657900", + 95446, + "372.61240000", + "37328177.84679910", + "0" + ], + [ + 1737075600000, + "100120.58000000", + "101833.28000000", + "100050.00000000", + "101659.80000000", + "3129.03705000", + 1737079199999, + "316540448.75447480", + 256937, + "1877.40129000", + "189844127.46101650", + "0" + ], + [ + 1737079200000, + "101659.80000000", + "102148.13000000", + "100780.54000000", + "101100.00000000", + "2269.38304000", + 1737082799999, + "230747638.60544690", + 251881, + "1285.24823000", + "130738424.54896060", + "0" + ], + [ + 1737082800000, + "101100.00000000", + "101271.74000000", + "100943.77000000", + "101051.73000000", + "759.63139000", + 1737086399999, + "76788176.96649470", + 91009, + "384.57729000", + "38876074.99584660", + "0" + ], + [ + 1737086400000, + "101051.73000000", + "101490.78000000", + "100952.10000000", + "101481.29000000", + "685.45637000", + 1737089999999, + "69347067.31335370", + 76873, + "413.89195000", + "41879007.14260560", + "0" + ], + [ + 1737090000000, + "101481.28000000", + "101782.02000000", + "101301.40000000", + "101334.05000000", + "905.85684000", + 1737093599999, + "91989101.60402870", + 88916, + "418.92938000", + "42555964.67323780", + "0" + ], + [ + 1737093600000, + "101334.06000000", + "101586.96000000", + "101302.60000000", + "101408.99000000", + "413.87668000", + 1737097199999, + "41985748.49036120", + 52083, + "170.28018000", + "17274587.48513210", + "0" + ], + [ + 1737097200000, + "101409.00000000", + "101899.49000000", + "101401.00000000", + "101440.50000000", + "1193.29541000", + 1737100799999, + "121219738.75169630", + 92738, + "621.49706000", + "63130338.33068450", + "0" + ], + [ + 1737100800000, + "101440.51000000", + "102220.14000000", + "101439.77000000", + "102136.01000000", + "1964.78851000", + 1737104399999, + "200206375.89538950", + 137687, + "1216.86616000", + "124005537.31140000", + "0" + ], + [ + 1737104400000, + "102136.00000000", + "102288.00000000", + "101743.19000000", + "101861.26000000", + "1177.21807000", + 1737107999999, + "120113686.77865610", + 119751, + "627.77593000", + "64057864.92296950", + "0" + ], + [ + 1737108000000, + "101861.26000000", + "102581.45000000", + "101794.14000000", + "102321.53000000", + "1549.58944000", + 1737111599999, + "158432566.02106260", + 142126, + "910.30908000", + "93076231.65164380", + "0" + ], + [ + 1737111600000, + "102321.54000000", + "102443.50000000", + "102082.64000000", + "102237.60000000", + "688.88715000", + 1737115199999, + "70447936.57611390", + 81858, + "298.96385000", + "30574993.96935920", + "0" + ], + [ + 1737115200000, + "102237.60000000", + "102959.66000000", + "102195.90000000", + "102745.69000000", + "1367.64014000", + 1737118799999, + "140364352.85703170", + 128233, + "764.42977000", + "78449567.31025520", + "0" + ], + [ + 1737118800000, + "102745.68000000", + "102980.00000000", + "102422.45000000", + "102474.14000000", + "1091.04308000", + 1737122399999, + "112027743.71268910", + 131905, + "518.03423000", + "53189913.54565920", + "0" + ], + [ + 1737122400000, + "102474.14000000", + "103395.47000000", + "102279.41000000", + "103378.95000000", + "2867.39252000", + 1737125999999, + "294844195.58411860", + 326996, + "1585.07510000", + "163047902.49277920", + "0" + ], + [ + 1737126000000, + "103379.23000000", + "104254.19000000", + "103285.79000000", + "104000.00000000", + "3972.29934000", + 1737129599999, + "412636102.28774170", + 395026, + "2165.28225000", + "224924307.04778050", + "0" + ], + [ + 1737129600000, + "104000.00000000", + "105000.00000000", + "103841.18000000", + "104972.81000000", + "3081.02614000", + 1737133199999, + "322096884.89792850", + 274460, + "1723.16735000", + "180123145.20078200", + "0" + ], + [ + 1737133200000, + "104972.81000000", + "105269.24000000", + "104025.49000000", + "104125.46000000", + "2634.44109000", + 1737136799999, + "275835323.15776370", + 255879, + "1118.33614000", + "117141424.88369200", + "0" + ], + [ + 1737136800000, + "104125.46000000", + "104946.01000000", + "104039.05000000", + "104835.68000000", + "1307.73288000", + 1737140399999, + "136739853.02849490", + 167101, + "655.38176000", + "68517154.51897540", + "0" + ], + [ + 1737140400000, + "104835.68000000", + "105865.22000000", + "104684.21000000", + "105834.93000000", + "2313.65354000", + 1737143999999, + "243896792.37655040", + 219206, + "1284.90529000", + "135448916.02962280", + "0" + ], + [ + 1737144000000, + "105834.93000000", + "105847.02000000", + "104539.18000000", + "104692.70000000", + "2246.47712000", + 1737147599999, + "236380663.68628280", + 221885, + "1058.07425000", + "111315089.60699870", + "0" + ], + [ + 1737147600000, + "104692.70000000", + "105041.05000000", + "104462.02000000", + "104604.49000000", + "1431.12357000", + 1737151199999, + "149891805.73022320", + 122733, + "613.01223000", + "64204249.31938930", + "0" + ], + [ + 1737151200000, + "104604.49000000", + "104694.42000000", + "104204.00000000", + "104410.39000000", + "838.35441000", + 1737154799999, + "87593406.05551530", + 90221, + "374.43232000", + "39119449.81165930", + "0" + ], + [ + 1737154800000, + "104410.40000000", + "104526.32000000", + "104065.25000000", + "104077.48000000", + "550.15648000", + 1737158399999, + "57387059.48704950", + 65957, + "214.72951000", + "22400843.09759730", + "0" + ], + [ + 1737158400000, + "104077.47000000", + "104656.87000000", + "104075.34000000", + "104656.87000000", + "638.77711000", + 1737161999999, + "66645241.64421560", + 86544, + "354.00547000", + "36934772.10282700", + "0" + ], + [ + 1737162000000, + "104656.87000000", + "104656.87000000", + "104082.19000000", + "104268.14000000", + "833.43737000", + 1737165599999, + "86987700.07909570", + 95346, + "304.45654000", + "31779939.04910050", + "0" + ], + [ + 1737165600000, + "104268.14000000", + "104500.00000000", + "104259.98000000", + "104327.98000000", + "432.64650000", + 1737169199999, + "45162194.61257700", + 56840, + "153.99095000", + "16073861.31872350", + "0" + ], + [ + 1737169200000, + "104327.99000000", + "104479.31000000", + "103000.25000000", + "103559.82000000", + "1613.96460000", + 1737172799999, + "167386345.97148840", + 180763, + "636.00006000", + "65965787.30230650", + "0" + ], + [ + 1737172800000, + "103559.82000000", + "103726.23000000", + "102666.55000000", + "103599.27000000", + "1465.98462000", + 1737176399999, + "151342471.47075540", + 156810, + "721.90496000", + "74512981.17844300", + "0" + ], + [ + 1737176400000, + "103599.27000000", + "103771.21000000", + "102818.00000000", + "102829.27000000", + "1378.08470000", + 1737179999999, + "142486174.54468610", + 161362, + "585.34669000", + "60542407.10637170", + "0" + ], + [ + 1737180000000, + "102829.27000000", + "103636.91000000", + "102822.16000000", + "103440.39000000", + "1129.47925000", + 1737183599999, + "116659436.54988300", + 136394, + "602.13289000", + "62185621.22800290", + "0" + ], + [ + 1737183600000, + "103440.39000000", + "103488.90000000", + "102602.48000000", + "102821.75000000", + "963.58283000", + 1737187199999, + "99224995.14027700", + 113363, + "422.49185000", + "43514920.52020230", + "0" + ], + [ + 1737187200000, + "102821.75000000", + "103344.70000000", + "102277.55000000", + "103272.00000000", + "1495.73398000", + 1737190799999, + "153687375.44691780", + 184604, + "757.08619000", + "77820562.20499510", + "0" + ], + [ + 1737190800000, + "103271.99000000", + "103455.89000000", + "103059.11000000", + "103159.29000000", + "744.01579000", + 1737194399999, + "76829082.64080760", + 108721, + "322.09092000", + "33259980.11232710", + "0" + ], + [ + 1737194400000, + "103159.29000000", + "103294.35000000", + "102828.95000000", + "103184.64000000", + "905.13882000", + 1737197999999, + "93284278.94144030", + 141334, + "460.88280000", + "47501371.46321120", + "0" + ], + [ + 1737198000000, + "103184.64000000", + "103883.01000000", + "102932.01000000", + "103589.29000000", + "969.22689000", + 1737201599999, + "100273223.30841300", + 134923, + "520.96012000", + "53898835.35008860", + "0" + ], + [ + 1737201600000, + "103589.29000000", + "104035.28000000", + "103372.08000000", + "103457.34000000", + "851.81122000", + 1737205199999, + "88311349.88491570", + 124468, + "437.57328000", + "45379838.77310440", + "0" + ], + [ + 1737205200000, + "103457.34000000", + "104395.92000000", + "103107.65000000", + "104365.81000000", + "1163.74718000", + 1737208799999, + "120789371.10436770", + 144985, + "679.22778000", + "70534962.40954230", + "0" + ], + [ + 1737208800000, + "104365.81000000", + "104562.50000000", + "103722.00000000", + "103993.03000000", + "1347.04684000", + 1737212399999, + "140271691.24374090", + 173556, + "647.12049000", + "67391629.04374220", + "0" + ], + [ + 1737212400000, + "103993.02000000", + "104988.88000000", + "103761.05000000", + "104568.96000000", + "1639.57277000", + 1737215999999, + "171164062.45831700", + 240966, + "824.54152000", + "86104931.59563910", + "0" + ], + [ + 1737216000000, + "104568.96000000", + "104719.29000000", + "103156.02000000", + "103253.66000000", + "1948.60197000", + 1737219599999, + "202562765.04981120", + 332468, + "819.01022000", + "85158174.70411790", + "0" + ], + [ + 1737219600000, + "103253.65000000", + "104207.97000000", + "103253.65000000", + "103826.16000000", + "805.95293000", + 1737223199999, + "83686684.38649890", + 184411, + "425.29103000", + "44156012.95807860", + "0" + ], + [ + 1737223200000, + "103826.16000000", + "104395.92000000", + "103779.76000000", + "104084.74000000", + "860.07852000", + 1737226799999, + "89515051.78975850", + 139308, + "439.90178000", + "45784120.79975650", + "0" + ], + [ + 1737226800000, + "104084.74000000", + "104486.93000000", + "104080.71000000", + "104382.01000000", + "582.52230000", + 1737230399999, + "60748023.90664960", + 114185, + "271.15951000", + "28275091.11654880", + "0" + ], + [ + 1737230400000, + "104382.00000000", + "104488.00000000", + "103765.44000000", + "104035.42000000", + "778.47913000", + 1737233999999, + "81000919.81943530", + 120106, + "359.39505000", + "37405599.12455370", + "0" + ], + [ + 1737234000000, + "104035.42000000", + "104276.34000000", + "104000.65000000", + "104014.31000000", + "308.59759000", + 1737237599999, + "32134828.32296770", + 48385, + "133.47046000", + "13898867.02030170", + "0" + ] +] \ No newline at end of file diff --git a/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetSymbolAvgPrice.json b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetSymbolAvgPrice.json new file mode 100644 index 0000000..71f7f66 --- /dev/null +++ b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetSymbolAvgPrice.json @@ -0,0 +1,5 @@ +{ + "mins": 5, + "price": "103911.79812313", + "closeTime": 1737237753542 +} \ No newline at end of file diff --git a/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetSymbolCurrentPrice.json b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetSymbolCurrentPrice.json new file mode 100644 index 0000000..245f9e1 --- /dev/null +++ b/CryptoPulse.Tests/BianceAPI/OutputTestContent/GetSymbolCurrentPrice.json @@ -0,0 +1,4 @@ +{ + "symbol": "BTCUSDT", + "price": "104627.18000000" +} \ No newline at end of file diff --git a/CryptoPulse.Tests/BinanceClientService/BinanceClientServiceTests.cs b/CryptoPulse.Tests/BinanceClientService/BinanceClientServiceTests.cs new file mode 100644 index 0000000..68838b8 --- /dev/null +++ b/CryptoPulse.Tests/BinanceClientService/BinanceClientServiceTests.cs @@ -0,0 +1,171 @@ +using AutoMapper; +using CryptoPulse.BianceApi.DTOs; +using CryptoPulse.BianceApi.Services.Interfaces; +using CryptoPulse.Infrastructure.Services.Interfaces; +using CryptoPulse.Mapping; +using CryptoPulse.Models; +using CryptoPulse.Services; +using Moq; +using Newtonsoft.Json; +using System.Globalization; + +namespace CryptoPulse.Tests.BianceApiClient; +public class BinanceClientServiceTests: BaseTest +{ + private readonly Mock _mockSecureStorage; + private readonly Mock _mockBinanceApiClient; + private readonly BinanceClientService _binanceClientService; + private readonly IMapper _mapper; + public BinanceClientServiceTests() + { + _mockBinanceApiClient = new Mock(); + _mockSecureStorage = new Mock(); + _mockSecureStorage.Setup(x => x.GetApiKeyAsync()).ReturnsAsync("testApiKey"); + _mockSecureStorage.Setup(x => x.GetApiPrivateKeyAsync()).ReturnsAsync("testApiSecret"); + _mockSecureStorage.Setup(x => x.GetApiKeyCashed()).Returns("testApiKey"); + _mockSecureStorage.Setup(x => x.GetApiPrivateKeyCashed()).Returns("testApiSecret"); + + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new MappingProfiles()); + }); + _mapper = new Mapper(config); + + _binanceClientService = new BinanceClientService(_mapper, _mockBinanceApiClient.Object); + } + + #region GetAccountTradeList + [Fact] + public async Task GetAccountTradeList_ReturnValidTradeList() + { + // Arrange + string symbol = "BTCUSDT"; + var jsonResponse = await GetBianceApiTestFileContent("GetAccountTradeLisHttpTestResult.json"); + + var jsonData = JsonConvert.DeserializeObject>(jsonResponse); + _mockBinanceApiClient.Setup(x => x.GetAccountTradeLisAsync(symbol)).ReturnsAsync(jsonData!); + Assert.NotNull(jsonData); + + // Act + List result = await _binanceClientService.GetAccountTradeList(symbol); + var firstJson = jsonData.First(); + var firstResult = result.First(); + + Assert.NotNull(result); + Assert.Equal(firstJson.Qty, firstResult.Qty); + Assert.Equal(firstJson.Commission, firstJson.Commission); + var mappedTime = DateTimeOffset.FromUnixTimeMilliseconds(firstJson.Time).DateTime.ToLocalTime(); + Assert.Equal(mappedTime, firstResult.Time); + } + #endregion + #region GetSymbolCurrentPrice + [Fact] + public async Task GetSymbolCurrentPrice_ReturnValidCurrentPrice() + { + // Arrange + string symbol = "BTCUSDT"; + var jsonResponse = await GetBianceApiTestFileContent("GetSymbolCurrentPrice"); + + var jsonData = JsonConvert.DeserializeObject(jsonResponse); + _mockBinanceApiClient.Setup(x => x.GetSymbolCurrentPriceAsync(symbol)).ReturnsAsync(jsonData!); + Assert.NotNull(jsonData); + + // Act + PairPriceTicker result = await _binanceClientService.GetSymbolCurrentPriceAsync(symbol); + + Assert.NotNull(result); + Assert.Equal(result.Price, jsonData.Price); + Assert.Equal(result.Symbol, jsonData.Symbol); + + } + #endregion + + #region GetAccountTradeLastPairOperationAsync + [Fact] + public async Task GetAccountTradeLastPairOperationAsync_ReturnValidAccountTrade() + { + // Arrange + string symbol = "BTCUSDT"; + var jsonResponse = await GetBianceApiTestFileContent("GetAccountTradeLastPairOperationTestResult"); + + var jsonData = JsonConvert.DeserializeObject>(jsonResponse); + var jsonDataFirstElement = jsonData!.First(); + _mockBinanceApiClient.Setup(x => x.GetAccountTradeLastPairOperationAsync(symbol)).ReturnsAsync(jsonDataFirstElement); + Assert.NotNull(jsonData); + + // Act + AccountTrade result = await _binanceClientService.GetAccountTradeLastPairOperationAsync(symbol); + + Assert.NotNull(result); + Assert.Equal(result.Price, jsonDataFirstElement.Price); + Assert.Equal(result.Symbol, jsonDataFirstElement.Symbol); + + } + #endregion + + #region GetSymbolAvgPriceAsync + [Fact] + public async Task GetSymbolAvgPriceAsync_ReturnValidPairAvgPrice() + { + // Arrange + string symbol = "BTCUSDT"; + var jsonResponse = await GetBianceApiTestFileContent("GetSymbolAvgPrice"); + + var jsonData = JsonConvert.DeserializeObject(jsonResponse); + _mockBinanceApiClient.Setup(x => x.GetSymbolAvgPriceAsync(symbol)).ReturnsAsync(jsonData!); + Assert.NotNull(jsonData); + + // Act + PairAvgPrice result = await _binanceClientService.GetSymbolAvgPriceAsync(symbol); + + Assert.NotNull(result); + Assert.Equal(result.Price, jsonData.Price); + Assert.Equal(result.Mins, jsonData.Mins); + Assert.Equal(result.CloseTime, jsonData.CloseTime); + + } + #endregion + + #region GetHistoricalDataAsync + [Fact] + public async Task GetHistoricalDataAsync_ReturnValidPairAvgPrice() + { + // Arrange + string symbol = "BTCUSDT"; + var jsonResponse = await GetBianceApiTestFileContent("GetHistoricalDataAsync"); + var jsonData = JsonConvert.DeserializeObject>>(jsonResponse)!.Select(kline => new KlineDataDto + { + OpenTime = (long)Convert.ToDouble(kline[0], CultureInfo.InvariantCulture), + OpenPrice = Convert.ToDecimal(kline[1], CultureInfo.InvariantCulture), + HighPrice = Convert.ToDecimal(kline[2], CultureInfo.InvariantCulture), + LowPrice = Convert.ToDecimal(kline[3], CultureInfo.InvariantCulture), + ClosePrice = Convert.ToDecimal(kline[4], CultureInfo.InvariantCulture), + Volume = Convert.ToDouble(kline[5], CultureInfo.InvariantCulture), + CloseTime = (long)Convert.ToDouble(kline[6], CultureInfo.InvariantCulture), + QuoteAssetVolume = Convert.ToDouble(kline[7], CultureInfo.InvariantCulture), + NumberOfTrades = (long)Convert.ToDouble(kline[8], CultureInfo.InvariantCulture), + TakerBuyBaseAssetVolume = Convert.ToDecimal(kline[9], CultureInfo.InvariantCulture), + TakerBuyQuoteAssetVolume = Convert.ToDecimal(kline[10], CultureInfo.InvariantCulture) + }).ToList(); + + _mockBinanceApiClient.Setup(x => x.GetHistoricalDataAsync(symbol, "1h", 168)).ReturnsAsync(jsonData!); + Assert.NotNull(jsonData); + + // Act + List result = await _binanceClientService.GetHistoricalDataAsync(symbol, "1h", 168); + + Assert.NotNull(result); + KlineDataDto firstDto = jsonData.First(); + KlineData firstrMaped = result.First(); + + var OpenTime = DateTimeOffset.FromUnixTimeMilliseconds(firstDto.OpenTime).DateTime.ToLocalTime(); + var AvgTime = DateTimeOffset.FromUnixTimeMilliseconds((firstDto.OpenTime + firstDto.CloseTime) / 2).DateTime.ToLocalTime(); + var AvgTimeLng = (firstDto.OpenTime + firstDto.CloseTime) / 2; + var AvgPrice = (firstDto.HighPrice + firstDto.LowPrice) / 2; + Assert.Equal(OpenTime, firstrMaped.OpenTime); + Assert.Equal(AvgTime, firstrMaped.AvgTime); + Assert.Equal(AvgTimeLng, firstrMaped.AvgTimeLng); + Assert.Equal(AvgPrice, firstrMaped.AvgPrice); + } + #endregion +} diff --git a/CryptoPulse.Tests/UnitTest1.cs b/CryptoPulse.Tests/UnitTest1.cs deleted file mode 100644 index 0211213..0000000 --- a/CryptoPulse.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace CryptoPulse.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} diff --git a/CryptoPulse/Mapping/MappingProfiles.cs b/CryptoPulse/Mapping/MappingProfiles.cs index e04a9be..d884652 100644 --- a/CryptoPulse/Mapping/MappingProfiles.cs +++ b/CryptoPulse/Mapping/MappingProfiles.cs @@ -31,7 +31,6 @@ public MappingProfiles() //KlineData CreateMap() - .ForMember(x => x.OpenTime, opt => opt.MapFrom(src => DateTimeOffset.FromUnixTimeMilliseconds(src.OpenTime).DateTime.ToLocalTime())) .ForMember(x => x.OpenTime, opt => opt.MapFrom(src => DateTimeOffset.FromUnixTimeMilliseconds(src.OpenTime).DateTime.ToLocalTime())) .ForMember(x => x.AvgTime, opt => opt.MapFrom(src => DateTimeOffset.FromUnixTimeMilliseconds((src.OpenTime + src.CloseTime) / 2).DateTime.ToLocalTime())) .ForMember(x => x.AvgTimeLng, opt => opt.MapFrom(src => (src.OpenTime + src.CloseTime) / 2)) diff --git a/CryptoPulse/Services/BinanceClientService.cs b/CryptoPulse/Services/BinanceClientService.cs index 59d9a82..1948dc0 100644 --- a/CryptoPulse/Services/BinanceClientService.cs +++ b/CryptoPulse/Services/BinanceClientService.cs @@ -15,15 +15,15 @@ public BinanceClientService(IMapper mapper, IBinanceApiClient bianceApiService) _binanceApiClient = bianceApiService; } - public async Task GetAccountTradeLastPairOperation(string symbol) + public async Task GetAccountTradeLastPairOperationAsync(string symbol) { - var res = await _binanceApiClient.GetAccountTradeLastPairOperation(symbol); + var res = await _binanceApiClient.GetAccountTradeLastPairOperationAsync(symbol); return _mapper.Map(res); } public async Task> GetAccountTradeList(string pair) { - var res = await _binanceApiClient.GetAccountTradeLis(pair); + var res = await _binanceApiClient.GetAccountTradeLisAsync(pair); return _mapper.Map>(res); } @@ -33,15 +33,15 @@ public async Task> GetHistoricalDataAsync(string symbol, string return _mapper.Map>(res); } - public async Task GetSymbolAvgPrice(string symbol) + public async Task GetSymbolAvgPriceAsync(string symbol) { - var res = await _binanceApiClient.GetSymbolAvgPrice(symbol); + var res = await _binanceApiClient.GetSymbolAvgPriceAsync(symbol); return _mapper.Map(res); } - public async Task GetSymbolCurrentPrice(string symbol, CancellationTokenSource token) + public async Task GetSymbolCurrentPriceAsync(string symbol) { - var res = await _binanceApiClient.GetSymbolCurrentPrice(symbol, token); + var res = await _binanceApiClient.GetSymbolCurrentPriceAsync(symbol); return _mapper.Map(res); } } diff --git a/CryptoPulse/Services/DatabaseService.cs b/CryptoPulse/Services/DatabaseService.cs index 0640d0a..647c528 100644 --- a/CryptoPulse/Services/DatabaseService.cs +++ b/CryptoPulse/Services/DatabaseService.cs @@ -33,7 +33,7 @@ public async Task> GetPairsAsync() var mappedPairs = _mapper.Map>(pairs); foreach (var pair in mappedPairs) { - pair.LastOperation = await _bianceClient.GetAccountTradeLastPairOperation(pair.Symbol); + pair.LastOperation = await _bianceClient.GetAccountTradeLastPairOperationAsync(pair.Symbol); if(pair.LastOperation != null) { pair.LastOperationPair = pair.LastOperation.IsBuyer ? $"{pair.CurrencyName2} ► {pair.CurrencyName1}" : $"{pair.CurrencyName1} ► {pair.CurrencyName2}"; diff --git a/CryptoPulse/Services/Interfaces/IBinanceClientService.cs b/CryptoPulse/Services/Interfaces/IBinanceClientService.cs index 1931e6e..5327ab1 100644 --- a/CryptoPulse/Services/Interfaces/IBinanceClientService.cs +++ b/CryptoPulse/Services/Interfaces/IBinanceClientService.cs @@ -9,8 +9,8 @@ namespace CryptoPulse.Services.Interfaces; public interface IBinanceClientService { public Task> GetAccountTradeList(string pair); - public Task GetSymbolCurrentPrice(string symbol, CancellationTokenSource token); - public Task GetAccountTradeLastPairOperation(string symbol); - public Task GetSymbolAvgPrice(string symbol); + public Task GetSymbolCurrentPriceAsync(string symbol); + public Task GetAccountTradeLastPairOperationAsync(string symbol); + public Task GetSymbolAvgPriceAsync(string symbol); public Task> GetHistoricalDataAsync(string symbol, string interval, int limit); } diff --git a/CryptoPulse/ViewModels/KeyInputViewModel.cs b/CryptoPulse/ViewModels/KeyInputViewModel.cs index 33b826b..5b5bfae 100644 --- a/CryptoPulse/ViewModels/KeyInputViewModel.cs +++ b/CryptoPulse/ViewModels/KeyInputViewModel.cs @@ -32,7 +32,7 @@ public void Initialize() { ApiKey = await _storageService.GetApiKeyAsync() ?? string.Empty; PrivateKey = await _storageService.GetApiPrivateKeyAsync() ?? string.Empty; - validKeys = await _binanceApiClient.GetUserKeysValidation(ApiKey, PrivateKey); + validKeys = await _binanceApiClient.ChceckUserKeysValidationAsync(ApiKey, PrivateKey, true); }).Wait(); @@ -55,7 +55,7 @@ public async Task SaveKeys() return; } - bool validKeys = await _binanceApiClient.GetUserKeysValidation(ApiKey, PrivateKey); + bool validKeys = await _binanceApiClient.ChceckUserKeysValidationAsync(ApiKey, PrivateKey); if (!validKeys) { await Application.Current!.Windows[0].Page!.DisplayAlert("Alert", "The provided api key or private key is not correct!", "OK"); diff --git a/CryptoPulse/ViewModels/MainPageViewModel.cs b/CryptoPulse/ViewModels/MainPageViewModel.cs index 86b3b89..d04d4a0 100644 --- a/CryptoPulse/ViewModels/MainPageViewModel.cs +++ b/CryptoPulse/ViewModels/MainPageViewModel.cs @@ -79,7 +79,7 @@ private async Task UpdateAveragePrices(CancellationTokenSource cancellationToken { if (!_cancellationTokenSource.IsCancellationRequested && !ActivityIndicatorIsRunning) { - var currPrice = await _bianceClientService.GetSymbolCurrentPrice(pair.Symbol, cancellationToken); + var currPrice = await _bianceClientService.GetSymbolCurrentPriceAsync(pair.Symbol); pair.LastPrice = pair.CurrentExchangeRate; pair.CurrentExchangeRate = currPrice.Price; }