< Summary

Information
Class: Services.EmailRoutingServices.ImapConnectionTester
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/EmailRoutingServices/ImapConnectionTester.cs
Line coverage
72%
Covered lines: 35
Uncovered lines: 13
Coverable lines: 48
Total lines: 88
Line coverage: 72.9%
Branch coverage
66%
Covered branches: 8
Total branches: 12
Branch coverage: 66.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
CheckAsync()66.66%141274.46%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/EmailRoutingServices/ImapConnectionTester.cs

#LineLine coverage
 1using MailKit;
 2using MailKit.Net.Imap;
 3using MailKit.Search;
 4using Microsoft.Extensions.Logging;
 5
 6namespace Services.EmailRoutingServices;
 7
 8public static class ImapConnectionTester
 9{
 10    public static async Task<ImapConnectionStatus> CheckAsync(
 11        ImapSettings settings,
 12        ILogger? logger = null,
 13        CancellationToken cancellationToken = default)
 14    {
 1415        var status = new ImapConnectionStatus
 1416        {
 1417            UserName = settings.UserName,
 1418            Host = settings.Host,
 1419            Port = settings.Port,
 1420            Folder = settings.Folder,
 1421            FetchLimit = settings.FetchLimit,
 1422            CheckedAtUtc = DateTime.UtcNow
 1423        };
 24
 1425        if (string.IsNullOrWhiteSpace(settings.Host) || string.IsNullOrWhiteSpace(settings.UserName))
 26        {
 827            status.IsConfigured = false;
 828            status.ErrorMessage = "IMAP не настроен: укажите Host и UserName.";
 829            return status;
 30        }
 31
 632        if (string.IsNullOrWhiteSpace(settings.Password))
 33        {
 434            status.IsConfigured = true;
 435            status.IsConnected = false;
 436            status.ErrorMessage = "Пароль не задан.";
 437            return status;
 38        }
 39
 240        status.IsConfigured = true;
 41
 42        try
 43        {
 244            using var client = new ImapClient();
 245            await client.ConnectAsync(settings.Host, settings.Port, settings.UseSsl, cancellationToken);
 046            await client.AuthenticateAsync(settings.UserName, settings.Password, cancellationToken);
 47
 048            var inbox = client.GetFolder(settings.Folder);
 049            await inbox.OpenAsync(FolderAccess.ReadOnly, cancellationToken);
 50
 051            var unseenUids = await inbox.SearchAsync(SearchQuery.NotSeen, cancellationToken);
 052            status.UnseenCount = unseenUids.Count;
 53
 054            var sinceUtc = ImapFetchWindow.ResolveSinceUtc(settings);
 055            var scanLimit = ImapFetchWindow.ResolveScanLimit(settings);
 056            var summaries = await ImapEmailInboxClient.LoadRecentSummariesAsync(inbox, scanLimit, cancellationToken);
 057            status.UnseenReadyCount = summaries.Count(s => ImapFetchWindow.IsCandidateMessage(s, sinceUtc));
 58
 059            await client.DisconnectAsync(true, cancellationToken);
 060            status.IsConnected = true;
 061        }
 162        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
 63        {
 64            // Клиент уже отменил HTTP-запрос: это не сбой IMAP и не повод писать Warning в errors-*.log.
 165            throw;
 66        }
 167        catch (Exception ex)
 68        {
 169            if (ImapEmailInboxClient.IsTransientConnectionException(ex))
 70            {
 171                logger?.LogInformation(
 172                    "IMAP connection check encountered transient connection issue for {UserName}@{Host}: {Message}",
 173                    settings.UserName,
 174                    settings.Host,
 175                    ex.Message);
 76            }
 77            else
 78            {
 079                logger?.LogWarning(ex, "IMAP connection check failed for {UserName}@{Host}", settings.UserName, settings
 80            }
 81
 182            status.IsConnected = false;
 183            status.ErrorMessage = ex.Message;
 184        }
 85
 186        return status;
 1387    }
 88}

Methods/Properties

CheckAsync()