diff --git a/samples/WorkerServiceExample/Worker.cs b/samples/WorkerServiceExample/Worker.cs index 41c26e2..5c801d1 100644 --- a/samples/WorkerServiceExample/Worker.cs +++ b/samples/WorkerServiceExample/Worker.cs @@ -138,7 +138,9 @@ private async Task CreateFolderAndMoveTopOneAsync(string mailFolderFullName = "P { //var mailFolderNames = await _imapReceiver.GetMailFolderNamesAsync(cancellationToken); using var mailFolderClient = _serviceScope.ServiceProvider.GetRequiredService(); - var mailFolder = await mailFolderClient.GetOrCreateFolderAsync(mailFolderFullName, cancellationToken); + var baseFolder = await mailFolderClient.GetFolderAsync(["INBOX"]); + var mailFolder = await baseFolder.GetOrCreateSubfolderAsync(mailFolderFullName, cancellationToken); + //var mailFolder = await mailFolderClient.GetOrCreateFolderAsync(mailFolderFullName, cancellationToken); await MoveTopOneToFolderAsync(mailFolderClient, mailFolderFullName, cancellationToken); } diff --git a/source/MailKitSimplified.Receiver/Extensions/ImapClientExtensions.cs b/source/MailKitSimplified.Receiver/Extensions/ImapClientExtensions.cs index 6ae73d0..19059fa 100644 --- a/source/MailKitSimplified.Receiver/Extensions/ImapClientExtensions.cs +++ b/source/MailKitSimplified.Receiver/Extensions/ImapClientExtensions.cs @@ -71,7 +71,7 @@ internal static async Task> GetAllSubfoldersAsync(this IImapC { var results = new List(); var folders = await imapClient.GetFoldersAsync(folderNamespace, subscribedOnly: false, cancellationToken).ConfigureAwait(false); - foreach (var folder in folders) + foreach (var folder in folders ?? Enumerable.Empty()) { cancellationToken.ThrowIfCancellationRequested(); var subfolders = await folder.GetSubfoldersAsync(subscribedOnly: false, cancellationToken).ConfigureAwait(false); diff --git a/source/MailKitSimplified.Receiver/Extensions/MailFolderExtensions.cs b/source/MailKitSimplified.Receiver/Extensions/MailFolderExtensions.cs index 9fcc2ab..39ea469 100644 --- a/source/MailKitSimplified.Receiver/Extensions/MailFolderExtensions.cs +++ b/source/MailKitSimplified.Receiver/Extensions/MailFolderExtensions.cs @@ -1,6 +1,7 @@ -using MailKit; -using System.Threading.Tasks; +using System; using System.Threading; +using System.Threading.Tasks; +using MailKit; namespace MailKitSimplified.Receiver.Extensions { @@ -9,20 +10,22 @@ public static class MailFolderExtensions /// /// Get a mail subfolder if it exists, or create it if not. /// - /// Folder name to search for. + /// Folder name to search for. /// Base folder to search in, Inbox by default /// Cancellation token. /// Mail folder with a matching name. - public static async Task GetOrCreateSubfolderAsync(this IMailFolder baseFolder, string mailFolderName, CancellationToken cancellationToken = default) + public static async Task GetOrCreateSubfolderAsync(this IMailFolder baseFolder, string mailFolderFullName, CancellationToken cancellationToken = default) { + if (baseFolder == null) + throw new ArgumentNullException(nameof(baseFolder)); IMailFolder mailFolder; try { - mailFolder = await baseFolder.GetSubfolderAsync(mailFolderName, cancellationToken); + mailFolder = await baseFolder.GetSubfolderAsync(mailFolderFullName, cancellationToken); } catch (FolderNotFoundException) { - mailFolder = await baseFolder.CreateAsync(mailFolderName, isMessageFolder: true, cancellationToken); + mailFolder = await baseFolder.CreateAsync(mailFolderFullName, isMessageFolder: true, cancellationToken).ConfigureAwait(false); } return mailFolder; } diff --git a/source/MailKitSimplified.Receiver/Models/EmailReceiverOptions.cs b/source/MailKitSimplified.Receiver/Models/EmailReceiverOptions.cs index c6772aa..655f95f 100644 --- a/source/MailKitSimplified.Receiver/Models/EmailReceiverOptions.cs +++ b/source/MailKitSimplified.Receiver/Models/EmailReceiverOptions.cs @@ -22,7 +22,7 @@ public string MailFolderName set => MailFolderNames = new List { value }; } - public IList MailFolderNames { get; set; } = new List { string.Empty }; + public IList MailFolderNames { get; set; } = new List { _inbox }; public FolderAccess MailFolderAccess { get; set; } = FolderAccess.None; diff --git a/source/MailKitSimplified.Receiver/Services/ImapReceiver.cs b/source/MailKitSimplified.Receiver/Services/ImapReceiver.cs index f6ae404..8f5795e 100644 --- a/source/MailKitSimplified.Receiver/Services/ImapReceiver.cs +++ b/source/MailKitSimplified.Receiver/Services/ImapReceiver.cs @@ -330,21 +330,18 @@ public async Task> GetMailFolderNamesAsync(CancellationToken cance { _ = await ConnectAuthenticatedImapClientAsync(cancellationToken).ConfigureAwait(false); var mailFolderNames = new List(); + var inboxSubfolders = await _imapClient.Inbox.GetSubfoldersAsync(subscribedOnly: false, cancellationToken).ConfigureAwait(false); + if (inboxSubfolders?.Count > 0) + { + var inboxSubfolderNames = inboxSubfolders.Select(sf => $"\"{sf.FullName}\""); + mailFolderNames.AddRange(inboxSubfolderNames); + _logger.LogDebug($"{inboxSubfolders.Count} Inbox folders: {inboxSubfolderNames.ToEnumeratedString()}."); + } if (_imapClient.PersonalNamespaces.Count > 0) { var subfolderNames = await GetAllSubfoldersAsync(_imapClient.PersonalNamespaces, "personal", cancellationToken).ConfigureAwait(false); mailFolderNames.AddRange(subfolderNames); } - else - { - var inboxSubfolders = await _imapClient.Inbox.GetSubfoldersAsync(subscribedOnly: false, cancellationToken).ConfigureAwait(false); - if (inboxSubfolders.Count > 0) - { - var inboxSubfolderNames = inboxSubfolders.Select(sf => $"\"{sf.FullName}\""); - mailFolderNames.AddRange(inboxSubfolderNames); - _logger.LogDebug($"{inboxSubfolders.Count} Inbox folders: {inboxSubfolderNames.ToEnumeratedString()}."); - } - } if (_imapClient.SharedNamespaces.Count > 0) { var subfolderNames = await GetAllSubfoldersAsync(_imapClient.SharedNamespaces, "shared", cancellationToken).ConfigureAwait(false); diff --git a/tests/MailKitSimplified.Receiver.Tests/ImapReceiverUnitTests.cs b/tests/MailKitSimplified.Receiver.Tests/ImapReceiverUnitTests.cs index 615ea99..76970b4 100644 --- a/tests/MailKitSimplified.Receiver.Tests/ImapReceiverUnitTests.cs +++ b/tests/MailKitSimplified.Receiver.Tests/ImapReceiverUnitTests.cs @@ -13,6 +13,7 @@ using MailKitSimplified.Receiver.Abstractions; using MailKitSimplified.Receiver.Models; using MailKitSimplified.Receiver.Extensions; +using System.Threading; namespace MailKitSimplified.Receiver.Tests { @@ -21,6 +22,7 @@ public class ImapReceiverUnitTests private const string _localhost = "localhost"; private const int _defaultPort = 143; private readonly Mock _imapClientMock = new(); + private readonly Mock _mailFolderMock = new(); private readonly ImapReceiver _imapReceiver; public ImapReceiverUnitTests() @@ -28,11 +30,15 @@ public ImapReceiverUnitTests() // Arrange var loggerMock = new Mock>(); var protocolLoggerMock = new Mock(); + //_mailFolderMock.SetupGet(_ => _.IsOpen).Returns(false).Verifiable(); + //_mailFolderMock.SetupGet(_ => _.Access).Returns(FolderAccess.None).Verifiable(); + //_mailFolderMock.Setup(_ => _.OpenAsync(It.IsAny(), It.IsAny())).Verifiable(); + //_mailFolderMock.Setup(_ => _.CloseAsync(It.IsAny(), It.IsAny())).Verifiable(); _imapClientMock.Setup(_ => _.ConnectAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Verifiable(); _imapClientMock.Setup(_ => _.AuthenticateAsync(It.IsAny(), It.IsAny())).Verifiable(); _imapClientMock.SetupGet(_ => _.AuthenticationMechanisms).Returns(new HashSet()).Verifiable(); _imapClientMock.Setup(_ => _.AuthenticateAsync(It.IsAny(), It.IsAny())).Verifiable(); - _imapClientMock.SetupGet(_ => _.Inbox).Returns(Mock.Of()).Verifiable(); + _imapClientMock.SetupGet(_ => _.Inbox).Returns(_mailFolderMock.Object).Verifiable(); var imapReceiverOptions = Options.Create(new EmailReceiverOptions(_localhost, new NetworkCredential())); _imapReceiver = new ImapReceiver(imapReceiverOptions, loggerMock.Object, protocolLoggerMock.Object, _imapClientMock.Object, NullLoggerFactory.Instance); } @@ -197,12 +203,15 @@ public async Task GetMailFolderNamesAsync_VerifyCalls() _imapClientMock.SetupGet(_ => _.OtherNamespaces).Returns(folderNamespaceStub); _imapClientMock.Setup(_ => _.GetFoldersAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(Array.Empty()).Verifiable(); + _mailFolderMock.Setup(_ => _.GetSubfoldersAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(new List { Mock.Of() }).Verifiable(); // Act var mailFolderNames = await _imapReceiver.GetMailFolderNamesAsync(It.IsAny()); // Assert Assert.NotNull(mailFolderNames); Assert.IsAssignableFrom>(mailFolderNames); - _imapClientMock.Verify(_ => _.GetFoldersAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(2)); + _imapClientMock.Verify(_ => _.GetFoldersAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(0)); + _mailFolderMock.Verify(_ => _.GetSubfoldersAsync(It.IsAny(), It.IsAny()), Times.Exactly(1)); }