public void Test_CronHelper_FindNextUpdateTime_Returns()
        {
            // Arrange
            var baseDateTime         = new DateTime(2020, 2, 18, 15, 50, 30);
            var expectedDateTime     = new DateTime(2020, 2, 18, 16, 00, 00);
            var cronEveryWeekdayAt16 = "0 16 * * 1-5";
            // Run
            var result = CronHelper.FindNextUpdateTime(baseDateTime, cronEveryWeekdayAt16);

            // Assert
            Assert.Equal(result, expectedDateTime);
        }
        public async Task <Exchange> ExchangeRatesBySourceAndTarget(string source, string target)
        {
            source = source?.ToUpper();
            target = target?.ToUpper();
            // Check source and target currency codes are valid
            var currencies = Currencies();

            if (!(currencies.Any(x => x.Code.Equals(source)) && currencies.Any(x => x.Code.Equals(target))))
            {
                _logger.LogError("Source or Target currency invalid!");
                throw new ArgumentException("Source or Target currency invalid");
            }

            var requestUrl = "?base=" + source + "&symbols=" + target;

            if (_cache.TryGetValue(requestUrl, out Exchange responseRate))
            {
                return(responseRate);
            }
            string cron       = "0 16 * * 1-5"; // Every weekday at 16.00 pm
            var    expiryDate = CronHelper.FindNextUpdateTime(DateTime.Now, cron);
            var    request    = new HttpRequestMessage(HttpMethod.Get, BASE_CURRENCY_EXCHANGE_SERVICE_URL + requestUrl);

            using (var client = _clientFactory.CreateClient())
            {
                var response = await client.SendAsync(request);

                if (response.IsSuccessStatusCode)
                {
                    var responseStream = await response.Content.ReadAsStringAsync();

                    var jo           = JObject.Parse(responseStream);
                    var currencyRate = jo["rates"][target].ToString();
                    var updateDate   = jo["date"].ToString();
                    var exchange     = new Exchange
                    {
                        SourceCurrency = source,
                        TargetCurrency = target,
                        ExchangeRate   = (decimal)double.Parse(currencyRate),
                        Date           = DateTime.Parse(updateDate)
                    };
                    _logger.LogInformation("Exchange information read successful!", exchange);
                    _cache.Set(requestUrl, exchange, expiryDate);
                    return(exchange);
                }
                else
                {
                    _logger.LogError("Exchange rates cannot be read!", response.StatusCode);
                }
            }
            return(default);