< Summary

Information
Class: c:\Source 2025\CurrencyConverter\CurrencyConverter\src\Application\Currencies\ConvertCurrency\ConvertCurrencyHandler.cs
Assembly: Default
File(s): c:\Source 2025\CurrencyConverter\CurrencyConverter\src\Application\Currencies\ConvertCurrency\ConvertCurrencyHandler.cs
Line coverage
100%
Covered lines: 46
Uncovered lines: 0
Coverable lines: 46
Total lines: 74
Line coverage: 100%
Branch coverage
100%
Covered branches: 14
Total branches: 14
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

File(s)

c:\Source 2025\CurrencyConverter\CurrencyConverter\src\Application\Currencies\ConvertCurrency\ConvertCurrencyHandler.cs

#LineLine coverage
 1using Application.Abstractions;
 2using Application.Currencies.ConvertCurrency.Dtos;
 3using Domain.Common;
 4using Domain.Currencies;
 5using MediatR;
 6using Microsoft.Extensions.Logging;
 7
 8namespace Application.Currencies.ConvertCurrency
 9{
 10    public class ConvertCurrencyHandler : IRequestHandler<ConvertCurrencyQuery, Result<ConvertCurrencyResultDto>>
 11    {
 12        private readonly IExchangeProviderFactory _exchangeFactory;
 13        private readonly ILogger<ConvertCurrencyHandler> _logger;
 14        private readonly ICacheService _cacheService;
 15
 2116        public ConvertCurrencyHandler(IExchangeProviderFactory exchangeFactory,
 2117            ILogger<ConvertCurrencyHandler> logger,
 2118            ICacheService cacheService)
 2119        {
 2120            _cacheService = cacheService;
 2121            _exchangeFactory = exchangeFactory;
 2122            _logger = logger;
 2123        }
 24
 25        public async Task<Result<ConvertCurrencyResultDto>> Handle(ConvertCurrencyQuery command, CancellationToken cance
 2126        {
 2127            var targetCurrencyCodeResult = CurrencyCode.FromCode(command.TargetCurrencyCode);
 2128            if (targetCurrencyCodeResult.IsFailure)
 129            {
 130                return Result.Failure<ConvertCurrencyResultDto>(targetCurrencyCodeResult.Error);
 31            }
 2032            var targetCode = targetCurrencyCodeResult.Value;
 33
 2034            if (!CurrencySnapshot.IsLegalConversion(targetCode))
 435            {
 436                return Result.Failure<ConvertCurrencyResultDto>(new Error(ErrorCode.BadInput, $"{command.TargetCurrencyC
 37            }
 38
 1639            var baseCurrencyCodeResult = CurrencyCode.FromCode(command.BaseCurrencyCode);
 1640            if (baseCurrencyCodeResult.IsFailure)
 141            {
 142                return Result.Failure<ConvertCurrencyResultDto>(baseCurrencyCodeResult.Error);
 43            }
 1544            var baseCode = baseCurrencyCodeResult.Value;
 45
 1546            var exchangeProvider = _exchangeFactory.GetProvider(ExchangeProviderType.Frankfurter);
 1547            if (exchangeProvider == null)
 148            {
 149                _logger.LogError("Could not find an exchange provider, {requestedProvider}", ExchangeProviderType.Frankf
 150                return Result.Failure<ConvertCurrencyResultDto>(Error.SystemError);
 51            }
 1452            var cacheKey = $"latest-{baseCode.Value}";
 1453            var currencySnapShot = await _cacheService.GetAsync<CurrencySnapshot>(cacheKey, cancellationToken);
 1454            if (currencySnapShot == null)
 1255            {
 1256                var result = await exchangeProvider.FindLatestAsync(baseCode);
 1257                if (result.IsFailure)
 158                {
 159                    return Result.Failure<ConvertCurrencyResultDto>(result.Error);
 60                }
 1161                currencySnapShot = result.Value;
 1162                await _cacheService.SetAsync(cacheKey, currencySnapShot, cancellationToken);
 1163            }
 1364            var conversionResult = currencySnapShot.Convert(command.BaseAmount, targetCode);
 1365            if (conversionResult.IsFailure)
 166            {
 167                return Result.Failure<ConvertCurrencyResultDto>(conversionResult.Error);
 68            }
 1269            return new ConvertCurrencyResultDto(currencySnapShot.DateCaptured,
 1270                conversionResult.Value.Code.Value,
 1271                conversionResult.Value.Amount);
 2172        }
 73    }
 74}