1 import unittest, doctest
2 import pyzmail
3 from pyzmail.parse import *
4
5
7 """mimic a email.Message"""
10
11 - def get_all(self, header_name, default):
12 if self.value:
13 return [self.value, ]
14 else:
15 return []
16
18
21
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
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
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
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
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
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
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
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')
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
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
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
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
217
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
230 subject=u'Beno\ufffd\ufffdt & Ant\ufffd\ufffdnio'
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
269
275
276
277
283
285
286 if sys.version_info<(2, 7):
287 return doctest.DocTestSuite(pyzmail.parse)
288 else:
289 return unittest.TestSuite()
290