public async Task OnSuccessShouldReturnValidObject()
        {
            // Arrange
            //
            var faceSettings = TestHelper.GetFaceSettings();

            var handler    = new Mock <HttpMessageHandler>();
            var ccResponse = "{\"EUR_PHP\": 51.440375}";

            handler.SetupRequest(HttpMethod.Get, faceSettings.BuildCurrencyConverterUrl("EUR", "PHP"))
            .ReturnsResponse(ccResponse, "application/json");

            var client = new CurrencyConverterClient(
                TestHelper.GetLoggerMock <CurrencyConverterClient>().Object,
                handler.CreateClient(),
                faceSettings,
                TestHelper.GetMetricsMock().Object);

            // Act
            //
            var result = await client.RequestCurrencyConverter("EUR", "PHP");

            // Assert
            //
            Assert.Equal(RequestStatusCode.Ok, result.RequestStatus.StatusCode);
            Assert.Equal((decimal)51.440375, result.ExchangeRate);
        }
        public async Task OnErrorShouldReturnErrorObject()
        {
            // Arrange
            //
            var faceSettings = TestHelper.GetFaceSettings();

            var handler = new Mock <HttpMessageHandler>();

            handler.SetupAnyRequest()
            .ReturnsResponse(HttpStatusCode.BadRequest);

            var client = new CurrencyConverterClient(
                TestHelper.GetLoggerMock <CurrencyConverterClient>().Object,
                handler.CreateClient(),
                faceSettings,
                TestHelper.GetMetricsMock().Object);

            // Act
            //
            var result = await client.RequestCurrencyConverter("EUR", "PHP");

            // Assert
            //
            Assert.Equal(RequestStatusCode.Error, result.RequestStatus.StatusCode);
            Assert.Equal(400, result.RequestStatus.ErrorCode);
        }
Пример #3
0
        /// <summary>
        /// Request current Exchange rate in local cache. If not found, try CurrencyConverter, if fails - try ExchangeRateApi.io
        /// </summary>
        /// <param name="baseCurrency">the currency from which convert</param>
        /// <param name="targetCurrency">the currency to which convert</param>
        /// <returns>Returns exchange rate <see cref="ExchangeRateInfo"/></returns>
        public async Task <ExchangeRateInfo> GetExchangeRate(string baseCurrency, string targetCurrency)
        {
            string cacheKey = $"er-{baseCurrency}-{targetCurrency}";

            if (_memoryCache.TryGetValue(cacheKey, out ExchangeRateInfo exchangeRateInfo))
            {
                _metrics.ExchangeRateIncrement("cache", SourceType.Memory, baseCurrency, targetCurrency);
                return(exchangeRateInfo);
            }

            var fallbackPolicy = Policy <ExchangeRateInfo>
                                 .Handle <Exception>()
                                 .OrResult(_ => _.RequestStatus.StatusCode == RequestStatusCode.Error)
                                 .FallbackAsync(async cancellationToken =>
            {
                if (_faceSettings.ExchangeRateSupportedCurrency.Contains(baseCurrency) &&
                    _faceSettings.ExchangeRateSupportedCurrency.Contains(targetCurrency))
                {
                    return(await _exchangeRateApiClient.RequestExchangeRateApi(baseCurrency, targetCurrency)
                           .ConfigureAwait(false));
                }
                return(new ExchangeRateInfo());
            }, onFallbackAsync: async _ =>
            {
                _logger.LogWarning(_.Exception, "Fallback, object state {@ExchangeRateInfo}", _.Result);
                await Task.CompletedTask.ConfigureAwait(false);
            });

            exchangeRateInfo = await fallbackPolicy.ExecuteAsync(async() =>
                                                                 await _currencyConverterClient.RequestCurrencyConverter(baseCurrency, targetCurrency)
                                                                 .ConfigureAwait(false));

            if (exchangeRateInfo.RequestStatus.StatusCode == RequestStatusCode.Ok && exchangeRateInfo.ExchangeRate != 0)
            {
                _memoryCache.Set(cacheKey, exchangeRateInfo, TimeSpan.FromMinutes(60));
            }
            return(exchangeRateInfo);
        }
        public async Task OnAuthErrorShouldLogAuthIssue()
        {
            // Arrange
            //
            var loggerMock   = TestHelper.GetLoggerMock <CurrencyConverterClient>();
            var faceSettings = TestHelper.GetFaceSettings();

            var handler = new Mock <HttpMessageHandler>();

            handler.SetupAnyRequest()
            .ReturnsResponse(HttpStatusCode.Unauthorized);

            var client = new CurrencyConverterClient(
                loggerMock.Object,
                handler.CreateClient(),
                faceSettings,
                TestHelper.GetMetricsMock().Object);

            // Act
            //
            var result = await client.RequestCurrencyConverter("EUR", "PHP");

            // Assert
            //
            Assert.Equal(RequestStatusCode.Error, result.RequestStatus.StatusCode);
            Assert.Equal(401, result.RequestStatus.ErrorCode);

            loggerMock.Verify(
                x => x.Log(
                    It.IsAny <LogLevel>(),
                    It.IsAny <EventId>(),
                    It.Is <It.IsAnyType>((o, t) => string.Equals("Unauthorized access to currencyconverterapi.com", o.ToString(), StringComparison.InvariantCultureIgnoreCase)),
                    It.IsAny <Exception>(),
                    (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()),
                Times.Once);
        }