source: products/vendor/Products.MailHost/current/src/Products/MailHost/tests/testMailHost.py @ 3356

Last change on this file since 3356 was 3356, checked in by fenix, 7 years ago

Load 2.13.1 into vendor/Products.MailHost?/current.

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