public async Task Run_DisplayMenuAndDisplayBTCQuoteThenExit_CheckConsoleAndCryptoCurrencyServiceMethods()
        {
            // Arrange
            Initialize();
            string cryptoSymbol = "BTN";

            _console.Setup(x => x.Clear());
            _console.Setup(x => x.WriteLine(It.IsAny <string>(), It.IsAny <ConsoleColor>()));
            _console.SetupSequence(x => x.ReadLine()).Returns(cryptoSymbol).Returns("e");

            _logger.Setup(x => x.Log(It.Is <LogLevel>(a => a == LogLevel.Information), It.IsAny <EventId>(), It.Is <It.IsAnyType>((v, t) => true), It.IsAny <Exception>(), It.Is <Func <It.IsAnyType, Exception, string> >((v, t) => true))).Verifiable();


            GetCryptoCurrencyQuoteResponse getCryptoCurrencyQuoteResponse = new GetCryptoCurrencyQuoteResponse();
            GetCryptoCurrencyQuoteRequest  getCryptoCurrencyQuoteRequest  = null;

            _cryptoCurrencyService.Setup(x => x.GetCryptoCurrencyQuoteAsync(It.IsAny <GetCryptoCurrencyQuoteRequest>()))
            .Callback <GetCryptoCurrencyQuoteRequest>(x => getCryptoCurrencyQuoteRequest = x)
            .ReturnsAsync(getCryptoCurrencyQuoteResponse);


            // Act
            await _applicationService.Run(new string[] { });

            // Assert
            _console.Verify(x => x.WriteLine(It.Is <string>(input => input == "(C)rypto Currencies"), It.IsAny <ConsoleColor>()), Times.Exactly(2));
            _console.Verify(x => x.WriteLine(It.Is <string>(input => input == "(E)xit"), It.IsAny <ConsoleColor>()), Times.Exactly(2));
            _console.Verify(x => x.WriteLine(It.Is <string>(input => input == "Choose An Option Or Enter Crypto Currency Symbol:"), It.IsAny <ConsoleColor>()), Times.Exactly(2));
            _cryptoCurrencyService.Verify(x => x.GetCryptoCurrenciesAsync(), Times.Never);
            _cryptoCurrencyService.Verify(x => x.GetCryptoCurrencyQuoteAsync(It.IsAny <GetCryptoCurrencyQuoteRequest>()), Times.Once);
            Assert.NotNull(getCryptoCurrencyQuoteRequest);
            Assert.NotNull(getCryptoCurrencyQuoteRequest.CryptoCurrencySymbol);
            Assert.Equal(cryptoSymbol.ToLower(), getCryptoCurrencyQuoteRequest.CryptoCurrencySymbol.ToLower());
        }
        public async Task GetCryptoCurrencyQuoteAsync_InactiveCryptoCurrency_ReturnRequestedCryptoCurrencyIsNotActiveInMessage()
        {
            // Arrange
            Initialize();

            var request = new GetCryptoCurrencyQuoteRequest
            {
                CryptoCurrencySymbol = "BTN"
            };

            GetCryptoCurrencies getCryptoCurrenciesResponse = new GetCryptoCurrencies
            {
                CryptoCurrencies = new List <CryptoCurrencyData>
                {
                    new CryptoCurrencyData
                    {
                        Id       = 1,
                        Name     = "Bitcoin",
                        Symbol   = "BTN",
                        IsActive = false
                    }
                },
                Status = new StatusData
                {
                    ErrorCode = 0
                }
            };

            _coinMarketCapProxy.Setup(x => x.GetCryptoCurrenciesAsync()).ReturnsAsync(getCryptoCurrenciesResponse);

            // Act
            var result = await _cryptoCurrencyService.GetCryptoCurrencyQuoteAsync(request).ConfigureAwait(false);

            // Assert
            Assert.NotNull(result);
            Assert.False(result.Success);
            Assert.Equal("Requested Crypto Currency Is Not Active.", result.Message);
            Assert.Null(result.Quotes);
            Assert.Equal(string.Empty, result.CryptoCurrencySymbol);

            _coinMarketCapProxy.Verify(x => x.GetCryptoCurrenciesAsync(), Times.Once);
        }
        public async Task GetCryptoCurrencyQuoteAsync_CryptoCurrencyQuoteWithExchangeApproach_VerifyCoinMarketCapProxyMethodsVerifyExchangeRatesProxyOnce()
        {
            // Arrange
            Initialize();
            _appSettings.CalculateQuoteApproach = "CryptoCurrencyQuoteWithExchangeApproach";
            _appSettings.Currencies             = new List <string> {
                "USD", "EUR"
            };
            _appSettings.BaseCurrency = "USD";
            _appSettings.MaximumFloatingPointDigit = 3;

            string cryptoCurrencySymbol = "BTN";
            int    cryptoCurrencyId     = 1;

            var request = new GetCryptoCurrencyQuoteRequest
            {
                CryptoCurrencySymbol = cryptoCurrencySymbol
            };

            GetCryptoCurrencies getCryptoCurrenciesResponse = new GetCryptoCurrencies
            {
                CryptoCurrencies = new List <CryptoCurrencyData>
                {
                    new CryptoCurrencyData
                    {
                        Id       = cryptoCurrencyId,
                        Name     = "Bitcoin",
                        Symbol   = cryptoCurrencySymbol,
                        IsActive = true
                    }
                },
                Status = new StatusData
                {
                    ErrorCode = 0
                }
            };

            _coinMarketCapProxy.Setup(x => x.GetCryptoCurrenciesAsync()).ReturnsAsync(getCryptoCurrenciesResponse);

            GetCryptoCurrencyQuotes getCryptoCurrencyQuotesRequestForUSD = null;
            decimal usdPrice = 100000;
            CryptoCurrencyQuotesData getCryptoCurrencyQuotesResponseForUSD = new CryptoCurrencyQuotesData
            {
                Data = new Dictionary <string, CryptoCurrencyQuoteData> {
                    { cryptoCurrencyId.ToString(), new CryptoCurrencyQuoteData {
                          Id = cryptoCurrencyId, Quotes = new Dictionary <string, QuoteData> {
                              { "USD", new QuoteData {
                                                                                                         Price = usdPrice
                                                                                                     } }
                          }
                      } }
                }
            };

            _coinMarketCapProxy.Setup(x => x.GetCryptoCurrencyQuotesAsync(It.IsAny <GetCryptoCurrencyQuotes>()))
            .Callback <GetCryptoCurrencyQuotes>(x => getCryptoCurrencyQuotesRequestForUSD = x)
            .ReturnsAsync(getCryptoCurrencyQuotesResponseForUSD);


            decimal         eurRateToUsd     = 0.1m;
            GetExchangeData exchangeRequest  = null;
            ExchangeData    exchangeResponse = new ExchangeData
            {
                Base  = _appSettings.BaseCurrency,
                Rates = new Dictionary <string, decimal> {
                    { "EUR", eurRateToUsd }
                }
            };

            _exchangeRatesProxy.Setup(x => x.GetExchangeRateAsync(It.IsAny <GetExchangeData>())).Callback <GetExchangeData>(x => exchangeRequest = x).ReturnsAsync(exchangeResponse);


            // Act
            var result = await _cryptoCurrencyService.GetCryptoCurrencyQuoteAsync(request).ConfigureAwait(false);

            // Assert
            Assert.NotNull(result);
            Assert.True(result.Success);
            Assert.Equal("Success", result.Message);
            Assert.NotNull(result.Quotes);
            Assert.Equal(cryptoCurrencySymbol, result.CryptoCurrencySymbol);

            Assert.True(result.Quotes.Count() == 2);
            var usdQuote = result.Quotes.FirstOrDefault(x => x.Key == "USD");

            Assert.NotNull(usdQuote);
            Assert.Equal(usdPrice, usdQuote.Value);
            var eurQuote = result.Quotes.FirstOrDefault(x => x.Key == "EUR");

            Assert.NotNull(eurQuote);
            Assert.Equal(decimal.Round(eurRateToUsd * usdPrice, _appSettings.MaximumFloatingPointDigit), eurQuote.Value);


            _coinMarketCapProxy.Verify(x => x.GetCryptoCurrenciesAsync(), Times.Once);
            _exchangeRatesProxy.Verify(x => x.GetExchangeRateAsync(It.IsAny <GetExchangeData>()), Times.Once);
            Assert.NotNull(exchangeRequest);
            Assert.Equal(_appSettings.BaseCurrency, exchangeRequest.BaseCurrency);
            Assert.NotNull(exchangeRequest.TargetCurrencies);
            Assert.True(_appSettings.Currencies.Count() == exchangeRequest.TargetCurrencies.Count());

            foreach (var currency in _appSettings.Currencies)
            {
                Assert.Contains(currency, exchangeRequest.TargetCurrencies);
            }

            _coinMarketCapProxy.Verify(x => x.GetCryptoCurrencyQuotesAsync(It.IsAny <GetCryptoCurrencyQuotes>()), Times.Once);

            Assert.NotNull(getCryptoCurrencyQuotesRequestForUSD);
            Assert.NotNull(getCryptoCurrencyQuotesRequestForUSD.CryptoCurrencies);
            Assert.True(getCryptoCurrencyQuotesRequestForUSD.CryptoCurrencies.Count() == 1);
            Assert.Contains(cryptoCurrencyId, getCryptoCurrencyQuotesRequestForUSD.CryptoCurrencies);

            Assert.NotNull(getCryptoCurrencyQuotesRequestForUSD.ConvertCurrencies);
            Assert.True(getCryptoCurrencyQuotesRequestForUSD.ConvertCurrencies.Count() == 1);
            Assert.Contains("USD", getCryptoCurrencyQuotesRequestForUSD.ConvertCurrencies);
        }
        public async Task GetCryptoCurrencyQuoteAsync_InvalidRequest_ResultIsNotSuccess(GetCryptoCurrencyQuoteRequest request, string message)
        {
            // Arrange
            Initialize();

            // Act
            var result = await _cryptoCurrencyService.GetCryptoCurrencyQuoteAsync(request).ConfigureAwait(false);

            // Assert
            Assert.NotNull(result);
            Assert.False(result.Success);
            Assert.Equal(message, result.Message);
            Assert.Null(result.Quotes);
            Assert.Equal(string.Empty, result.CryptoCurrencySymbol);

            _coinMarketCapProxy.Verify(x => x.GetCryptoCurrenciesAsync(), Times.Never);
        }
