[System] Fix tests that regressed in e6536dd.
[mono.git] / mcs / class / System / Test / System.Net.Mail / SmtpClientTest.cs
1 //
2 // SmtpClientTest.cs - NUnit Test Cases for System.Net.Mail.SmtpClient
3 //
4 // Authors:
5 //   John Luke (john.luke@gmail.com)
6 //
7 // (C) 2006 John Luke
8 //
9 using NUnit.Framework;
10 using System;
11 using System.IO;
12 using System.Net.Mail;
13 using System.Net.Mime;
14 using System.Threading;
15
16 namespace MonoTests.System.Net.Mail
17 {
18         [TestFixture]
19         public class SmtpClientTest
20         {
21                 SmtpClient _smtp;
22                 SmtpClient smtp { get { return _smtp ?? (_smtp = new SmtpClient ()); } }
23                 string tempFolder;
24                 
25                 [SetUp]
26                 public void GetReady ()
27                 {
28                         tempFolder = Path.Combine (Path.GetTempPath (), this.GetType ().FullName);
29                         if (Directory.Exists (tempFolder))
30                                 Directory.Delete (tempFolder, true);
31                         Directory.CreateDirectory (tempFolder);
32                 }
33
34                 [TearDown]
35                 public void TearDown ()
36                 {
37                         _smtp = null;
38                         if (Directory.Exists (tempFolder))
39                                 Directory.Delete (tempFolder, true);
40                 }
41
42                 [Test]
43 #if FEATURE_NO_BSD_SOCKETS
44                 [ExpectedException (typeof (PlatformNotSupportedException))]
45 #endif
46                 public void Credentials_Default ()
47                 {
48                         Assert.IsNull (smtp.Credentials);
49                 }
50
51                 [Test]
52 #if FEATURE_NO_BSD_SOCKETS
53                 [ExpectedException (typeof (PlatformNotSupportedException))]
54 #endif
55                 public void DeliveryMethod ()
56                 {
57                         Assert.AreEqual (SmtpDeliveryMethod.Network, smtp.DeliveryMethod, "#1");
58                         smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
59                         Assert.AreEqual (SmtpDeliveryMethod.SpecifiedPickupDirectory,
60                                 smtp.DeliveryMethod, "#2");
61                         smtp.DeliveryMethod = SmtpDeliveryMethod.PickupDirectoryFromIis;
62                         Assert.AreEqual (SmtpDeliveryMethod.PickupDirectoryFromIis,
63                                 smtp.DeliveryMethod, "#3");
64                         smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
65                         Assert.AreEqual (SmtpDeliveryMethod.Network,
66                                 smtp.DeliveryMethod, "#4");
67                 }
68
69                 [Test]
70 #if FEATURE_NO_BSD_SOCKETS
71                 [ExpectedException (typeof (PlatformNotSupportedException))]
72 #endif
73                 public void EnableSsl ()
74                 {
75                         Assert.IsFalse (smtp.EnableSsl, "#1");
76                         smtp.EnableSsl = true;
77                         Assert.IsTrue (smtp.EnableSsl, "#2");
78                         smtp.EnableSsl = false;
79                         Assert.IsFalse (smtp.EnableSsl, "#3");
80                 }
81
82                 [Test]
83 #if FEATURE_NO_BSD_SOCKETS
84                 [ExpectedException (typeof (PlatformNotSupportedException))]
85 #endif
86                 public void Host ()
87                 {
88                         smtp.Host = "127.0.0.1";
89                         Assert.AreEqual ("127.0.0.1", smtp.Host, "#2");
90                         smtp.Host = "smtp.ximian.com";
91                         Assert.AreEqual ("smtp.ximian.com", smtp.Host, "#3");
92                 }
93
94                 [Test]
95                 [Category ("NotWorking")]
96                 public void Host_Default ()
97                 {
98                         Assert.IsNull (smtp.Host);
99                 }
100
101                 [Test]
102 #if FEATURE_NO_BSD_SOCKETS
103                 [ExpectedException (typeof (PlatformNotSupportedException))]
104 #endif
105                 public void Host_Value_Null ()
106                 {
107                         try {
108                                 smtp.Host = null;
109                                 Assert.Fail ("#1");
110                         } catch (ArgumentNullException ex) {
111                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
112                                 Assert.IsNull (ex.InnerException, "#3");
113                                 Assert.IsNotNull (ex.Message, "#4");
114                                 Assert.AreEqual ("value", ex.ParamName, "#5");
115                         }
116                 }
117
118                 [Test]
119 #if FEATURE_NO_BSD_SOCKETS
120                 [ExpectedException (typeof (PlatformNotSupportedException))]
121 #endif
122                 public void Host_Value_Empty ()
123                 {
124                         try {
125                                 smtp.Host = String.Empty;
126                                 Assert.Fail ("#1");
127                         } catch (ArgumentException ex) {
128                                 // This property cannot be set to an empty string
129                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
130                                 Assert.IsNull (ex.InnerException, "#3");
131                                 Assert.IsNotNull (ex.Message, "#4");
132                                 Assert.AreEqual ("value", ex.ParamName, "#5");
133                         }
134                 }
135
136                 [Test]
137 #if FEATURE_NO_BSD_SOCKETS
138                 [ExpectedException (typeof (PlatformNotSupportedException))]
139 #endif
140                 public void PickupDirectoryLocation ()
141                 {
142                         Assert.IsNull (smtp.PickupDirectoryLocation, "#1");
143                         smtp.PickupDirectoryLocation = tempFolder;
144                         Assert.AreSame (tempFolder, smtp.PickupDirectoryLocation, "#2");
145                         smtp.PickupDirectoryLocation = "shouldnotexist";
146                         Assert.AreEqual ("shouldnotexist", smtp.PickupDirectoryLocation, "#3");
147                         smtp.PickupDirectoryLocation = null;
148                         Assert.IsNull (smtp.PickupDirectoryLocation, "#4");
149                         smtp.PickupDirectoryLocation = string.Empty;
150                         Assert.AreEqual (string.Empty, smtp.PickupDirectoryLocation, "#5");
151                         smtp.PickupDirectoryLocation = "\0";
152                         Assert.AreEqual ("\0", smtp.PickupDirectoryLocation, "#6");
153                 }
154
155                 [Test]
156 #if FEATURE_NO_BSD_SOCKETS
157                 [ExpectedException (typeof (PlatformNotSupportedException))]
158 #endif
159                 public void Port ()
160                 {
161                         Assert.AreEqual (25, smtp.Port, "#1");
162                         smtp.Port = 1;
163                         Assert.AreEqual (1, smtp.Port, "#2");
164                         smtp.Port = int.MaxValue;
165                         Assert.AreEqual (int.MaxValue, smtp.Port, "#3");
166                 }
167
168                 [Test]
169 #if FEATURE_NO_BSD_SOCKETS
170                 [ExpectedException (typeof (PlatformNotSupportedException))]
171 #endif
172                 public void Port_Value_Invalid ()
173                 {
174                         // zero
175                         try {
176                                 smtp.Port = 0;
177                                 Assert.Fail ("#A1");
178                         } catch (ArgumentOutOfRangeException ex) {
179                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#A2");
180                                 Assert.IsNull (ex.InnerException, "#A3");
181                                 Assert.IsNotNull (ex.Message, "#A4");
182                                 Assert.AreEqual ("value", ex.ParamName, "#A5");
183                         }
184
185                         // negative
186                         try {
187                                 smtp.Port = -1;
188                                 Assert.Fail ("#B1");
189                         } catch (ArgumentOutOfRangeException ex) {
190                                 Assert.AreEqual (typeof (ArgumentOutOfRangeException), ex.GetType (), "#B2");
191                                 Assert.IsNull (ex.InnerException, "#B3");
192                                 Assert.IsNotNull (ex.Message, "#B4");
193                                 Assert.AreEqual ("value", ex.ParamName, "#B5");
194                         }
195                 }
196
197                 [Test]
198 #if FEATURE_NO_BSD_SOCKETS
199                 [ExpectedException (typeof (PlatformNotSupportedException))]
200 #endif
201                 public void Send_Message_Null ()
202                 {
203                         try {
204                                 smtp.Send ((MailMessage) null);
205                                 Assert.Fail ("#1");
206                         } catch (ArgumentNullException ex) {
207                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
208                                 Assert.IsNull (ex.InnerException, "#B3");
209                                 Assert.IsNotNull (ex.Message, "#B4");
210                                 Assert.AreEqual ("message", ex.ParamName, "#B5");
211                         }
212                 }
213
214                 [Test]
215 #if FEATURE_NO_BSD_SOCKETS
216                 [ExpectedException (typeof (PlatformNotSupportedException))]
217 #endif
218                 public void Send_Network_Host_Null ()
219                 {
220                         try {
221                                 smtp.Send ("mono@novell.com", "everyone@novell.com",
222                                         "introduction", "hello");
223                                 Assert.Fail ("#1");
224                         } catch (InvalidOperationException ex) {
225                                 // The SMTP host was not specified
226                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
227                                 Assert.IsNull (ex.InnerException, "#3");
228                                 Assert.IsNotNull (ex.Message, "#4");
229                         }
230                 }
231
232                 [Test]
233 #if FEATURE_NO_BSD_SOCKETS
234                 [ExpectedException (typeof (PlatformNotSupportedException))]
235 #endif
236                 public void Send_Network_Host_Whitespace ()
237                 {
238                         smtp.Host = " \r\n ";
239                         try {
240                                 smtp.Send ("mono@novell.com", "everyone@novell.com",
241                                         "introduction", "hello");
242                                 Assert.Fail ("#1");
243                         } catch (InvalidOperationException ex) {
244                                 // The SMTP host was not specified
245                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
246                                 Assert.IsNull (ex.InnerException, "#3");
247                                 Assert.IsNotNull (ex.Message, "#4");
248                         }
249                 }
250
251                 [Test]
252 #if FEATURE_NO_BSD_SOCKETS
253                 [ExpectedException (typeof (PlatformNotSupportedException))]
254 #endif
255                 public void Send_SpecifiedPickupDirectory ()
256                 {
257                         smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
258                         smtp.PickupDirectoryLocation = tempFolder;
259                         smtp.Send ("mono@novell.com", "everyone@novell.com",
260                                 "introduction", "hello");
261
262                         string [] files = Directory.GetFiles (tempFolder, "*");
263                         Assert.AreEqual (1, files.Length, "#1");
264                         Assert.AreEqual (".eml", Path.GetExtension (files [0]), "#2");
265                 }
266
267                 [Test]
268 #if FEATURE_NO_BSD_SOCKETS
269                 [ExpectedException (typeof (PlatformNotSupportedException))]
270 #endif
271                 public void Send_SpecifiedPickupDirectory_PickupDirectoryLocation_DirectoryNotFound ()
272                 {
273                         Directory.Delete (tempFolder);
274
275                         smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
276                         smtp.PickupDirectoryLocation = tempFolder;
277                         try {
278                                 smtp.Send ("mono@novell.com", "everyone@novell.com",
279                                         "introduction", "hello");
280                                 Assert.Fail ("#1");
281                         } catch (SmtpException ex) {
282                                 // Failure sending email
283                                 Assert.AreEqual (typeof (SmtpException), ex.GetType (), "#2");
284                                 Assert.IsNotNull (ex.InnerException, "#3");
285                                 Assert.AreEqual (typeof (DirectoryNotFoundException), ex.InnerException.GetType (), "#4");
286                                 Assert.IsNotNull (ex.Message, "#5");
287                                 Assert.AreEqual (SmtpStatusCode.GeneralFailure, ex.StatusCode, "#6");
288
289                                 // Could not find a part of the path '...'
290                                 DirectoryNotFoundException inner = (DirectoryNotFoundException) ex.InnerException;
291                                 Assert.IsNull (inner.InnerException, "#7");
292                                 Assert.IsNotNull (inner.Message, "#8");
293                                 Assert.IsTrue (inner.Message.IndexOf (tempFolder) != -1, "#9");
294                         }
295                 }
296
297                 [Test]
298 #if FEATURE_NO_BSD_SOCKETS
299                 [ExpectedException (typeof (PlatformNotSupportedException))]
300 #endif
301                 public void Send_SpecifiedPickupDirectory_PickupDirectoryLocation_Empty ()
302                 {
303                         smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
304                         smtp.PickupDirectoryLocation = string.Empty;
305                         try {
306                                 smtp.Send ("mono@novell.com", "everyone@novell.com",
307                                         "introduction", "hello");
308                                 Assert.Fail ("#1");
309                         } catch (SmtpException ex) {
310                                 // Only absolute directories are allowed for
311                                 // pickup directory
312                                 Assert.AreEqual (typeof (SmtpException), ex.GetType (), "#2");
313                                 Assert.IsNull (ex.InnerException, "#3");
314                                 Assert.IsNotNull (ex.Message, "#4");
315                                 Assert.AreEqual (SmtpStatusCode.GeneralFailure, ex.StatusCode, "#5");
316                         }
317                 }
318
319                 [Test]
320 #if FEATURE_NO_BSD_SOCKETS
321                 [ExpectedException (typeof (PlatformNotSupportedException))]
322 #endif
323                 public void Send_SpecifiedPickupDirectory_PickupDirectoryLocation_IllegalChars ()
324                 {
325                         smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
326                         smtp.PickupDirectoryLocation = "\0abc";
327                         try {
328                                 smtp.Send ("mono@novell.com", "everyone@novell.com",
329                                         "introduction", "hello");
330                                 Assert.Fail ("#1");
331                         } catch (SmtpException ex) {
332                                 // Failure sending email
333                                 Assert.AreEqual (typeof (SmtpException), ex.GetType (), "#2");
334                                 Assert.IsNotNull (ex.InnerException, "#3");
335                                 Assert.AreEqual (typeof (ArgumentException), ex.InnerException.GetType (), "#4");
336                                 Assert.IsNotNull (ex.Message, "#5");
337                                 Assert.AreEqual (SmtpStatusCode.GeneralFailure, ex.StatusCode, "#6");
338
339                                 // Illegal characters in path
340                                 ArgumentException inner = (ArgumentException) ex.InnerException;
341                                 Assert.IsNull (inner.InnerException, "#7");
342                                 Assert.IsNotNull (inner.Message, "#8");
343                                 Assert.IsNull (inner.ParamName, "#9");
344                         }
345                 }
346
347                 [Test]
348 #if FEATURE_NO_BSD_SOCKETS
349                 [ExpectedException (typeof (PlatformNotSupportedException))]
350 #endif
351                 public void Send_SpecifiedPickupDirectory_PickupDirectoryLocation_NotAbsolute ()
352                 {
353                         smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
354                         smtp.PickupDirectoryLocation = "relative";
355                         try {
356                                 smtp.Send ("mono@novell.com", "everyone@novell.com",
357                                         "introduction", "hello");
358                                 Assert.Fail ("#1");
359                         } catch (SmtpException ex) {
360                                 // Only absolute directories are allowed for
361                                 // pickup directory
362                                 Assert.AreEqual (typeof (SmtpException), ex.GetType (), "#2");
363                                 Assert.IsNull (ex.InnerException, "#3");
364                                 Assert.IsNotNull (ex.Message, "#4");
365                                 Assert.AreEqual (SmtpStatusCode.GeneralFailure, ex.StatusCode, "#5");
366                         }
367                 }
368
369                 [Test]
370 #if FEATURE_NO_BSD_SOCKETS
371                 [ExpectedException (typeof (PlatformNotSupportedException))]
372 #endif
373                 public void Send_SpecifiedPickupDirectory_PickupDirectoryLocation_Null ()
374                 {
375                         smtp.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;
376                         try {
377                                 smtp.Send ("mono@novell.com", "everyone@novell.com",
378                                         "introduction", "hello");
379                                 Assert.Fail ("#1");
380                         } catch (SmtpException ex) {
381                                 // Only absolute directories are allowed for
382                                 // pickup directory
383                                 Assert.AreEqual (typeof (SmtpException), ex.GetType (), "#2");
384                                 Assert.IsNull (ex.InnerException, "#3");
385                                 Assert.IsNotNull (ex.Message, "#4");
386                                 Assert.AreEqual (SmtpStatusCode.GeneralFailure, ex.StatusCode, "#5");
387                         }
388                 }
389
390                 [Test]
391 #if FEATURE_NO_BSD_SOCKETS
392                 [ExpectedException (typeof (PlatformNotSupportedException))]
393 #endif
394                 public void Timeout ()
395                 {
396                         Assert.AreEqual (100000, smtp.Timeout, "#1");
397                         smtp.Timeout = 50;
398                         Assert.AreEqual (50, smtp.Timeout, "#2");
399                         smtp.Timeout = 0;
400                         Assert.AreEqual (0, smtp.Timeout, "#3");
401                 }
402
403                 [Test]
404 #if FEATURE_NO_BSD_SOCKETS
405                 [ExpectedException (typeof (PlatformNotSupportedException))]
406 #else
407                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
408 #endif
409                 public void Timeout_Value_Negative ()
410                 {
411                         smtp.Timeout = -1;
412                 }
413
414                 [Test]
415 #if FEATURE_NO_BSD_SOCKETS
416                 [ExpectedException (typeof (PlatformNotSupportedException))]
417 #endif
418                 public void UseDefaultCredentials_Default ()
419                 {
420                         Assert.IsFalse (smtp.UseDefaultCredentials);
421                 }
422
423                 [Test]
424 #if FEATURE_NO_BSD_SOCKETS
425                 [ExpectedException (typeof (PlatformNotSupportedException))]
426 #endif
427                 public void Deliver ()
428                 {
429                         var server = new SmtpServer ();
430                         var client = new SmtpClient ("localhost", server.EndPoint.Port);
431                         var msg = new MailMessage ("foo@example.com", "bar@example.com", "hello", "howdydoo\r\n");
432
433                         Thread t = new Thread (server.Run);
434                         t.Start ();
435                         client.Send (msg);
436                         t.Join ();
437
438                         Assert.AreEqual ("<foo@example.com>", server.mail_from);
439                         Assert.AreEqual ("<bar@example.com>", server.rcpt_to);
440                 }
441
442                 [Test]
443 #if FEATURE_NO_BSD_SOCKETS
444                 [ExpectedException (typeof (PlatformNotSupportedException))]
445 #endif
446                 public void Deliver_Envelope ()
447                 {
448                         var server = new SmtpServer ();
449                         var client = new SmtpClient ("localhost", server.EndPoint.Port);
450                         var msg = new MailMessage ("foo@example.com", "bar@example.com", "hello", "howdydoo\r\n");
451
452                         msg.Sender = new MailAddress ("baz@example.com");
453
454                         Thread t = new Thread (server.Run);
455                         t.Start ();
456                         client.Send (msg);
457                         t.Join ();
458
459                         Assert.AreEqual ("<baz@example.com>", server.mail_from);
460                         Assert.AreEqual ("<bar@example.com>", server.rcpt_to);
461                 }
462
463                 [Test]
464 #if FEATURE_NO_BSD_SOCKETS
465                 [ExpectedException (typeof (PlatformNotSupportedException))]
466 #endif
467                 public void Deliver_Async ()
468                 {
469                         // SmtpClient uses BackgroundWorker and listens for the RunWorkerCompleted
470                         // to mark an async task as completed. The problem is that BackgroundWorker uses
471                         // System.ComponentModel.AsyncOperationManager to get the synchronization
472                         // context, and in monotouch that returns by default a synchronization
473                         // context for the main thread. Since tests are also run on the main thread,
474                         // we'll block the main thread while waiting for the async send to complete,
475                         // while the async completion is waiting for the main thread to process it.
476                         // So instead use a SynchronizationContext that uses the threadpool instead
477                         // of the main thread.
478                         var existing_context = global::System.ComponentModel.AsyncOperationManager.SynchronizationContext;
479                         global::System.ComponentModel.AsyncOperationManager.SynchronizationContext = new ThreadPoolSynchronizationContext ();
480                         try {
481                                 var server = new SmtpServer ();
482                                 var client = new SmtpClient ("localhost", server.EndPoint.Port);
483                                 var msg = new MailMessage ("foo@example.com", "bar@example.com", "hello", "howdydoo\r\n");
484
485                                 Thread t = new Thread (server.Run);
486                                 t.Start ();
487                                 var task = client.SendMailAsync (msg);
488                                 t.Join ();
489
490                                 Assert.AreEqual ("<foo@example.com>", server.mail_from);
491                                 Assert.AreEqual ("<bar@example.com>", server.rcpt_to);
492
493                                 Assert.IsTrue (task.Wait (1000));
494                                 Assert.IsTrue (task.IsCompleted, "task");
495                         } finally {
496                                 global::System.ComponentModel.AsyncOperationManager.SynchronizationContext = existing_context;
497                         }
498                 }
499
500                 internal class ThreadPoolSynchronizationContext : SynchronizationContext
501                 {
502                         public override void Post (SendOrPostCallback d, object state)
503                         {
504                                 ThreadPool.QueueUserWorkItem ((v) => d (state));
505                         }
506
507                         public override void Send (SendOrPostCallback d, object state)
508                         {
509                                 d (state);
510                         }
511                 }
512         }
513 }