< Summary

Information
Class: c:\Source 2025\CurrencyConverter\CurrencyConverter\src\Application\Currencies\FindLatestCurrency\FindLatestCurrencyHandler.cs
Assembly: Default
File(s): c:\Source 2025\CurrencyConverter\CurrencyConverter\src\Application\Currencies\FindLatestCurrency\FindLatestCurrencyHandler.cs
Line coverage
100%
Covered lines: 38
Uncovered lines: 0
Coverable lines: 38
Total lines: 61
Line coverage: 100%
Branch coverage
100%
Covered branches: 8
Total branches: 8
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\FindLatestCurrency\FindLatestCurrencyHandler.cs

#LineLine coverage
 1using Application.Abstractions;
 2using Application.Currencies.FindLatestCurrency.Dtos;
 3using Domain.Common;
 4using Domain.Currencies;
 5using MediatR;
 6using Microsoft.Extensions.Logging;
 7
 8namespace Application.Currencies.FindLatestCurrency
 9{
 10    public class FindLatestCurrencyHandler : IRequestHandler<FindLatestCurrencyQuery, Result<FindLatestCurrencyResultDto
 11    {
 12        private readonly IExchangeProviderFactory _exchangeFactory;
 13        private readonly ILogger<FindLatestCurrencyHandler> _logger;
 14        private readonly ICacheService _cacheService;
 15        private readonly ITimeProvider _timeProvider;
 16
 1017        public FindLatestCurrencyHandler(IExchangeProviderFactory exchangeFactory,
 1018            ILogger<FindLatestCurrencyHandler> logger,
 1019            ICacheService cacheService,
 1020            ITimeProvider timeProvider)
 1021        {
 1022            _cacheService = cacheService;
 1023            _exchangeFactory = exchangeFactory;
 1024            _logger = logger;
 1025            _timeProvider = timeProvider;
 1026        }
 27
 28        public async Task<Result<FindLatestCurrencyResultDto>> Handle(FindLatestCurrencyQuery command, CancellationToken
 1029        {
 1030            var currencyCodeResult = CurrencyCode.FromCode(command.CurrencyCode);
 1031            if (currencyCodeResult.IsFailure)
 132            {
 133                return Result.Failure<FindLatestCurrencyResultDto>(currencyCodeResult.Error);
 34            }
 935            var currencyCode = currencyCodeResult.Value;
 936            var exchangeProvider = _exchangeFactory.GetProvider(ExchangeProviderType.Frankfurter);
 937            if (exchangeProvider == null)
 138            {
 139                _logger.LogError("Could not find an exchange provider, {requestedProvider}", ExchangeProviderType.Frankf
 140                return Result.Failure<FindLatestCurrencyResultDto>(Error.SystemError);
 41            }
 842            var cacheKey = $"{_timeProvider.UtcNow().ToString("yyyy-MM-dd")}-{currencyCode.Value}";
 843            var currencySnapShot = await _cacheService.GetAsync<CurrencySnapshot>(cacheKey, cancellationToken);
 844            if (currencySnapShot == null)
 645            {
 646                var result = await exchangeProvider.FindLatestAsync(currencyCode);
 647                if (result.IsFailure)
 148                {
 149                    return Result.Failure<FindLatestCurrencyResultDto>(result.Error);
 50                }
 551                currencySnapShot = result.Value;
 552                await _cacheService.SetAsync(cacheKey, currencySnapShot, cancellationToken);
 553            }
 754            return new FindLatestCurrencyResultDto(currencySnapShot.Code.Value,
 755                currencySnapShot.DateCaptured,
 756                currencySnapShot.ExchangeRates
 1457                    .Select(x => new FindLatestCurrencyExchangeRateDto(x.Code.Value, x.Amount))
 758                .ToList());
 1059        }
 60    }
 61}