Package pyzmail :: Package tests :: Module test_parse
[hide private]
[frames] | no frames]

Source Code for Module pyzmail.tests.test_parse

  1  import unittest, doctest 
  2  import pyzmail 
  3  from pyzmail.parse import * 
  4   
  5   
6 -class Msg:
7 """mimic a email.Message"""
8 - def __init__(self, value):
9 self.value=value
10
11 - def get_all(self, header_name, default):
12 if self.value: 13 return [self.value, ] 14 else: 15 return []
16
17 -class TestParse(unittest.TestCase):
18
19 - def setUp(self):
20 pass
21
22 - def test_decode_mail_header(self):
23 """test decode_mail_header()""" 24 self.assertEqual(decode_mail_header(''), u'') 25 self.assertEqual(decode_mail_header('hello'), u'hello') 26 self.assertEqual(decode_mail_header('hello '), u'hello ') 27 self.assertEqual(decode_mail_header('=?iso-8859-1?q?Courrier_=E8lectronique_Fran=E7ais?='), u'Courrier \xe8lectronique Fran\xe7ais') 28 self.assertEqual(decode_mail_header('=?utf8?q?Courrier_=C3=A8lectronique_Fran=C3=A7ais?='), u'Courrier \xe8lectronique Fran\xe7ais') 29 self.assertEqual(decode_mail_header('=?utf-8?b?RnJhbsOnYWlz?='), u'Fran\xe7ais') 30 self.assertEqual(decode_mail_header('=?iso-8859-1?q?Courrier_=E8lectronique_?= =?utf8?q?Fran=C3=A7ais?='), u'Courrier \xe8lectronique Fran\xe7ais') 31 self.assertEqual(decode_mail_header('=?iso-8859-1?q?Courrier_=E8lectronique_?= =?utf-8?b?RnJhbsOnYWlz?='), u'Courrier \xe8lectronique Fran\xe7ais') 32 self.assertEqual(decode_mail_header('h_subject_q_iso_8858_1 : =?ISO-8859-1?Q?Fran=E7ais=E20accentu=E9?= !'), u'h_subject_q_iso_8858_1 :Fran\xe7ais\xe20accentu\xe9!')
33
34 - def test_get_mail_addresses(self):
35 """test get_mail_addresses()""" 36 self.assertEqual([ ('foo@example.com', 'foo@example.com') ], get_mail_addresses(Msg('foo@example.com'), 'to')) 37 self.assertEqual([ ('Foo', 'foo@example.com'), ], get_mail_addresses(Msg('Foo <foo@example.com>'), 'to')) 38 # notice the space around the comma 39 self.assertEqual([ ('foo@example.com', 'foo@example.com'), ('bar@example.com', 'bar@example.com')], get_mail_addresses(Msg('foo@example.com , bar@example.com'), 'to')) 40 self.assertEqual([ ('Foo', 'foo@example.com'), ( 'Bar', 'bar@example.com')], get_mail_addresses(Msg('Foo <foo@example.com> , Bar <bar@example.com>'), 'to')) 41 self.assertEqual([ ('Foo', 'foo@example.com'), ('bar@example.com', 'bar@example.com')], get_mail_addresses(Msg('Foo <foo@example.com> , bar@example.com'), 'to')) 42 self.assertEqual([ ('Mr Foo', 'foo@example.com'), ('bar@example.com', 'bar@example.com')], get_mail_addresses(Msg('Mr\nFoo <foo@example.com> , bar@example.com'), 'to')) 43 44 self.assertEqual([ (u'Beno\xeet', 'benoit@example.com')], get_mail_addresses(Msg('=?utf-8?q?Beno=C3=AEt?= <benoit@example.com>'), 'to')) 45 46 # address already encoded into utf8 (bad) 47 address=u'Ant\xf3nio Foo <a.foo@example.com>'.encode('utf8') 48 if sys.version_info<(3, 0): 49 self.assertEqual([(u'Ant\ufffd\ufffdnio Foo', 'a.foo@example.com')], get_mail_addresses(Msg(address), 'to')) 50 else: 51 # Python 3.2 return header when surrogate characters are used in header 52 self.assertEqual([(u'Ant??nio Foo', 'a.foo@example.com'), ], get_mail_addresses(Msg(email.header.Header(address, charset=email.charset.UNKNOWN8BIT, header_name='to')), 'to'))
53
54 - def test_get_filename(self):
55 """test get_filename()""" 56 import email.mime.image 57 58 filename=u'Fran\xe7ais.png' 59 if sys.version_info<(3, 0): 60 encoded_filename=filename.encode('iso-8859-1') 61 else: 62 encoded_filename=filename 63 64 payload=b'data' 65 attach=email.mime.image.MIMEImage(payload, 'png') 66 attach.add_header('Content-Disposition', 'attachment', filename='image.png') 67 self.assertEqual('image.png', get_filename(attach)) 68 69 attach=email.mime.image.MIMEImage(payload, 'png') 70 attach.add_header('Content-Disposition', 'attachment', filename=('iso-8859-1', 'fr', encoded_filename)) 71 self.assertEqual(u'Fran\xe7ais.png', get_filename(attach)) 72 73 attach=email.mime.image.MIMEImage(payload, 'png') 74 attach.set_param('name', 'image.png') 75 self.assertEqual('image.png', get_filename(attach)) 76 77 attach=email.mime.image.MIMEImage(payload, 'png') 78 attach.set_param('name', ('iso-8859-1', 'fr', encoded_filename)) 79 self.assertEqual(u'Fran\xe7ais.png', get_filename(attach)) 80 81 attach=email.mime.image.MIMEImage(payload, 'png') 82 attach.add_header('Content-Disposition', 'attachment', filename='image.png') 83 attach.set_param('name', 'image_wrong.png') 84 self.assertEqual('image.png', get_filename(attach))
85
86 - def test_get_mailparts(self):
87 """test get_mailparts()""" 88 import email.mime.multipart 89 import email.mime.text 90 import email.mime.image 91 msg=email.mime.multipart.MIMEMultipart(boundary='===limit1==') 92 txt=email.mime.text.MIMEText('The text.', 'plain', 'us-ascii') 93 msg.attach(txt) 94 image=email.mime.image.MIMEImage(b'data', 'png') 95 image.add_header('Content-Disposition', 'attachment', filename='image.png') 96 image.add_header('Content-Description', 'the description') 97 image.add_header('Content-ID', '<this.is.the.normaly.unique.contentid>') 98 msg.attach(image) 99 100 raw=msg.as_string(unixfrom=False) 101 expected_raw="""Content-Type: multipart/mixed; boundary="===limit1==" 102 MIME-Version: 1.0 103 104 --===limit1== 105 Content-Type: text/plain; charset="us-ascii" 106 MIME-Version: 1.0 107 Content-Transfer-Encoding: 7bit 108 109 The text. 110 --===limit1== 111 Content-Type: image/png 112 MIME-Version: 1.0 113 Content-Transfer-Encoding: base64 114 Content-Disposition: attachment; filename="image.png" 115 Content-Description: the description 116 Content-ID: <this.is.the.normaly.unique.contentid> 117 118 ZGF0YQ==<HERE1> 119 --===limit1==--""" 120 121 if sys.version_info<(3, 0): 122 expected_raw=expected_raw.replace('<HERE1>','') 123 else: 124 expected_raw=expected_raw.replace('<HERE1>','\n') 125 126 self.assertEqual(raw, expected_raw) 127 128 parts=get_mail_parts(msg) 129 # [MailPart<*text/plain charset=us-ascii len=9>, MailPart<image/png filename=image.png len=4>] 130 131 self.assertEqual(len(parts), 2) 132 133 self.assertEqual(parts[0].type, 'text/plain') 134 self.assertEqual(parts[0].is_body, 'text/plain') # not a error, is_body must be type 135 self.assertEqual(parts[0].charset, 'us-ascii') 136 self.assertEqual(parts[0].get_payload().decode(parts[0].charset), 'The text.') 137 138 self.assertEqual(parts[1].type, 'image/png') 139 self.assertEqual(parts[1].is_body, False) 140 self.assertEqual(parts[1].charset, None) 141 self.assertEqual(parts[1].filename, 'image.png') 142 self.assertEqual(parts[1].description, 'the description') 143 self.assertEqual(parts[1].content_id, 'this.is.the.normaly.unique.contentid') 144 self.assertEqual(parts[1].get_payload(), b'data')
145 146 147 raw_1='''Content-Type: text/plain; charset="us-ascii" 148 MIME-Version: 1.0 149 Content-Transfer-Encoding: 7bit 150 Subject: simple test 151 From: Me <me@foo.com> 152 To: A <a@foo.com>, B <b@foo.com> 153 Cc: C <c@foo.com>, d@foo.com 154 User-Agent: pyzmail 155 156 The text. 157 ''' 158
159 - def check_message_1(self, msg):
160 self.assertEqual(msg.get_subject(), u'simple test') 161 self.assertEqual(msg.get_decoded_header('subject'), u'simple test') 162 self.assertEqual(msg.get_decoded_header('User-Agent'), u'pyzmail') 163 self.assertEqual(msg.get('User-Agent'), 'pyzmail') 164 self.assertEqual(msg.get_address('from'), (u'Me', 'me@foo.com')) 165 self.assertEqual(msg.get_addresses('to'), [(u'A', 'a@foo.com'), (u'B', 'b@foo.com')]) 166 self.assertEqual(msg.get_addresses('cc'), [(u'C', 'c@foo.com'), (u'd@foo.com', 'd@foo.com')]) 167 self.assertEqual(len(msg.mailparts), 1) 168 self.assertEqual(msg.text_part, msg.mailparts[0]) 169 self.assertEqual(msg.html_part, None)
170 171 # use 8bits encoding and 2 different charsets ! python 3.0 & 3.1 are not eable to parse this sample 172 raw_2=b"""From: sender@domain.com 173 To: recipient@domain.com 174 Date: Tue, 7 Jun 2011 16:32:17 +0200 175 Subject: contains 8bits attachments using different encoding 176 Content-Type: multipart/mixed; boundary=mixed 177 178 --mixed 179 Content-Type: text/plain; charset="us-ascii" 180 MIME-Version: 1.0 181 Content-Transfer-Encoding: 7bit 182 183 body 184 --mixed 185 Content-Type: text/plain; charset="windows-1252" 186 MIME-Version: 1.0 187 Content-Transfer-Encoding: 8bit 188 Content-Disposition: attachment; filename="file1.txt" 189 190 bo\xeete mail = mailbox 191 --mixed 192 Content-Type: text/plain; charset="utf-8" 193 MIME-Version: 1.0 194 Content-Transfer-Encoding: 8bit 195 Content-Disposition: attachment; filename="file2.txt" 196 197 bo\xc3\xaete mail = mailbox 198 --mixed-- 199 """ 200
201 - def check_message_2(self, msg):
202 self.assertEqual(msg.get_subject(), u'contains 8bits attachments using different encoding') 203 204 body, file1, file2=msg.mailparts 205 206 self.assertEqual('file1.txt', file1.filename) 207 self.assertEqual('file2.txt', file2.filename) 208 self.assertEqual('windows-1252', file1.charset) 209 self.assertEqual('utf-8', file2.charset) 210 content=b'bo\xeete mail = mailbox'.decode("windows-1252") 211 content1=file1.get_payload().decode(file1.charset) 212 content2=file2.get_payload().decode(file2.charset) 213 self.assertEqual(content, content1) 214 self.assertEqual(content, content2)
215 216 # this one contain non us-ascii chars in the header 217 # py 2x and py3k return different value here 218 raw_3=b'Content-Type: text/plain; charset="us-ascii"\n' \ 219 b'MIME-Version: 1.0\n' \ 220 b'Content-Transfer-Encoding: 7bit\n' \ 221 + u'Subject: Beno\xeet & Ant\xf3nio\n'.encode('utf8') +\ 222 b'From: =?utf-8?q?Beno=C3=AEt?= <benoit@example.com>\n' \ 223 + u'To: Ant\xf3nio Foo <a.foo@example.com>\n'.encode('utf8') \ 224 + u'Cc: Beno\xeet <benoit@foo.com>, d@foo.com\n'.encode('utf8') +\ 225 b'User-Agent: pyzmail\n' \ 226 b'\n' \ 227 b'The text.\n' 228
229 - def check_message_3(self, msg):
230 subject=u'Beno\ufffd\ufffdt & Ant\ufffd\ufffdnio' # if sys.version_info<(3, 0) else u'Beno??t & Ant??nio' 231 self.assertEqual(msg.get_subject(), subject) 232 self.assertEqual(msg.get_decoded_header('subject'), subject) 233 self.assertEqual(msg.get_decoded_header('User-Agent'), u'pyzmail') 234 self.assertEqual(msg.get('User-Agent'), 'pyzmail') 235 self.assertEqual(msg.get_address('from'), (u'Beno\xeet', 'benoit@example.com')) 236 237 to=msg.get_addresses('to') 238 self.assertEqual(to[0][1], 'a.foo@example.com') 239 self.assertEqual(to[0][0], u'Ant\ufffd\ufffdnio Foo' if sys.version_info<(3, 0) else u'Ant??nio Foo') 240 241 cc=msg.get_addresses('cc') 242 self.assertEqual(cc[0][1], 'benoit@foo.com') 243 self.assertEqual(cc[0][0], u'Beno\ufffd\ufffdt' if sys.version_info<(3, 0) else u'Beno??t') 244 self.assertEqual(cc[1], ('d@foo.com', 'd@foo.com')) 245 246 self.assertEqual(len(msg.mailparts), 1) 247 self.assertEqual(msg.text_part, msg.mailparts[0]) 248 self.assertEqual(msg.html_part, None)
249 250
251 - def check_pyzmessage_factories(self, input, check):
252 """test PyzMessage from different sources""" 253 if isinstance(input, bytes) and sys.version_info>=(3, 2): 254 check(PyzMessage.factory(input)) 255 check(message_from_bytes(input)) 256 257 import io 258 check(PyzMessage.factory(io.BytesIO(input))) 259 check(message_from_binary_file(io.BytesIO(input))) 260 261 if isinstance(input, basestring): 262 263 check(PyzMessage.factory(input)) 264 check(message_from_string(input)) 265 266 import StringIO 267 check(PyzMessage.factory(StringIO.StringIO(input))) 268 check(message_from_file(StringIO.StringIO(input)))
269
271 """test PyzMessage class different sources""" 272 self.check_pyzmessage_factories(self.raw_1, self.check_message_1) 273 self.check_pyzmessage_factories(self.raw_2, self.check_message_2) 274 self.check_pyzmessage_factories(self.raw_3, self.check_message_3)
275 276 277 # Add doctest
278 -def load_tests(loader, tests, ignore):
279 # this works with python 2.7 and 3.x 280 if sys.version_info<(3, 0): 281 tests.addTests(doctest.DocTestSuite(pyzmail.parse)) 282 return tests
283
284 -def additional_tests():
285 # Add doctest for python 2.6 and below 286 if sys.version_info<(2, 7): 287 return doctest.DocTestSuite(pyzmail.parse) 288 else: 289 return unittest.TestSuite()
290