1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Copyright (C) 2001-2010 Python Software Foundation 2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Contact: email-sig@python.org 3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# email package unit tests 4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport os 6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport sys 7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport time 8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport base64 9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport difflib 10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport unittest 11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport warnings 12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport textwrap 13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom cStringIO import StringIO 14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport email 16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.Charset import Charset 18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.Header import Header, decode_header, make_header 19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.Parser import Parser, HeaderParser 20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.Generator import Generator, DecodedGenerator 21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.Message import Message 22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.MIMEAudio import MIMEAudio 23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.MIMEText import MIMEText 24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.MIMEImage import MIMEImage 25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.MIMEBase import MIMEBase 26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.MIMEMessage import MIMEMessage 27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.MIMEMultipart import MIMEMultipart 28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email import Utils 29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email import Errors 30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email import Encoders 31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email import Iterators 32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email import base64MIME 33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email import quopriMIME 34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom test.test_support import findfile, run_unittest 36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom email.test import __file__ as landmark 37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepNL = '\n' 40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepEMPTYSTRING = '' 41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSPACE = ' ' 42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef openfile(filename, mode='r'): 46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep path = os.path.join(os.path.dirname(landmark), 'data', filename) 47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return open(path, mode) 48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Base test class 52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestEmailBase(unittest.TestCase): 53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def ndiffAssertEqual(self, first, second): 54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Like assertEqual except use ndiff for readable output.""" 55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if first != second: 56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfirst = str(first) 57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ssecond = str(second) 58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep diff = difflib.ndiff(sfirst.splitlines(), ssecond.splitlines()) 59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = StringIO() 60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep print >> fp, NL, NL.join(diff) 61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise self.failureException, fp.getvalue() 62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _msgobj(self, filename): 64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile(findfile(filename)) 65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_file(fp) 67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return msg 70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test various aspects of the Message class's API 74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestMessageAPI(TestEmailBase): 75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_all(self): 76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_20.txt') 78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_all('cc'), ['ccc@zzz.org', 'ddd@zzz.org', 'eee@zzz.org']) 79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_all('xx', 'n/a'), 'n/a') 80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_getset_charset(self): 82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset(), None) 85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset = Charset('iso-8859-1') 86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_charset(charset) 87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['mime-version'], '1.0') 88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'text/plain') 89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset="iso-8859-1"') 90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('charset'), 'iso-8859-1') 91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], 'quoted-printable') 92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset().input_charset, 'iso-8859-1') 93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Remove the charset 94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_charset(None) 95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset(), None) 96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain') 97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try adding a charset when there's already MIME headers present 98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['MIME-Version'] = '2.0' 100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'text/x-weird' 101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Transfer-Encoding'] = 'quinted-puntable' 102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_charset(charset) 103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['mime-version'], '2.0') 104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/x-weird; charset="iso-8859-1"') 105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], 'quinted-puntable') 106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_set_charset_from_string(self): 108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_charset('us-ascii') 111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset().input_charset, 'us-ascii') 112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset="us-ascii"') 113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_set_payload_with_charset(self): 115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset = Charset('iso-8859-1') 117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload('This is a string payload', charset) 118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_charset().input_charset, 'iso-8859-1') 119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_charsets(self): 121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_08.txt') 124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charsets = msg.get_charsets() 125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charsets, [None, 'us-ascii', 'iso-8859-1', 'iso-8859-2', 'koi8-r']) 126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_09.txt') 128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charsets = msg.get_charsets('dingbat') 129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charsets, ['dingbat', 'us-ascii', 'iso-8859-1', 'dingbat', 130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'koi8-r']) 131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_12.txt') 133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charsets = msg.get_charsets() 134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charsets, [None, 'us-ascii', 'iso-8859-1', None, 'iso-8859-2', 135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'iso-8859-3', 'us-ascii', 'koi8-r']) 136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_filename(self): 138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_04.txt') 141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filenames = [p.get_filename() for p in msg.get_payload()] 142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(filenames, ['msg.txt', 'msg.txt']) 143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_07.txt') 145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart = msg.get_payload(1) 146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart.get_filename(), 'dingusfish.gif') 147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_filename_with_name_parameter(self): 149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_44.txt') 152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filenames = [p.get_filename() for p in msg.get_payload()] 153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(filenames, ['msg.txt', 'msg.txt']) 154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_boundary(self): 156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_07.txt') 158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # No quotes! 159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_boundary(), 'BOUNDARY') 160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_set_boundary(self): 162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This one has no existing boundary parameter, but the Content-Type: 164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # header appears fifth. 165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_boundary('BOUNDARY') 167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header, value = msg.items()[4] 168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(header.lower(), 'content-type') 169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(value, 'text/plain; charset="us-ascii"; boundary="BOUNDARY"') 170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This one has a Content-Type: header, with a boundary, stuck in the 171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # middle of its headers. Make sure the order is preserved; it should 172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # be fifth. 173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_04.txt') 174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_boundary('BOUNDARY') 175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header, value = msg.items()[4] 176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(header.lower(), 'content-type') 177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(value, 'multipart/mixed; boundary="BOUNDARY"') 178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # And this one has no Content-Type: header at all. 179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_03.txt') 180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(Errors.HeaderParseError, 181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_boundary, 'BOUNDARY') 182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_make_boundary(self): 184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEMultipart('form-data') 185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Note that when the boundary gets created is an implementation 186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # detail and might change. 187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.items()[0][1], 'multipart/form-data') 188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Trigger creation of boundary 189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.as_string() 190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.items()[0][1][:33], 191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'multipart/form-data; boundary="==') 192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # XXX: there ought to be tests of the uniqueness of the boundary, too. 193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_message_rfc822_only(self): 195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Issue 7970: message/rfc822 not in multipart parsed by 196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # HeaderParser caused an exception when flattened. 197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile(findfile('msg_46.txt')) 198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msgdata = fp.read() 199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep parser = email.Parser.HeaderParser() 200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = parser.parsestr(msgdata) 201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep out = StringIO() 202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep gen = email.Generator.Generator(out, True, 0) 203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep gen.flatten(msg, False) 204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(out.getvalue(), msgdata) 205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_decoded_payload(self): 207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_10.txt') 209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The outer message is a multipart 210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(decode=True), None) 211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 1 is 7bit encoded 212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(0).get_payload(decode=True), 213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is a 7bit encoded message.\n') 214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 2 is quopri 215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(1).get_payload(decode=True), 216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\xa1This is a Quoted Printable encoded message!\n') 217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 3 is base64 218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(2).get_payload(decode=True), 219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is a Base64 encoded message.') 220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 4 is base64 with a trailing newline, which 221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # used to be stripped (issue 7143). 222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(3).get_payload(decode=True), 223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is a Base64 encoded message.\n') 224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 5 has no Content-Transfer-Encoding: header. 225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(4).get_payload(decode=True), 226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This has no Content-Transfer-Encoding: header.\n') 227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_decoded_uu_payload(self): 229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload('begin 666 -\n+:&5L;&\\@=V]R;&0 \n \nend\n') 232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): 233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['content-transfer-encoding'] = cte 234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(decode=True), 'hello world') 235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Now try some bogus data 236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload('foo') 237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(decode=True), 'foo') 238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_decode_bogus_uu_payload_quietly(self): 240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload('begin 664 foo.txt\n%<W1F=0000H \n \nend\n') 242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Transfer-Encoding'] = 'x-uuencode' 243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep old_stderr = sys.stderr 244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sys.stderr = sfp = StringIO() 246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # We don't care about the payload 247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.get_payload(decode=True) 248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sys.stderr = old_stderr 250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(sfp.getvalue(), '') 251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_decoded_generator(self): 253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_07.txt') 255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_17.txt') 256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = fp.read() 258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = DecodedGenerator(s) 262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s.getvalue(), text) 264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test__contains__(self): 266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['From'] = 'Me' 268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['to'] = 'You' 269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Check for case insensitivity 270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue('from' in msg) 271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue('From' in msg) 272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue('FROM' in msg) 273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue('to' in msg) 274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue('To' in msg) 275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue('TO' in msg) 276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_as_string(self): 278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_01.txt') 281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # BAW 30-Mar-2009 Evil be here. So, the generator is broken with 283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # respect to long line breaking. It's also not idempotent when a 284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # header from a parsed message is continued with tabs rather than 285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # spaces. Before we fixed bug 1974 it was reversedly broken, 286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # i.e. headers that were continued with spaces got continued with 287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # tabs. For Python 2.x there's really no good fix and in Python 288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 3.x all this stuff is re-written to be right(er). Chris Withers 289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # convinced me that using space as the default continuation 290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # character is less bad for more applications. 291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = fp.read().replace('\t', ' ') 292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(text, msg.as_string()) 295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fullrepr = str(msg) 296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines = fullrepr.split('\n') 297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(lines[0].startswith('From ')) 298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(text, NL.join(lines[1:])) 299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_bad_param(self): 301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string("Content-Type: blarg; baz; boo\n") 302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_param('baz'), '') 303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_missing_filename(self): 305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string("From: foo\n") 306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_filename(), None) 307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_bogus_filename(self): 309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Content-Disposition: blarg; filename\n") 311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_filename(), '') 312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_missing_boundary(self): 314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string("From: foo\n") 315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_boundary(), None) 316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_params(self): 318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'X-Header: foo=one; bar=two; baz=three\n') 321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(header='x-header'), 322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('foo', 'one'), ('bar', 'two'), ('baz', 'three')]) 323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'X-Header: foo; bar=one; baz=two\n') 325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(header='x-header'), 326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('foo', ''), ('bar', 'one'), ('baz', 'two')]) 327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(), None) 328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'X-Header: foo; bar="one"; baz=two\n') 330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(header='x-header'), 331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('foo', ''), ('bar', 'one'), ('baz', 'two')]) 332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_param_liberal(self): 334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'Content-Type: Multipart/mixed; boundary = "CPIMSSMTPC06p5f3tG"' 336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_param('boundary'), 'CPIMSSMTPC06p5f3tG') 337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_param(self): 339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "X-Header: foo=one; bar=two; baz=three\n") 342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('bar', header='x-header'), 'two') 343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('quuz', header='x-header'), None) 344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('quuz'), None) 345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'X-Header: foo; bar="one"; baz=two\n') 347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('foo', header='x-header'), '') 348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('bar', header='x-header'), 'one') 349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('baz', header='x-header'), 'two') 350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # XXX: We are not RFC-2045 compliant! We cannot parse: 351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # msg["Content-Type"] = 'text/plain; weird="hey; dolly? [you] @ <\\"home\\">?"' 352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # msg.get_param("weird") 353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # yet. 354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_param_funky_continuation_lines(self): 356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_22.txt') 357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(1).get_param('name'), 'wibble.JPG') 358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_param_with_semis_in_quotes(self): 360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Content-Type: image/pjpeg; name="Jim&&Jill"\n') 362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_param('name'), 'Jim&&Jill') 363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_param('name', unquote=False), 364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '"Jim&&Jill"') 365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_param_with_quotes(self): 367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Content-Type: foo; bar*0="baz\\"foobar"; bar*1="\\"baz"') 369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_param('bar'), 'baz"foobar"baz') 370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string( 371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Content-Type: foo; bar*0=\"baz\\\"foobar\"; bar*1=\"\\\"baz\"") 372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_param('bar'), 'baz"foobar"baz') 373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_has_key(self): 375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string('Header: exists') 376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(msg.has_key('header')) 377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(msg.has_key('Header')) 378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(msg.has_key('HEADER')) 379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertFalse(msg.has_key('headeri')) 380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_set_param(self): 382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('charset', 'iso-2022-jp') 385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('charset'), 'iso-2022-jp') 386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('importance', 'high value') 387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('importance'), 'high value') 388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('importance', unquote=False), '"high value"') 389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(), [('text/plain', ''), 390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('charset', 'iso-2022-jp'), 391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('importance', 'high value')]) 392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(unquote=False), [('text/plain', ''), 393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('charset', '"iso-2022-jp"'), 394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('importance', '"high value"')]) 395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('charset', 'iso-9999-xx', header='X-Jimmy') 396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('charset', header='X-Jimmy'), 'iso-9999-xx') 397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_del_param(self): 399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_05.txt') 401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(), 402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('multipart/report', ''), ('report-type', 'delivery-status'), 403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('boundary', 'D1690A7AC1.996856090/mail.example.com')]) 404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep old_val = msg.get_param("report-type") 405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.del_param("report-type") 406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(), 407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('multipart/report', ''), 408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('boundary', 'D1690A7AC1.996856090/mail.example.com')]) 409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param("report-type", old_val) 410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(), 411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('multipart/report', ''), 412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('boundary', 'D1690A7AC1.996856090/mail.example.com'), 413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('report-type', old_val)]) 414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_del_param_on_other_header(self): 416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('Content-Disposition', 'attachment', filename='bud.gif') 418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.del_param('filename', 'content-disposition') 419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg['content-disposition'], 'attachment') 420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_set_type(self): 422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(ValueError, msg.set_type, 'text') 425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_type('text/plain') 426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain') 427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('charset', 'us-ascii') 428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset="us-ascii"') 429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_type('text/html') 430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/html; charset="us-ascii"') 431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_set_type_on_other_header(self): 433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['X-Content-Type'] = 'text/plain' 435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_type('application/octet-stream', 'X-Content-Type') 436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg['x-content-type'], 'application/octet-stream') 437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_type_missing(self): 439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_type(), 'text/plain') 441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_type_missing_with_default_type(self): 443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_default_type('message/rfc822') 445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_type(), 'message/rfc822') 446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_type_from_message_implicit(self): 448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_30.txt') 449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(0).get_content_type(), 450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'message/rfc822') 451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_type_from_message_explicit(self): 453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_28.txt') 454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(0).get_content_type(), 455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'message/rfc822') 456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_type_from_message_text_plain_implicit(self): 458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_03.txt') 459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_type(), 'text/plain') 460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_type_from_message_text_plain_explicit(self): 462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_type(), 'text/plain') 464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_maintype_missing(self): 466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_maintype(), 'text') 468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_maintype_missing_with_default_type(self): 470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_default_type('message/rfc822') 472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_maintype(), 'message') 473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_maintype_from_message_implicit(self): 475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_30.txt') 476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message') 477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_maintype_from_message_explicit(self): 479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_28.txt') 480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message') 481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_maintype_from_message_text_plain_implicit(self): 483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_03.txt') 484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_maintype(), 'text') 485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_maintype_from_message_text_plain_explicit(self): 487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_maintype(), 'text') 489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_subtype_missing(self): 491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_subtype(), 'plain') 493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_subtype_missing_with_default_type(self): 495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_default_type('message/rfc822') 497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_subtype(), 'rfc822') 498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_subtype_from_message_implicit(self): 500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_30.txt') 501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822') 502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_subtype_from_message_explicit(self): 504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_28.txt') 505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822') 506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_subtype_from_message_text_plain_implicit(self): 508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_03.txt') 509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_subtype(), 'plain') 510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_subtype_from_message_text_plain_explicit(self): 512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_subtype(), 'plain') 514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_maintype_error(self): 516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'no-slash-in-this-string' 518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_maintype(), 'text') 519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_subtype_error(self): 521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'no-slash-in-this-string' 523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_subtype(), 'plain') 524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_replace_header(self): 526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('First', 'One') 529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('Second', 'Two') 530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('Third', 'Three') 531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.keys(), ['First', 'Second', 'Third']) 532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.values(), ['One', 'Two', 'Three']) 533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.replace_header('Second', 'Twenty') 534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.keys(), ['First', 'Second', 'Third']) 535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.values(), ['One', 'Twenty', 'Three']) 536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('First', 'Eleven') 537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.replace_header('First', 'One Hundred') 538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.keys(), ['First', 'Second', 'Third', 'First']) 539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.values(), ['One Hundred', 'Twenty', 'Three', 'Eleven']) 540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(KeyError, msg.replace_header, 'Fourth', 'Missing') 541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_broken_base64_payload(self): 543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = 'AwDp0P7//y6LwKEAcPa/6Q=9' 544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['content-type'] = 'audio/x-midi' 546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['content-transfer-encoding'] = 'base64' 547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload(x) 548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_payload(decode=True), x) 549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_content_charset(self): 551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_charset('us-ascii') 553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual('us-ascii', msg.get_content_charset()) 554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_charset(u'us-ascii') 555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual('us-ascii', msg.get_content_charset()) 556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Issue 5871: reject an attempt to embed a header inside a header value 558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # (header injection attack). 559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_embeded_header_via_Header_rejected(self): 560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Dummy'] = Header('dummy\nX-Injected-Header: test') 562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(Errors.HeaderParseError, msg.as_string) 563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_embeded_header_via_string_rejected(self): 565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Dummy'] = 'dummy\nX-Injected-Header: test' 567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(Errors.HeaderParseError, msg.as_string) 568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test the email.Encoders module 571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestEncoders(unittest.TestCase): 572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encode_empty_payload(self): 573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_charset('us-ascii') 576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], '7bit') 577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_default_cte(self): 579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 7bit data and the default us-ascii _charset 581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello world') 582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], '7bit') 583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Similar, but with 8bit data 584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello \xf8 world') 585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], '8bit') 586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # And now with a different charset 587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello \xf8 world', _charset='iso-8859-1') 588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], 'quoted-printable') 589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encode7or8bit(self): 591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Make sure a charset whose input character set is 8bit but 592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # whose output character set is 7bit gets a transfer-encoding 593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # of 7bit. 594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.MIMEText.MIMEText('\xca\xb8', _charset='euc-jp') 596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], '7bit') 597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test long header wrapping 600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestLongHeaders(TestEmailBase): 601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_split_long_continuation(self): 602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string("""\ 604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: bug demonstration 605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tmore text 607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptest 609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(sfp) 612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), """\ 614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: bug demonstration 615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep more text 617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptest 619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_another_long_almost_unsplittable_header(self): 622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hstr = """\ 624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepbug demonstration 625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tmore text""" 627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr, continuation_ws='\t') 628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepbug demonstration 630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tmore text""") 632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr) 633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepbug demonstration 635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep more text""") 637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_nonstring(self): 639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Charset("iso-8859-1") 641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cz = Charset("iso-8859-2") 642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep utf8 = Charset("utf-8") 643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g_head = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. " 644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " 645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8") 646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(g_head, g, header_name='Subject') 647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append(cz_head, cz) 648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append(utf8_head, utf8) 649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Subject'] = h 651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(sfp) 653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), """\ 655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= 656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= 657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= 658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= 659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= 660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= 661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= 662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= 663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= 664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= 665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44Gm44GE44G+44GZ44CC?= 666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= 670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= 671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= 672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= 673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= 674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= 675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= 676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= 677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= 678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= 679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44Gm44GE44G+44GZ44CC?=""") 680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_header_encode(self): 682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header('wasnipoop; giraffes="very-long-necked-animals"; ' 684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"', 685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header_name='X-Foobar-Spoink-Defrobnit') 686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), '''\ 687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepwasnipoop; giraffes="very-long-necked-animals"; 688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''') 689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_header_encode_with_tab_continuation(self): 691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header('wasnipoop; giraffes="very-long-necked-animals"; ' 693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"', 694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header_name='X-Foobar-Spoink-Defrobnit', 695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep continuation_ws='\t') 696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), '''\ 697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepwasnipoop; giraffes="very-long-necked-animals"; 698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''') 699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_splitter(self): 701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('') 703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # It'd be great if we could use add_header() here, but that doesn't 704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # guarantee an order of the parameters. 705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['X-Foobar-Spoink-Defrobnit'] = ( 706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'wasnipoop; giraffes="very-long-necked-animals"; ' 707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"') 708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(sfp) 710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), '''\ 712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepX-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; 716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep spooge="yummy"; hippos="gargantuan"; marshmallows="gooey" 717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_semis_header_splitter(self): 721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['From'] = 'test@dom.ain' 724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['References'] = SPACE.join(['<%d@dom.ain>' % i for i in range(10)]) 725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload('Test') 726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(sfp) 728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), """\ 730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: test@dom.ain 731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReferences: <0@dom.ain> <1@dom.ain> <2@dom.ain> <3@dom.ain> <4@dom.ain> 732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep <5@dom.ain> <6@dom.ain> <7@dom.ain> <8@dom.ain> <9@dom.ain> 733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTest""") 735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_split_long_header(self): 737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hstr = 'References: ' + 'x' * 80 739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr, continuation_ws='\t') 740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReferences: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx""") 742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_splitting_multiple_long_lines(self): 744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hstr = """\ 746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin@babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST) 747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin@babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST) 748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); by babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; for <mailman-admin@babylon.socal-raves.org>; Sat, 2 Feb 2002 17:00:06 -0800 (PST) 749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr, continuation_ws='\t') 751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom babylon.socal-raves.org (localhost [127.0.0.1]); 753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; 754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfor <mailman-admin@babylon.socal-raves.org>; 755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tSat, 2 Feb 2002 17:00:06 -0800 (PST) 756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); 757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; 758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfor <mailman-admin@babylon.socal-raves.org>; 759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tSat, 2 Feb 2002 17:00:06 -0800 (PST) 760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); 761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; 762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfor <mailman-admin@babylon.socal-raves.org>; 763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tSat, 2 Feb 2002 17:00:06 -0800 (PST)""") 764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_splitting_first_line_only_is_long(self): 766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hstr = """\ 768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93] helo=cthulhu.gerg.ca) 769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tby kronos.mems-exchange.org with esmtp (Exim 4.05) 770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tid 17k4h5-00034i-00 771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfor test@mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400""" 772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr, maxlinelen=78, header_name='Received', 773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep continuation_ws='\t') 774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93] 776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\thelo=cthulhu.gerg.ca) 777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tby kronos.mems-exchange.org with esmtp (Exim 4.05) 778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tid 17k4h5-00034i-00 779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfor test@mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400""") 780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_8bit_header(self): 782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header('Britische Regierung gibt', 'iso-8859-1', 785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header_name='Subject') 786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte') 787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Subject'] = h 788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), """\ 789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: =?iso-8859-1?q?Britische_Regierung_gibt?= =?iso-8859-1?q?gr=FCnes?= 790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?_Licht_f=FCr_Offshore-Windkraftprojekte?= 791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_8bit_header_no_charset(self): 795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Reply-To'] = 'Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address@example.com>' 798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), """\ 799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReply-To: Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address@example.com> 800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_to_header(self): 804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep to = '"Someone Test #A" <someone@eecs.umich.edu>,<someone@eecs.umich.edu>,"Someone Test #B" <someone@umich.edu>, "Someone Test #C" <someone@eecs.umich.edu>, "Someone Test #D" <someone@eecs.umich.edu>' 806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['To'] = to 808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(0), '''\ 809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: "Someone Test #A" <someone@eecs.umich.edu>, <someone@eecs.umich.edu>, 810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Someone Test #B" <someone@umich.edu>, 811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Someone Test #C" <someone@eecs.umich.edu>, 812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Someone Test #D" <someone@eecs.umich.edu> 813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_line_after_append(self): 817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'This is an example of string which has almost the limit of header length.' 819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(s) 820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('Add another line.') 821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis is an example of string which has almost the limit of header length. 823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Add another line.""") 824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_shorter_line_with_append(self): 826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'This is a shorter line.' 828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(s) 829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('Add another sentence. (Surprise?)') 830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), 831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is a shorter line. Add another sentence. (Surprise?)') 832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_field_name(self): 834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fn = 'X-Very-Very-Very-Long-Header-Name' 836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep gs = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. " 837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(gs, 'iso-8859-1', header_name=fn) 838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # BAW: this seems broken because the first line is too long 839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), """\ 840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep=?iso-8859-1?q?Die_Mieter_treten_hier_?= 841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?ein_werden_mit_einem_Foerderband_komfortabel_den_Korridor_?= 842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?entlang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei=2C_g?= 843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?egen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""") 844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_received_header(self): 846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = 'from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; Wed, 05 Mar 2003 18:10:18 -0700' 847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Received-1'] = Header(h, continuation_ws='\t') 849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Received-2'] = h 850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.as_string(), """\ 851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived-1: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by 852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP; 853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tWed, 05 Mar 2003 18:10:18 -0700 854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived-2: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by 855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; 856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Wed, 05 Mar 2003 18:10:18 -0700 857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_string_headerinst_eq(self): 861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = '<15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> (David Bremner\'s message of "Thu, 6 Mar 2003 13:58:21 +0100")' 862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Received'] = Header(h, header_name='Received', 864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep continuation_ws='\t') 865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Received'] = h 866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.ndiffAssertEqual(msg.as_string(), """\ 867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> 868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") 869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> 870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") 871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_unbreakable_lines_with_continuation(self): 875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep t = """\ 878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp""" 880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Face-1'] = t 881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Face-2'] = Header(t, header_name='Face-2') 882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), """\ 883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFace-1: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp 885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFace-2: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp 887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_another_long_multiline_header(self): 891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with Microsoft SMTPSVC(5.0.2195.4905); 894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Wed, 16 Oct 2002 07:41:11 -0700''' 895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), '''\ 897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with 898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Microsoft SMTPSVC(5.0.2195.4905); Wed, 16 Oct 2002 07:41:11 -0700 899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_lines_with_different_header(self): 903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = """\ 905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepList-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>, 906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep <mailto:spamassassin-talk-request@lists.sourceforge.net?subject=unsubscribe>""" 907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['List'] = h 909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['List'] = Header(h, header_name='List') 910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), """\ 911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepList: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>, 912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep <mailto:spamassassin-talk-request@lists.sourceforge.net?subject=unsubscribe> 913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepList: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>, 914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep <mailto:spamassassin-talk-request@lists.sourceforge.net?subject=unsubscribe> 915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test mangling of "From " lines in the body of a message 921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestFromMangling(unittest.TestCase): 922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self): 923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.msg = Message() 924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.msg['From'] = 'aaa@bbb.org' 925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.msg.set_payload("""\ 926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom the desk of A.A.A.: 927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepBlah blah blah 928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_mangled_from(self): 931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s, mangle_from_=True) 933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(self.msg) 934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(s.getvalue(), """\ 935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: aaa@bbb.org 936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep>From the desk of A.A.A.: 938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepBlah blah blah 939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_dont_mangle_from(self): 942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s, mangle_from_=False) 944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(self.msg) 945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(s.getvalue(), """\ 946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: aaa@bbb.org 947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom the desk of A.A.A.: 949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepBlah blah blah 950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_mangle_from_in_preamble_and_epilog(self): 953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s, mangle_from_=True) 955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(textwrap.dedent("""\ 956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep From: foo@bar.com 957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Mime-Version: 1.0 958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Content-Type: multipart/mixed; boundary=XXX 959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep From somewhere unknown 961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep --XXX 963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Content-Type: text/plain 964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep foo 966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep --XXX-- 968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep From somewhere unknowable 970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """)) 971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len([1 for x in s.getvalue().split('\n') 973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if x.startswith('>From ')]), 2) 974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test the basic MIMEAudio class 977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestMIMEAudio(unittest.TestCase): 978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self): 979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Make sure we pick up the audiotest.au that lives in email/test/data. 980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # In Python, there's an audiotest.au living in Lib/test but that isn't 981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # included in some binary distros that don't include the test 982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # package. The trailing empty string on the .join() is significant 983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # since findfile() will do a dirname(). 984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep datadir = os.path.join(os.path.dirname(landmark), 'data', '') 985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = open(findfile('audiotest.au', datadir), 'rb') 986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._audiodata = fp.read() 988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._au = MIMEAudio(self._audiodata) 991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_guess_minor_type(self): 993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(self._au.get_content_type(), 'audio/basic') 994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encoding(self): 996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = self._au.get_payload() 997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(base64.decodestring(payload), self._audiodata) 998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_checkSetMinor(self): 1000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep au = MIMEAudio(self._audiodata, 'fish') 1001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(au.get_content_type(), 'audio/fish') 1002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_add_header(self): 1004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._au.add_header('Content-Disposition', 'attachment', 1007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filename='audiotest.au') 1008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._au['content-disposition'], 1009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'attachment; filename="audiotest.au"') 1010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._au.get_params(header='content-disposition'), 1011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('attachment', ''), ('filename', 'audiotest.au')]) 1012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._au.get_param('filename', header='content-disposition'), 1013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'audiotest.au') 1014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep missing = [] 1015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._au.get_param('attachment', header='content-disposition'), '') 1016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._au.get_param('foo', failobj=missing, 1017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header='content-disposition') is missing) 1018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try some missing stuff 1019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._au.get_param('foobar', missing) is missing) 1020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._au.get_param('attachment', missing, 1021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header='foobar') is missing) 1022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test the basic MIMEImage class 1026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestMIMEImage(unittest.TestCase): 1027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self): 1028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('PyBanner048.gif') 1029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 1030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._imgdata = fp.read() 1031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 1032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 1033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._im = MIMEImage(self._imgdata) 1034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_guess_minor_type(self): 1036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(self._im.get_content_type(), 'image/gif') 1037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encoding(self): 1039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = self._im.get_payload() 1040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(base64.decodestring(payload), self._imgdata) 1041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_checkSetMinor(self): 1043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep im = MIMEImage(self._imgdata, 'fish') 1044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(im.get_content_type(), 'image/fish') 1045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_add_header(self): 1047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._im.add_header('Content-Disposition', 'attachment', 1050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filename='dingusfish.gif') 1051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._im['content-disposition'], 1052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'attachment; filename="dingusfish.gif"') 1053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._im.get_params(header='content-disposition'), 1054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('attachment', ''), ('filename', 'dingusfish.gif')]) 1055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._im.get_param('filename', header='content-disposition'), 1056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'dingusfish.gif') 1057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep missing = [] 1058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._im.get_param('attachment', header='content-disposition'), '') 1059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._im.get_param('foo', failobj=missing, 1060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header='content-disposition') is missing) 1061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try some missing stuff 1062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._im.get_param('foobar', missing) is missing) 1063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._im.get_param('attachment', missing, 1064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep header='foobar') is missing) 1065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test the basic MIMEText class 1069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestMIMEText(unittest.TestCase): 1070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self): 1071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._msg = MIMEText('hello there') 1072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_types(self): 1074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._msg.get_content_type(), 'text/plain') 1077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(self._msg.get_param('charset'), 'us-ascii') 1078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep missing = [] 1079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._msg.get_param('foobar', missing) is missing) 1080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(self._msg.get_param('charset', missing, header='foobar') 1081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep is missing) 1082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_payload(self): 1084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(self._msg.get_payload(), 'hello there') 1085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(not self._msg.is_multipart()) 1086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_charset(self): 1088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello there', _charset='us-ascii') 1090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset().input_charset, 'us-ascii') 1091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset="us-ascii"') 1092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_7bit_unicode_input(self): 1094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText(u'hello there', _charset='us-ascii') 1096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset().input_charset, 'us-ascii') 1097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset="us-ascii"') 1098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_7bit_unicode_input_no_charset(self): 1100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText(u'hello there') 1102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset(), 'us-ascii') 1103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset="us-ascii"') 1104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue('hello there' in msg.as_string()) 1105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_8bit_unicode_input(self): 1107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep teststr = u'\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' 1108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText(teststr, _charset='utf-8') 1110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_charset().output_charset, 'utf-8') 1111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset="utf-8"') 1112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(decode=True), teststr.encode('utf-8')) 1113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_8bit_unicode_input_no_charset(self): 1115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep teststr = u'\u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0430' 1116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(UnicodeEncodeError, MIMEText, teststr) 1117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test complicated multipart/* messages 1121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestMultipart(TestEmailBase): 1122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self): 1123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('PyBanner048.gif') 1124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 1125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep data = fp.read() 1126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 1127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 1128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') 1130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep image = MIMEImage(data, name='dingusfish.gif') 1131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep image.add_header('content-disposition', 'attachment', 1132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filename='dingusfish.gif') 1133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep intro = MIMEText('''\ 1134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHi there, 1135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis is the dingus fish. 1137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container.attach(intro) 1139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container.attach(image) 1140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container['From'] = 'Barry <barry@digicool.com>' 1141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container['To'] = 'Dingus Lovers <cravindogs@cravindogs.com>' 1142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container['Subject'] = 'Here is your dingus fish' 1143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep now = 987809702.54848599 1145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep timetuple = time.localtime(now) 1146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if timetuple[-1] == 0: 1147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tzsecs = time.timezone 1148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tzsecs = time.altzone 1150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if tzsecs > 0: 1151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = '-' 1152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 1153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sign = '+' 1154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep tzoffset = ' %s%04d' % (sign, tzsecs // 36) 1155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container['Date'] = time.strftime( 1156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '%a, %d %b %Y %H:%M:%S', 1157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep time.localtime(now)) + tzoffset 1158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._msg = container 1159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._im = image 1160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._txt = intro 1161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_hierarchy(self): 1163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # convenience 1164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raises = self.assertRaises 1167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # tests 1168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = self._msg 1169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(m.is_multipart()) 1170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(m.get_content_type(), 'multipart/mixed') 1171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(m.get_payload()), 2) 1172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raises(IndexError, m.get_payload, 2) 1173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m0 = m.get_payload(0) 1174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m1 = m.get_payload(1) 1175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(m0 is self._txt) 1176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(m1 is self._im) 1177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(m.get_payload(), [m0, m1]) 1178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(not m0.is_multipart()) 1179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(not m1.is_multipart()) 1180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_empty_multipart_idempotent(self): 1182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = """\ 1183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 1195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Parser().parsestr(text) 1196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.ndiffAssertEqual(text, msg.as_string()) 1197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_parts_in_a_multipart_with_none_epilogue(self): 1199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.ndiffAssertEqual(outer.as_string(), '''\ 1205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY--''') 1214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_parts_in_a_multipart_with_empty_epilogue(self): 1216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.preamble = '' 1221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.epilogue = '' 1222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.ndiffAssertEqual(outer.as_string(), '''\ 1224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_one_part_in_a_multipart(self): 1237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello world') 1244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.attach(msg) 1245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(outer.as_string(), '''\ 1246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoephello world 1258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY--''') 1259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_seq_parts_in_a_multipart_with_empty_preamble(self): 1261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.preamble = '' 1267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello world') 1268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.attach(msg) 1269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(outer.as_string(), '''\ 1271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoephello world 1284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY--''') 1285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_seq_parts_in_a_multipart_with_none_preamble(self): 1288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.preamble = None 1294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello world') 1295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.attach(msg) 1296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(outer.as_string(), '''\ 1298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoephello world 1310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY--''') 1311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_seq_parts_in_a_multipart_with_none_epilogue(self): 1314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.epilogue = None 1320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello world') 1321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.attach(msg) 1322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(outer.as_string(), '''\ 1324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoephello world 1336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY--''') 1337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_seq_parts_in_a_multipart_with_empty_epilogue(self): 1340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.epilogue = '' 1346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello world') 1347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.attach(msg) 1348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(outer.as_string(), '''\ 1350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoephello world 1362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_seq_parts_in_a_multipart_with_nl_epilogue(self): 1367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = MIMEBase('multipart', 'mixed') 1369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['Subject'] = 'A subject' 1370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['To'] = 'aperson@dom.ain' 1371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer['From'] = 'bperson@dom.ain' 1372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.epilogue = '\n' 1373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEText('hello world') 1374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.attach(msg) 1375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer.set_boundary('BOUNDARY') 1376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(outer.as_string(), '''\ 1377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: A subject 1380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: aperson@dom.ain 1381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bperson@dom.ain 1382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoephello world 1389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_message_external_body(self): 1394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_36.txt') 1396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.get_payload()), 2) 1397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg1 = msg.get_payload(1) 1398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg1.get_content_type(), 'multipart/alternative') 1399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg1.get_payload()), 2) 1400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for subpart in msg1.get_payload(): 1401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart.get_content_type(), 'message/external-body') 1402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(subpart.get_payload()), 1) 1403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subsubpart = subpart.get_payload(0) 1404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subsubpart.get_content_type(), 'text/plain') 1405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_double_boundary(self): 1407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # msg_37.txt is a multipart that contains two dash-boundary's in a 1408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # row. Our interpretation of RFC 2046 calls for ignoring the second 1409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # and subsequent boundaries. 1410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_37.txt') 1411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len(msg.get_payload()), 3) 1412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_nested_inner_contains_outer_boundary(self): 1414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # msg_38.txt has an inner part that contains outer boundaries. My 1416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # interpretation of RFC 2046 (based on sections 5.1 and 5.1.2) say 1417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # these are illegal and should be interpreted as unterminated inner 1418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # parts. 1419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_38.txt') 1420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 1421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Iterators._structure(msg, sfp) 1422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), """\ 1423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmultipart/mixed 1424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multipart/mixed 1425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multipart/alternative 1426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 1427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 1428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 1429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 1430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 1431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_nested_with_same_boundary(self): 1433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # msg 39.txt is similarly evil in that it's got inner parts that use 1435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the same boundary as outer parts. Again, I believe the way this is 1436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # parsed is closest to the spirit of RFC 2046 1437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_39.txt') 1438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 1439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Iterators._structure(msg, sfp) 1440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), """\ 1441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmultipart/mixed 1442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multipart/mixed 1443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep multipart/alternative 1444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep application/octet-stream 1445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep application/octet-stream 1446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 1447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 1448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_boundary_in_non_multipart(self): 1450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_40.txt') 1451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.as_string(), '''\ 1452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/html; boundary="--961284236552522269" 1454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep----961284236552522269 1456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/html; 1457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7Bit 1458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep<html></html> 1460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep----961284236552522269-- 1462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_boundary_with_leading_space(self): 1465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string('''\ 1467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary=" XXXX" 1469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-- XXXX 1471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain 1472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-- XXXX 1475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain 1476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-- XXXX-- 1478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(msg.is_multipart()) 1480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_boundary(), ' XXXX') 1481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.get_payload()), 2) 1482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_boundary_without_trailing_newline(self): 1484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = Parser().parsestr("""\ 1485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="===============0012394164==" 1486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--===============0012394164== 1489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: image/file1.jpg 1490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: base64 1492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepYXNkZg== 1494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--===============0012394164==--""") 1495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(m.get_payload(0).get_payload(), 'YXNkZg==') 1496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test some badly formatted messages 1500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestNonConformant(TestEmailBase): 1501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parse_missing_minor_type(self): 1502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_14.txt') 1504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'text/plain') 1505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_maintype(), 'text') 1506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_subtype(), 'plain') 1507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_same_boundary_inner_outer(self): 1509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_15.txt') 1511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # XXX We can probably eventually do better 1512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep inner = msg.get_payload(0) 1513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(hasattr(inner, 'defects')) 1514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len(inner.defects), 1) 1515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(inner.defects[0], 1516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Errors.StartBoundaryNotFoundDefect)) 1517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_multipart_no_boundary(self): 1519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_25.txt') 1521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg.get_payload(), str)) 1522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len(msg.defects), 2) 1523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg.defects[0], Errors.NoBoundaryInMultipartDefect)) 1524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg.defects[1], 1525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Errors.MultipartInvariantViolationDefect)) 1526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_invalid_content_type(self): 1528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq = self.ndiffAssertEqual 1530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 1531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # RFC 2045, $5.2 says invalid yields text/plain 1532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'text' 1533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_maintype(), 'text') 1534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_subtype(), 'plain') 1535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'text/plain') 1536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Clear the old value and try something /really/ invalid 1537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del msg['content-type'] 1538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'foo' 1539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_maintype(), 'text') 1540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_subtype(), 'plain') 1541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'text/plain') 1542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Still, make sure that the message is idempotently generated 1543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 1544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s) 1545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 1546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq(s.getvalue(), 'Content-Type: foo\n\n') 1547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_start_boundary(self): 1549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_31.txt') 1551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), """\ 1552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain 1554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmessage 1 1556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain 1559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmessage 2 1561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 1564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_separating_blank_line(self): 1566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_35.txt') 1568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), """\ 1569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: aperson@dom.ain 1570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: bperson@dom.ain 1571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: here's something interesting 1572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepcounter to RFC 2822, there's no separating newline here 1574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 1575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_lying_multipart(self): 1577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_41.txt') 1579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(hasattr(msg, 'defects')) 1580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len(msg.defects), 2) 1581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg.defects[0], Errors.NoBoundaryInMultipartDefect)) 1582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg.defects[1], 1583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Errors.MultipartInvariantViolationDefect)) 1584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_missing_start_boundary(self): 1586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outer = self._msgobj('msg_42.txt') 1587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The message structure is: 1588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # multipart/mixed 1590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # text/plain 1591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # message/rfc822 1592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # multipart/mixed [*] 1593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # 1594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # [*] This message is missing its start boundary 1595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep bad = outer.get_payload(1).get_payload(0) 1596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len(bad.defects), 1) 1597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(isinstance(bad.defects[0], 1598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Errors.StartBoundaryNotFoundDefect)) 1599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_first_line_is_continuation_header(self): 1601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = ' Line 1\nLine 2\nLine 3' 1603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 1604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.keys(), []) 1605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), 'Line 2\nLine 3') 1606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.defects), 1) 1607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(isinstance(msg.defects[0], 1608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Errors.FirstHeaderLineIsContinuationDefect)) 1609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.defects[0].line, ' Line 1\n') 1610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test RFC 2047 header encoding and decoding 1615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestRFC2047(unittest.TestCase): 1616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2047_multiline(self): 1617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz 1619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep foo bar =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""" 1620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dh = decode_header(s) 1621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dh, [ 1622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('Re:', None), 1623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('r\x8aksm\x9arg\x8cs', 'mac-iceland'), 1624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('baz foo bar', None), 1625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('r\x8aksm\x9arg\x8cs', 'mac-iceland')]) 1626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(str(make_header(dh)), 1627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz foo bar 1628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""") 1629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_whitespace_eater_unicode(self): 1631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = '=?ISO-8859-1?Q?Andr=E9?= Pirard <pirard@dom.ain>' 1633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dh = decode_header(s) 1634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dh, [('Andr\xe9', 'iso-8859-1'), ('Pirard <pirard@dom.ain>', None)]) 1635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hu = unicode(make_header(dh)).encode('latin-1') 1636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(hu, 'Andr\xe9 Pirard <pirard@dom.ain>') 1637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_whitespace_eater_unicode_2(self): 1639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'The =?iso-8859-1?b?cXVpY2sgYnJvd24gZm94?= jumped over the =?iso-8859-1?b?bGF6eSBkb2c=?=' 1641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dh = decode_header(s) 1642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dh, [('The', None), ('quick brown fox', 'iso-8859-1'), 1643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('jumped over the', None), ('lazy dog', 'iso-8859-1')]) 1644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hu = make_header(dh).__unicode__() 1645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(hu, u'The quick brown fox jumped over the lazy dog') 1646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2047_without_whitespace(self): 1648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord' 1649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dh = decode_header(s) 1650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(dh, [(s, None)]) 1651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2047_with_whitespace(self): 1653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'Sm =?ISO-8859-1?B?9g==?= rg =?ISO-8859-1?B?5Q==?= sbord' 1654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dh = decode_header(s) 1655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(dh, [('Sm', None), ('\xf6', 'iso-8859-1'), 1656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('rg', None), ('\xe5', 'iso-8859-1'), 1657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('sbord', None)]) 1658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2047_B_bad_padding(self): 1660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = '=?iso-8859-1?B?%s?=' 1661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep data = [ # only test complete bytes 1662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('dm==', 'v'), ('dm=', 'v'), ('dm', 'v'), 1663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('dmk=', 'vi'), ('dmk', 'vi') 1664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ] 1665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for q, a in data: 1666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dh = decode_header(s % q) 1667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(dh, [(a, 'iso-8859-1')]) 1668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2047_Q_invalid_digits(self): 1670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # issue 10004. 1671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = '=?iso-8659-1?Q?andr=e9=zz?=' 1672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(decode_header(s), 1673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [(b'andr\xe9=zz', 'iso-8659-1')]) 1674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test the MIMEMessage class 1677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestMIMEMessage(TestEmailBase): 1678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self): 1679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_11.txt') 1680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 1681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._text = fp.read() 1682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 1683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 1684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_type_error(self): 1686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(TypeError, MIMEMessage, 'a plain string') 1687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_valid_argument(self): 1689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subject = 'A sub-message' 1692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = Message() 1693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m['Subject'] = subject 1694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = MIMEMessage(m) 1695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(r.get_content_type(), 'message/rfc822') 1696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = r.get_payload() 1697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(payload, list)) 1698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(payload), 1) 1699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart = payload[0] 1700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(subpart is m) 1701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart['subject'], subject) 1702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_bad_multipart(self): 1704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg1 = Message() 1706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg1['Subject'] = 'subpart 1' 1707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg2 = Message() 1708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg2['Subject'] = 'subpart 2' 1709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = MIMEMessage(msg1) 1710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(Errors.MultipartConversionError, r.attach, msg2) 1711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_generate(self): 1713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # First craft the message to be encapsulated 1714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = Message() 1715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m['Subject'] = 'An enclosed message' 1716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m.set_payload('Here is the body of the message.\n') 1717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r = MIMEMessage(m) 1718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r['Subject'] = 'The enclosing message' 1719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 1720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s) 1721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(r) 1722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(s.getvalue(), """\ 1723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: message/rfc822 1724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: The enclosing message 1726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: An enclosed message 1728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHere is the body of the message. 1730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 1731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parse_message_rfc822(self): 1733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_11.txt') 1736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'message/rfc822') 1737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = msg.get_payload() 1738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(payload, list)) 1739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(payload), 1) 1740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep submsg = payload[0] 1741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(isinstance(submsg, Message)) 1742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(submsg['subject'], 'An enclosed message') 1743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(submsg.get_payload(), 'Here is the body of the message.\n') 1744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_dsn(self): 1746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 1748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # msg 16 is a Delivery Status Notification, see RFC 1894 1749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_16.txt') 1750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'multipart/report') 1751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(msg.is_multipart()) 1752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.get_payload()), 3) 1753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 1 is a text/plain, human readable section 1754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart = msg.get_payload(0) 1755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart.get_content_type(), 'text/plain') 1756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart.get_payload(), """\ 1757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepThis report relates to a message you sent with the following header fields: 1758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Message-id: <002001c144a6$8752e060$56104586@oxy.edu> 1760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Date: Sun, 23 Sep 2001 20:10:55 -0700 1761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep From: "Ian T. Henry" <henryi@oxy.edu> 1762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep To: SoCal Raves <scr@socal-raves.org> 1763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Subject: [scr] yeah for Ians!! 1764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepYour message cannot be delivered to the following recipients: 1766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Recipient address: jangel1@cougar.noc.ucla.edu 1768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Reason: recipient reached disk quota 1769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 1771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 2 contains the machine parsable DSN information. It 1772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # consists of two blocks of headers, represented by two nested Message 1773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # objects. 1774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart = msg.get_payload(1) 1775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart.get_content_type(), 'message/delivery-status') 1776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(subpart.get_payload()), 2) 1777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # message/delivery-status should treat each block as a bunch of 1778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # headers, i.e. a bunch of Message objects. 1779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dsn1 = subpart.get_payload(0) 1780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(dsn1, Message)) 1781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dsn1['original-envelope-id'], '0GK500B4HD0888@cougar.noc.ucla.edu') 1782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dsn1.get_param('dns', header='reporting-mta'), '') 1783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try a missing one <wink> 1784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dsn1.get_param('nsd', header='reporting-mta'), None) 1785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep dsn2 = subpart.get_payload(1) 1786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(dsn2, Message)) 1787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dsn2['action'], 'failed') 1788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dsn2.get_params(header='original-recipient'), 1789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('rfc822', ''), ('jangel1@cougar.noc.ucla.edu', '')]) 1790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(dsn2.get_param('rfc822', header='final-recipient'), '') 1791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Subpart 3 is the original message 1792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart = msg.get_payload(2) 1793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart.get_content_type(), 'message/rfc822') 1794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = subpart.get_payload() 1795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(payload, list)) 1796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(payload), 1) 1797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subsubpart = payload[0] 1798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(subsubpart, Message)) 1799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subsubpart.get_content_type(), 'text/plain') 1800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subsubpart['message-id'], 1801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '<002001c144a6$8752e060$56104586@oxy.edu>') 1802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_epilogue(self): 1804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_21.txt') 1806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 1807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = fp.read() 1808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 1809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 1810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 1811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['From'] = 'aperson@dom.ain' 1812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['To'] = 'bperson@dom.ain' 1813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Subject'] = 'Test' 1814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.preamble = 'MIME message' 1815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.epilogue = 'End of MIME message\n' 1816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg1 = MIMEText('One') 1817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg2 = MIMEText('Two') 1818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY') 1819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.attach(msg1) 1820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.attach(msg2) 1821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 1822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(sfp) 1823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 1824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), text) 1825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_nl_preamble(self): 1827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 1828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 1829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['From'] = 'aperson@dom.ain' 1830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['To'] = 'bperson@dom.ain' 1831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Subject'] = 'Test' 1832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.preamble = 'MIME message' 1833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.epilogue = '' 1834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg1 = MIMEText('One') 1835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg2 = MIMEText('Two') 1836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY') 1837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.attach(msg1) 1838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.attach(msg2) 1839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), """\ 1840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: aperson@dom.ain 1841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: bperson@dom.ain 1842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: Test 1843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/mixed; boundary="BOUNDARY" 1844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME message 1846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepOne 1852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTwo 1858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 1860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_default_type(self): 1862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_30.txt') 1864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 1865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_file(fp) 1866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 1867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 1868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container1 = msg.get_payload(0) 1869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1.get_default_type(), 'message/rfc822') 1870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1.get_content_type(), 'message/rfc822') 1871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container2 = msg.get_payload(1) 1872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2.get_default_type(), 'message/rfc822') 1873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2.get_content_type(), 'message/rfc822') 1874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container1a = container1.get_payload(0) 1875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1a.get_default_type(), 'text/plain') 1876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1a.get_content_type(), 'text/plain') 1877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container2a = container2.get_payload(0) 1878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2a.get_default_type(), 'text/plain') 1879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2a.get_content_type(), 'text/plain') 1880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_default_type_with_explicit_container_type(self): 1882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_28.txt') 1884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 1885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_file(fp) 1886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 1887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 1888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container1 = msg.get_payload(0) 1889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1.get_default_type(), 'message/rfc822') 1890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1.get_content_type(), 'message/rfc822') 1891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container2 = msg.get_payload(1) 1892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2.get_default_type(), 'message/rfc822') 1893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2.get_content_type(), 'message/rfc822') 1894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container1a = container1.get_payload(0) 1895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1a.get_default_type(), 'text/plain') 1896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container1a.get_content_type(), 'text/plain') 1897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container2a = container2.get_payload(0) 1898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2a.get_default_type(), 'text/plain') 1899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(container2a.get_content_type(), 'text/plain') 1900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_default_type_non_parsed(self): 1902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq = self.ndiffAssertEqual 1904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Set up container 1905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container = MIMEMultipart('digest', 'BOUNDARY') 1906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container.epilogue = '' 1907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Set up subparts 1908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart1a = MIMEText('message 1\n') 1909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart2a = MIMEText('message 2\n') 1910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart1 = MIMEMessage(subpart1a) 1911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subpart2 = MIMEMessage(subpart2a) 1912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container.attach(subpart1) 1913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep container.attach(subpart2) 1914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart1.get_content_type(), 'message/rfc822') 1915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart1.get_default_type(), 'message/rfc822') 1916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart2.get_content_type(), 'message/rfc822') 1917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart2.get_default_type(), 'message/rfc822') 1918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq(container.as_string(0), '''\ 1919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/digest; boundary="BOUNDARY" 1920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: message/rfc822 1924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmessage 1 1931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: message/rfc822 1934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmessage 2 1941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del subpart1['content-type'] 1945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del subpart1['mime-version'] 1946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del subpart2['content-type'] 1947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del subpart2['mime-version'] 1948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart1.get_content_type(), 'message/rfc822') 1949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart1.get_default_type(), 'message/rfc822') 1950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart2.get_content_type(), 'message/rfc822') 1951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subpart2.get_default_type(), 'message/rfc822') 1952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq(container.as_string(0), '''\ 1953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/digest; boundary="BOUNDARY" 1954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmessage 1 1963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY 1965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii" 1967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 1968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 1969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmessage 2 1971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep--BOUNDARY-- 1973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''') 1974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_mime_attachments_in_constructor(self): 1976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 1977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text1 = MIMEText('') 1978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text2 = MIMEText('') 1979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEMultipart(_subparts=(text1, text2)) 1980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.get_payload()), 2) 1981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(0), text1) 1982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(1), text2) 1983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_default_multipart_constructor(self): 1985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = MIMEMultipart() 1986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(msg.is_multipart()) 1987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 1989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# A general test of parser->model->generator idempotency. IOW, read a message 1990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# in, parse it into a message object tree, then without touching the tree, 1991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# regenerate the plain text. The original text and the transformed text 1992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# should be identical. Note: that we ignore the Unix-From since that may 1993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# contain a changed date. 1994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestIdempotent(TestEmailBase): 1995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _msgobj(self, filename): 1996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile(filename) 1997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 1998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep data = fp.read() 1999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(data) 2002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return msg, data 2003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _idempotent(self, msg, text): 2005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 2006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 2007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s, maxheaderlen=0) 2008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 2009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(text, s.getvalue()) 2010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parse_text_message(self): 2012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_01.txt') 2014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'text/plain') 2015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_maintype(), 'text') 2016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_subtype(), 'plain') 2017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params()[1], ('charset', 'us-ascii')) 2018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('charset'), 'us-ascii') 2019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.preamble, None) 2020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.epilogue, None) 2021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parse_untyped_message(self): 2024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_03.txt') 2026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'text/plain') 2027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_params(), None) 2028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('charset'), None) 2029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_simple_multipart(self): 2032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_04.txt') 2033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_MIME_digest(self): 2036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_02.txt') 2037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_header(self): 2040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_27.txt') 2041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_MIME_digest_with_part_headers(self): 2044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_28.txt') 2045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_mixed_with_image(self): 2048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_06.txt') 2049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_multipart_report(self): 2052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_05.txt') 2053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_dsn(self): 2056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_16.txt') 2057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_preamble_epilogue(self): 2060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_21.txt') 2061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_multipart_one_part(self): 2064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_23.txt') 2065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_multipart_no_parts(self): 2068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_24.txt') 2069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_no_start_boundary(self): 2072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_31.txt') 2073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_charset(self): 2076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_32.txt') 2077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_more_rfc2231_parameters(self): 2080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_33.txt') 2081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_text_plain_in_a_multipart_digest(self): 2084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_34.txt') 2085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_nested_multipart_mixeds(self): 2088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_12a.txt') 2089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_message_external_body_idempotent(self): 2092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_36.txt') 2093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._idempotent(msg, text) 2094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_content_type(self): 2096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 2098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Get a message object and reset the seek pointer for other tests 2099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_05.txt') 2100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'multipart/report') 2101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the Content-Type: parameters 2102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep params = {} 2103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for pk, pv in msg.get_params(): 2104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep params[pk] = pv 2105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(params['report-type'], 'delivery-status') 2106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(params['boundary'], 'D1690A7AC1.996856090/mail.example.com') 2107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.preamble, 'This is a MIME-encapsulated message.\n') 2108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.epilogue, '\n') 2109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.get_payload()), 3) 2110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Make sure the subparts are what we expect 2111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg1 = msg.get_payload(0) 2112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg1.get_content_type(), 'text/plain') 2113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg1.get_payload(), 'Yadda yadda yadda\n') 2114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg2 = msg.get_payload(1) 2115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg2.get_content_type(), 'text/plain') 2116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg2.get_payload(), 'Yadda yadda yadda\n') 2117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg3 = msg.get_payload(2) 2118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg3.get_content_type(), 'message/rfc822') 2119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(isinstance(msg3, Message)) 2120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = msg3.get_payload() 2121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(payload, list)) 2122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(payload), 1) 2123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg4 = payload[0] 2124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg4, Message)) 2125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg4.get_payload(), 'Yadda yadda yadda\n') 2126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parser(self): 2128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 2130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg, text = self._msgobj('msg_06.txt') 2131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Check some of the outer headers 2132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'message/rfc822') 2133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Make sure the payload is a list of exactly one sub-Message, and that 2134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # that submessage has a type of text/plain 2135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep payload = msg.get_payload() 2136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(payload, list)) 2137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(payload), 1) 2138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg1 = payload[0] 2139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(isinstance(msg1, Message)) 2140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg1.get_content_type(), 'text/plain') 2141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(isinstance(msg1.get_payload(), str)) 2142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg1.get_payload(), '\n') 2143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test various other bits of the package's functionality 2147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestMiscellaneous(TestEmailBase): 2148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_message_from_string(self): 2149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_01.txt') 2150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = fp.read() 2152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(text) 2155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 2156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Don't wrap/continue long headers since we're trying to test 2157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # idempotency. 2158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s, maxheaderlen=0) 2159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 2160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(text, s.getvalue()) 2161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_message_from_file(self): 2163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_01.txt') 2164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = fp.read() 2166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.seek(0) 2167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_file(fp) 2168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = StringIO() 2169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Don't wrap/continue long headers since we're trying to test 2170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # idempotency. 2171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Generator(s, maxheaderlen=0) 2172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g.flatten(msg) 2173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(text, s.getvalue()) 2174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_message_from_string_with_class(self): 2178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 2179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_01.txt') 2180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = fp.read() 2182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Create a subclass 2185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep class MyMessage(Message): 2186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 2187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(text, MyMessage) 2189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg, MyMessage)) 2190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try something more complicated 2191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_02.txt') 2192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text = fp.read() 2194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(text, MyMessage) 2197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for subpart in msg.walk(): 2198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(subpart, MyMessage)) 2199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_message_from_file_with_class(self): 2201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless = self.assertTrue 2202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Create a subclass 2203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep class MyMessage(Message): 2204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 2205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_01.txt') 2207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_file(fp, MyMessage) 2209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(msg, MyMessage)) 2212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try something more complicated 2213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_02.txt') 2214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_file(fp, MyMessage) 2216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for subpart in msg.walk(): 2219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unless(isinstance(subpart, MyMessage)) 2220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test__all__(self): 2222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep module = __import__('email') 2223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep all = module.__all__ 2224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep all.sort() 2225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(all, [ 2226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Old names 2227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Charset', 'Encoders', 'Errors', 'Generator', 2228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Header', 'Iterators', 'MIMEAudio', 'MIMEBase', 2229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'MIMEImage', 'MIMEMessage', 'MIMEMultipart', 2230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'MIMENonMultipart', 'MIMEText', 'Message', 2231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Parser', 'Utils', 'base64MIME', 2232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # new names 2233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'base64mime', 'charset', 'encoders', 'errors', 'generator', 2234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'header', 'iterators', 'message', 'message_from_file', 2235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'message_from_string', 'mime', 'parser', 2236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'quopriMIME', 'quoprimime', 'utils', 2237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ]) 2238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_formatdate(self): 2240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep now = time.time() 2241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parsedate(Utils.formatdate(now))[:6], 2242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep time.gmtime(now)[:6]) 2243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_formatdate_localtime(self): 2245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep now = time.time() 2246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 2247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.parsedate(Utils.formatdate(now, localtime=True))[:6], 2248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep time.localtime(now)[:6]) 2249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_formatdate_usegmt(self): 2251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep now = time.time() 2252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 2253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.formatdate(now, localtime=False), 2254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep time.strftime('%a, %d %b %Y %H:%M:%S -0000', time.gmtime(now))) 2255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 2256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.formatdate(now, localtime=False, usegmt=True), 2257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(now))) 2258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parsedate_none(self): 2260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parsedate(''), None) 2261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parsedate_compact(self): 2263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The FWS after the comma is optional 2264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parsedate('Wed,3 Apr 2002 14:58:26 +0800'), 2265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.parsedate('Wed, 3 Apr 2002 14:58:26 +0800')) 2266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parsedate_no_dayofweek(self): 2268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.parsedate_tz('25 Feb 2003 13:47:26 -0800'), 2270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (2003, 2, 25, 13, 47, 26, 0, 1, -1, -28800)) 2271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parsedate_compact_no_dayofweek(self): 2273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'), 2275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800)) 2276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parsedate_acceptable_to_time_functions(self): 2278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep timetup = Utils.parsedate('5 Feb 2003 13:47:26 -0800') 2280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep t = int(time.mktime(timetup)) 2281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(time.localtime(t)[:6], timetup[:6]) 2282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(int(time.strftime('%Y', timetup)), 2003) 2283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep timetup = Utils.parsedate_tz('5 Feb 2003 13:47:26 -0800') 2284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep t = int(time.mktime(timetup[:9])) 2285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(time.localtime(t)[:6], timetup[:6]) 2286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(int(time.strftime('%Y', timetup[:9])), 2003) 2287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_mktime_tz(self): 2289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.mktime_tz((1970, 1, 1, 0, 0, 0, 2290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -1, -1, -1, 0)), 0) 2291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.mktime_tz((1970, 1, 1, 0, 0, 0, 2292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep -1, -1, -1, 1234)), -1234) 2293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parsedate_y2k(self): 2295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Test for parsing a date with a two-digit year. 2296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Parsing a date with a two-digit year should return the correct 2298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep four-digit year. RFC822 allows two-digit years, but RFC2822 (which 2299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obsoletes RFC822) requires four-digit years. 2300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """ 2302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parsedate_tz('25 Feb 03 13:47:26 -0800'), 2303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.parsedate_tz('25 Feb 2003 13:47:26 -0800')) 2304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parsedate_tz('25 Feb 71 13:47:26 -0800'), 2305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.parsedate_tz('25 Feb 1971 13:47:26 -0800')) 2306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parseaddr_empty(self): 2308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parseaddr('<>'), ('', '')) 2309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.formataddr(Utils.parseaddr('<>')), '') 2310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_noquote_dump(self): 2312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 2313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.formataddr(('A Silly Person', 'person@dom.ain')), 2314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'A Silly Person <person@dom.ain>') 2315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_escape_dump(self): 2317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 2318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.formataddr(('A (Very) Silly Person', 'person@dom.ain')), 2319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r'"A \(Very\) Silly Person" <person@dom.ain>') 2320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = r'A \(Special\) Person' 2321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep b = 'person@dom.ain' 2322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parseaddr(Utils.formataddr((a, b))), (a, b)) 2323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_escape_backslashes(self): 2325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 2326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.formataddr(('Arthur \Backslash\ Foobar', 'person@dom.ain')), 2327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r'"Arthur \\Backslash\\ Foobar" <person@dom.ain>') 2328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a = r'Arthur \Backslash\ Foobar' 2329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep b = 'person@dom.ain' 2330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parseaddr(Utils.formataddr((a, b))), (a, b)) 2331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_name_with_dot(self): 2333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = 'John X. Doe <jxd@example.com>' 2334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep y = '"John X. Doe" <jxd@example.com>' 2335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep a, b = ('John X. Doe', 'jxd@example.com') 2336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parseaddr(x), (a, b)) 2337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parseaddr(y), (a, b)) 2338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # formataddr() quotes the name if there's a dot in it 2339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.formataddr((a, b)), y) 2340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_parseaddr_preserves_quoted_pairs_in_addresses(self): 2342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # issue 10005. Note that in the third test the second pair of 2343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # backslashes is not actually a quoted pair because it is not inside a 2344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # comment or quoted string: the address being parsed has a quoted 2345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # string containing a quoted backslash, followed by 'example' and two 2346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # backslashes, followed by another quoted string containing a space and 2347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # the word 'example'. parseaddr copies those two backslashes 2348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # literally. Per rfc5322 this is not technically correct since a \ may 2349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # not appear in an address outside of a quoted string. It is probably 2350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # a sensible Postel interpretation, though. 2351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.parseaddr('""example" example"@example.com'), 2353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('', '""example" example"@example.com')) 2354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.parseaddr('"\\"example\\" example"@example.com'), 2355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('', '"\\"example\\" example"@example.com')) 2356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.parseaddr('"\\\\"example\\\\" example"@example.com'), 2357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('', '"\\\\"example\\\\" example"@example.com')) 2358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_multiline_from_comment(self): 2360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = """\ 2361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFoo 2362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tBar <foo@example.com>""" 2363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(Utils.parseaddr(x), ('Foo Bar', 'foo@example.com')) 2364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_quote_dump(self): 2366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 2367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Utils.formataddr(('A Silly; Person', 'person@dom.ain')), 2368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep r'"A Silly; Person" <person@dom.ain>') 2369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_fix_eols(self): 2371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.fix_eols('hello'), 'hello') 2373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.fix_eols('hello\n'), 'hello\r\n') 2374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.fix_eols('hello\r'), 'hello\r\n') 2375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.fix_eols('hello\r\n'), 'hello\r\n') 2376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.fix_eols('hello\n\r'), 'hello\r\n\r\n') 2377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_charset_richcomparisons(self): 2379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ne = self.assertNotEqual 2381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cset1 = Charset() 2382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cset2 = Charset() 2383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(cset1, 'us-ascii') 2384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(cset1, 'US-ASCII') 2385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(cset1, 'Us-AsCiI') 2386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('us-ascii', cset1) 2387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('US-ASCII', cset1) 2388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('Us-AsCiI', cset1) 2389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ne(cset1, 'usascii') 2390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ne(cset1, 'USASCII') 2391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ne(cset1, 'UsAsCiI') 2392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ne('usascii', cset1) 2393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ne('USASCII', cset1) 2394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ne('UsAsCiI', cset1) 2395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(cset1, cset2) 2396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(cset2, cset1) 2397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_getaddresses(self): 2399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.getaddresses(['aperson@dom.ain (Al Person)', 2401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Bud Person <bperson@dom.ain>']), 2402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('Al Person', 'aperson@dom.ain'), 2403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('Bud Person', 'bperson@dom.ain')]) 2404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_getaddresses_nasty(self): 2406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.getaddresses(['foo: ;']), [('', '')]) 2408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.getaddresses( 2409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ['[]*-- =~$']), 2410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('', ''), ('', ''), ('', '*--')]) 2411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(Utils.getaddresses( 2412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ['foo: ;', '"Jason R. Mastaler" <jason@dom.ain>']), 2413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) 2414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_getaddresses_embedded_comment(self): 2416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep """Test proper handling of a nested comment""" 2417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep addrs = Utils.getaddresses(['User ((nested comment)) <foo@bar.com>']) 2419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(addrs[0][1], 'foo@bar.com') 2420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_utils_quote_unquote(self): 2422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 2424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('content-disposition', 'attachment', 2425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filename='foo\\wacky"name') 2426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_filename(), 'foo\\wacky"name') 2427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_body_encoding_with_bogus_charset(self): 2429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset = Charset('not a charset') 2430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(charset.get_body_encoding(), 'base64') 2431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_body_encoding_with_uppercase_charset(self): 2433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 2435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'text/plain; charset=UTF-8' 2436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-type'], 'text/plain; charset=UTF-8') 2437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charsets = msg.get_charsets() 2438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(charsets), 1) 2439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charsets[0], 'utf-8') 2440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset = Charset(charsets[0]) 2441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charset.get_body_encoding(), 'base64') 2442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload('hello world', charset=charset) 2443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), 'aGVsbG8gd29ybGQ=\n') 2444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(decode=True), 'hello world') 2445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], 'base64') 2446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try another one 2447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 2448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Type'] = 'text/plain; charset="US-ASCII"' 2449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charsets = msg.get_charsets() 2450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(charsets), 1) 2451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charsets[0], 'us-ascii') 2452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset = Charset(charsets[0]) 2453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charset.get_body_encoding(), Encoders.encode_7or8bit) 2454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_payload('hello world', charset=charset) 2455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), 'hello world') 2456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['content-transfer-encoding'], '7bit') 2457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_charsets_case_insensitive(self): 2459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lc = Charset('us-ascii') 2460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep uc = Charset('US-ASCII') 2461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(lc.get_body_encoding(), uc.get_body_encoding()) 2462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_partial_falls_inside_message_delivery_status(self): 2464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 2465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # The Parser interface provides chunks of data to FeedParser in 8192 2466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # byte gulps. SF bug #1076485 found one of those chunks inside 2467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # message/delivery-status header block, which triggered an 2468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # unreadline() of NeedMoreData. 2469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_43.txt') 2470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sfp = StringIO() 2471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Iterators._structure(msg, sfp) 2472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(sfp.getvalue(), """\ 2473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepmultipart/report 2474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep message/delivery-status 2476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/plain 2502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep text/rfc822-headers 2503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 2504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test the iterator/generators 2508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestIterators(TestEmailBase): 2509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_body_line_iterator(self): 2510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq = self.ndiffAssertEqual 2512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # First a simple non-multipart message 2513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 2514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep it = Iterators.body_line_iterator(msg) 2515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines = list(it) 2516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(lines), 6) 2517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq(EMPTYSTRING.join(lines), msg.get_payload()) 2518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Now a more complicated multipart 2519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_02.txt') 2520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep it = Iterators.body_line_iterator(msg) 2521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines = list(it) 2522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(lines), 43) 2523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_19.txt') 2524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq(EMPTYSTRING.join(lines), fp.read()) 2526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_typed_subpart_iterator(self): 2530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_04.txt') 2532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep it = Iterators.typed_subpart_iterator(msg, 'text') 2533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines = [] 2534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subparts = 0 2535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for subpart in it: 2536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subparts += 1 2537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines.append(subpart.get_payload()) 2538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subparts, 2) 2539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(EMPTYSTRING.join(lines), """\ 2540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepa simple kind of mirror 2541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepto reflect upon our own 2542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepa simple kind of mirror 2543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepto reflect upon our own 2544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 2545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_typed_subpart_iterator_default_type(self): 2547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_03.txt') 2549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep it = Iterators.typed_subpart_iterator(msg, 'text', 'plain') 2550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines = [] 2551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subparts = 0 2552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for subpart in it: 2553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep subparts += 1 2554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines.append(subpart.get_payload()) 2555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(subparts, 1) 2556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(EMPTYSTRING.join(lines), """\ 2557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHi, 2559edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2560edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDo you like this message? 2561edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2562edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-Me 2563edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 2564edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2565edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_pushCR_LF(self): 2566edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '''FeedParser BufferedSubFile.push() assumed it received complete 2567edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep line endings. A CR ending one push() followed by a LF starting 2568edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep the next push() added an empty line. 2569edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 2570edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep imt = [ 2571edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("a\r \n", 2), 2572edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("b", 0), 2573edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("c\n", 1), 2574edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("", 0), 2575edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("d\r\n", 1), 2576edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("e\r", 0), 2577edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("\nf", 1), 2578edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ("\r\n", 1), 2579edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ] 2580edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from email.feedparser import BufferedSubFile, NeedMoreData 2581edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep bsf = BufferedSubFile() 2582edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep om = [] 2583edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nt = 0 2584edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for il, n in imt: 2585edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep bsf.push(il) 2586edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nt += n 2587edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n1 = 0 2588edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep while True: 2589edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ol = bsf.readline() 2590edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if ol == NeedMoreData: 2591edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep break 2592edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep om.append(ol) 2593edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep n1 += 1 2594edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(n == n1) 2595edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(len(om) == nt) 2596edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(''.join([il for il, n in imt]) == ''.join(om)) 2597edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2598edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2599edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2600edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestParsers(TestEmailBase): 2601edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_parser(self): 2602edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2603edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Parse only the headers of a complex multipart MIME document 2604edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_02.txt') 2605edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2606edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = HeaderParser().parse(fp) 2607edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2608edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2609edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['from'], 'ppp-request@zzz.org') 2610edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['to'], 'ppp@zzz.org') 2611edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_type(), 'multipart/mixed') 2612edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertFalse(msg.is_multipart()) 2613edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(isinstance(msg.get_payload(), str)) 2614edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2615edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_whitespace_continuation(self): 2616edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2617edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This message contains a line after the Subject: header that has only 2618edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # whitespace, but it is not empty! 2619edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string("""\ 2620edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: aperson@dom.ain 2621edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: bperson@dom.ain 2622edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: the next line has a space on it 2623edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\x20 2624edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDate: Mon, 8 Apr 2002 15:09:19 -0400 2625edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMessage-ID: spam 2626edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2627edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHere's the message body 2628edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 2629edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['subject'], 'the next line has a space on it\n ') 2630edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['message-id'], 'spam') 2631edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), "Here's the message body\n") 2632edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2633edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_whitespace_continuation_last_header(self): 2634edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2635edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Like the previous test, but the subject line is the last 2636edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # header. 2637edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string("""\ 2638edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: aperson@dom.ain 2639edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: bperson@dom.ain 2640edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDate: Mon, 8 Apr 2002 15:09:19 -0400 2641edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMessage-ID: spam 2642edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: the next line has a space on it 2643edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\x20 2644edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2645edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHere's the message body 2646edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 2647edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['subject'], 'the next line has a space on it\n ') 2648edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg['message-id'], 'spam') 2649edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), "Here's the message body\n") 2650edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2651edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_crlf_separation(self): 2652edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2653edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_26.txt', mode='rb') 2654edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2655edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Parser().parse(fp) 2656edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2657edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2658edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.get_payload()), 2) 2659edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep part1 = msg.get_payload(0) 2660edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part1.get_content_type(), 'text/plain') 2661edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part1.get_payload(), 'Simple email with attachment.\r\n\r\n') 2662edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep part2 = msg.get_payload(1) 2663edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part2.get_content_type(), 'application/riscos') 2664edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2665edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_multipart_digest_with_extra_mime_headers(self): 2666edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2667edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq = self.ndiffAssertEqual 2668edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile('msg_28.txt') 2669edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2670edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_file(fp) 2671edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 2672edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 2673edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Structure is: 2674edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # multipart/digest 2675edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # message/rfc822 2676edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # text/plain 2677edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # message/rfc822 2678edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # text/plain 2679edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.is_multipart(), 1) 2680edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.get_payload()), 2) 2681edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep part1 = msg.get_payload(0) 2682edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part1.get_content_type(), 'message/rfc822') 2683edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part1.is_multipart(), 1) 2684edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(part1.get_payload()), 1) 2685edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep part1a = part1.get_payload(0) 2686edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part1a.is_multipart(), 0) 2687edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part1a.get_content_type(), 'text/plain') 2688edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq(part1a.get_payload(), 'message 1\n') 2689edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # next message/rfc822 2690edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep part2 = msg.get_payload(1) 2691edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part2.get_content_type(), 'message/rfc822') 2692edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part2.is_multipart(), 1) 2693edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(part2.get_payload()), 1) 2694edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep part2a = part2.get_payload(0) 2695edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part2a.is_multipart(), 0) 2696edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(part2a.get_content_type(), 'text/plain') 2697edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep neq(part2a.get_payload(), 'message 2\n') 2698edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2699edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_three_lines(self): 2700edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # A bug report by Andrew McNamara 2701edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lines = ['From: Andrew Person <aperson@dom.ain', 2702edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Subject: Test', 2703edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Date: Tue, 20 Aug 2002 16:43:45 +1000'] 2704edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(NL.join(lines)) 2705edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg['date'], 'Tue, 20 Aug 2002 16:43:45 +1000') 2706edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2707edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_strip_line_feed_and_carriage_return_in_headers(self): 2708edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2709edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # For [ 1002475 ] email message parser doesn't handle \r\n correctly 2710edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value1 = 'text' 2711edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value2 = 'more text' 2712edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = 'Header: %s\r\nNext-Header: %s\r\n\r\nBody\r\n\r\n' % ( 2713edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value1, value2) 2714edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 2715edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get('Header'), value1) 2716edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get('Next-Header'), value2) 2717edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2718edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2822_header_syntax(self): 2719edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2720edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '>From: foo\nFrom: bar\n!"#QUX;~: zoo\n\nbody' 2721edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 2722edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.keys()), 3) 2723edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep keys = msg.keys() 2724edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep keys.sort() 2725edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(keys, ['!"#QUX;~', '>From', 'From']) 2726edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), 'body') 2727edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2728edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2822_space_not_allowed_in_header(self): 2729edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2730edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '>From foo@example.com 11:25:53\nFrom: bar\n!"#QUX;~: zoo\n\nbody' 2731edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 2732edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(len(msg.keys()), 0) 2733edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2734edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2822_one_character_header(self): 2735edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2736edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = 'A: first header\nB: second header\nCC: third header\n\nbody' 2737edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 2738edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep headers = msg.keys() 2739edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep headers.sort() 2740edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(headers, ['A', 'B', 'CC']) 2741edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_payload(), 'body') 2742edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2743edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_CRLFLF_at_end_of_part(self): 2744edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # issue 5610: feedparser should not eat two chars from body part ending 2745edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # with "\r\n\n". 2746edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = ( 2747edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "From: foo@bar.com\n" 2748edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "To: baz\n" 2749edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Mime-Version: 1.0\n" 2750edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Content-Type: multipart/mixed; boundary=BOUNDARY\n" 2751edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "\n" 2752edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "--BOUNDARY\n" 2753edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "Content-Type: text/plain\n" 2754edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "\n" 2755edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "body ending with CRLF newline\r\n" 2756edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "\n" 2757edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep "--BOUNDARY--\n" 2758edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ) 2759edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 2760edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(msg.get_payload(0).get_payload().endswith('\r\n')) 2761edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2762edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2763edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestBase64(unittest.TestCase): 2764edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_len(self): 2765edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2766edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.base64_len('hello'), 2767edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep len(base64MIME.encode('hello', eol=''))) 2768edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for size in range(15): 2769edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if size == 0 : bsize = 0 2770edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif size <= 3 : bsize = 4 2771edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif size <= 6 : bsize = 8 2772edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif size <= 9 : bsize = 12 2773edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif size <= 12: bsize = 16 2774edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else : bsize = 20 2775edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.base64_len('x'*size), bsize) 2776edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2777edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_decode(self): 2778edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2779edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.decode(''), '') 2780edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.decode('aGVsbG8='), 'hello') 2781edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.decode('aGVsbG8=', 'X'), 'hello') 2782edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.decode('aGVsbG8NCndvcmxk\n', 'X'), 'helloXworld') 2783edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2784edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encode(self): 2785edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2786edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.encode(''), '') 2787edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.encode('hello'), 'aGVsbG8=\n') 2788edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the binary flag 2789edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.encode('hello\n'), 'aGVsbG8K\n') 2790edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.encode('hello\n', 0), 'aGVsbG8NCg==\n') 2791edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the maxlinelen arg 2792edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.encode('xxxx ' * 20, maxlinelen=40), """\ 2793edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg 2794edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg 2795edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg 2796edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IA== 2797edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 2798edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the eol argument 2799edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(base64MIME.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 2800edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r 2801edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r 2802edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r 2803edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepeHh4eCB4eHh4IA==\r 2804edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 2805edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2806edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_encode(self): 2807edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2808edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep he = base64MIME.header_encode 2809edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello'), '=?iso-8859-1?b?aGVsbG8=?=') 2810edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello\nworld'), '=?iso-8859-1?b?aGVsbG8NCndvcmxk?=') 2811edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the charset option 2812edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?b?aGVsbG8=?=') 2813edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the keep_eols flag 2814edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello\nworld', keep_eols=True), 2815edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '=?iso-8859-1?b?aGVsbG8Kd29ybGQ=?=') 2816edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the maxlinelen argument 2817edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('xxxx ' * 20, maxlinelen=40), """\ 2818edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?= 2819edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?= 2820edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?= 2821edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?= 2822edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?= 2823edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""") 2824edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the eol argument 2825edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 2826edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?=\r 2827edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?=\r 2828edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?=\r 2829edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?=\r 2830edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?=\r 2831edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""") 2832edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2833edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2834edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2835edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestQuopri(unittest.TestCase): 2836edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self): 2837edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.hlit = [chr(x) for x in range(ord('a'), ord('z')+1)] + \ 2838edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [chr(x) for x in range(ord('A'), ord('Z')+1)] + \ 2839edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [chr(x) for x in range(ord('0'), ord('9')+1)] + \ 2840edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ['!', '*', '+', '-', '/', ' '] 2841edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.hnon = [chr(x) for x in range(256) if chr(x) not in self.hlit] 2842edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep assert len(self.hlit) + len(self.hnon) == 256 2843edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.blit = [chr(x) for x in range(ord(' '), ord('~')+1)] + ['\t'] 2844edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.blit.remove('=') 2845edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.bnon = [chr(x) for x in range(256) if chr(x) not in self.blit] 2846edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep assert len(self.blit) + len(self.bnon) == 256 2847edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2848edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_quopri_check(self): 2849edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.hlit: 2850edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertFalse(quopriMIME.header_quopri_check(c)) 2851edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.hnon: 2852edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(quopriMIME.header_quopri_check(c)) 2853edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2854edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_body_quopri_check(self): 2855edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.blit: 2856edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertFalse(quopriMIME.body_quopri_check(c)) 2857edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.bnon: 2858edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(quopriMIME.body_quopri_check(c)) 2859edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2860edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_quopri_len(self): 2861edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2862edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hql = quopriMIME.header_quopri_len 2863edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep enc = quopriMIME.header_encode 2864edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for s in ('hello', 'h@e@l@l@o@'): 2865edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Empty charset and no line-endings. 7 == RFC chrome 2866edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(hql(s), len(enc(s, charset='', eol=''))-7) 2867edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.hlit: 2868edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(hql(c), 1) 2869edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.hnon: 2870edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(hql(c), 3) 2871edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2872edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_body_quopri_len(self): 2873edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2874edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep bql = quopriMIME.body_quopri_len 2875edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.blit: 2876edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(bql(c), 1) 2877edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for c in self.bnon: 2878edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(bql(c), 3) 2879edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2880edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_quote_unquote_idempotent(self): 2881edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for x in range(256): 2882edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = chr(x) 2883edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(quopriMIME.unquote(quopriMIME.quote(c)), c) 2884edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2885edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_encode(self): 2886edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2887edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep he = quopriMIME.header_encode 2888edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello'), '=?iso-8859-1?q?hello?=') 2889edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello\nworld'), '=?iso-8859-1?q?hello=0D=0Aworld?=') 2890edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the charset option 2891edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?q?hello?=') 2892edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the keep_eols flag 2893edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello\nworld', keep_eols=True), '=?iso-8859-1?q?hello=0Aworld?=') 2894edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test a non-ASCII character 2895edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('hello\xc7there'), '=?iso-8859-1?q?hello=C7there?=') 2896edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the maxlinelen argument 2897edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('xxxx ' * 20, maxlinelen=40), """\ 2898edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?= 2899edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?= 2900edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?= 2901edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?= 2902edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?x_xxxx_xxxx_?=""") 2903edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the eol argument 2904edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 2905edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?=\r 2906edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?=\r 2907edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?=\r 2908edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?=\r 2909edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?x_xxxx_xxxx_?=""") 2910edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2911edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_decode(self): 2912edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2913edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.decode(''), '') 2914edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.decode('hello'), 'hello') 2915edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.decode('hello', 'X'), 'hello') 2916edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.decode('hello\nworld', 'X'), 'helloXworld') 2917edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2918edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encode(self): 2919edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2920edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.encode(''), '') 2921edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.encode('hello'), 'hello') 2922edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the binary flag 2923edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.encode('hello\r\nworld'), 'hello\nworld') 2924edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.encode('hello\r\nworld', 0), 'hello\nworld') 2925edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the maxlinelen arg 2926edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.encode('xxxx ' * 20, maxlinelen=40), """\ 2927edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepxxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx= 2928edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx= 2929edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepx xxxx xxxx xxxx xxxx=20""") 2930edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test the eol argument 2931edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 2932edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepxxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx=\r 2933edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx=\r 2934edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepx xxxx xxxx xxxx xxxx=20""") 2935edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(quopriMIME.encode("""\ 2936edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepone line 2937edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2938edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptwo line"""), """\ 2939edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepone line 2940edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2941edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptwo line""") 2942edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2943edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2944edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2945edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test the Charset class 2946edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestCharset(unittest.TestCase): 2947edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def tearDown(self): 2948edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from email import Charset as CharsetModule 2949edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2950edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del CharsetModule.CHARSETS['fake'] 2951edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except KeyError: 2952edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 2953edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2954edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_idempotent(self): 2955edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2956edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Make sure us-ascii = no Unicode conversion 2957edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = Charset('us-ascii') 2958edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'Hello World!' 2959edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sp = c.to_splittable(s) 2960edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, c.from_splittable(sp)) 2961edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # test 8-bit idempotency with us-ascii 2962edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = '\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa' 2963edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep sp = c.to_splittable(s) 2964edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, c.from_splittable(sp)) 2965edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2966edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_body_encode(self): 2967edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 2968edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try a charset with QP body encoding 2969edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = Charset('iso-8859-1') 2970edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('hello w=F6rld', c.body_encode('hello w\xf6rld')) 2971edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try a charset with Base64 body encoding 2972edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = Charset('utf-8') 2973edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('aGVsbG8gd29ybGQ=\n', c.body_encode('hello world')) 2974edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try a charset with None body encoding 2975edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = Charset('us-ascii') 2976edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('hello world', c.body_encode('hello world')) 2977edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Try the convert argument, where input codec != output codec 2978edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = Charset('euc-jp') 2979edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # With apologies to Tokio Kikuchi ;) 2980edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 2981edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('\x1b$B5FCO;~IW\x1b(B', 2982edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7')) 2983edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7', 2984edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7', False)) 2985edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except LookupError: 2986edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # We probably don't have the Japanese codecs installed 2987edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep pass 2988edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Testing SF bug #625509, which we have to fake, since there are no 2989edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # built-in encodings where the header encoding is QP but the body 2990edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # encoding is not. 2991edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep from email import Charset as CharsetModule 2992edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep CharsetModule.add_charset('fake', CharsetModule.QP, None) 2993edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep c = Charset('fake') 2994edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq('hello w\xf6rld', c.body_encode('hello w\xf6rld')) 2995edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 2996edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_unicode_charset_name(self): 2997edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset = Charset(u'us-ascii') 2998edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(str(charset), 'us-ascii') 2999edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertRaises(Errors.CharsetError, Charset, 'asc\xffii') 3000edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3001edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_codecs_aliases_accepted(self): 3002edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset = Charset('utf8') 3003edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(str(charset), 'utf-8') 3004edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3005edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3006edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test multilingual MIME headers. 3007edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestHeader(TestEmailBase): 3008edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_simple(self): 3009edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 3010edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header('Hello World!') 3011edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), 'Hello World!') 3012edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append(' Goodbye World!') 3013edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), 'Hello World! Goodbye World!') 3014edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3015edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_simple_surprise(self): 3016edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 3017edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header('Hello World!') 3018edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), 'Hello World!') 3019edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('Goodbye World!') 3020edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), 'Hello World! Goodbye World!') 3021edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3022edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_needs_no_decoding(self): 3023edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = 'no decoding needed' 3024edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(decode_header(h), [(h, None)]) 3025edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3026edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long(self): 3027edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header("I am the very model of a modern Major-General; I've information vegetable, animal, and mineral; I know the kings of England, and I quote the fights historical from Marathon to Waterloo, in order categorical; I'm very well acquainted, too, with matters mathematical; I understand equations, both the simple and quadratical; about binomial theorem I'm teeming with a lot o' news, with many cheerful facts about the square of the hypotenuse.", 3028edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep maxlinelen=76) 3029edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for l in h.encode(splitchars=' ').split('\n '): 3030edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(len(l) <= 76) 3031edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3032edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_multilingual(self): 3033edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 3034edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g = Charset("iso-8859-1") 3035edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cz = Charset("iso-8859-2") 3036edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep utf8 = Charset("utf-8") 3037edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep g_head = "Die Mieter treten hier ein werden mit einem Foerderband komfortabel den Korridor entlang, an s\xfcdl\xfcndischen Wandgem\xe4lden vorbei, gegen die rotierenden Klingen bef\xf6rdert. " 3038edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " 3039edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep utf8_head = u"\u6b63\u78ba\u306b\u8a00\u3046\u3068\u7ffb\u8a33\u306f\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002\u4e00\u90e8\u306f\u30c9\u30a4\u30c4\u8a9e\u3067\u3059\u304c\u3001\u3042\u3068\u306f\u3067\u305f\u3089\u3081\u3067\u3059\u3002\u5b9f\u969b\u306b\u306f\u300cWenn ist das Nunstuck git und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt gersput.\u300d\u3068\u8a00\u3063\u3066\u3044\u307e\u3059\u3002".encode("utf-8") 3040edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(g_head, g) 3041edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append(cz_head, cz) 3042edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append(utf8_head, utf8) 3043edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep enc = h.encode() 3044edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(enc, """\ 3045edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?= 3046edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wan?= 3047edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?dgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef=F6?= 3048edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-1?q?rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutily?= 3049edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?iso-8859-2?q?_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j56K6?= 3050edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT44CC?= 3051edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv44Gn?= 3052edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGFz?= 3053edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?q?_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_die_Fl?= 3054edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?aXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBo+OBpuOBhOOBvuOBmQ==?= 3055edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep =?utf-8?b?44CC?=""") 3056edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(decode_header(enc), 3057edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), 3058edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep (utf8_head, "utf-8")]) 3059edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ustr = unicode(h) 3060edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(ustr.encode('utf-8'), 3061edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Die Mieter treten hier ein werden mit einem Foerderband ' 3062edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'komfortabel den Korridor entlang, an s\xc3\xbcdl\xc3\xbcndischen ' 3063edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Wandgem\xc3\xa4lden vorbei, gegen die rotierenden Klingen ' 3064edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'bef\xc3\xb6rdert. Finan\xc4\x8dni metropole se hroutily pod ' 3065edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'tlakem jejich d\xc5\xafvtipu.. \xe6\xad\xa3\xe7\xa2\xba\xe3\x81' 3066edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\xab\xe8\xa8\x80\xe3\x81\x86\xe3\x81\xa8\xe7\xbf\xbb\xe8\xa8\xb3' 3067edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\xe3\x81\xaf\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3' 3068edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x80\x82\xe4\xb8\x80\xe9\x83' 3069edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\xa8\xe3\x81\xaf\xe3\x83\x89\xe3\x82\xa4\xe3\x83\x84\xe8\xaa\x9e' 3070edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\xe3\x81\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\xe3\x81\x82\xe3' 3071edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\x81\xa8\xe3\x81\xaf\xe3\x81\xa7\xe3\x81\x9f\xe3\x82\x89\xe3\x82' 3072edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\x81\xe3\x81\xa7\xe3\x81\x99\xe3\x80\x82\xe5\xae\x9f\xe9\x9a\x9b' 3073edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x8cWenn ist das Nunstuck git ' 3074edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt ' 3075edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'gersput.\xe3\x80\x8d\xe3\x81\xa8\xe8\xa8\x80\xe3\x81\xa3\xe3\x81' 3076edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep '\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82') 3077edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Test make_header() 3078edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep newh = make_header(decode_header(enc)) 3079edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(newh, enc) 3080edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3081edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_header_ctor_default_args(self): 3082edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 3083edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header() 3084edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h, '') 3085edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('foo', Charset('iso-8859-1')) 3086edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h, '=?iso-8859-1?q?foo?=') 3087edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3088edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_explicit_maxlinelen(self): 3089edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 3090edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hstr = 'A very long line that must get split to something other than at the 76th character boundary to test the non-default behavior' 3091edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr) 3092edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), '''\ 3093edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepA very long line that must get split to something other than at the 76th 3094edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep character boundary to test the non-default behavior''') 3095edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr, header_name='Subject') 3096edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), '''\ 3097edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepA very long line that must get split to something other than at the 3098edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 76th character boundary to test the non-default behavior''') 3099edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(hstr, maxlinelen=1024, header_name='Subject') 3100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), hstr) 3101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_us_ascii_header(self): 3103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'hello' 3105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = decode_header(s) 3106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(x, [('hello', None)]) 3107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = make_header(x) 3108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, h.encode()) 3109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_string_charset(self): 3111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header() 3113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('hello', 'iso-8859-1') 3114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h, '=?iso-8859-1?q?hello?=') 3115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## def test_unicode_error(self): 3117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## raises = self.assertRaises 3118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## raises(UnicodeError, Header, u'[P\xf6stal]', 'us-ascii') 3119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## raises(UnicodeError, Header, '[P\xf6stal]', 'us-ascii') 3120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## h = Header() 3121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## raises(UnicodeError, h.append, u'[P\xf6stal]', 'us-ascii') 3122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## raises(UnicodeError, h.append, '[P\xf6stal]', 'us-ascii') 3123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep## raises(UnicodeError, Header, u'\u83ca\u5730\u6642\u592b', 'iso-8859-1') 3124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_utf8_shortest(self): 3126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(u'p\xf6stal', 'utf-8') 3128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), '=?utf-8?q?p=C3=B6stal?=') 3129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header(u'\u83ca\u5730\u6642\u592b', 'utf-8') 3130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), '=?utf-8?b?6I+K5Zyw5pmC5aSr?=') 3131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_bad_8bit_header(self): 3133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raises = self.assertRaises 3134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep x = 'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' 3136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raises(UnicodeError, Header, x) 3137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header() 3138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raises(UnicodeError, h.append, x) 3139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(str(Header(x, errors='replace')), x) 3140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append(x, errors='replace') 3141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(str(h), x) 3142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encoded_adjacent_nonencoded(self): 3144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = Header() 3146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('hello', 'iso-8859-1') 3147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h.append('world') 3148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = h.encode() 3149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, '=?iso-8859-1?q?hello?= world') 3150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep h = make_header(decode_header(s)) 3151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(h.encode(), s) 3152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_whitespace_eater(self): 3154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztk=?= =?koi8-r?q?=CA?= zz.' 3156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep parts = decode_header(s) 3157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(parts, [('Subject:', None), ('\xf0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 \xce\xc1 \xc6\xc9\xce\xc1\xcc\xd8\xce\xd9\xca', 'koi8-r'), ('zz.', None)]) 3158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep hdr = make_header(parts) 3159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(hdr.encode(), 3160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztnK?= zz.') 3161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_broken_base64_header(self): 3163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raises = self.assertRaises 3164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3I ?=' 3165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raises(Errors.HeaderParseError, decode_header, s) 3166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Issue 1078919 3168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_ascii_add_header(self): 3169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 3170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('Content-Disposition', 'attachment', 3171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filename='bud.gif') 3172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual('attachment; filename="bud.gif"', 3173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Disposition']) 3174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_nonascii_add_header_via_triple(self): 3176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 3177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.add_header('Content-Disposition', 'attachment', 3178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep filename=('iso-8859-1', '', 'Fu\xdfballer.ppt')) 3179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 3180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'attachment; filename*="iso-8859-1\'\'Fu%DFballer.ppt"', 3181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg['Content-Disposition']) 3182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_encode_unaliased_charset(self): 3184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Issue 1379416: when the charset has no output conversion, 3185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # output was accidentally getting coerced to unicode. 3186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep res = Header('abc','iso-8859-2').encode() 3187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(res, '=?iso-8859-2?q?abc?=') 3188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertIsInstance(res, str) 3189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Test RFC 2231 header parameters (en/de)coding 3192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestRFC2231(TestEmailBase): 3193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_get_param(self): 3194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_29.txt') 3196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('title'), 3197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!')) 3198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('title', unquote=False), 3199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('us-ascii', 'en', '"This is even more ***fun*** isn\'t it!"')) 3200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_set_param(self): 3202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = Message() 3204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 3205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset='us-ascii') 3206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('title'), 3207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('us-ascii', '', 'This is even more ***fun*** isn\'t it!')) 3208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 3209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset='us-ascii', language='en') 3210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('title'), 3211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!')) 3212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 3213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 3214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset='us-ascii', language='en') 3215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.ndiffAssertEqual(msg.as_string(), """\ 3216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReturn-Path: <bbb@zzz.org> 3217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDelivered-To: bbb@zzz.org 3218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived: by mail.zzz.org (Postfix, from userid 889) 3219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) 3220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 3221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 3222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMessage-ID: <15090.61304.110929.45684@aaa.zzz.org> 3223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bbb@ddd.com (John X. Doe) 3224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: bbb@zzz.org 3225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: This is a test message 3226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDate: Fri, 4 May 2001 14:05:44 -0400 3227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset=us-ascii; 3228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep title*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21" 3229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHi, 3232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDo you like this message? 3234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-Me 3236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 3237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_del_param(self): 3239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.ndiffAssertEqual 3240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_01.txt') 3241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('foo', 'bar', charset='us-ascii', language='en') 3242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 3243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset='us-ascii', language='en') 3244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.del_param('foo', header='Content-Type') 3245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.as_string(), """\ 3246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReturn-Path: <bbb@zzz.org> 3247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDelivered-To: bbb@zzz.org 3248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepReceived: by mail.zzz.org (Postfix, from userid 889) 3249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) 3250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMIME-Version: 1.0 3251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 7bit 3252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepMessage-ID: <15090.61304.110929.45684@aaa.zzz.org> 3253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepFrom: bbb@ddd.com (John X. Doe) 3254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepTo: bbb@zzz.org 3255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepSubject: This is a test message 3256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDate: Fri, 4 May 2001 14:05:44 -0400 3257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset="us-ascii"; 3258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep title*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21" 3259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepHi, 3262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepDo you like this message? 3264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep-Me 3266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""") 3267edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3268edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_get_content_charset(self): 3269edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3270edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = self._msgobj('msg_32.txt') 3271edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_content_charset(), 'us-ascii') 3272edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3273edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_no_language_or_charset(self): 3274edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3275edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 8bit 3276edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; filename="file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm" 3277edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/html; NAME*0=file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEM; NAME*1=P_nsmail.htm 3278edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3279edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3280edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3281edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep param = msg.get_param('NAME') 3282edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertFalse(isinstance(param, tuple)) 3283edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 3284edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep param, 3285edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm') 3286edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3287edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_no_language_or_charset_in_filename(self): 3288edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3289edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; 3290edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*0*="''This%20is%20even%20more%20"; 3291edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 3292edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*2="is it not.pdf" 3293edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3294edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3295edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3296edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_filename(), 3297edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is even more ***fun*** is it not.pdf') 3298edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3299edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_no_language_or_charset_in_filename_encoded(self): 3300edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3301edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; 3302edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*0*="''This%20is%20even%20more%20"; 3303edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 3304edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*2="is it not.pdf" 3305edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3306edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3307edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3308edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_filename(), 3309edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is even more ***fun*** is it not.pdf') 3310edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3311edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_partly_encoded(self): 3312edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3313edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; 3314edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*0="''This%20is%20even%20more%20"; 3315edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 3316edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*2="is it not.pdf" 3317edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3318edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3319edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3320edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 3321edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.get_filename(), 3322edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This%20is%20even%20more%20***fun*** is it not.pdf') 3323edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3324edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_partly_nonencoded(self): 3325edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3326edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; 3327edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*0="This%20is%20even%20more%20"; 3328edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20"; 3329edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*2="is it not.pdf" 3330edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3331edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3332edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3333edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual( 3334edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg.get_filename(), 3335edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf') 3336edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3337edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_no_language_or_charset_in_boundary(self): 3338edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3339edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: multipart/alternative; 3340edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tboundary*0*="''This%20is%20even%20more%20"; 3341edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20"; 3342edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tboundary*2="is it not.pdf" 3343edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3344edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3345edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3346edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_boundary(), 3347edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is even more ***fun*** is it not.pdf') 3348edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3349edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_no_language_or_charset_in_charset(self): 3350edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This is a nonsensical charset value, but tests the code anyway 3351edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3352edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; 3353edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tcharset*0*="This%20is%20even%20more%20"; 3354edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20"; 3355edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tcharset*2="is it not.pdf" 3356edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3357edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3358edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3359edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_charset(), 3360edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'this is even more ***fun*** is it not.pdf') 3361edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3362edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_bad_encoding_in_filename(self): 3363edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3364edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; 3365edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*0*="bogus'xx'This%20is%20even%20more%20"; 3366edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 3367edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*2="is it not.pdf" 3368edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3369edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3370edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3371edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_filename(), 3372edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'This is even more ***fun*** is it not.pdf') 3373edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3374edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_bad_encoding_in_charset(self): 3375edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3376edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset*=bogus''utf-8%E2%80%9D 3377edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3378edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3379edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3380edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This should return None because non-ascii characters in the charset 3381edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # are not allowed. 3382edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_charset(), None) 3383edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3384edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_bad_character_in_charset(self): 3385edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3386edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: text/plain; charset*=ascii''utf-8%E2%80%9D 3387edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3388edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3389edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3390edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # This should return None because non-ascii characters in the charset 3391edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # are not allowed. 3392edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_content_charset(), None) 3393edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3394edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_bad_character_in_filename(self): 3395edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = '''\ 3396edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; 3397edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*0*="ascii'xx'This%20is%20even%20more%20"; 3398edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 3399edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tfilename*2*="is it not.pdf%E2" 3400edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3401edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 3402edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3403edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_filename(), 3404edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep u'This is even more ***fun*** is it not.pdf\ufffd') 3405edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3406edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_unknown_encoding(self): 3407edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3408edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Transfer-Encoding: 8bit 3409edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Disposition: inline; filename*=X-UNKNOWN''myfile.txt 3410edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3411edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3412edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3413edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(msg.get_filename(), 'myfile.txt') 3414edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3415edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_single_tick_in_filename_extended(self): 3416edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3417edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3418edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: application/x-foo; 3419edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*0*=\"Frank's\"; name*1*=\" Document\" 3420edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3421edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3422edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3423edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset, language, s = msg.get_param('name') 3424edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charset, None) 3425edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(language, None) 3426edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, "Frank's Document") 3427edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3428edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_single_tick_in_filename(self): 3429edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3430edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\" 3431edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3432edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3433edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3434edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep param = msg.get_param('name') 3435edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertFalse(isinstance(param, tuple)) 3436edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(param, "Frank's Document") 3437edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3438edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_tick_attack_extended(self): 3439edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3440edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3441edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: application/x-foo; 3442edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\" 3443edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3444edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3445edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3446edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset, language, s = msg.get_param('name') 3447edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charset, 'us-ascii') 3448edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(language, 'en-us') 3449edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, "Frank's Document") 3450edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3451edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_tick_attack(self): 3452edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3453edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: application/x-foo; 3454edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\" 3455edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3456edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3457edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3458edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep param = msg.get_param('name') 3459edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertFalse(isinstance(param, tuple)) 3460edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(param, "us-ascii'en-us'Frank's Document") 3461edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3462edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_no_extended_values(self): 3463edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3464edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3465edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: application/x-foo; name=\"Frank's Document\" 3466edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3467edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3468edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3469edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(msg.get_param('name'), "Frank's Document") 3470edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3471edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_encoded_then_unencoded_segments(self): 3472edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3473edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3474edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: application/x-foo; 3475edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*0*=\"us-ascii'en-us'My\"; 3476edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*1=\" Document\"; 3477edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*2*=\" For You\" 3478edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3479edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3480edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3481edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset, language, s = msg.get_param('name') 3482edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charset, 'us-ascii') 3483edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(language, 'en-us') 3484edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, 'My Document For You') 3485edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3486edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_rfc2231_unencoded_then_encoded_segments(self): 3487edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq = self.assertEqual 3488edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep m = """\ 3489edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander StoepContent-Type: application/x-foo; 3490edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*0=\"us-ascii'en-us'My\"; 3491edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*1*=\" Document\"; 3492edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep\tname*2*=\" For You\" 3493edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3494edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3495edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(m) 3496edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep charset, language, s = msg.get_param('name') 3497edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(charset, 'us-ascii') 3498edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(language, 'en-us') 3499edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep eq(s, 'My Document For You') 3500edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3501edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3502edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3503edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Tests to ensure that signed parts of an email are completely preserved, as 3504edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# required by RFC1847 section 2.1. Note that these are incomplete, because the 3505edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# email package does not currently always preserve the body. See issue 1670765. 3506edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass TestSigned(TestEmailBase): 3507edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3508edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _msg_and_obj(self, filename): 3509edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = openfile(findfile(filename)) 3510edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 3511edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep original = fp.read() 3512edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep msg = email.message_from_string(original) 3513edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 3514edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp.close() 3515edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return original, msg 3516edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3517edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _signed_parts_eq(self, original, result): 3518edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Extract the first mime part of each message 3519edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep import re 3520edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep repart = re.compile(r'^--([^\n]+)\n(.*?)\n--\1$', re.S | re.M) 3521edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep inpart = repart.search(original).group(2) 3522edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep outpart = repart.search(result).group(2) 3523edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(outpart, inpart) 3524edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3525edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_headers_as_string(self): 3526edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep original, msg = self._msg_and_obj('msg_45.txt') 3527edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = msg.as_string() 3528edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._signed_parts_eq(original, result) 3529edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3530edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test_long_headers_flatten(self): 3531edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep original, msg = self._msg_and_obj('msg_45.txt') 3532edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep fp = StringIO() 3533edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Generator(fp).flatten(msg) 3534edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = fp.getvalue() 3535edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._signed_parts_eq(original, result) 3536edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3537edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3538edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3539edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _testclasses(): 3540edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep mod = sys.modules[__name__] 3541edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')] 3542edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3543edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3544edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef suite(): 3545edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep suite = unittest.TestSuite() 3546edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for testclass in _testclasses(): 3547edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep suite.addTest(unittest.makeSuite(testclass)) 3548edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return suite 3549edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3550edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3551edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef test_main(): 3552edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for testclass in _testclasses(): 3553edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep run_unittest(testclass) 3554edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3555edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3556edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 3557edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepif __name__ == '__main__': 3558edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unittest.main(defaultTest='suite') 3559