source: products/Products.MailHost/trunk/src/Products/MailHost/tests/testMailHost.py @ 3384

Last change on this file since 3384 was 3384, checked in by fenix, 12 years ago

added tests

  • Property svn:eol-style set to native
File size: 26.7 KB
Line 
1##############################################################################
2#
3# Copyright (c) 2002 Zope Foundation and Contributors.
4#
5# This software is subject to the provisions of the Zope Public License,
6# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
7# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10# FOR A PARTICULAR PURPOSE.
11#
12##############################################################################
13"""MailHost unit tests.
14"""
15
16import unittest
17from email import message_from_string
18
19from Products.MailHost.MailHost import MailHost
20from Products.MailHost.MailHost import MailHostError, _mungeHeaders
21
22
23class DummyMailHost(MailHost):
24    meta_type = 'Dummy Mail Host'
25    def __init__(self, id):
26        self.id = id
27        self.sent = ''
28    def _send(self, mfrom, mto, messageText, immediate=False):
29        self.mfrom = mfrom
30        self.mto = mto
31        self.sent = messageText
32        self.immediate = immediate
33
34
35class FakeContent(object):
36    def __init__(self, template_name, message):
37        def template(self, context, REQUEST=None):
38            return message
39        setattr(self, template_name, template)
40
41    @staticmethod
42    def check_status(context, REQUEST=None):
43        return 'Message Sent'
44
45
46class TestMailHost(unittest.TestCase):
47
48    def _getTargetClass(self):
49        return DummyMailHost
50
51    def _makeOne(self, *args, **kw):
52        return self._getTargetClass()(*args, **kw)
53
54    def test_z3interfaces(self):
55        from Products.MailHost.interfaces import IMailHost
56        from zope.interface.verify import verifyClass
57
58        verifyClass(IMailHost, self._getTargetClass())
59
60    def testAllHeaders(self):
61        msg = """To: recipient@domain.com
62From: sender@domain.com
63Subject: This is the subject
64
65This is the message body."""
66        # No additional info
67        resmsg, resto, resfrom = _mungeHeaders(msg)
68        self.failUnless(resto == ['recipient@domain.com'])
69        self.failUnless(resfrom == 'sender@domain.com')
70
71        # Add duplicated info
72        resmsg, resto, resfrom = _mungeHeaders(msg, 'recipient@domain.com',
73                                  'sender@domain.com', 'This is the subject')
74        self.failUnlessEqual(resto, ['recipient@domain.com'])
75        self.failUnlessEqual(resfrom, 'sender@domain.com')
76
77        # Add extra info
78        resmsg, resto, resfrom = _mungeHeaders(msg, 'recipient2@domain.com',
79                            'sender2@domain.com', 'This is the real subject')
80        self.failUnlessEqual(resto, ['recipient2@domain.com'])
81        self.failUnlessEqual(resfrom, 'sender2@domain.com')
82
83    def testMissingHeaders(self):
84        msg = """X-Header: Dummy header
85
86This is the message body."""
87        # Doesn't specify to
88        self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
89                              mfrom='sender@domain.com')
90        # Doesn't specify from
91        self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
92                              mto='recipient@domain.com')
93
94    def testNoHeaders(self):
95        msg = """This is the message body."""
96        # Doesn't specify to
97        self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
98                              mfrom='sender@domain.com')
99        # Doesn't specify from
100        self.failUnlessRaises(MailHostError, _mungeHeaders, msg,
101                              mto='recipient@domain.com')
102        # Specify all
103        resmsg, resto, resfrom = _mungeHeaders(msg, 'recipient2@domain.com',
104                             'sender2@domain.com', 'This is the real subject')
105        self.failUnlessEqual(resto, ['recipient2@domain.com'])
106        self.failUnlessEqual(resfrom, 'sender2@domain.com')
107
108    def testBCCHeader(self):
109        msg = "From: me@example.com\nBcc: many@example.com\n\nMessage text"
110        # Specify only the "Bcc" header.  Useful for bulk emails.
111        resmsg, resto, resfrom = _mungeHeaders(msg)
112        self.failUnlessEqual(resto, ['many@example.com'])
113        self.failUnlessEqual(resfrom, 'me@example.com')
114
115    def test__getThreadKey_uses_fspath(self):
116        mh1 = self._makeOne('mh1')
117        mh1.smtp_queue_directory = '/abc'
118        mh1.absolute_url = lambda self: 'http://example.com/mh1'
119        mh2 = self._makeOne('mh2')
120        mh2.smtp_queue_directory = '/abc'
121        mh2.absolute_url = lambda self: 'http://example.com/mh2'
122        self.assertEqual(mh1._getThreadKey(), mh2._getThreadKey())
123
124    def testAddressParser(self):
125        msg = """\
126To: "Name, Nick" <recipient@domain.com>, "Foo Bar" <foo@domain.com>
127CC: "Web, Jack" <jack@web.com>
128From: sender@domain.com
129Subject: This is the subject
130
131This is the message body."""
132
133        # Test Address-Parser for To & CC given in messageText
134
135        resmsg, resto, resfrom = _mungeHeaders(msg)
136        self.failUnlessEqual(resto, ['"Name, Nick" <recipient@domain.com>',
137                                  'Foo Bar <foo@domain.com>',
138                                  '"Web, Jack" <jack@web.com>'])
139        self.failUnlessEqual(resfrom, 'sender@domain.com')
140
141        # Test Address-Parser for a given mto-string
142
143        resmsg, resto, resfrom = _mungeHeaders(msg,
144            mto='"Public, Joe" <pjoe@domain.com>, Foo Bar <foo@domain.com>')
145
146        self.failUnlessEqual(resto, ['"Public, Joe" <pjoe@domain.com>',
147                                  'Foo Bar <foo@domain.com>'])
148        self.failUnlessEqual(resfrom, 'sender@domain.com')
149
150    def testSendMessageOnly(self):
151        msg = """\
152To: "Name, Nick" <recipient@domain.com>, "Foo Bar" <foo@domain.com>
153From: sender@domain.com
154Subject: This is the subject
155Date: Sun, 27 Aug 2006 17:00:00 +0200
156
157This is the message body."""
158
159        mailhost = self._makeOne('MailHost')
160        mailhost.send(msg)
161        self.assertEqual(mailhost.sent, msg)
162
163    def testSendWithArguments(self):
164        inmsg = """\
165Date: Sun, 27 Aug 2006 17:00:00 +0200
166
167This is the message body."""
168
169        outmsg = """\
170Date: Sun, 27 Aug 2006 17:00:00 +0200
171Subject: This is the subject
172To: "Name, Nick" <recipient@domain.com>, Foo Bar <foo@domain.com>
173From: sender@domain.com
174
175This is the message body."""
176
177        mailhost = self._makeOne('MailHost')
178        mailhost.send(messageText=inmsg,
179                      mto='"Name, Nick" <recipient@domain.com>, '
180                          '"Foo Bar" <foo@domain.com>',
181                      mfrom='sender@domain.com', subject='This is the subject')
182        self.assertEqual(mailhost.sent, outmsg)
183
184    def testSendWithMtoList(self):
185        inmsg = """\
186Date: Sun, 27 Aug 2006 17:00:00 +0200
187
188This is the message body."""
189
190        outmsg = """\
191Date: Sun, 27 Aug 2006 17:00:00 +0200
192Subject: This is the subject
193To: "Name, Nick" <recipient@domain.com>, Foo Bar <foo@domain.com>
194From: sender@domain.com
195
196This is the message body."""
197
198        mailhost = self._makeOne('MailHost')
199        mailhost.send(messageText=inmsg,
200                      mto=['"Name, Nick" <recipient@domain.com>',
201                           '"Foo Bar" <foo@domain.com>'],
202                      mfrom='sender@domain.com', subject='This is the subject')
203        self.assertEqual(mailhost.sent, outmsg)
204
205    def testSimpleSend(self):
206        outmsg = """\
207From: sender@domain.com
208To: "Name, Nick" <recipient@domain.com>, "Foo Bar" <foo@domain.com>
209Subject: This is the subject
210
211This is the message body."""
212
213        mailhost = self._makeOne('MailHost')
214        mailhost.simple_send(mto='"Name, Nick" <recipient@domain.com>, '
215                                 '"Foo Bar" <foo@domain.com>',
216                             mfrom='sender@domain.com',
217                             subject='This is the subject',
218                             body='This is the message body.')
219        self.assertEqual(mailhost.sent, outmsg)
220        self.assertEqual(mailhost.immediate, False)
221
222    def testSendImmediate(self):
223        outmsg = """\
224From: sender@domain.com
225To: "Name, Nick" <recipient@domain.com>, "Foo Bar" <foo@domain.com>
226Subject: This is the subject
227
228This is the message body."""
229
230        mailhost = self._makeOne('MailHost')
231        mailhost.simple_send(mto='"Name, Nick" <recipient@domain.com>, '
232                                 '"Foo Bar" <foo@domain.com>',
233                             mfrom='sender@domain.com',
234                             subject='This is the subject',
235                             body='This is the message body.',
236                             immediate=True)
237        self.assertEqual(mailhost.sent, outmsg)
238        self.assertEqual(mailhost.immediate, True)
239
240    def testSendBodyWithUrl(self):
241        # The implementation of rfc822.Message reacts poorly to
242        # message bodies containing ':' characters as in a url
243        msg = "Here's a nice link: http://www.zope.org/"
244
245        mailhost = self._makeOne('MailHost')
246        mailhost.send(messageText=msg,
247                      mto='"Name, Nick" <recipient@domain.com>, '
248                          '"Foo Bar" <foo@domain.com>',
249                      mfrom='sender@domain.com',
250                      subject='This is the subject')
251        out = message_from_string(mailhost.sent)
252        self.failUnlessEqual(out.get_payload(), msg)
253        self.failUnlessEqual(out['To'],
254            '"Name, Nick" <recipient@domain.com>, Foo Bar <foo@domain.com>')
255        self.failUnlessEqual(out['From'], 'sender@domain.com')
256
257    def testSendEncodedBody(self):
258        # If a charset is specified the correct headers for content
259        # encoding will be set if not already set.  Additionally, if
260        # there is a default transfer encoding for the charset, then
261        # the content will be encoded and the transfer encoding header
262        # will be set.
263        msg = "Here's some encoded t\xc3\xa9xt."
264        mailhost = self._makeOne('MailHost')
265        mailhost.send(messageText=msg,
266                      mto='"Name, Nick" <recipient@domain.com>, '
267                          '"Foo Bar" <foo@domain.com>',
268                      mfrom='sender@domain.com',
269                      subject='This is the subject',
270                      charset='utf-8')
271        out = message_from_string(mailhost.sent)
272        self.failUnlessEqual(out['To'],
273            '"Name, Nick" <recipient@domain.com>, Foo Bar <foo@domain.com>')
274        self.failUnlessEqual(out['From'], 'sender@domain.com')
275        # utf-8 will default to Quoted Printable encoding
276        self.failUnlessEqual(out['Content-Transfer-Encoding'],
277                             'quoted-printable')
278        self.failUnlessEqual(out['Content-Type'],
279                             'text/plain; charset="utf-8"')
280        self.failUnlessEqual(out.get_payload(),
281                             "Here's some encoded t=C3=A9xt.")
282
283    def testEncodedHeaders(self):
284        # Headers are encoded automatically, email headers are encoded
285        # piece-wise to ensure the adresses remain ASCII
286        mfrom = "Jos\xc3\xa9 Andr\xc3\xa9s <jose@example.com>"
287        mto = "Ferran Adri\xc3\xa0 <ferran@example.com>"
288        subject = "\xc2\xbfEsferificaci\xc3\xb3n?"
289        mailhost = self._makeOne('MailHost')
290        mailhost.send(messageText='A message.', mto=mto, mfrom=mfrom,
291                      subject=subject, charset='utf-8')
292        out = message_from_string(mailhost.sent)
293        self.failUnlessEqual(out['To'],
294                         '=?utf-8?q?Ferran_Adri=C3=A0?= <ferran@example.com>')
295        self.failUnlessEqual(out['From'],
296            '=?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>')
297        self.failUnlessEqual(out['Subject'],
298            '=?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=')
299        # utf-8 will default to Quoted Printable encoding
300        self.failUnlessEqual(out['Content-Transfer-Encoding'],
301                             'quoted-printable')
302        self.failUnlessEqual(out['Content-Type'],
303                             'text/plain; charset="utf-8"')
304        self.failUnlessEqual(out.get_payload(), "A message.")
305
306    def testAlreadyEncodedMessage(self):
307        # If the message already specifies encodings, it is
308        # essentially not altered this is true even if charset or
309        # msg_type is specified
310        msg = """\
311From: =?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>
312To: =?utf-8?q?Ferran_Adri=C3=A0?= <ferran@example.com>
313Subject: =?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=
314Date: Sun, 27 Aug 2006 17:00:00 +0200
315Content-Type: text/html; charset="utf-8"
316Content-Transfer-Encoding: base64
317MIME-Version: 1.0 (Generated by testMailHost.py)
318
319wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
320"""
321        mailhost = self._makeOne('MailHost')
322        mailhost.send(messageText=msg)
323        self.failUnlessEqual(mailhost.sent, msg)
324        mailhost.send(messageText=msg, msg_type='text/plain')
325        # The msg_type is ignored if already set
326        self.failUnlessEqual(mailhost.sent, msg)
327
328    def testAlreadyEncodedMessageWithCharset(self):
329        # If the message already specifies encodings, it is
330        # essentially not altered this is true even if charset or
331        # msg_type is specified
332        msg = """\
333From: =?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>
334To: =?utf-8?q?Ferran_Adri=C3=A0?= <ferran@example.com>
335Subject: =?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=
336Date: Sun, 27 Aug 2006 17:00:00 +0200
337Content-Type: text/html; charset="utf-8"
338Content-Transfer-Encoding: base64
339MIME-Version: 1.0 (Generated by testMailHost.py)
340
341wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
342"""
343        mailhost = self._makeOne('MailHost')
344        # Pass a different charset, which will apply to any explicitly
345        # set headers
346        mailhost.send(messageText=msg,
347                      subject='\xbfEsferificaci\xf3n?',
348                      charset='iso-8859-1', msg_type='text/plain')
349        # The charset for the body should remain the same, but any
350        # headers passed into the method will be encoded using the
351        # specified charset
352        out = message_from_string(mailhost.sent)
353        self.failUnlessEqual(out['Content-Type'], 'text/html; charset="utf-8"')
354        self.failUnlessEqual(out['Content-Transfer-Encoding'],
355                                 'base64')
356        # Headers set by parameter will be set using charset parameter
357        self.failUnlessEqual(out['Subject'],
358                             '=?iso-8859-1?q?=BFEsferificaci=F3n=3F?=')
359        # original headers will be unaltered
360        self.failUnlessEqual(out['From'],
361            '=?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>')
362
363    def testUnicodeMessage(self):
364        # unicode messages and headers are decoded using the given charset
365        msg = unicode("Here's some unencoded <strong>t\xc3\xa9xt</strong>.",
366                      'utf-8')
367        mfrom = unicode('Ferran Adri\xc3\xa0 <ferran@example.com>', 'utf-8')
368        subject = unicode('\xc2\xa1Andr\xc3\xa9s!', 'utf-8')
369        mailhost = self._makeOne('MailHost')
370        mailhost.send(messageText=msg,
371                      mto='"Name, Nick" <recipient@domain.com>',
372                      mfrom=mfrom, subject=subject, charset='utf-8',
373                      msg_type='text/html')
374        out = message_from_string(mailhost.sent)
375        self.failUnlessEqual(out['To'],
376                         '"Name, Nick" <recipient@domain.com>')
377        self.failUnlessEqual(out['From'],
378            '=?utf-8?q?Ferran_Adri=C3=A0?= <ferran@example.com>')
379        self.failUnlessEqual(out['Subject'], '=?utf-8?q?=C2=A1Andr=C3=A9s!?=')
380        self.failUnlessEqual(out['Content-Transfer-Encoding'],
381                             'quoted-printable')
382        self.failUnlessEqual(out['Content-Type'], 'text/html; charset="utf-8"')
383        self.failUnlessEqual(out.get_payload(),
384            "Here's some unencoded <strong>t=C3=A9xt</strong>.")
385
386    def testUnicodeNoEncodingErrors(self):
387        # Unicode messages and headers raise errors if no charset is passed to
388        # send
389        msg = unicode("Here's some unencoded <strong>t\xc3\xa9xt</strong>.",
390                      'utf-8')
391        subject = unicode('\xc2\xa1Andr\xc3\xa9s!', 'utf-8')
392        mailhost = self._makeOne('MailHost')
393        self.assertRaises(UnicodeEncodeError,
394                          mailhost.send, msg,
395                          mto='"Name, Nick" <recipient@domain.com>',
396                          mfrom='Foo Bar <foo@domain.com>',
397                          subject=subject)
398
399    def testUnicodeDefaultEncoding(self):
400        # However if we pass unicode that can be encoded to the
401        # default encoding (generally 'us-ascii'), no error is raised.
402        # We include a date in the messageText to make inspecting the
403        # results more convenient.
404        msg = u"""\
405Date: Sun, 27 Aug 2006 17:00:00 +0200
406
407Here's some unencoded <strong>text</strong>."""
408        subject = u'Andres!'
409        mailhost = self._makeOne('MailHost')
410        mailhost.send(msg, mto=u'"Name, Nick" <recipient@domain.com>',
411                      mfrom=u'Foo Bar <foo@domain.com>', subject=subject)
412        out = mailhost.sent
413        # Ensure the results are not unicode
414        self.failUnlessEqual(out, """\
415Date: Sun, 27 Aug 2006 17:00:00 +0200
416Subject: Andres!
417To: "Name, Nick" <recipient@domain.com>
418From: Foo Bar <foo@domain.com>
419
420Here's some unencoded <strong>text</strong>.""")
421        self.failUnlessEqual(type(out), str)
422
423    def testSendMessageObject(self):
424        # send will accept an email.Message.Message object directly
425        msg = message_from_string("""\
426From: =?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>
427To: =?utf-8?q?Ferran_Adri=C3=A0?= <ferran@example.com>
428Subject: =?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=
429Date: Sun, 27 Aug 2006 17:00:00 +0200
430Content-Type: text/html; charset="utf-8"
431Content-Transfer-Encoding: base64
432MIME-Version: 1.1
433
434wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
435""")
436        mailhost = self._makeOne('MailHost')
437        mailhost.send(msg)
438        out = message_from_string(mailhost.sent)
439        self.failUnlessEqual(out.as_string(), msg.as_string())
440
441        # we can even alter a from and subject headers without affecting the
442        # original object
443        mailhost.send(msg,
444                      mfrom='Foo Bar <foo@domain.com>', subject='Changed!')
445        out = message_from_string(mailhost.sent)
446
447        # We need to make sure we didn't mutate the message we were passed
448        self.failIfEqual(out.as_string(), msg.as_string())
449        self.failUnlessEqual(out['From'],
450            '=?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>')
451        self.failUnlessEqual(msg['From'],
452            '=?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>')
453        # The subject is encoded with the body encoding since no
454        # explicit encoding was specified
455        self.failUnlessEqual(out['Subject'], '=?utf-8?q?Changed!?=')
456        self.failUnlessEqual(msg['Subject'],
457                             '=?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=')
458
459    def testExplicitUUEncoding(self):
460        # We can request a payload encoding explicitly, though this
461        # should probably be considered deprecated functionality.
462        mailhost = self._makeOne('MailHost')
463        # uuencoding
464        mailhost.send('Date: Sun, 27 Aug 2006 17:00:00 +0200\n\nA Message',
465                      mfrom='sender@domain.com',
466                      mto='Foo Bar <foo@domain.com>', encode='uue')
467        out = message_from_string(mailhost.sent)
468        self.failUnlessEqual(mailhost.sent, """\
469Date: Sun, 27 Aug 2006 17:00:00 +0200
470Subject: [No Subject]
471To: Foo Bar <foo@domain.com>
472From: sender@domain.com
473Content-Transfer-Encoding: uue
474Mime-Version: 1.0
475
476begin 666 -
477)02!-97-S86=E
478 
479end
480""")
481
482    def testExplicitBase64Encoding(self):
483        mailhost = self._makeOne('MailHost')
484        mailhost.send('Date: Sun, 27 Aug 2006 17:00:00 +0200\n\nA Message',
485                      mfrom='sender@domain.com',
486                      mto='Foo Bar <foo@domain.com>', encode='base64')
487        out = message_from_string(mailhost.sent)
488        self.failUnlessEqual(mailhost.sent, """\
489Date: Sun, 27 Aug 2006 17:00:00 +0200
490Subject: [No Subject]
491To: Foo Bar <foo@domain.com>
492From: sender@domain.com
493Content-Transfer-Encoding: base64
494Mime-Version: 1.0
495
496QSBNZXNzYWdl""")
497
498    def testExplicit7bitEncoding(self):
499        mailhost = self._makeOne('MailHost')
500        mailhost.send('Date: Sun, 27 Aug 2006 17:00:00 +0200\n\nA Message',
501                      mfrom='sender@domain.com',
502                      mto='Foo Bar <foo@domain.com>', encode='7bit')
503        out = message_from_string(mailhost.sent)
504        self.failUnlessEqual(mailhost.sent, """\
505Date: Sun, 27 Aug 2006 17:00:00 +0200
506Subject: [No Subject]
507To: Foo Bar <foo@domain.com>
508From: sender@domain.com
509Content-Transfer-Encoding: 7bit
510Mime-Version: 1.0
511
512A Message""")
513
514    def testExplicit8bitEncoding(self):
515        mailhost = self._makeOne('MailHost')
516        # We pass an encoded string with unspecified charset, it should be
517        # encoded 8bit
518        mailhost.send('Date: Sun, 27 Aug 2006 17:00:00 +0200\n\n'
519                      'A M\xc3\xa9ssage',
520                      mfrom='sender@domain.com',
521                      mto='Foo Bar <foo@domain.com>', encode='8bit')
522        out = message_from_string(mailhost.sent)
523        self.failUnlessEqual(mailhost.sent, """\
524Date: Sun, 27 Aug 2006 17:00:00 +0200
525Subject: [No Subject]
526To: Foo Bar <foo@domain.com>
527From: sender@domain.com
528Content-Transfer-Encoding: 8bit
529Mime-Version: 1.0
530
531A M\xc3\xa9ssage""")
532
533    def testSendTemplate(self):
534        content = FakeContent('my_template', 'A Message')
535        mailhost = self._makeOne('MailHost')
536        result = mailhost.sendTemplate(content, 'my_template',
537                                       mto='Foo Bar <foo@domain.com>',
538                                       mfrom='sender@domain.com')
539        self.failUnlessEqual(result, 'SEND OK')
540        result = mailhost.sendTemplate(content, 'my_template',
541                                       mto='Foo Bar <foo@domain.com>',
542                                       mfrom='sender@domain.com',
543                                       statusTemplate='wrong_name')
544        self.failUnlessEqual(result, 'SEND OK')
545        result = mailhost.sendTemplate(content, 'my_template',
546                                       mto='Foo Bar <foo@domain.com>',
547                                       mfrom='sender@domain.com',
548                                       statusTemplate='check_status')
549        self.failUnlessEqual(result, 'Message Sent')
550
551    def testSendMultiPartAlternativeMessage(self):
552        msg = ("""\
553Content-Type: multipart/alternative; boundary="===============0490954888=="
554MIME-Version: 1.0
555Date: Sun, 27 Aug 2006 17:00:00 +0200
556Subject: My multipart email
557To: Foo Bar <foo@domain.com>
558From: sender@domain.com
559
560--===============0490954888==
561Content-Type: text/plain; charset="utf-8"
562MIME-Version: 1.0
563Content-Transfer-Encoding: quoted-printable
564
565This is plain text.
566
567--===============0490954888==
568Content-Type: multipart/related; boundary="===============2078950065=="
569MIME-Version: 1.0
570
571--===============2078950065==
572Content-Type: text/html; charset="utf-8"
573MIME-Version: 1.0
574Content-Transfer-Encoding: quoted-printable
575
576<p>This is html.</p>
577--===============2078950065==--
578--===============0490954888==--
579""")
580
581        mailhost = self._makeOne('MailHost')
582        # Specifying a charset for the header may have unwanted side
583        # effects in the case of multipart mails.
584        # (TypeError: expected string or buffer)
585        mailhost.send(msg, charset='utf-8')
586        self.assertEqual(mailhost.sent, msg)
587
588    def testSendMultiPartMixedMessage(self):
589        msg = ("""\
590Content-Type: multipart/mixed; boundary="XOIedfhf+7KOe/yw"
591Content-Disposition: inline
592MIME-Version: 1.0
593Date: Sun, 27 Aug 2006 17:00:00 +0200
594Subject: My multipart email
595To: Foo Bar <foo@domain.com>
596From: sender@domain.com
597
598--XOIedfhf+7KOe/yw
599Content-Type: text/plain; charset=us-ascii
600Content-Disposition: inline
601
602This is a test with as attachment OFS/www/new.gif.
603
604--XOIedfhf+7KOe/yw
605Content-Type: image/gif
606Content-Disposition: attachment; filename="new.gif"
607Content-Transfer-Encoding: base64
608
609R0lGODlhCwAQAPcAAP8A/wAAAFBQUICAgMDAwP8AAIAAQAAAoABAgIAAgEAAQP//AP//gACA
610gECAgP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
611AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
612AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
613AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
614AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
615AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
616AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
617AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
618AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
619AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
620AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
621AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
623AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAALABAAAAg7AAEIFKhgoEGC
624CwoeRKhwoYKEBhVIfLgg4UQAFCtqbJixYkOEHg9SHDmQJEmMEBkS/IiR5cKXMGPKDAgAOw==
625
626--XOIedfhf+7KOe/yw
627Content-Type: text/plain; charset=iso-8859-1
628Content-Disposition: attachment; filename="test.txt"
629Content-Transfer-Encoding: quoted-printable
630
631D=EDt =EFs =E9=E9n test
632
633--XOIedfhf+7KOe/yw--
634""")
635
636        mailhost = self._makeOne('MailHost')
637        # Specifying a charset for the header may have unwanted side
638        # effects in the case of multipart mails.
639        # (TypeError: expected string or buffer)
640        mailhost.send(msg, charset='utf-8')
641        self.assertEqual(mailhost.sent, msg)
642
643    def testSMTPMailFromHeaderSetup(self):
644        msg = message_from_string("""\
645From: =?utf-8?q?Jos=C3=A9_Andr=C3=A9s?= <jose@example.com>
646To: =?utf-8?q?Ferran_Adri=C3=A0?= <ferran@example.com>
647Subject: =?utf-8?q?=C2=BFEsferificaci=C3=B3n=3F?=
648Date: Sun, 27 Aug 2006 17:00:00 +0200
649Content-Type: text/html; charset="utf-8"
650Content-Transfer-Encoding: base64
651MIME-Version: 1.1
652
653wqFVbiB0cnVjbyA8c3Ryb25nPmZhbnTDoXN0aWNvPC9zdHJvbmc+IQ=3D=3D
654""")
655        mailhost = self._makeOne('MailHost')
656        mailhost.send(msg, mfrom='Foo Bar <foo@domain.com>')
657        out = message_from_string(mailhost.sent)
658
659        # We need to check if the 'From' header in message that we passed
660        # haven't changed.
661        self.failUnlessEqual(out['From'], msg['From'])
662
663        # We need to make sure that proper 'SMTP MAIL FROM' header was send.
664        self.failUnlessEqual(mailhost.mfrom, 'Foo Bar <foo@domain.com>')
665
666        # If 'From' header is missing in the message
667        # it should be added with 'MAIL FROM' SMTP Envelope header value.
668        del msg['From']
669        mailhost.send(msg, mfrom='Foo Bar <foo@domain.com>')
670        out = message_from_string(mailhost.sent)
671        self.failUnlessEqual(out['From'], 'Foo Bar <foo@domain.com>')
672
673
674def test_suite():
675    suite = unittest.TestSuite()
676    suite.addTest(unittest.makeSuite(TestMailHost))
677    return suite
Note: See TracBrowser for help on using the repository browser.