예제 #5
0
        public async Task <GetCryptoCurrencyQuoteResponse> GetCryptoCurrencyQuoteAsync(GetCryptoCurrencyQuoteRequest request)
        {
            _logger.LogInformation($"Getting Crypto Currency Quote Started. Request: {request}");
            if (request == null)
            {
                return(new GetCryptoCurrencyQuoteResponse
                {
                    CryptoCurrencySymbol = string.Empty,
                    Quotes = null,
                    Success = false,
                    Message = "Request Is Null"
                });
            }
            if (string.IsNullOrWhiteSpace(request.CryptoCurrencySymbol))
            {
                return(new GetCryptoCurrencyQuoteResponse
                {
                    CryptoCurrencySymbol = string.Empty,
                    Quotes = null,
                    Success = false,
                    Message = "CryptoCurrencySymbol Is Null Or Empty"
                });
            }

            await SetCryptoCurrencies().ConfigureAwait(false);

            var cryptoCurrencySymbolMinLength = CryptoCurrencies.Min(x => x.Symbol.Length);
            var cryptoCurrencySymbolMaxLength = CryptoCurrencies.Max(x => x.Symbol.Length);

            if (request.CryptoCurrencySymbol.Trim().Length < cryptoCurrencySymbolMinLength || request.CryptoCurrencySymbol.Trim().Length > cryptoCurrencySymbolMaxLength)
            {
                return(new GetCryptoCurrencyQuoteResponse
                {
                    CryptoCurrencySymbol = request.CryptoCurrencySymbol,
                    Quotes = null,
                    Success = false,
                    Message = $"CryptoCurrencySymbol Lentgh Is Invalid. Should Be Between {cryptoCurrencySymbolMinLength} And {cryptoCurrencySymbolMaxLength}"
                });
            }

            var cryptoCurrency = CryptoCurrencies.FirstOrDefault(x => x.Symbol.ToLower() == request.CryptoCurrencySymbol.ToLower());

            if (cryptoCurrency == null)
            {
                return(new GetCryptoCurrencyQuoteResponse
                {
                    Success = false,
                    Message = "Invalid Crypto Currency Symbol.",
                    CryptoCurrencySymbol = request.CryptoCurrencySymbol,
                    Quotes = null
                });
            }

            if (!cryptoCurrency.IsActive)
            {
                return(new GetCryptoCurrencyQuoteResponse
                {
                    Success = false,
                    Message = "Requested Crypto Currency Is Not Active.",
                    CryptoCurrencySymbol = string.Empty,
                    Quotes = null
                });
            }

            if (IsCryptoCurrencyQuoteOnlyCallCoinMarketCapApproach())
            {
                return(await CryptoCurrencyQuoteOnlyCallCoinMarketCapApproach(request.CryptoCurrencySymbol, cryptoCurrency.Id).ConfigureAwait(false));
            }

            return(await CryptoCurrencyQuoteWithExchangeApproach(request.CryptoCurrencySymbol, cryptoCurrency.Id).ConfigureAwait(false));
        }