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