/// <summary> /// Asynchronously gets the specified metadata. /// </summary> /// <remarks> /// Asynchronously gets the specified metadata. /// </remarks> /// <returns>The requested metadata.</returns> /// <param name="options">The metadata options.</param> /// <param name="tags">The metadata tags.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="tags"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="System.NotSupportedException"> /// The folder does not support metadata. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task <MetadataCollection> GetMetadataAsync(MetadataOptions options, IEnumerable <MetadataTag> tags, CancellationToken cancellationToken = default(CancellationToken)) { return(Task.Factory.StartNew(() => { lock (SyncRoot) { return GetMetadata(options, tags, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default)); }
/// <summary> /// Asynchronously gets the specified metadata. /// </summary> /// <remarks> /// Asynchronously gets the specified metadata. /// </remarks> /// <returns>The requested metadata.</returns> /// <param name="options">The metadata options.</param> /// <param name="tags">The metadata tags.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="tags"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="System.NotSupportedException"> /// The folder does not support metadata. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract Task <MetadataCollection> GetMetadataAsync(MetadataOptions options, IEnumerable <MetadataTag> tags, CancellationToken cancellationToken = default(CancellationToken));
public void TestArgumentExceptions () { var enumeratedRights = new [] { AccessRight.OpenFolder, AccessRight.CreateFolder }; Assert.Throws<ArgumentNullException> (() => new AccessControl (null)); Assert.Throws<ArgumentNullException> (() => new AccessControl (null, "rk")); Assert.Throws<ArgumentNullException> (() => new AccessControl (null, enumeratedRights)); Assert.Throws<ArgumentNullException> (() => new AccessControl ("name", (string) null)); Assert.Throws<ArgumentNullException> (() => new AccessControl ("name", (IEnumerable<AccessRight>) null)); Assert.Throws<ArgumentNullException> (() => new AccessControlList (null)); Assert.Throws<ArgumentNullException> (() => new AccessRights ((IEnumerable<AccessRight>) null)); Assert.Throws<ArgumentNullException> (() => new AccessRights ((string) null)); var rights = new AccessRights (); Assert.Throws<ArgumentNullException> (() => rights.AddRange ((string) null)); Assert.Throws<ArgumentNullException> (() => rights.AddRange ((IEnumerable<AccessRight>) null)); Assert.Throws<ArgumentNullException> (() => new AlertEventArgs (null)); Assert.Throws<ArgumentNullException> (() => new FolderNamespace ('.', null)); var namespaces = new FolderNamespaceCollection (); FolderNamespace ns; Assert.Throws<ArgumentNullException> (() => namespaces.Add (null)); Assert.Throws<ArgumentNullException> (() => namespaces.Contains (null)); Assert.Throws<ArgumentNullException> (() => namespaces.Remove (null)); Assert.Throws<ArgumentOutOfRangeException> (() => ns = namespaces[-1]); Assert.Throws<ArgumentOutOfRangeException> (() => namespaces[-1] = new FolderNamespace ('.', "")); namespaces.Add (new FolderNamespace ('.', "")); Assert.Throws<ArgumentNullException> (() => namespaces[0] = null); Assert.Throws<ArgumentNullException> (() => new FolderNotFoundException (null)); Assert.Throws<ArgumentNullException> (() => new FolderNotFoundException ("message", null)); Assert.Throws<ArgumentNullException> (() => new FolderNotFoundException ("message", null, new Exception ("message"))); Assert.Throws<ArgumentNullException> (() => new FolderNotOpenException (null, FolderAccess.ReadOnly)); Assert.Throws<ArgumentNullException> (() => new FolderNotOpenException (null, FolderAccess.ReadOnly, "message")); Assert.Throws<ArgumentNullException> (() => new FolderNotOpenException (null, FolderAccess.ReadOnly, "message", new Exception ("message"))); Assert.Throws<ArgumentNullException> (() => new FolderRenamedEventArgs (null, "name")); Assert.Throws<ArgumentNullException> (() => new FolderRenamedEventArgs ("name", null)); Assert.Throws<ArgumentOutOfRangeException> (() => new MessageEventArgs (-1)); Assert.Throws<ArgumentNullException> (() => new MessageFlagsChangedEventArgs (0, MessageFlags.Answered, null)); Assert.Throws<ArgumentNullException> (() => new MessageFlagsChangedEventArgs (0, MessageFlags.Answered, null, 1)); Assert.Throws<ArgumentNullException> (() => new MessageFlagsChangedEventArgs (0, UniqueId.MinValue, MessageFlags.Answered, null)); Assert.Throws<ArgumentNullException> (() => new MessageFlagsChangedEventArgs (0, UniqueId.MinValue, MessageFlags.Answered, null, 1)); Assert.Throws<ArgumentNullException> (() => new MessageLabelsChangedEventArgs (0, null)); Assert.Throws<ArgumentNullException> (() => new MessageLabelsChangedEventArgs (0, null, 1)); Assert.Throws<ArgumentNullException> (() => new MessageLabelsChangedEventArgs (0, UniqueId.MinValue, null)); Assert.Throws<ArgumentNullException> (() => new MessageLabelsChangedEventArgs (0, UniqueId.MinValue, null, 1)); Assert.Throws<ArgumentNullException> (() => new MessageSentEventArgs (null, "response")); Assert.Throws<ArgumentNullException> (() => new MessageSentEventArgs (new MimeMessage (), null)); Assert.Throws<ArgumentNullException> (() => new MessageSummaryFetchedEventArgs (null)); Assert.Throws<ArgumentNullException> (() => new MessagesVanishedEventArgs (null, false)); Assert.Throws<ArgumentNullException> (() => new MetadataCollection (null)); var metadataOptions = new MetadataOptions (); Assert.Throws<ArgumentOutOfRangeException> (() => metadataOptions.Depth = 500); Assert.Throws<ArgumentOutOfRangeException> (() => new ModSeqChangedEventArgs (-1)); Assert.Throws<ArgumentOutOfRangeException> (() => new ModSeqChangedEventArgs (-1, 1)); Assert.Throws<ArgumentOutOfRangeException> (() => new ModSeqChangedEventArgs (-1, UniqueId.MinValue, 1)); Assert.Throws<ArgumentOutOfRangeException> (() => new OrderBy (OrderByType.To, SortOrder.None)); Assert.Throws<ArgumentNullException> (() => new ProtocolLogger ((string) null)); Assert.Throws<ArgumentNullException> (() => new ProtocolLogger ((Stream) null)); using (var logger = new ProtocolLogger (new MemoryStream ())) { var buffer = new byte[1024]; Assert.Throws<ArgumentNullException> (() => logger.LogConnect (null)); Assert.Throws<ArgumentNullException> (() => logger.LogClient (null, 0, 0)); Assert.Throws<ArgumentNullException> (() => logger.LogServer (null, 0, 0)); Assert.Throws<ArgumentOutOfRangeException> (() => logger.LogClient (buffer, -1, 0)); Assert.Throws<ArgumentOutOfRangeException> (() => logger.LogServer (buffer, -1, 0)); Assert.Throws<ArgumentOutOfRangeException> (() => logger.LogClient (buffer, 0, -1)); Assert.Throws<ArgumentOutOfRangeException> (() => logger.LogServer (buffer, 0, -1)); } Assert.Throws<ArgumentNullException> (() => new UniqueIdMap (null, new [] { UniqueId.MinValue })); Assert.Throws<ArgumentNullException> (() => new UniqueIdMap (new [] { UniqueId.MinValue }, null)); }
public async void TestMetadata () { var commands = new List<ImapReplayCommand> (); commands.Add (new ImapReplayCommand ("", "gmail.greeting.txt")); commands.Add (new ImapReplayCommand ("A00000000 CAPABILITY\r\n", "metadata.capability.txt")); commands.Add (new ImapReplayCommand ("A00000001 AUTHENTICATE PLAIN AHVzZXJuYW1lAHBhc3N3b3Jk\r\n", "metadata.authenticate.txt")); commands.Add (new ImapReplayCommand ("A00000002 NAMESPACE\r\n", "gmail.namespace.txt")); commands.Add (new ImapReplayCommand ("A00000003 LIST \"\" \"INBOX\"\r\n", "gmail.list-inbox.txt")); commands.Add (new ImapReplayCommand ("A00000004 XLIST \"\" \"*\"\r\n", "gmail.xlist.txt")); commands.Add (new ImapReplayCommand ("A00000005 GETMETADATA \"\" /private/comment\r\n", "metadata.getmetadata.txt")); commands.Add (new ImapReplayCommand ("A00000006 GETMETADATA \"\" (MAXSIZE 1024 DEPTH infinity) (/private)\r\n", "metadata.getmetadata-options.txt")); commands.Add (new ImapReplayCommand ("A00000007 GETMETADATA \"\" /private/comment /shared/comment\r\n", "metadata.getmetadata-multi.txt")); commands.Add (new ImapReplayCommand ("A00000008 SETMETADATA \"\" (/private/comment \"this is a comment\")\r\n", "metadata.setmetadata-noprivate.txt")); commands.Add (new ImapReplayCommand ("A00000009 SETMETADATA \"\" (/private/comment \"this comment is too long!\")\r\n", "metadata.setmetadata-maxsize.txt")); commands.Add (new ImapReplayCommand ("A00000010 SETMETADATA \"\" (/private/comment \"this is a private comment\" /shared/comment \"this is a shared comment\")\r\n", "metadata.setmetadata-toomany.txt")); commands.Add (new ImapReplayCommand ("A00000011 SETMETADATA \"\" (/private/comment NIL)\r\n", ImapReplayCommandResponse.OK)); commands.Add (new ImapReplayCommand ("A00000012 GETMETADATA INBOX /private/comment\r\n", "metadata.inbox-getmetadata.txt")); commands.Add (new ImapReplayCommand ("A00000013 GETMETADATA INBOX (MAXSIZE 1024 DEPTH infinity) (/private)\r\n", "metadata.inbox-getmetadata-options.txt")); commands.Add (new ImapReplayCommand ("A00000014 GETMETADATA INBOX /private/comment /shared/comment\r\n", "metadata.inbox-getmetadata-multi.txt")); commands.Add (new ImapReplayCommand ("A00000015 SETMETADATA INBOX (/private/comment \"this is a comment\")\r\n", "metadata.inbox-setmetadata-noprivate.txt")); commands.Add (new ImapReplayCommand ("A00000016 SETMETADATA INBOX (/private/comment \"this comment is too long!\")\r\n", "metadata.inbox-setmetadata-maxsize.txt")); commands.Add (new ImapReplayCommand ("A00000017 SETMETADATA INBOX (/private/comment \"this is a private comment\" /shared/comment \"this is a shared comment\")\r\n", "metadata.inbox-setmetadata-toomany.txt")); commands.Add (new ImapReplayCommand ("A00000018 SETMETADATA INBOX (/private/comment NIL)\r\n", ImapReplayCommandResponse.OK)); using (var client = new ImapClient ()) { MetadataCollection metadata; MetadataOptions options; try { client.ReplayConnect ("localhost", new ImapReplayStream (commands, false)); } catch (Exception ex) { Assert.Fail ("Did not expect an exception in Connect: {0}", ex); } Assert.IsTrue (client.IsConnected, "Client failed to connect."); Assert.AreEqual (MetadataInitialCapabilities, client.Capabilities); Assert.AreEqual (4, client.AuthenticationMechanisms.Count); Assert.IsTrue (client.AuthenticationMechanisms.Contains ("XOAUTH"), "Expected SASL XOAUTH auth mechanism"); Assert.IsTrue (client.AuthenticationMechanisms.Contains ("XOAUTH2"), "Expected SASL XOAUTH2 auth mechanism"); Assert.IsTrue (client.AuthenticationMechanisms.Contains ("PLAIN"), "Expected SASL PLAIN auth mechanism"); Assert.IsTrue (client.AuthenticationMechanisms.Contains ("PLAIN-CLIENTTOKEN"), "Expected SASL PLAIN-CLIENTTOKEN auth mechanism"); // Note: Do not try XOAUTH2 client.AuthenticationMechanisms.Remove ("XOAUTH2"); try { await client.AuthenticateAsync ("username", "password"); } catch (Exception ex) { Assert.Fail ("Did not expect an exception in Authenticate: {0}", ex); } Assert.AreEqual (MetadataAuthenticatedCapabilities, client.Capabilities); var inbox = client.Inbox; Assert.IsNotNull (inbox, "Expected non-null Inbox folder."); Assert.AreEqual (FolderAttributes.Inbox | FolderAttributes.HasNoChildren, inbox.Attributes, "Expected Inbox attributes to be \\HasNoChildren."); foreach (var special in Enum.GetValues (typeof (SpecialFolder)).OfType<SpecialFolder> ()) { var folder = client.GetFolder (special); if (special != SpecialFolder.Archive) { var expected = GetSpecialFolderAttribute (special) | FolderAttributes.HasNoChildren; Assert.IsNotNull (folder, "Expected non-null {0} folder.", special); Assert.AreEqual (expected, folder.Attributes, "Expected {0} attributes to be \\HasNoChildren.", special); } else { Assert.IsNull (folder, "Expected null {0} folder.", special); } } // GETMETADATA Assert.AreEqual ("this is a comment", await client.GetMetadataAsync (MetadataTag.PrivateComment), "The shared comment does not match."); options = new MetadataOptions { Depth = int.MaxValue, MaxSize = 1024 }; metadata = await client.GetMetadataAsync (options, new [] { new MetadataTag ("/private") }); Assert.AreEqual (1, metadata.Count, "Expected 1 metadata value."); Assert.AreEqual (MetadataTag.PrivateComment.Id, metadata[0].Tag.Id, "Metadata tag did not match."); Assert.AreEqual ("this is a private comment", metadata[0].Value, "Metadata value did not match."); Assert.AreEqual (2199, options.LongEntries, "LongEntries does not match."); metadata = await client.GetMetadataAsync (new [] { MetadataTag.PrivateComment, MetadataTag.SharedComment }); Assert.AreEqual (2, metadata.Count, "Expected 2 metadata values."); Assert.AreEqual (MetadataTag.PrivateComment.Id, metadata[0].Tag.Id, "First metadata tag did not match."); Assert.AreEqual (MetadataTag.SharedComment.Id, metadata[1].Tag.Id, "Second metadata tag did not match."); Assert.AreEqual ("this is a private comment", metadata[0].Value, "First metadata value did not match."); Assert.AreEqual ("this is a shared comment", metadata[1].Value, "Second metadata value did not match."); // SETMETADATA Assert.Throws<ImapCommandException> (async () => await client.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, "this is a comment") })), "Expected NOPRIVATE RESP-CODE."); Assert.Throws<ImapCommandException> (async () => await client.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, "this comment is too long!") })), "Expected MAXSIZE RESP-CODE."); Assert.Throws<ImapCommandException> (async () => await client.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, "this is a private comment"), new Metadata (MetadataTag.SharedComment, "this is a shared comment"), })), "Expected TOOMANY RESP-CODE."); await client.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, null) })); // GETMETADATA folder Assert.AreEqual ("this is a comment", await inbox.GetMetadataAsync (MetadataTag.PrivateComment), "The shared comment does not match."); options = new MetadataOptions { Depth = int.MaxValue, MaxSize = 1024 }; metadata = await inbox.GetMetadataAsync (options, new [] { new MetadataTag ("/private") }); Assert.AreEqual (1, metadata.Count, "Expected 1 metadata value."); Assert.AreEqual (MetadataTag.PrivateComment.Id, metadata[0].Tag.Id, "Metadata tag did not match."); Assert.AreEqual ("this is a private comment", metadata[0].Value, "Metadata value did not match."); Assert.AreEqual (2199, options.LongEntries, "LongEntries does not match."); metadata = await inbox.GetMetadataAsync (new [] { MetadataTag.PrivateComment, MetadataTag.SharedComment }); Assert.AreEqual (2, metadata.Count, "Expected 2 metadata values."); Assert.AreEqual (MetadataTag.PrivateComment.Id, metadata[0].Tag.Id, "First metadata tag did not match."); Assert.AreEqual (MetadataTag.SharedComment.Id, metadata[1].Tag.Id, "Second metadata tag did not match."); Assert.AreEqual ("this is a private comment", metadata[0].Value, "First metadata value did not match."); Assert.AreEqual ("this is a shared comment", metadata[1].Value, "Second metadata value did not match."); // SETMETADATA folder Assert.Throws<ImapCommandException> (async () => await inbox.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, "this is a comment") })), "Expected NOPRIVATE RESP-CODE."); Assert.Throws<ImapCommandException> (async () => await inbox.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, "this comment is too long!") })), "Expected MAXSIZE RESP-CODE."); Assert.Throws<ImapCommandException> (async () => await inbox.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, "this is a private comment"), new Metadata (MetadataTag.SharedComment, "this is a shared comment"), })), "Expected TOOMANY RESP-CODE."); await inbox.SetMetadataAsync (new MetadataCollection (new [] { new Metadata (MetadataTag.PrivateComment, null) })); await client.DisconnectAsync (false); } }
/// <summary> /// Asynchronously gets the specified metadata. /// </summary> /// <remarks> /// Asynchronously gets the specified metadata. /// </remarks> /// <returns>The requested metadata.</returns> /// <param name="options">The metadata options.</param> /// <param name="tags">The metadata tags.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="tags"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="System.NotSupportedException"> /// The folder does not support metadata. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public virtual Task<MetadataCollection> GetMetadataAsync (MetadataOptions options, IEnumerable<MetadataTag> tags, CancellationToken cancellationToken = default (CancellationToken)) { return Task.Factory.StartNew (() => { lock (SyncRoot) { return GetMetadata (options, tags, cancellationToken); } }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default); }
/// <summary> /// Gets the specified metadata. /// </summary> /// <remarks> /// Gets the specified metadata. /// </remarks> /// <returns>The requested metadata.</returns> /// <param name="options">The metadata options.</param> /// <param name="tags">The metadata tags.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <exception cref="System.ArgumentNullException"> /// <para><paramref name="options"/> is <c>null</c>.</para> /// <para>-or-</para> /// <para><paramref name="tags"/> is <c>null</c>.</para> /// </exception> /// <exception cref="System.ObjectDisposedException"> /// The <see cref="IMailStore"/> has been disposed. /// </exception> /// <exception cref="ServiceNotConnectedException"> /// The <see cref="IMailStore"/> is not connected. /// </exception> /// <exception cref="ServiceNotAuthenticatedException"> /// The <see cref="IMailStore"/> is not authenticated. /// </exception> /// <exception cref="System.NotSupportedException"> /// The folder does not support metadata. /// </exception> /// <exception cref="System.OperationCanceledException"> /// The operation was canceled via the cancellation token. /// </exception> /// <exception cref="System.IO.IOException"> /// An I/O error occurred. /// </exception> /// <exception cref="ProtocolException"> /// The server's response contained unexpected tokens. /// </exception> /// <exception cref="CommandException"> /// The command failed. /// </exception> public abstract MetadataCollection GetMetadata (MetadataOptions options, IEnumerable<MetadataTag> tags, CancellationToken cancellationToken = default (CancellationToken));