A set of options to use when requesting metadata.
A set of options to use when requesting metadata.
Beispiel #1
0
 /// <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));
 }
Beispiel #2
0
 /// <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));
		}
Beispiel #4
0
		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);
			}
		}
Beispiel #5
0
		/// <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);
		}
Beispiel #6
0
		/// <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));