10c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Copyright (C) 2001-2007 Python Software Foundation 20c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Contact: email-sig@python.org 30c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# email package unit tests 40c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 50c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport os 60c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport sys 70c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport time 80c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport base64 90c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport difflib 100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport unittest 110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport warnings 120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom cStringIO import StringIO 130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiimport email 150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.charset import Charset 170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.header import Header, decode_header, make_header 180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.parser import Parser, HeaderParser 190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.generator import Generator, DecodedGenerator 200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.message import Message 210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.mime.application import MIMEApplication 220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.mime.audio import MIMEAudio 230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.mime.text import MIMEText 240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.mime.image import MIMEImage 250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.mime.base import MIMEBase 260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.mime.message import MIMEMessage 270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.mime.multipart import MIMEMultipart 280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email import utils 290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email import errors 300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email import encoders 310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email import iterators 320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email import base64mime 330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email import quoprimime 340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom test.test_support import findfile, run_unittest 360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom email.test import __file__ as landmark 370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiNL = '\n' 400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiEMPTYSTRING = '' 410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSPACE = ' ' 420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef openfile(filename, mode='r'): 460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi path = os.path.join(os.path.dirname(landmark), 'data', filename) 470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return open(path, mode) 480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Base test class 520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestEmailBase(unittest.TestCase): 530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def ndiffAssertEqual(self, first, second): 540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Like assertEqual except use ndiff for readable output.""" 550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if first != second: 560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfirst = str(first) 570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ssecond = str(second) 580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi diff = difflib.ndiff(sfirst.splitlines(), ssecond.splitlines()) 590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = StringIO() 600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi print >> fp, NL, NL.join(diff) 610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raise self.failureException, fp.getvalue() 620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _msgobj(self, filename): 640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile(findfile(filename)) 650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_file(fp) 670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return msg 700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test various aspects of the Message class's API 740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMessageAPI(TestEmailBase): 750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_all(self): 760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_20.txt') 780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_all('cc'), ['ccc@zzz.org', 'ddd@zzz.org', 'eee@zzz.org']) 790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_all('xx', 'n/a'), 'n/a') 800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_getset_charset(self): 820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_charset(), None) 850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset = Charset('iso-8859-1') 860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_charset(charset) 870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['mime-version'], '1.0') 880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'text/plain') 890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/plain; charset="iso-8859-1"') 900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('charset'), 'iso-8859-1') 910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], 'quoted-printable') 920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_charset().input_charset, 'iso-8859-1') 930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Remove the charset 940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_charset(None) 950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_charset(), None) 960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/plain') 970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try adding a charset when there's already MIME headers present 980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['MIME-Version'] = '2.0' 1000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'text/x-weird' 1010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Transfer-Encoding'] = 'quinted-puntable' 1020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_charset(charset) 1030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['mime-version'], '2.0') 1040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/x-weird; charset="iso-8859-1"') 1050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], 'quinted-puntable') 1060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_set_charset_from_string(self): 1080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 1090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 1100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_charset('us-ascii') 1110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_charset().input_charset, 'us-ascii') 1120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/plain; charset="us-ascii"') 1130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_set_payload_with_charset(self): 1150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 1160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset = Charset('iso-8859-1') 1170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_payload('This is a string payload', charset) 1180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_charset().input_charset, 'iso-8859-1') 1190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_charsets(self): 1210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 1220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_08.txt') 1240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charsets = msg.get_charsets() 1250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charsets, [None, 'us-ascii', 'iso-8859-1', 'iso-8859-2', 'koi8-r']) 1260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_09.txt') 1280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charsets = msg.get_charsets('dingbat') 1290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charsets, ['dingbat', 'us-ascii', 'iso-8859-1', 'dingbat', 1300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'koi8-r']) 1310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_12.txt') 1330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charsets = msg.get_charsets() 1340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charsets, [None, 'us-ascii', 'iso-8859-1', None, 'iso-8859-2', 1350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'iso-8859-3', 'us-ascii', 'koi8-r']) 1360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_filename(self): 1380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 1390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_04.txt') 1410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi filenames = [p.get_filename() for p in msg.get_payload()] 1420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(filenames, ['msg.txt', 'msg.txt']) 1430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_07.txt') 1450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart = msg.get_payload(1) 1460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart.get_filename(), 'dingusfish.gif') 1470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_filename_with_name_parameter(self): 1490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 1500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_44.txt') 1520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi filenames = [p.get_filename() for p in msg.get_payload()] 1530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(filenames, ['msg.txt', 'msg.txt']) 1540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_boundary(self): 1560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 1570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_07.txt') 1580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # No quotes! 1590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_boundary(), 'BOUNDARY') 1600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_set_boundary(self): 1620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 1630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This one has no existing boundary parameter, but the Content-Type: 1640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # header appears fifth. 1650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 1660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_boundary('BOUNDARY') 1670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header, value = msg.items()[4] 1680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(header.lower(), 'content-type') 1690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(value, 'text/plain; charset="us-ascii"; boundary="BOUNDARY"') 1700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This one has a Content-Type: header, with a boundary, stuck in the 1710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # middle of its headers. Make sure the order is preserved; it should 1720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # be fifth. 1730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_04.txt') 1740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_boundary('BOUNDARY') 1750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header, value = msg.items()[4] 1760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(header.lower(), 'content-type') 1770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(value, 'multipart/mixed; boundary="BOUNDARY"') 1780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # And this one has no Content-Type: header at all. 1790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_03.txt') 1800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(errors.HeaderParseError, 1810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_boundary, 'BOUNDARY') 1820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 1830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_decoded_payload(self): 1840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 1850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_10.txt') 1860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The outer message is a multipart 1870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(decode=True), None) 1880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 1 is 7bit encoded 1890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(0).get_payload(decode=True), 1900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is a 7bit encoded message.\n') 1910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 2 is quopri 1920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(1).get_payload(decode=True), 1930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\xa1This is a Quoted Printable encoded message!\n') 1940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 3 is base64 1950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(2).get_payload(decode=True), 1960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is a Base64 encoded message.') 1970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 4 is base64 with a trailing newline, which 1980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # used to be stripped (issue 7143). 1990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(3).get_payload(decode=True), 2000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is a Base64 encoded message.\n') 2010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 5 has no Content-Transfer-Encoding: header. 2020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(4).get_payload(decode=True), 2030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This has no Content-Transfer-Encoding: header.\n') 2040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_decoded_uu_payload(self): 2060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 2070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 2080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_payload('begin 666 -\n+:&5L;&\\@=V]R;&0 \n \nend\n') 2090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for cte in ('x-uuencode', 'uuencode', 'uue', 'x-uue'): 2100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['content-transfer-encoding'] = cte 2110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(decode=True), 'hello world') 2120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Now try some bogus data 2130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_payload('foo') 2140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(decode=True), 'foo') 2150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_decoded_generator(self): 2170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 2180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_07.txt') 2190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_17.txt') 2200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 2210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = fp.read() 2220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 2230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 2240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 2250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = DecodedGenerator(s) 2260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 2270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s.getvalue(), text) 2280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test__contains__(self): 2300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 2310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['From'] = 'Me' 2320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['to'] = 'You' 2330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check for case insensitivity 2340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue('from' in msg) 2350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue('From' in msg) 2360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue('FROM' in msg) 2370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue('to' in msg) 2380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue('To' in msg) 2390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue('TO' in msg) 2400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_as_string(self): 2420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 2430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 2440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_01.txt') 2450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 2460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # BAW 30-Mar-2009 Evil be here. So, the generator is broken with 2470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # respect to long line breaking. It's also not idempotent when a 2480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # header from a parsed message is continued with tabs rather than 2490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # spaces. Before we fixed bug 1974 it was reversedly broken, 2500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # i.e. headers that were continued with spaces got continued with 2510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # tabs. For Python 2.x there's really no good fix and in Python 2520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 3.x all this stuff is re-written to be right(er). Chris Withers 2530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # convinced me that using space as the default continuation 2540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # character is less bad for more applications. 2550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = fp.read().replace('\t', ' ') 2560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 2570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 2580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(text, msg.as_string()) 2590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fullrepr = str(msg) 2600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines = fullrepr.split('\n') 2610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(lines[0].startswith('From ')) 2620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(text, NL.join(lines[1:])) 2630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_bad_param(self): 2650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string("Content-Type: blarg; baz; boo\n") 2660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_param('baz'), '') 2670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_missing_filename(self): 2690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string("From: foo\n") 2700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_filename(), None) 2710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_bogus_filename(self): 2730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string( 2740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "Content-Disposition: blarg; filename\n") 2750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_filename(), '') 2760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_missing_boundary(self): 2780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string("From: foo\n") 2790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_boundary(), None) 2800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_params(self): 2820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 2830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string( 2840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'X-Header: foo=one; bar=two; baz=three\n') 2850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(header='x-header'), 2860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('foo', 'one'), ('bar', 'two'), ('baz', 'three')]) 2870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string( 2880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'X-Header: foo; bar=one; baz=two\n') 2890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(header='x-header'), 2900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('foo', ''), ('bar', 'one'), ('baz', 'two')]) 2910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(), None) 2920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string( 2930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'X-Header: foo; bar="one"; baz=two\n') 2940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(header='x-header'), 2950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('foo', ''), ('bar', 'one'), ('baz', 'two')]) 2960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 2970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_param_liberal(self): 2980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 2990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'Content-Type: Multipart/mixed; boundary = "CPIMSSMTPC06p5f3tG"' 3000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_param('boundary'), 'CPIMSSMTPC06p5f3tG') 3010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_param(self): 3030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 3040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string( 3050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "X-Header: foo=one; bar=two; baz=three\n") 3060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('bar', header='x-header'), 'two') 3070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('quuz', header='x-header'), None) 3080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('quuz'), None) 3090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string( 3100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'X-Header: foo; bar="one"; baz=two\n') 3110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('foo', header='x-header'), '') 3120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('bar', header='x-header'), 'one') 3130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('baz', header='x-header'), 'two') 3140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # XXX: We are not RFC-2045 compliant! We cannot parse: 3150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # msg["Content-Type"] = 'text/plain; weird="hey; dolly? [you] @ <\\"home\\">?"' 3160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # msg.get_param("weird") 3170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # yet. 3180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_param_funky_continuation_lines(self): 3200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_22.txt') 3210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(1).get_param('name'), 'wibble.JPG') 3220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_param_with_semis_in_quotes(self): 3240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string( 3250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Content-Type: image/pjpeg; name="Jim&&Jill"\n') 3260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_param('name'), 'Jim&&Jill') 3270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_param('name', unquote=False), 3280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '"Jim&&Jill"') 3290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_has_key(self): 3310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string('Header: exists') 3320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(msg.has_key('header')) 3330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(msg.has_key('Header')) 3340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(msg.has_key('HEADER')) 3350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertFalse(msg.has_key('headeri')) 3360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_set_param(self): 3380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 3390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 3400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('charset', 'iso-2022-jp') 3410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('charset'), 'iso-2022-jp') 3420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('importance', 'high value') 3430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('importance'), 'high value') 3440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('importance', unquote=False), '"high value"') 3450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(), [('text/plain', ''), 3460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('charset', 'iso-2022-jp'), 3470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('importance', 'high value')]) 3480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(unquote=False), [('text/plain', ''), 3490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('charset', '"iso-2022-jp"'), 3500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('importance', '"high value"')]) 3510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('charset', 'iso-9999-xx', header='X-Jimmy') 3520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('charset', header='X-Jimmy'), 'iso-9999-xx') 3530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_del_param(self): 3550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 3560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_05.txt') 3570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(), 3580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('multipart/report', ''), ('report-type', 'delivery-status'), 3590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('boundary', 'D1690A7AC1.996856090/mail.example.com')]) 3600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi old_val = msg.get_param("report-type") 3610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.del_param("report-type") 3620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(), 3630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('multipart/report', ''), 3640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('boundary', 'D1690A7AC1.996856090/mail.example.com')]) 3650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param("report-type", old_val) 3660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(), 3670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('multipart/report', ''), 3680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('boundary', 'D1690A7AC1.996856090/mail.example.com'), 3690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('report-type', old_val)]) 3700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_del_param_on_other_header(self): 3720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 3730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('Content-Disposition', 'attachment', filename='bud.gif') 3740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.del_param('filename', 'content-disposition') 3750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg['content-disposition'], 'attachment') 3760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_set_type(self): 3780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 3790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 3800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(ValueError, msg.set_type, 'text') 3810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_type('text/plain') 3820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/plain') 3830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('charset', 'us-ascii') 3840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/plain; charset="us-ascii"') 3850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_type('text/html') 3860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/html; charset="us-ascii"') 3870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_set_type_on_other_header(self): 3890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 3900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['X-Content-Type'] = 'text/plain' 3910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_type('application/octet-stream', 'X-Content-Type') 3920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg['x-content-type'], 'application/octet-stream') 3930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_type_missing(self): 3950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 3960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_type(), 'text/plain') 3970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 3980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_type_missing_with_default_type(self): 3990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_default_type('message/rfc822') 4010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_type(), 'message/rfc822') 4020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_type_from_message_implicit(self): 4040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_30.txt') 4050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(0).get_content_type(), 4060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'message/rfc822') 4070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_type_from_message_explicit(self): 4090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_28.txt') 4100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(0).get_content_type(), 4110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'message/rfc822') 4120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_type_from_message_text_plain_implicit(self): 4140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_03.txt') 4150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_type(), 'text/plain') 4160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_type_from_message_text_plain_explicit(self): 4180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 4190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_type(), 'text/plain') 4200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_maintype_missing(self): 4220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_maintype(), 'text') 4240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_maintype_missing_with_default_type(self): 4260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_default_type('message/rfc822') 4280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_maintype(), 'message') 4290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_maintype_from_message_implicit(self): 4310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_30.txt') 4320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message') 4330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_maintype_from_message_explicit(self): 4350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_28.txt') 4360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(0).get_content_maintype(), 'message') 4370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_maintype_from_message_text_plain_implicit(self): 4390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_03.txt') 4400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_maintype(), 'text') 4410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_maintype_from_message_text_plain_explicit(self): 4430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 4440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_maintype(), 'text') 4450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_subtype_missing(self): 4470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_subtype(), 'plain') 4490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_subtype_missing_with_default_type(self): 4510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_default_type('message/rfc822') 4530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_subtype(), 'rfc822') 4540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_subtype_from_message_implicit(self): 4560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_30.txt') 4570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822') 4580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_subtype_from_message_explicit(self): 4600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_28.txt') 4610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(0).get_content_subtype(), 'rfc822') 4620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_subtype_from_message_text_plain_implicit(self): 4640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_03.txt') 4650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_subtype(), 'plain') 4660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_subtype_from_message_text_plain_explicit(self): 4680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 4690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_subtype(), 'plain') 4700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_maintype_error(self): 4720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'no-slash-in-this-string' 4740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_maintype(), 'text') 4750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_content_subtype_error(self): 4770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'no-slash-in-this-string' 4790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_subtype(), 'plain') 4800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_replace_header(self): 4820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 4830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 4840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('First', 'One') 4850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('Second', 'Two') 4860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('Third', 'Three') 4870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.keys(), ['First', 'Second', 'Third']) 4880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.values(), ['One', 'Two', 'Three']) 4890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.replace_header('Second', 'Twenty') 4900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.keys(), ['First', 'Second', 'Third']) 4910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.values(), ['One', 'Twenty', 'Three']) 4920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('First', 'Eleven') 4930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.replace_header('First', 'One Hundred') 4940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.keys(), ['First', 'Second', 'Third', 'First']) 4950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.values(), ['One Hundred', 'Twenty', 'Three', 'Eleven']) 4960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(KeyError, msg.replace_header, 'Fourth', 'Missing') 4970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 4980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_broken_base64_payload(self): 4990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = 'AwDp0P7//y6LwKEAcPa/6Q=9' 5000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 5010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['content-type'] = 'audio/x-midi' 5020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['content-transfer-encoding'] = 'base64' 5030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_payload(x) 5040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(decode=True), x) 5050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the email.encoders module 5090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestEncoders(unittest.TestCase): 5100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_encode_empty_payload(self): 5110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 5120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 5130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_charset('us-ascii') 5140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], '7bit') 5150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_default_cte(self): 5170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 5180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 5190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], '7bit') 5200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_default_cte(self): 5220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 5230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # With no explicit _charset its us-ascii, and all are 7-bit 5240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 5250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], '7bit') 5260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Similar, but with 8-bit data 5270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello \xf8 world') 5280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], '8bit') 5290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # And now with a different charset 5300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello \xf8 world', _charset='iso-8859-1') 5310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], 'quoted-printable') 5320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test long header wrapping 5360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestLongHeaders(TestEmailBase): 5370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_split_long_continuation(self): 5380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 5390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string("""\ 5400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: bug demonstration 5410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 5420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tmore text 5430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitest 5450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 5460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 5470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(sfp) 5480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 5490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), """\ 5500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: bug demonstration 5510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 5520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi more text 5530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitest 5550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 5560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_another_long_almost_unsplittable_header(self): 5580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 5590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hstr = """\ 5600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yibug demonstration 5610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 5620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tmore text""" 5630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr, continuation_ws='\t') 5640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 5650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yibug demonstration 5660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\t12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 5670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tmore text""") 5680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr) 5690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 5700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yibug demonstration 5710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12345678911234567892123456789312345678941234567895123456789612345678971234567898112345678911234567892123456789112345678911234567892123456789 5720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi more text""") 5730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 5740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_nonstring(self): 5750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 5760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Charset("iso-8859-1") 5770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cz = Charset("iso-8859-2") 5780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utf8 = Charset("utf-8") 5790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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. " 5800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " 5810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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") 5820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(g_head, g, header_name='Subject') 5830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append(cz_head, cz) 5840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append(utf8_head, utf8) 5850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 5860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Subject'] = h 5870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 5880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(sfp) 5890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 5900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), """\ 5910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: =?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= 5920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= 5930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= 5940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= 5950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= 5960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= 5970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= 5980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= 5990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= 6000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= 6010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44Gm44GE44G+44GZ44CC?= 6020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 6040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 6050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerd?= 6060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?erband_komfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndi?= 6070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?schen_Wandgem=E4lden_vorbei=2C_gegen_die_rotierenden_Kling?= 6080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?en_bef=F6rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_met?= 6090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-2?q?ropole_se_hroutily_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= 6100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?5q2j56K644Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE?= 6110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44G+44Gb44KT44CC5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB?= 6120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44GC44Go44Gv44Gn44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CM?= 6130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?q?Wenn_ist_das_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das?= 6140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?IE9kZXIgZGllIEZsaXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBow==?= 6150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44Gm44GE44G+44GZ44CC?=""") 6160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_header_encode(self): 6180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 6190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header('wasnipoop; giraffes="very-long-necked-animals"; ' 6200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"', 6210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header_name='X-Foobar-Spoink-Defrobnit') 6220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), '''\ 6230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiwasnipoop; giraffes="very-long-necked-animals"; 6240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''') 6250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_header_encode_with_tab_continuation(self): 6270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 6280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header('wasnipoop; giraffes="very-long-necked-animals"; ' 6290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"', 6300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header_name='X-Foobar-Spoink-Defrobnit', 6310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi continuation_ws='\t') 6320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), '''\ 6330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiwasnipoop; giraffes="very-long-necked-animals"; 6340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tspooge="yummy"; hippos="gargantuan"; marshmallows="gooey"''') 6350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_splitter(self): 6370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 6380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('') 6390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # It'd be great if we could use add_header() here, but that doesn't 6400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # guarantee an order of the parameters. 6410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['X-Foobar-Spoink-Defrobnit'] = ( 6420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'wasnipoop; giraffes="very-long-necked-animals"; ' 6430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"') 6440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 6450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(sfp) 6460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 6470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), '''\ 6480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 6490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 6500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 6510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiX-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; 6520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi spooge="yummy"; hippos="gargantuan"; marshmallows="gooey" 6530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 6550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_semis_header_splitter(self): 6570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 6580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 6590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['From'] = 'test@dom.ain' 6600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['References'] = SPACE.join(['<%d@dom.ain>' % i for i in range(10)]) 6610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_payload('Test') 6620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 6630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(sfp) 6640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 6650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), """\ 6660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: test@dom.ain 6670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReferences: <0@dom.ain> <1@dom.ain> <2@dom.ain> <3@dom.ain> <4@dom.ain> 6680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi <5@dom.ain> <6@dom.ain> <7@dom.ain> <8@dom.ain> <9@dom.ain> 6690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTest""") 6710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_split_long_header(self): 6730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 6740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hstr = 'References: ' + 'x' * 80 6750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr, continuation_ws='\t') 6760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 6770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReferences: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx""") 6780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 6790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_splitting_multiple_long_lines(self): 6800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 6810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hstr = """\ 6820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom 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) 6830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\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) 6840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\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) 6850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 6860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr, continuation_ws='\t') 6870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 6880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom babylon.socal-raves.org (localhost [127.0.0.1]); 6890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; 6900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfor <mailman-admin@babylon.socal-raves.org>; 6910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tSat, 2 Feb 2002 17:00:06 -0800 (PST) 6920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); 6930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; 6940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfor <mailman-admin@babylon.socal-raves.org>; 6950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tSat, 2 Feb 2002 17:00:06 -0800 (PST) 6960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfrom babylon.socal-raves.org (localhost [127.0.0.1]); 6970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tby babylon.socal-raves.org (Postfix) with ESMTP id B570E51B81; 6980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfor <mailman-admin@babylon.socal-raves.org>; 6990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tSat, 2 Feb 2002 17:00:06 -0800 (PST)""") 7000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_splitting_first_line_only_is_long(self): 7020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 7030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hstr = """\ 7040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93] helo=cthulhu.gerg.ca) 7050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tby kronos.mems-exchange.org with esmtp (Exim 4.05) 7060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tid 17k4h5-00034i-00 7070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfor test@mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400""" 7080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr, maxlinelen=78, header_name='Received', 7090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi continuation_ws='\t') 7100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 7110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yifrom modemcable093.139-201-24.que.mc.videotron.ca ([24.201.139.93] 7120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\thelo=cthulhu.gerg.ca) 7130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tby kronos.mems-exchange.org with esmtp (Exim 4.05) 7140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tid 17k4h5-00034i-00 7150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfor test@mems-exchange.org; Wed, 28 Aug 2002 11:25:20 -0400""") 7160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_8bit_header(self): 7180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 7190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 7200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header('Britische Regierung gibt', 'iso-8859-1', 7210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header_name='Subject') 7220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte') 7230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Subject'] = h 7240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(), """\ 7250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: =?iso-8859-1?q?Britische_Regierung_gibt?= =?iso-8859-1?q?gr=FCnes?= 7260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?_Licht_f=FCr_Offshore-Windkraftprojekte?= 7270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 7290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_8bit_header_no_charset(self): 7310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 7320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 7330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Reply-To'] = 'Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address@example.com>' 7340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(), """\ 7350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReply-To: Britische Regierung gibt gr\xfcnes Licht f\xfcr Offshore-Windkraftprojekte <a-very-long-address@example.com> 7360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 7380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_to_header(self): 7400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 7410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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>' 7420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 7430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['To'] = to 7440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(0), '''\ 7450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: "Someone Test #A" <someone@eecs.umich.edu>, <someone@eecs.umich.edu>, 7460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "Someone Test #B" <someone@umich.edu>, 7470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "Someone Test #C" <someone@eecs.umich.edu>, 7480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi "Someone Test #D" <someone@eecs.umich.edu> 7490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 7510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_line_after_append(self): 7530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 7540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'This is an example of string which has almost the limit of header length.' 7550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(s) 7560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('Add another line.') 7570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 7580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiThis is an example of string which has almost the limit of header length. 7590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Add another line.""") 7600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_shorter_line_with_append(self): 7620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 7630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'This is a shorter line.' 7640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(s) 7650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('Add another sentence. (Surprise?)') 7660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), 7670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is a shorter line. Add another sentence. (Surprise?)') 7680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_field_name(self): 7700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 7710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fn = 'X-Very-Very-Very-Long-Header-Name' 7720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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. " 7730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(gs, 'iso-8859-1', header_name=fn) 7740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # BAW: this seems broken because the first line is too long 7750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), """\ 7760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi=?iso-8859-1?q?Die_Mieter_treten_hier_?= 7770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?ein_werden_mit_einem_Foerderband_komfortabel_den_Korridor_?= 7780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?entlang=2C_an_s=FCdl=FCndischen_Wandgem=E4lden_vorbei=2C_g?= 7790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?egen_die_rotierenden_Klingen_bef=F6rdert=2E_?=""") 7800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_received_header(self): 7820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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' 7830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 7840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Received-1'] = Header(h, continuation_ws='\t') 7850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Received-2'] = h 7860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(msg.as_string(), """\ 7870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived-1: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by 7880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\throthgar.la.mastaler.com (tmda-ofmipd) with ESMTP; 7890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tWed, 05 Mar 2003 18:10:18 -0700 7900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived-2: from FOO.TLD (vizworld.acl.foo.tld [123.452.678.9]) by 7910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hrothgar.la.mastaler.com (tmda-ofmipd) with ESMTP; 7920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Wed, 05 Mar 2003 18:10:18 -0700 7930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 7950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 7960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_string_headerinst_eq(self): 7970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = '<15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> (David Bremner\'s message of "Thu, 6 Mar 2003 13:58:21 +0100")' 7980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 7990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Received'] = Header(h, header_name='Received-1', 8000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi continuation_ws='\t') 8010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Received'] = h 8020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(msg.as_string(), """\ 8030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> 8040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\t(David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") 8050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived: <15975.17901.207240.414604@sgigritzmann1.mathematik.tu-muenchen.de> 8060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (David Bremner's message of "Thu, 6 Mar 2003 13:58:21 +0100") 8070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 8090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_unbreakable_lines_with_continuation(self): 8110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 8120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 8130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t = """\ 8140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 8150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp""" 8160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Face-1'] = t 8170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Face-2'] = Header(t, header_name='Face-2') 8180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(), """\ 8190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFace-1: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 8200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp 8210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFace-2: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEUAAAAkHiJeRUIcGBi9 8220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi locQDQ4zJykFBAXJfWDjAAACYUlEQVR4nF2TQY/jIAyFc6lydlG5x8Nyp1Y69wj1PN2I5gzp 8230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 8250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_another_long_multiline_header(self): 8270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 8280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 8290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with Microsoft SMTPSVC(5.0.2195.4905); 8300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Wed, 16 Oct 2002 07:41:11 -0700''' 8310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 8320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(), '''\ 8330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived: from siimage.com ([172.25.1.3]) by zima.siliconimage.com with 8340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Microsoft SMTPSVC(5.0.2195.4905); Wed, 16 Oct 2002 07:41:11 -0700 8350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 8370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_lines_with_different_header(self): 8390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 8400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = """\ 8410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiList-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>, 8420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi <mailto:spamassassin-talk-request@lists.sourceforge.net?subject=unsubscribe>""" 8430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 8440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['List'] = h 8450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['List'] = Header(h, header_name='List') 8460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(msg.as_string(), """\ 8470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiList: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>, 8480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi <mailto:spamassassin-talk-request@lists.sourceforge.net?subject=unsubscribe> 8490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiList: List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/spamassassin-talk>, 8500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi <mailto:spamassassin-talk-request@lists.sourceforge.net?subject=unsubscribe> 8510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 8530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test mangling of "From " lines in the body of a message 8570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestFromMangling(unittest.TestCase): 8580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUp(self): 8590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.msg = Message() 8600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.msg['From'] = 'aaa@bbb.org' 8610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.msg.set_payload("""\ 8620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom the desk of A.A.A.: 8630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiBlah blah blah 8640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 8650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_mangled_from(self): 8670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 8680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s, mangle_from_=True) 8690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(self.msg) 8700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(s.getvalue(), """\ 8710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: aaa@bbb.org 8720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi>From the desk of A.A.A.: 8740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiBlah blah blah 8750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 8760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_dont_mangle_from(self): 8780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 8790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s, mangle_from_=False) 8800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(self.msg) 8810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(s.getvalue(), """\ 8820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: aaa@bbb.org 8830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom the desk of A.A.A.: 8850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiBlah blah blah 8860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 8870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 8900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the basic MIMEAudio class 8910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMIMEAudio(unittest.TestCase): 8920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUp(self): 8930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Make sure we pick up the audiotest.au that lives in email/test/data. 8940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # In Python, there's an audiotest.au living in Lib/test but that isn't 8950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # included in some binary distros that don't include the test 8960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # package. The trailing empty string on the .join() is significant 8970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # since findfile() will do a dirname(). 8980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi datadir = os.path.join(os.path.dirname(landmark), 'data', '') 8990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = open(findfile('audiotest.au', datadir), 'rb') 9000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 9010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._audiodata = fp.read() 9020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 9030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 9040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._au = MIMEAudio(self._audiodata) 9050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_guess_minor_type(self): 9070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(self._au.get_content_type(), 'audio/basic') 9080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_encoding(self): 9100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = self._au.get_payload() 9110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(base64.decodestring(payload), self._audiodata) 9120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_checkSetMinor(self): 9140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi au = MIMEAudio(self._audiodata, 'fish') 9150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(au.get_content_type(), 'audio/fish') 9160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_add_header(self): 9180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 9190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 9200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._au.add_header('Content-Disposition', 'attachment', 9210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi filename='audiotest.au') 9220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._au['content-disposition'], 9230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'attachment; filename="audiotest.au"') 9240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._au.get_params(header='content-disposition'), 9250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('attachment', ''), ('filename', 'audiotest.au')]) 9260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._au.get_param('filename', header='content-disposition'), 9270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'audiotest.au') 9280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi missing = [] 9290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._au.get_param('attachment', header='content-disposition'), '') 9300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._au.get_param('foo', failobj=missing, 9310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header='content-disposition') is missing) 9320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try some missing stuff 9330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._au.get_param('foobar', missing) is missing) 9340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._au.get_param('attachment', missing, 9350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header='foobar') is missing) 9360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the basic MIMEImage class 9400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMIMEImage(unittest.TestCase): 9410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUp(self): 9420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('PyBanner048.gif') 9430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 9440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._imgdata = fp.read() 9450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 9460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 9470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._im = MIMEImage(self._imgdata) 9480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_guess_minor_type(self): 9500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(self._im.get_content_type(), 'image/gif') 9510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_encoding(self): 9530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = self._im.get_payload() 9540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(base64.decodestring(payload), self._imgdata) 9550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_checkSetMinor(self): 9570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi im = MIMEImage(self._imgdata, 'fish') 9580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(im.get_content_type(), 'image/fish') 9590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_add_header(self): 9610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 9620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 9630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._im.add_header('Content-Disposition', 'attachment', 9640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi filename='dingusfish.gif') 9650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._im['content-disposition'], 9660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'attachment; filename="dingusfish.gif"') 9670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._im.get_params(header='content-disposition'), 9680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('attachment', ''), ('filename', 'dingusfish.gif')]) 9690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._im.get_param('filename', header='content-disposition'), 9700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'dingusfish.gif') 9710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi missing = [] 9720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._im.get_param('attachment', header='content-disposition'), '') 9730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._im.get_param('foo', failobj=missing, 9740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header='content-disposition') is missing) 9750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try some missing stuff 9760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._im.get_param('foobar', missing) is missing) 9770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._im.get_param('attachment', missing, 9780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi header='foobar') is missing) 9790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the basic MIMEApplication class 9830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMIMEApplication(unittest.TestCase): 9840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_headers(self): 9850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 9860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEApplication('\xfa\xfb\xfc\xfd\xfe\xff') 9870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'application/octet-stream') 9880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], 'base64') 9890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_body(self): 9910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 9920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bytes = '\xfa\xfb\xfc\xfd\xfe\xff' 9930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEApplication(bytes) 9940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), '+vv8/f7/') 9950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(decode=True), bytes) 9960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 9970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_binary_body_with_encode_7or8bit(self): 9980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Issue 17171. 9990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bytesdata = b'\xfa\xfb\xfc\xfd\xfe\xff' 10000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEApplication(bytesdata, _encoder=encoders.encode_7or8bit) 10010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Treated as a string, this will be invalid code points. 10020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(), bytesdata) 10030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(decode=True), bytesdata) 10040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg['Content-Transfer-Encoding'], '8bit') 10050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 10060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s) 10070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 10080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi wireform = s.getvalue() 10090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg2 = email.message_from_string(wireform) 10100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(), bytesdata) 10110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg2.get_payload(decode=True), bytesdata) 10120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg2['Content-Transfer-Encoding'], '8bit') 10130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_binary_body_with_encode_noop(self): 10150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Issue 16564: This does not produce an RFC valid message, since to be 10160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # valid it should have a CTE of binary. But the below works, and is 10170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # documented as working this way. 10180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bytesdata = b'\xfa\xfb\xfc\xfd\xfe\xff' 10190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEApplication(bytesdata, _encoder=encoders.encode_noop) 10200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(), bytesdata) 10210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(decode=True), bytesdata) 10220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 10230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s) 10240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 10250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi wireform = s.getvalue() 10260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg2 = email.message_from_string(wireform) 10270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_payload(), bytesdata) 10280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg2.get_payload(decode=True), bytesdata) 10290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the basic MIMEText class 10320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMIMEText(unittest.TestCase): 10330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUp(self): 10340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._msg = MIMEText('hello there') 10350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_types(self): 10370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 10380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 10390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._msg.get_content_type(), 'text/plain') 10400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(self._msg.get_param('charset'), 'us-ascii') 10410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi missing = [] 10420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._msg.get_param('foobar', missing) is missing) 10430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(self._msg.get_param('charset', missing, header='foobar') 10440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi is missing) 10450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_payload(self): 10470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(self._msg.get_payload(), 'hello there') 10480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(not self._msg.is_multipart()) 10490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_charset(self): 10510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 10520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello there', _charset='us-ascii') 10530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_charset().input_charset, 'us-ascii') 10540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/plain; charset="us-ascii"') 10550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test complicated multipart/* messages 10590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMultipart(TestEmailBase): 10600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUp(self): 10610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('PyBanner048.gif') 10620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 10630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi data = fp.read() 10640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 10650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 10660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') 10680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi image = MIMEImage(data, name='dingusfish.gif') 10690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi image.add_header('content-disposition', 'attachment', 10700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi filename='dingusfish.gif') 10710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi intro = MIMEText('''\ 10720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHi there, 10730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiThis is the dingus fish. 10750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 10760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container.attach(intro) 10770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container.attach(image) 10780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container['From'] = 'Barry <barry@digicool.com>' 10790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container['To'] = 'Dingus Lovers <cravindogs@cravindogs.com>' 10800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container['Subject'] = 'Here is your dingus fish' 10810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 10820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi now = 987809702.54848599 10830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi timetuple = time.localtime(now) 10840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if timetuple[-1] == 0: 10850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tzsecs = time.timezone 10860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tzsecs = time.altzone 10880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if tzsecs > 0: 10890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = '-' 10900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else: 10910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sign = '+' 10920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi tzoffset = ' %s%04d' % (sign, tzsecs // 36) 10930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container['Date'] = time.strftime( 10940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '%a, %d %b %Y %H:%M:%S', 10950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi time.localtime(now)) + tzoffset 10960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._msg = container 10970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._im = image 10980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._txt = intro 10990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_hierarchy(self): 11010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # convenience 11020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 11030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 11040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raises = self.assertRaises 11050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # tests 11060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = self._msg 11070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(m.is_multipart()) 11080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(m.get_content_type(), 'multipart/mixed') 11090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(m.get_payload()), 2) 11100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raises(IndexError, m.get_payload, 2) 11110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m0 = m.get_payload(0) 11120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m1 = m.get_payload(1) 11130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(m0 is self._txt) 11140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(m1 is self._im) 11150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(m.get_payload(), [m0, m1]) 11160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(not m0.is_multipart()) 11170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(not m1.is_multipart()) 11180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_empty_multipart_idempotent(self): 11200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = """\ 11210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 11220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 11230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 11240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 11250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 11260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 11290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 11320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 11330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Parser().parsestr(text) 11340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(text, msg.as_string()) 11350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_parts_in_a_multipart_with_none_epilogue(self): 11370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 11380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 11390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 11400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 11410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 11420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(outer.as_string(), '''\ 11430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 11440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 11450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 11460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 11470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 11480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 11500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY--''') 11520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_parts_in_a_multipart_with_empty_epilogue(self): 11540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 11550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 11560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 11570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 11580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.preamble = '' 11590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.epilogue = '' 11600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 11610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(outer.as_string(), '''\ 11620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 11630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 11640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 11650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 11660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 11670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 11700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 11720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 11730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_one_part_in_a_multipart(self): 11750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 11760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 11770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 11780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 11790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 11800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 11810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 11820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.attach(msg) 11830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(outer.as_string(), '''\ 11840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 11850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 11860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 11870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 11880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 11890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 11910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 11920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 11930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 11940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yihello world 11960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY--''') 11970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 11980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_seq_parts_in_a_multipart_with_empty_preamble(self): 11990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 12000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 12010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 12020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 12030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 12040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.preamble = '' 12050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 12060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.attach(msg) 12070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 12080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(outer.as_string(), '''\ 12090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 12100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 12120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 12130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 12140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 12170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 12180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 12200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yihello world 12220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY--''') 12230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_seq_parts_in_a_multipart_with_none_preamble(self): 12260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 12270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 12280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 12290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 12300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 12310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.preamble = None 12320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 12330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.attach(msg) 12340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 12350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(outer.as_string(), '''\ 12360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 12370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 12390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 12400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 12410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 12430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 12440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 12460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yihello world 12480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY--''') 12490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_seq_parts_in_a_multipart_with_none_epilogue(self): 12520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 12530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 12540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 12550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 12560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 12570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.epilogue = None 12580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 12590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.attach(msg) 12600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 12610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(outer.as_string(), '''\ 12620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 12630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 12650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 12660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 12670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 12690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 12700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 12720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yihello world 12740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY--''') 12750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_seq_parts_in_a_multipart_with_empty_epilogue(self): 12780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 12790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 12800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 12810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 12820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 12830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.epilogue = '' 12840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 12850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.attach(msg) 12860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 12870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(outer.as_string(), '''\ 12880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 12890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 12910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 12920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 12930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 12950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 12960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 12970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 12980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 12990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yihello world 13000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 13010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 13020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_seq_parts_in_a_multipart_with_nl_epilogue(self): 13050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 13060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = MIMEBase('multipart', 'mixed') 13070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['Subject'] = 'A subject' 13080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['To'] = 'aperson@dom.ain' 13090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer['From'] = 'bperson@dom.ain' 13100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.epilogue = '\n' 13110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEText('hello world') 13120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.attach(msg) 13130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer.set_boundary('BOUNDARY') 13140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(outer.as_string(), '''\ 13150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 13160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 13170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: A subject 13180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: aperson@dom.ain 13190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bperson@dom.ain 13200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 13220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 13230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 13240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 13250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yihello world 13270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 13280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 13300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_message_external_body(self): 13320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 13330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_36.txt') 13340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.get_payload()), 2) 13350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg1 = msg.get_payload(1) 13360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg1.get_content_type(), 'multipart/alternative') 13370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg1.get_payload()), 2) 13380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for subpart in msg1.get_payload(): 13390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart.get_content_type(), 'message/external-body') 13400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(subpart.get_payload()), 1) 13410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subsubpart = subpart.get_payload(0) 13420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subsubpart.get_content_type(), 'text/plain') 13430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_double_boundary(self): 13450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # msg_37.txt is a multipart that contains two dash-boundary's in a 13460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # row. Our interpretation of RFC 2046 calls for ignoring the second 13470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # and subsequent boundaries. 13480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_37.txt') 13490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(len(msg.get_payload()), 3) 13500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_nested_inner_contains_outer_boundary(self): 13520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 13530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # msg_38.txt has an inner part that contains outer boundaries. My 13540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # interpretation of RFC 2046 (based on sections 5.1 and 5.1.2) say 13550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # these are illegal and should be interpreted as unterminated inner 13560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # parts. 13570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_38.txt') 13580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 13590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi iterators._structure(msg, sfp) 13600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), """\ 13610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimultipart/mixed 13620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multipart/mixed 13630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multipart/alternative 13640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 13650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 13660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 13670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 13680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 13690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_nested_with_same_boundary(self): 13710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 13720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # msg 39.txt is similarly evil in that it's got inner parts that use 13730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # the same boundary as outer parts. Again, I believe the way this is 13740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # parsed is closest to the spirit of RFC 2046 13750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_39.txt') 13760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 13770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi iterators._structure(msg, sfp) 13780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), """\ 13790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimultipart/mixed 13800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multipart/mixed 13810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi multipart/alternative 13820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi application/octet-stream 13830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi application/octet-stream 13840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 13850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 13860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_boundary_in_non_multipart(self): 13880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_40.txt') 13890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.as_string(), '''\ 13900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 13910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/html; boundary="--961284236552522269" 13920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi----961284236552522269 13940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/html; 13950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7Bit 13960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi<html></html> 13980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 13990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi----961284236552522269-- 14000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 14010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_boundary_with_leading_space(self): 14030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 14040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string('''\ 14050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 14060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary=" XXXX" 14070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-- XXXX 14090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain 14100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-- XXXX 14130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain 14140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-- XXXX-- 14160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 14170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(msg.is_multipart()) 14180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_boundary(), ' XXXX') 14190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.get_payload()), 2) 14200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_boundary_without_trailing_newline(self): 14220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = Parser().parsestr("""\ 14230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="===============0012394164==" 14240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 14250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--===============0012394164== 14270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: image/file1.jpg 14280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 14290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: base64 14300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiYXNkZg== 14320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--===============0012394164==--""") 14330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(m.get_payload(0).get_payload(), 'YXNkZg==') 14340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test some badly formatted messages 14380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestNonConformant(TestEmailBase): 14390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parse_missing_minor_type(self): 14400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 14410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_14.txt') 14420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'text/plain') 14430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_maintype(), 'text') 14440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_subtype(), 'plain') 14450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_same_boundary_inner_outer(self): 14470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 14480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_15.txt') 14490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # XXX We can probably eventually do better 14500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi inner = msg.get_payload(0) 14510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(hasattr(inner, 'defects')) 14520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(len(inner.defects), 1) 14530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(inner.defects[0], 14540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi errors.StartBoundaryNotFoundDefect)) 14550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_multipart_no_boundary(self): 14570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 14580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_25.txt') 14590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg.get_payload(), str)) 14600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(len(msg.defects), 2) 14610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg.defects[0], errors.NoBoundaryInMultipartDefect)) 14620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg.defects[1], 14630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi errors.MultipartInvariantViolationDefect)) 14640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_invalid_content_type(self): 14660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 14670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq = self.ndiffAssertEqual 14680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 14690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # RFC 2045, $5.2 says invalid yields text/plain 14700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'text' 14710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_maintype(), 'text') 14720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_subtype(), 'plain') 14730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'text/plain') 14740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Clear the old value and try something /really/ invalid 14750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del msg['content-type'] 14760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'foo' 14770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_maintype(), 'text') 14780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_subtype(), 'plain') 14790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'text/plain') 14800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Still, make sure that the message is idempotently generated 14810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 14820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s) 14830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 14840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq(s.getvalue(), 'Content-Type: foo\n\n') 14850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_start_boundary(self): 14870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 14880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_31.txt') 14890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), """\ 14900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 14910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain 14920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimessage 1 14940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 14960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain 14970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 14980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimessage 2 14990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 15010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 15020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_separating_blank_line(self): 15040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 15050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_35.txt') 15060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(), """\ 15070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: aperson@dom.ain 15080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: bperson@dom.ain 15090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: here's something interesting 15100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yicounter to RFC 2822, there's no separating newline here 15120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 15130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_lying_multipart(self): 15150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 15160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_41.txt') 15170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(hasattr(msg, 'defects')) 15180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(len(msg.defects), 2) 15190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg.defects[0], errors.NoBoundaryInMultipartDefect)) 15200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg.defects[1], 15210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi errors.MultipartInvariantViolationDefect)) 15220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_missing_start_boundary(self): 15240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi outer = self._msgobj('msg_42.txt') 15250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The message structure is: 15260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 15270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # multipart/mixed 15280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # text/plain 15290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # message/rfc822 15300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # multipart/mixed [*] 15310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # 15320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # [*] This message is missing its start boundary 15330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bad = outer.get_payload(1).get_payload(0) 15340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(len(bad.defects), 1) 15350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(isinstance(bad.defects[0], 15360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi errors.StartBoundaryNotFoundDefect)) 15370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_first_line_is_continuation_header(self): 15390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 15400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = ' Line 1\nLine 2\nLine 3' 15410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 15420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.keys(), []) 15430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), 'Line 2\nLine 3') 15440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.defects), 1) 15450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(isinstance(msg.defects[0], 15460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi errors.FirstHeaderLineIsContinuationDefect)) 15470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.defects[0].line, ' Line 1\n') 15480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test RFC 2047 header encoding and decoding 15520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestRFC2047(unittest.TestCase): 15530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2047_multiline(self): 15540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 15550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz 15560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi foo bar =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""" 15570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dh = decode_header(s) 15580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dh, [ 15590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('Re:', None), 15600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('r\x8aksm\x9arg\x8cs', 'mac-iceland'), 15610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('baz foo bar', None), 15620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('r\x8aksm\x9arg\x8cs', 'mac-iceland')]) 15630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(str(make_header(dh)), 15640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Re: =?mac-iceland?q?r=8Aksm=9Arg=8Cs?= baz foo bar 15650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?mac-iceland?q?r=8Aksm=9Arg=8Cs?=""") 15660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_whitespace_eater_unicode(self): 15680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 15690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = '=?ISO-8859-1?Q?Andr=E9?= Pirard <pirard@dom.ain>' 15700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dh = decode_header(s) 15710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dh, [('Andr\xe9', 'iso-8859-1'), ('Pirard <pirard@dom.ain>', None)]) 15720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hu = unicode(make_header(dh)).encode('latin-1') 15730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(hu, 'Andr\xe9 Pirard <pirard@dom.ain>') 15740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_whitespace_eater_unicode_2(self): 15760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 15770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'The =?iso-8859-1?b?cXVpY2sgYnJvd24gZm94?= jumped over the =?iso-8859-1?b?bGF6eSBkb2c=?=' 15780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dh = decode_header(s) 15790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dh, [('The', None), ('quick brown fox', 'iso-8859-1'), 15800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('jumped over the', None), ('lazy dog', 'iso-8859-1')]) 15810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hu = make_header(dh).__unicode__() 15820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(hu, u'The quick brown fox jumped over the lazy dog') 15830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2047_missing_whitespace(self): 15850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'Sm=?ISO-8859-1?B?9g==?=rg=?ISO-8859-1?B?5Q==?=sbord' 15860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dh = decode_header(s) 15870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(dh, [(s, None)]) 15880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2047_with_whitespace(self): 15900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'Sm =?ISO-8859-1?B?9g==?= rg =?ISO-8859-1?B?5Q==?= sbord' 15910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dh = decode_header(s) 15920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(dh, [('Sm', None), ('\xf6', 'iso-8859-1'), 15930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('rg', None), ('\xe5', 'iso-8859-1'), 15940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('sbord', None)]) 15950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 15980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the MIMEMessage class 15990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMIMEMessage(TestEmailBase): 16000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUp(self): 16010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_11.txt') 16020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 16030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._text = fp.read() 16040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 16050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 16060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_type_error(self): 16080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(TypeError, MIMEMessage, 'a plain string') 16090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_valid_argument(self): 16110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 16120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 16130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subject = 'A sub-message' 16140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = Message() 16150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m['Subject'] = subject 16160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = MIMEMessage(m) 16170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(r.get_content_type(), 'message/rfc822') 16180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = r.get_payload() 16190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(payload, list)) 16200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(payload), 1) 16210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart = payload[0] 16220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(subpart is m) 16230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart['subject'], subject) 16240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_bad_multipart(self): 16260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 16270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg1 = Message() 16280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg1['Subject'] = 'subpart 1' 16290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg2 = Message() 16300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg2['Subject'] = 'subpart 2' 16310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = MIMEMessage(msg1) 16320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(errors.MultipartConversionError, r.attach, msg2) 16330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_generate(self): 16350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # First craft the message to be encapsulated 16360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = Message() 16370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m['Subject'] = 'An enclosed message' 16380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m.set_payload('Here is the body of the message.\n') 16390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r = MIMEMessage(m) 16400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r['Subject'] = 'The enclosing message' 16410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 16420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s) 16430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(r) 16440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(s.getvalue(), """\ 16450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: message/rfc822 16460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 16470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: The enclosing message 16480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: An enclosed message 16500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHere is the body of the message. 16520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 16530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parse_message_rfc822(self): 16550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 16560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 16570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_11.txt') 16580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'message/rfc822') 16590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = msg.get_payload() 16600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(payload, list)) 16610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(payload), 1) 16620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi submsg = payload[0] 16630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(isinstance(submsg, Message)) 16640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(submsg['subject'], 'An enclosed message') 16650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(submsg.get_payload(), 'Here is the body of the message.\n') 16660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_dsn(self): 16680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 16690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 16700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # msg 16 is a Delivery Status Notification, see RFC 1894 16710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_16.txt') 16720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'multipart/report') 16730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(msg.is_multipart()) 16740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.get_payload()), 3) 16750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 1 is a text/plain, human readable section 16760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart = msg.get_payload(0) 16770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart.get_content_type(), 'text/plain') 16780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart.get_payload(), """\ 16790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiThis report relates to a message you sent with the following header fields: 16800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Message-id: <002001c144a6$8752e060$56104586@oxy.edu> 16820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Date: Sun, 23 Sep 2001 20:10:55 -0700 16830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi From: "Ian T. Henry" <henryi@oxy.edu> 16840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi To: SoCal Raves <scr@socal-raves.org> 16850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Subject: [scr] yeah for Ians!! 16860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiYour message cannot be delivered to the following recipients: 16880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Recipient address: jangel1@cougar.noc.ucla.edu 16900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi Reason: recipient reached disk quota 16910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 16920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 16930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 2 contains the machine parsable DSN information. It 16940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # consists of two blocks of headers, represented by two nested Message 16950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # objects. 16960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart = msg.get_payload(1) 16970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart.get_content_type(), 'message/delivery-status') 16980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(subpart.get_payload()), 2) 16990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # message/delivery-status should treat each block as a bunch of 17000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # headers, i.e. a bunch of Message objects. 17010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dsn1 = subpart.get_payload(0) 17020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(dsn1, Message)) 17030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dsn1['original-envelope-id'], '0GK500B4HD0888@cougar.noc.ucla.edu') 17040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dsn1.get_param('dns', header='reporting-mta'), '') 17050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try a missing one <wink> 17060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dsn1.get_param('nsd', header='reporting-mta'), None) 17070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi dsn2 = subpart.get_payload(1) 17080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(dsn2, Message)) 17090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dsn2['action'], 'failed') 17100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dsn2.get_params(header='original-recipient'), 17110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('rfc822', ''), ('jangel1@cougar.noc.ucla.edu', '')]) 17120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(dsn2.get_param('rfc822', header='final-recipient'), '') 17130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Subpart 3 is the original message 17140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart = msg.get_payload(2) 17150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart.get_content_type(), 'message/rfc822') 17160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = subpart.get_payload() 17170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(payload, list)) 17180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(payload), 1) 17190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subsubpart = payload[0] 17200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(subsubpart, Message)) 17210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subsubpart.get_content_type(), 'text/plain') 17220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subsubpart['message-id'], 17230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '<002001c144a6$8752e060$56104586@oxy.edu>') 17240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_epilogue(self): 17260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 17270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_21.txt') 17280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 17290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = fp.read() 17300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 17310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 17320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 17330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['From'] = 'aperson@dom.ain' 17340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['To'] = 'bperson@dom.ain' 17350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Subject'] = 'Test' 17360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.preamble = 'MIME message' 17370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.epilogue = 'End of MIME message\n' 17380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg1 = MIMEText('One') 17390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg2 = MIMEText('Two') 17400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY') 17410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.attach(msg1) 17420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.attach(msg2) 17430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 17440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(sfp) 17450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 17460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), text) 17470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_nl_preamble(self): 17490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 17500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 17510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['From'] = 'aperson@dom.ain' 17520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['To'] = 'bperson@dom.ain' 17530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Subject'] = 'Test' 17540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.preamble = 'MIME message' 17550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.epilogue = '' 17560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg1 = MIMEText('One') 17570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg2 = MIMEText('Two') 17580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('Content-Type', 'multipart/mixed', boundary='BOUNDARY') 17590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.attach(msg1) 17600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.attach(msg2) 17610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(), """\ 17620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: aperson@dom.ain 17630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: bperson@dom.ain 17640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: Test 17650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/mixed; boundary="BOUNDARY" 17660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME message 17680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 17690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 17700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 17710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 17720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiOne 17740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 17750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 17760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 17770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 17780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTwo 17800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 17810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 17820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 17830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_default_type(self): 17840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 17850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_30.txt') 17860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 17870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_file(fp) 17880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 17890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 17900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container1 = msg.get_payload(0) 17910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1.get_default_type(), 'message/rfc822') 17920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1.get_content_type(), 'message/rfc822') 17930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container2 = msg.get_payload(1) 17940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2.get_default_type(), 'message/rfc822') 17950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2.get_content_type(), 'message/rfc822') 17960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container1a = container1.get_payload(0) 17970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1a.get_default_type(), 'text/plain') 17980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1a.get_content_type(), 'text/plain') 17990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container2a = container2.get_payload(0) 18000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2a.get_default_type(), 'text/plain') 18010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2a.get_content_type(), 'text/plain') 18020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_default_type_with_explicit_container_type(self): 18040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 18050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_28.txt') 18060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 18070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_file(fp) 18080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 18090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 18100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container1 = msg.get_payload(0) 18110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1.get_default_type(), 'message/rfc822') 18120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1.get_content_type(), 'message/rfc822') 18130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container2 = msg.get_payload(1) 18140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2.get_default_type(), 'message/rfc822') 18150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2.get_content_type(), 'message/rfc822') 18160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container1a = container1.get_payload(0) 18170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1a.get_default_type(), 'text/plain') 18180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container1a.get_content_type(), 'text/plain') 18190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container2a = container2.get_payload(0) 18200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2a.get_default_type(), 'text/plain') 18210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(container2a.get_content_type(), 'text/plain') 18220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_default_type_non_parsed(self): 18240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 18250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq = self.ndiffAssertEqual 18260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Set up container 18270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container = MIMEMultipart('digest', 'BOUNDARY') 18280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container.epilogue = '' 18290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Set up subparts 18300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart1a = MIMEText('message 1\n') 18310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart2a = MIMEText('message 2\n') 18320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart1 = MIMEMessage(subpart1a) 18330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subpart2 = MIMEMessage(subpart2a) 18340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container.attach(subpart1) 18350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi container.attach(subpart2) 18360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart1.get_content_type(), 'message/rfc822') 18370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart1.get_default_type(), 'message/rfc822') 18380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart2.get_content_type(), 'message/rfc822') 18390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart2.get_default_type(), 'message/rfc822') 18400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq(container.as_string(0), '''\ 18410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/digest; boundary="BOUNDARY" 18420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 18450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: message/rfc822 18460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 18490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 18510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimessage 1 18530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 18550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: message/rfc822 18560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 18590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 18610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimessage 2 18630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 18650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 18660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del subpart1['content-type'] 18670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del subpart1['mime-version'] 18680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del subpart2['content-type'] 18690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del subpart2['mime-version'] 18700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart1.get_content_type(), 'message/rfc822') 18710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart1.get_default_type(), 'message/rfc822') 18720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart2.get_content_type(), 'message/rfc822') 18730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subpart2.get_default_type(), 'message/rfc822') 18740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq(container.as_string(0), '''\ 18750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/digest; boundary="BOUNDARY" 18760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 18790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 18810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 18830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimessage 1 18850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY 18870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii" 18890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 18900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 18910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimessage 2 18930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi--BOUNDARY-- 18950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''') 18960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 18970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_mime_attachments_in_constructor(self): 18980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 18990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text1 = MIMEText('') 19000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text2 = MIMEText('') 19010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = MIMEMultipart(_subparts=(text1, text2)) 19020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.get_payload()), 2) 19030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(0), text1) 19040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(1), text2) 19050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# A general test of parser->model->generator idempotency. IOW, read a message 19090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# in, parse it into a message object tree, then without touching the tree, 19100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# regenerate the plain text. The original text and the transformed text 19110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# should be identical. Note: that we ignore the Unix-From since that may 19120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# contain a changed date. 19130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestIdempotent(TestEmailBase): 19140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _msgobj(self, filename): 19150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile(filename) 19160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 19170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi data = fp.read() 19180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 19190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 19200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(data) 19210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return msg, data 19220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def _idempotent(self, msg, text): 19240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 19250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 19260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s, maxheaderlen=0) 19270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 19280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(text, s.getvalue()) 19290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parse_text_message(self): 19310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 19320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_01.txt') 19330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'text/plain') 19340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_maintype(), 'text') 19350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_subtype(), 'plain') 19360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params()[1], ('charset', 'us-ascii')) 19370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('charset'), 'us-ascii') 19380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.preamble, None) 19390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.epilogue, None) 19400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parse_untyped_message(self): 19430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 19440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_03.txt') 19450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'text/plain') 19460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_params(), None) 19470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('charset'), None) 19480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_simple_multipart(self): 19510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_04.txt') 19520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_MIME_digest(self): 19550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_02.txt') 19560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long_header(self): 19590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_27.txt') 19600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_MIME_digest_with_part_headers(self): 19630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_28.txt') 19640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_mixed_with_image(self): 19670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_06.txt') 19680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_multipart_report(self): 19710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_05.txt') 19720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_dsn(self): 19750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_16.txt') 19760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_preamble_epilogue(self): 19790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_21.txt') 19800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_multipart_one_part(self): 19830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_23.txt') 19840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_multipart_no_parts(self): 19870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_24.txt') 19880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_no_start_boundary(self): 19910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_31.txt') 19920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_charset(self): 19950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_32.txt') 19960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 19970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 19980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_more_rfc2231_parameters(self): 19990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_33.txt') 20000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 20010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_text_plain_in_a_multipart_digest(self): 20030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_34.txt') 20040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 20050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_nested_multipart_mixeds(self): 20070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_12a.txt') 20080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 20090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_message_external_body_idempotent(self): 20110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_36.txt') 20120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self._idempotent(msg, text) 20130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_content_type(self): 20150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 20160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 20170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Get a message object and reset the seek pointer for other tests 20180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_05.txt') 20190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'multipart/report') 20200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the Content-Type: parameters 20210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi params = {} 20220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for pk, pv in msg.get_params(): 20230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi params[pk] = pv 20240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(params['report-type'], 'delivery-status') 20250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(params['boundary'], 'D1690A7AC1.996856090/mail.example.com') 20260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.preamble, 'This is a MIME-encapsulated message.\n') 20270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.epilogue, '\n') 20280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.get_payload()), 3) 20290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Make sure the subparts are what we expect 20300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg1 = msg.get_payload(0) 20310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg1.get_content_type(), 'text/plain') 20320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg1.get_payload(), 'Yadda yadda yadda\n') 20330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg2 = msg.get_payload(1) 20340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg2.get_content_type(), 'text/plain') 20350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg2.get_payload(), 'Yadda yadda yadda\n') 20360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg3 = msg.get_payload(2) 20370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg3.get_content_type(), 'message/rfc822') 20380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(isinstance(msg3, Message)) 20390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = msg3.get_payload() 20400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(payload, list)) 20410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(payload), 1) 20420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg4 = payload[0] 20430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg4, Message)) 20440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg4.get_payload(), 'Yadda yadda yadda\n') 20450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parser(self): 20470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 20480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 20490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg, text = self._msgobj('msg_06.txt') 20500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Check some of the outer headers 20510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'message/rfc822') 20520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Make sure the payload is a list of exactly one sub-Message, and that 20530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # that submessage has a type of text/plain 20540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi payload = msg.get_payload() 20550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(payload, list)) 20560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(payload), 1) 20570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg1 = payload[0] 20580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(isinstance(msg1, Message)) 20590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg1.get_content_type(), 'text/plain') 20600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(isinstance(msg1.get_payload(), str)) 20610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg1.get_payload(), '\n') 20620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test various other bits of the package's functionality 20660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestMiscellaneous(TestEmailBase): 20670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_message_from_string(self): 20680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_01.txt') 20690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 20700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = fp.read() 20710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 20720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 20730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(text) 20740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 20750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Don't wrap/continue long headers since we're trying to test 20760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # idempotency. 20770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s, maxheaderlen=0) 20780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 20790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(text, s.getvalue()) 20800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_message_from_file(self): 20820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_01.txt') 20830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 20840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = fp.read() 20850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.seek(0) 20860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_file(fp) 20870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = StringIO() 20880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Don't wrap/continue long headers since we're trying to test 20890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # idempotency. 20900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Generator(s, maxheaderlen=0) 20910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g.flatten(msg) 20920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(text, s.getvalue()) 20930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 20940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 20950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 20960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_message_from_string_with_class(self): 20970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 20980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_01.txt') 20990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 21000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = fp.read() 21010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 21020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 21030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Create a subclass 21040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi class MyMessage(Message): 21050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 21060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(text, MyMessage) 21080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg, MyMessage)) 21090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try something more complicated 21100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_02.txt') 21110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 21120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text = fp.read() 21130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 21140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 21150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(text, MyMessage) 21160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for subpart in msg.walk(): 21170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(subpart, MyMessage)) 21180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_message_from_file_with_class(self): 21200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless = self.assertTrue 21210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Create a subclass 21220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi class MyMessage(Message): 21230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 21240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_01.txt') 21260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 21270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_file(fp, MyMessage) 21280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 21290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 21300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(msg, MyMessage)) 21310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try something more complicated 21320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_02.txt') 21330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 21340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_file(fp, MyMessage) 21350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 21360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 21370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for subpart in msg.walk(): 21380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unless(isinstance(subpart, MyMessage)) 21390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test__all__(self): 21410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi module = __import__('email') 21420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Can't use sorted() here due to Python 2.3 compatibility 21430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi all = module.__all__[:] 21440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi all.sort() 21450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(all, [ 21460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Old names 21470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Charset', 'Encoders', 'Errors', 'Generator', 21480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Header', 'Iterators', 'MIMEAudio', 'MIMEBase', 21490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'MIMEImage', 'MIMEMessage', 'MIMEMultipart', 21500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'MIMENonMultipart', 'MIMEText', 'Message', 21510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Parser', 'Utils', 'base64MIME', 21520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # new names 21530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'base64mime', 'charset', 'encoders', 'errors', 'generator', 21540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'header', 'iterators', 'message', 'message_from_file', 21550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'message_from_string', 'mime', 'parser', 21560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'quopriMIME', 'quoprimime', 'utils', 21570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ]) 21580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_formatdate(self): 21600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi now = time.time() 21610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parsedate(utils.formatdate(now))[:6], 21620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi time.gmtime(now)[:6]) 21630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_formatdate_localtime(self): 21650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi now = time.time() 21660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 21670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.parsedate(utils.formatdate(now, localtime=True))[:6], 21680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi time.localtime(now)[:6]) 21690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_formatdate_usegmt(self): 21710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi now = time.time() 21720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 21730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.formatdate(now, localtime=False), 21740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi time.strftime('%a, %d %b %Y %H:%M:%S -0000', time.gmtime(now))) 21750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 21760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.formatdate(now, localtime=False, usegmt=True), 21770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(now))) 21780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parsedate_none(self): 21800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parsedate(''), None) 21810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parsedate_compact(self): 21830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The FWS after the comma is optional 21840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parsedate('Wed,3 Apr 2002 14:58:26 +0800'), 21850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.parsedate('Wed, 3 Apr 2002 14:58:26 +0800')) 21860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parsedate_no_dayofweek(self): 21880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 21890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.parsedate_tz('25 Feb 2003 13:47:26 -0800'), 21900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (2003, 2, 25, 13, 47, 26, 0, 1, -1, -28800)) 21910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parsedate_compact_no_dayofweek(self): 21930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 21940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.parsedate_tz('5 Feb 2003 13:47:26 -0800'), 21950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (2003, 2, 5, 13, 47, 26, 0, 1, -1, -28800)) 21960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 21970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parsedate_acceptable_to_time_functions(self): 21980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 21990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi timetup = utils.parsedate('5 Feb 2003 13:47:26 -0800') 22000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t = int(time.mktime(timetup)) 22010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(time.localtime(t)[:6], timetup[:6]) 22020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(int(time.strftime('%Y', timetup)), 2003) 22030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi timetup = utils.parsedate_tz('5 Feb 2003 13:47:26 -0800') 22040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi t = int(time.mktime(timetup[:9])) 22050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(time.localtime(t)[:6], timetup[:6]) 22060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(int(time.strftime('%Y', timetup[:9])), 2003) 22070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_parseaddr_empty(self): 22090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parseaddr('<>'), ('', '')) 22100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.formataddr(utils.parseaddr('<>')), '') 22110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_noquote_dump(self): 22130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 22140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.formataddr(('A Silly Person', 'person@dom.ain')), 22150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'A Silly Person <person@dom.ain>') 22160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_escape_dump(self): 22180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 22190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.formataddr(('A (Very) Silly Person', 'person@dom.ain')), 22200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r'"A \(Very\) Silly Person" <person@dom.ain>') 22210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = r'A \(Special\) Person' 22220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi b = 'person@dom.ain' 22230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parseaddr(utils.formataddr((a, b))), (a, b)) 22240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_escape_backslashes(self): 22260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 22270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.formataddr(('Arthur \Backslash\ Foobar', 'person@dom.ain')), 22280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r'"Arthur \\Backslash\\ Foobar" <person@dom.ain>') 22290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a = r'Arthur \Backslash\ Foobar' 22300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi b = 'person@dom.ain' 22310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parseaddr(utils.formataddr((a, b))), (a, b)) 22320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_name_with_dot(self): 22340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = 'John X. Doe <jxd@example.com>' 22350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi y = '"John X. Doe" <jxd@example.com>' 22360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi a, b = ('John X. Doe', 'jxd@example.com') 22370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parseaddr(x), (a, b)) 22380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parseaddr(y), (a, b)) 22390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # formataddr() quotes the name if there's a dot in it 22400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.formataddr((a, b)), y) 22410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_multiline_from_comment(self): 22430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = """\ 22440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFoo 22450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tBar <foo@example.com>""" 22460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(utils.parseaddr(x), ('Foo Bar', 'foo@example.com')) 22470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_quote_dump(self): 22490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 22500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utils.formataddr(('A Silly; Person', 'person@dom.ain')), 22510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi r'"A Silly; Person" <person@dom.ain>') 22520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_fix_eols(self): 22540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 22550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.fix_eols('hello'), 'hello') 22560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.fix_eols('hello\n'), 'hello\r\n') 22570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.fix_eols('hello\r'), 'hello\r\n') 22580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.fix_eols('hello\r\n'), 'hello\r\n') 22590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.fix_eols('hello\n\r'), 'hello\r\n\r\n') 22600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_charset_richcomparisons(self): 22620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 22630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ne = self.assertNotEqual 22640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cset1 = Charset() 22650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cset2 = Charset() 22660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(cset1, 'us-ascii') 22670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(cset1, 'US-ASCII') 22680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(cset1, 'Us-AsCiI') 22690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('us-ascii', cset1) 22700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('US-ASCII', cset1) 22710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('Us-AsCiI', cset1) 22720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ne(cset1, 'usascii') 22730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ne(cset1, 'USASCII') 22740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ne(cset1, 'UsAsCiI') 22750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ne('usascii', cset1) 22760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ne('USASCII', cset1) 22770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ne('UsAsCiI', cset1) 22780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(cset1, cset2) 22790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(cset2, cset1) 22800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_getaddresses(self): 22820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 22830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.getaddresses(['aperson@dom.ain (Al Person)', 22840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Bud Person <bperson@dom.ain>']), 22850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('Al Person', 'aperson@dom.ain'), 22860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('Bud Person', 'bperson@dom.ain')]) 22870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_getaddresses_nasty(self): 22890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 22900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.getaddresses(['foo: ;']), [('', '')]) 22910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.getaddresses( 22920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ['[]*-- =~$']), 22930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('', ''), ('', ''), ('', '*--')]) 22940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(utils.getaddresses( 22950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ['foo: ;', '"Jason R. Mastaler" <jason@dom.ain>']), 22960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [('', ''), ('Jason R. Mastaler', 'jason@dom.ain')]) 22970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 22980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_getaddresses_embedded_comment(self): 22990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi """Test proper handling of a nested comment""" 23000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 23010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi addrs = utils.getaddresses(['User ((nested comment)) <foo@bar.com>']) 23020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(addrs[0][1], 'foo@bar.com') 23030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_utils_quote_unquote(self): 23050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 23060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 23070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.add_header('content-disposition', 'attachment', 23080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi filename='foo\\wacky"name') 23090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_filename(), 'foo\\wacky"name') 23100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_body_encoding_with_bogus_charset(self): 23120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset = Charset('not a charset') 23130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(charset.get_body_encoding(), 'base64') 23140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_body_encoding_with_uppercase_charset(self): 23160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 23170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 23180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'text/plain; charset=UTF-8' 23190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-type'], 'text/plain; charset=UTF-8') 23200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charsets = msg.get_charsets() 23210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(charsets), 1) 23220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charsets[0], 'utf-8') 23230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset = Charset(charsets[0]) 23240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charset.get_body_encoding(), 'base64') 23250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_payload('hello world', charset=charset) 23260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), 'aGVsbG8gd29ybGQ=\n') 23270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(decode=True), 'hello world') 23280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], 'base64') 23290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try another one 23300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 23310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg['Content-Type'] = 'text/plain; charset="US-ASCII"' 23320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charsets = msg.get_charsets() 23330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(charsets), 1) 23340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charsets[0], 'us-ascii') 23350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset = Charset(charsets[0]) 23360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charset.get_body_encoding(), encoders.encode_7or8bit) 23370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_payload('hello world', charset=charset) 23380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), 'hello world') 23390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['content-transfer-encoding'], '7bit') 23400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_charsets_case_insensitive(self): 23420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lc = Charset('us-ascii') 23430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi uc = Charset('US-ASCII') 23440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(lc.get_body_encoding(), uc.get_body_encoding()) 23450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_partial_falls_inside_message_delivery_status(self): 23470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 23480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # The Parser interface provides chunks of data to FeedParser in 8192 23490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # byte gulps. SF bug #1076485 found one of those chunks inside 23500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # message/delivery-status header block, which triggered an 23510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # unreadline() of NeedMoreData. 23520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_43.txt') 23530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sfp = StringIO() 23540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi iterators._structure(msg, sfp) 23550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(sfp.getvalue(), """\ 23560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yimultipart/report 23570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi message/delivery-status 23590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/plain 23850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi text/rfc822-headers 23860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 23870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 23900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the iterator/generators 23910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestIterators(TestEmailBase): 23920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_body_line_iterator(self): 23930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 23940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq = self.ndiffAssertEqual 23950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # First a simple non-multipart message 23960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 23970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi it = iterators.body_line_iterator(msg) 23980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines = list(it) 23990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(lines), 6) 24000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq(EMPTYSTRING.join(lines), msg.get_payload()) 24010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Now a more complicated multipart 24020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_02.txt') 24030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi it = iterators.body_line_iterator(msg) 24040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines = list(it) 24050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(lines), 43) 24060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_19.txt') 24070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 24080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq(EMPTYSTRING.join(lines), fp.read()) 24090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 24100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 24110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_typed_subpart_iterator(self): 24130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 24140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_04.txt') 24150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi it = iterators.typed_subpart_iterator(msg, 'text') 24160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines = [] 24170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subparts = 0 24180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for subpart in it: 24190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subparts += 1 24200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines.append(subpart.get_payload()) 24210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subparts, 2) 24220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(EMPTYSTRING.join(lines), """\ 24230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yia simple kind of mirror 24240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yito reflect upon our own 24250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yia simple kind of mirror 24260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yito reflect upon our own 24270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 24280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_typed_subpart_iterator_default_type(self): 24300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 24310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_03.txt') 24320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi it = iterators.typed_subpart_iterator(msg, 'text', 'plain') 24330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines = [] 24340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subparts = 0 24350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for subpart in it: 24360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi subparts += 1 24370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines.append(subpart.get_payload()) 24380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(subparts, 1) 24390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(EMPTYSTRING.join(lines), """\ 24400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHi, 24420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDo you like this message? 24440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-Me 24460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 24470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestParsers(TestEmailBase): 24510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_parser(self): 24520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 24530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Parse only the headers of a complex multipart MIME document 24540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_02.txt') 24550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 24560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = HeaderParser().parse(fp) 24570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 24580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 24590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['from'], 'ppp-request@zzz.org') 24600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['to'], 'ppp@zzz.org') 24610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_type(), 'multipart/mixed') 24620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertFalse(msg.is_multipart()) 24630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(isinstance(msg.get_payload(), str)) 24640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_whitespace_continuation(self): 24660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 24670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This message contains a line after the Subject: header that has only 24680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # whitespace, but it is not empty! 24690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string("""\ 24700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: aperson@dom.ain 24710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: bperson@dom.ain 24720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: the next line has a space on it 24730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\x20 24740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDate: Mon, 8 Apr 2002 15:09:19 -0400 24750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMessage-ID: spam 24760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHere's the message body 24780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 24790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['subject'], 'the next line has a space on it\n ') 24800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['message-id'], 'spam') 24810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), "Here's the message body\n") 24820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_whitespace_continuation_last_header(self): 24840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 24850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Like the previous test, but the subject line is the last 24860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # header. 24870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string("""\ 24880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: aperson@dom.ain 24890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: bperson@dom.ain 24900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDate: Mon, 8 Apr 2002 15:09:19 -0400 24910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMessage-ID: spam 24920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: the next line has a space on it 24930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\x20 24940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 24950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHere's the message body 24960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 24970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['subject'], 'the next line has a space on it\n ') 24980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg['message-id'], 'spam') 24990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), "Here's the message body\n") 25000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_crlf_separation(self): 25020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 25030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_26.txt', mode='rb') 25040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 25050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Parser().parse(fp) 25060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 25070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 25080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.get_payload()), 2) 25090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi part1 = msg.get_payload(0) 25100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part1.get_content_type(), 'text/plain') 25110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part1.get_payload(), 'Simple email with attachment.\r\n\r\n') 25120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi part2 = msg.get_payload(1) 25130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part2.get_content_type(), 'application/riscos') 25140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_multipart_digest_with_extra_mime_headers(self): 25160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 25170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq = self.ndiffAssertEqual 25180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp = openfile('msg_28.txt') 25190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 25200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_file(fp) 25210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi finally: 25220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi fp.close() 25230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Structure is: 25240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # multipart/digest 25250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # message/rfc822 25260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # text/plain 25270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # message/rfc822 25280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # text/plain 25290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.is_multipart(), 1) 25300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.get_payload()), 2) 25310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi part1 = msg.get_payload(0) 25320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part1.get_content_type(), 'message/rfc822') 25330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part1.is_multipart(), 1) 25340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(part1.get_payload()), 1) 25350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi part1a = part1.get_payload(0) 25360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part1a.is_multipart(), 0) 25370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part1a.get_content_type(), 'text/plain') 25380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq(part1a.get_payload(), 'message 1\n') 25390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # next message/rfc822 25400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi part2 = msg.get_payload(1) 25410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part2.get_content_type(), 'message/rfc822') 25420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part2.is_multipart(), 1) 25430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(part2.get_payload()), 1) 25440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi part2a = part2.get_payload(0) 25450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part2a.is_multipart(), 0) 25460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(part2a.get_content_type(), 'text/plain') 25470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi neq(part2a.get_payload(), 'message 2\n') 25480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_three_lines(self): 25500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # A bug report by Andrew McNamara 25510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi lines = ['From: Andrew Person <aperson@dom.ain', 25520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Subject: Test', 25530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Date: Tue, 20 Aug 2002 16:43:45 +1000'] 25540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(NL.join(lines)) 25550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg['date'], 'Tue, 20 Aug 2002 16:43:45 +1000') 25560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_strip_line_feed_and_carriage_return_in_headers(self): 25580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 25590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # For [ 1002475 ] email message parser doesn't handle \r\n correctly 25600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value1 = 'text' 25610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value2 = 'more text' 25620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = 'Header: %s\r\nNext-Header: %s\r\n\r\nBody\r\n\r\n' % ( 25630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi value1, value2) 25640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 25650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get('Header'), value1) 25660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get('Next-Header'), value2) 25670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2822_header_syntax(self): 25690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 25700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '>From: foo\nFrom: bar\n!"#QUX;~: zoo\n\nbody' 25710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 25720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.keys()), 3) 25730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi keys = msg.keys() 25740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi keys.sort() 25750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(keys, ['!"#QUX;~', '>From', 'From']) 25760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), 'body') 25770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2822_space_not_allowed_in_header(self): 25790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 25800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '>From foo@example.com 11:25:53\nFrom: bar\n!"#QUX;~: zoo\n\nbody' 25810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 25820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(len(msg.keys()), 0) 25830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2822_one_character_header(self): 25850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 25860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = 'A: first header\nB: second header\nCC: third header\n\nbody' 25870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 25880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi headers = msg.keys() 25890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi headers.sort() 25900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(headers, ['A', 'B', 'CC']) 25910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_payload(), 'body') 25920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 25950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestBase64(unittest.TestCase): 25960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_len(self): 25970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 25980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.base64_len('hello'), 25990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi len(base64mime.encode('hello', eol=''))) 26000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for size in range(15): 26010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi if size == 0 : bsize = 0 26020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif size <= 3 : bsize = 4 26030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif size <= 6 : bsize = 8 26040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif size <= 9 : bsize = 12 26050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi elif size <= 12: bsize = 16 26060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi else : bsize = 20 26070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.base64_len('x'*size), bsize) 26080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_decode(self): 26100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 26110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.decode(''), '') 26120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.decode('aGVsbG8='), 'hello') 26130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.decode('aGVsbG8=', 'X'), 'hello') 26140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.decode('aGVsbG8NCndvcmxk\n', 'X'), 'helloXworld') 26150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_encode(self): 26170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 26180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.encode(''), '') 26190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.encode('hello'), 'aGVsbG8=\n') 26200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the binary flag 26210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.encode('hello\n'), 'aGVsbG8K\n') 26220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.encode('hello\n', 0), 'aGVsbG8NCg==\n') 26230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the maxlinelen arg 26240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.encode('xxxx ' * 20, maxlinelen=40), """\ 26250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg 26260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg 26270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg 26280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IA== 26290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 26300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the eol argument 26310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(base64mime.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 26320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r 26330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r 26340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IHh4eHggeHh4eCB4eHh4IHh4eHgg\r 26350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YieHh4eCB4eHh4IA==\r 26360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 26370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_encode(self): 26390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 26400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi he = base64mime.header_encode 26410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello'), '=?iso-8859-1?b?aGVsbG8=?=') 26420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello\nworld'), '=?iso-8859-1?b?aGVsbG8NCndvcmxk?=') 26430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the charset option 26440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?b?aGVsbG8=?=') 26450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the keep_eols flag 26460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello\nworld', keep_eols=True), 26470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '=?iso-8859-1?b?aGVsbG8Kd29ybGQ=?=') 26480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the maxlinelen argument 26490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('xxxx ' * 20, maxlinelen=40), """\ 26500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?= 26510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?= 26520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?= 26530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?= 26540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?= 26550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""") 26560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the eol argument 26570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 26580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi=?iso-8859-1?b?eHh4eCB4eHh4IHh4eHggeHg=?=\r 26590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eHggeHh4eCB4eHh4IHh4eHg=?=\r 26600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?IHh4eHggeHh4eCB4eHh4IHg=?=\r 26610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eHh4IHh4eHggeHh4eCB4eHg=?=\r 26620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eCB4eHh4IHh4eHggeHh4eCA=?=\r 26630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?b?eHh4eCB4eHh4IHh4eHgg?=""") 26640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestQuopri(unittest.TestCase): 26680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def setUp(self): 26690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.hlit = [chr(x) for x in range(ord('a'), ord('z')+1)] + \ 26700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [chr(x) for x in range(ord('A'), ord('Z')+1)] + \ 26710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [chr(x) for x in range(ord('0'), ord('9')+1)] + \ 26720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ['!', '*', '+', '-', '/', ' '] 26730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.hnon = [chr(x) for x in range(256) if chr(x) not in self.hlit] 26740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi assert len(self.hlit) + len(self.hnon) == 256 26750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.blit = [chr(x) for x in range(ord(' '), ord('~')+1)] + ['\t'] 26760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.blit.remove('=') 26770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.bnon = [chr(x) for x in range(256) if chr(x) not in self.blit] 26780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi assert len(self.blit) + len(self.bnon) == 256 26790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_quopri_check(self): 26810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.hlit: 26820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertFalse(quoprimime.header_quopri_check(c)) 26830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.hnon: 26840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(quoprimime.header_quopri_check(c)) 26850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_body_quopri_check(self): 26870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.blit: 26880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertFalse(quoprimime.body_quopri_check(c)) 26890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.bnon: 26900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(quoprimime.body_quopri_check(c)) 26910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 26920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_quopri_len(self): 26930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 26940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hql = quoprimime.header_quopri_len 26950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi enc = quoprimime.header_encode 26960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for s in ('hello', 'h@e@l@l@o@'): 26970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Empty charset and no line-endings. 7 == RFC chrome 26980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(hql(s), len(enc(s, charset='', eol=''))-7) 26990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.hlit: 27000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(hql(c), 1) 27010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.hnon: 27020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(hql(c), 3) 27030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_body_quopri_len(self): 27050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 27060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi bql = quoprimime.body_quopri_len 27070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.blit: 27080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(bql(c), 1) 27090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for c in self.bnon: 27100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(bql(c), 3) 27110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_quote_unquote_idempotent(self): 27130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for x in range(256): 27140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = chr(x) 27150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(quoprimime.unquote(quoprimime.quote(c)), c) 27160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_encode(self): 27180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 27190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi he = quoprimime.header_encode 27200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello'), '=?iso-8859-1?q?hello?=') 27210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello\nworld'), '=?iso-8859-1?q?hello=0D=0Aworld?=') 27220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the charset option 27230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello', charset='iso-8859-2'), '=?iso-8859-2?q?hello?=') 27240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the keep_eols flag 27250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello\nworld', keep_eols=True), '=?iso-8859-1?q?hello=0Aworld?=') 27260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test a non-ASCII character 27270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('hello\xc7there'), '=?iso-8859-1?q?hello=C7there?=') 27280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the maxlinelen argument 27290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('xxxx ' * 20, maxlinelen=40), """\ 27300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?= 27310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?= 27320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?= 27330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?= 27340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?x_xxxx_xxxx_?=""") 27350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the eol argument 27360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(he('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 27370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi=?iso-8859-1?q?xxxx_xxxx_xxxx_xxxx_xx?=\r 27380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?xx_xxxx_xxxx_xxxx_xxxx?=\r 27390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?_xxxx_xxxx_xxxx_xxxx_x?=\r 27400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?xxx_xxxx_xxxx_xxxx_xxx?=\r 27410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?x_xxxx_xxxx_?=""") 27420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_decode(self): 27440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 27450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.decode(''), '') 27460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.decode('hello'), 'hello') 27470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.decode('hello', 'X'), 'hello') 27480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.decode('hello\nworld', 'X'), 'helloXworld') 27490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_encode(self): 27510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 27520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.encode(''), '') 27530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.encode('hello'), 'hello') 27540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the binary flag 27550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.encode('hello\r\nworld'), 'hello\nworld') 27560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.encode('hello\r\nworld', 0), 'hello\nworld') 27570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the maxlinelen arg 27580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.encode('xxxx ' * 20, maxlinelen=40), """\ 27590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yixxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx= 27600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx= 27610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yix xxxx xxxx xxxx xxxx=20""") 27620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test the eol argument 27630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.encode('xxxx ' * 20, maxlinelen=40, eol='\r\n'), """\ 27640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yixxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx=\r 27650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxx=\r 27660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yix xxxx xxxx xxxx xxxx=20""") 27670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(quoprimime.encode("""\ 27680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yione line 27690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitwo line"""), """\ 27710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yione line 27720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yitwo line""") 27740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test the Charset class 27780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestCharset(unittest.TestCase): 27790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def tearDown(self): 27800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from email import charset as CharsetModule 27810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 27820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi del CharsetModule.CHARSETS['fake'] 27830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except KeyError: 27840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 27850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_idempotent(self): 27870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 27880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Make sure us-ascii = no Unicode conversion 27890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = Charset('us-ascii') 27900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'Hello World!' 27910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sp = c.to_splittable(s) 27920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, c.from_splittable(sp)) 27930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # test 8-bit idempotency with us-ascii 27940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = '\xa4\xa2\xa4\xa4\xa4\xa6\xa4\xa8\xa4\xaa' 27950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi sp = c.to_splittable(s) 27960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, c.from_splittable(sp)) 27970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 27980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_body_encode(self): 27990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 28000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try a charset with QP body encoding 28010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = Charset('iso-8859-1') 28020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('hello w=F6rld', c.body_encode('hello w\xf6rld')) 28030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try a charset with Base64 body encoding 28040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = Charset('utf-8') 28050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('aGVsbG8gd29ybGQ=\n', c.body_encode('hello world')) 28060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try a charset with None body encoding 28070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = Charset('us-ascii') 28080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('hello world', c.body_encode('hello world')) 28090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Try the convert argument, where input codec != output codec 28100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = Charset('euc-jp') 28110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # With apologies to Tokio Kikuchi ;) 28120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi try: 28130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('\x1b$B5FCO;~IW\x1b(B', 28140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7')) 28150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7', 28160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c.body_encode('\xb5\xc6\xc3\xcf\xbb\xfe\xc9\xd7', False)) 28170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi except LookupError: 28180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # We probably don't have the Japanese codecs installed 28190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi pass 28200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Testing SF bug #625509, which we have to fake, since there are no 28210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # built-in encodings where the header encoding is QP but the body 28220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # encoding is not. 28230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi from email import charset as CharsetModule 28240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi CharsetModule.add_charset('fake', CharsetModule.QP, None) 28250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi c = Charset('fake') 28260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq('hello w\xf6rld', c.body_encode('hello w\xf6rld')) 28270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_unicode_charset_name(self): 28290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset = Charset(u'us-ascii') 28300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(str(charset), 'us-ascii') 28310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertRaises(errors.CharsetError, Charset, 'asc\xffii') 28320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test multilingual MIME headers. 28360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestHeader(TestEmailBase): 28370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_simple(self): 28380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 28390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header('Hello World!') 28400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), 'Hello World!') 28410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append(' Goodbye World!') 28420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), 'Hello World! Goodbye World!') 28430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_simple_surprise(self): 28450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 28460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header('Hello World!') 28470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), 'Hello World!') 28480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('Goodbye World!') 28490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), 'Hello World! Goodbye World!') 28500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_needs_no_decoding(self): 28520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = 'no decoding needed' 28530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(decode_header(h), [(h, None)]) 28540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_long(self): 28560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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.", 28570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi maxlinelen=76) 28580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for l in h.encode(splitchars=' ').split('\n '): 28590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertTrue(len(l) <= 76) 28600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 28610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_multilingual(self): 28620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 28630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi g = Charset("iso-8859-1") 28640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cz = Charset("iso-8859-2") 28650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi utf8 = Charset("utf-8") 28660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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. " 28670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi cz_head = "Finan\xe8ni metropole se hroutily pod tlakem jejich d\xf9vtipu.. " 28680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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") 28690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(g_head, g) 28700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append(cz_head, cz) 28710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append(utf8_head, utf8) 28720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi enc = h.encode() 28730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(enc, """\ 28740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi=?iso-8859-1?q?Die_Mieter_treten_hier_ein_werden_mit_einem_Foerderband_ko?= 28750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?mfortabel_den_Korridor_entlang=2C_an_s=FCdl=FCndischen_Wan?= 28760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?dgem=E4lden_vorbei=2C_gegen_die_rotierenden_Klingen_bef=F6?= 28770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-1?q?rdert=2E_?= =?iso-8859-2?q?Finan=E8ni_metropole_se_hroutily?= 28780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?iso-8859-2?q?_pod_tlakem_jejich_d=F9vtipu=2E=2E_?= =?utf-8?b?5q2j56K6?= 28790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44Gr6KiA44GG44Go57+76Kiz44Gv44GV44KM44Gm44GE44G+44Gb44KT44CC?= 28800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?5LiA6YOo44Gv44OJ44Kk44OE6Kqe44Gn44GZ44GM44CB44GC44Go44Gv44Gn?= 28810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44Gf44KJ44KB44Gn44GZ44CC5a6f6Zqb44Gr44Gv44CMV2VubiBpc3QgZGFz?= 28820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?q?_Nunstuck_git_und_Slotermeyer=3F_Ja!_Beiherhund_das_Oder_die_Fl?= 28830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?aXBwZXJ3YWxkdCBnZXJzcHV0LuOAjeOBqOiogOOBo+OBpuOBhOOBvuOBmQ==?= 28840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi =?utf-8?b?44CC?=""") 28850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(decode_header(enc), 28860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi [(g_head, "iso-8859-1"), (cz_head, "iso-8859-2"), 28870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi (utf8_head, "utf-8")]) 28880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ustr = unicode(h) 28890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(ustr.encode('utf-8'), 28900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Die Mieter treten hier ein werden mit einem Foerderband ' 28910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'komfortabel den Korridor entlang, an s\xc3\xbcdl\xc3\xbcndischen ' 28920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Wandgem\xc3\xa4lden vorbei, gegen die rotierenden Klingen ' 28930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'bef\xc3\xb6rdert. Finan\xc4\x8dni metropole se hroutily pod ' 28940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'tlakem jejich d\xc5\xafvtipu.. \xe6\xad\xa3\xe7\xa2\xba\xe3\x81' 28950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\xab\xe8\xa8\x80\xe3\x81\x86\xe3\x81\xa8\xe7\xbf\xbb\xe8\xa8\xb3' 28960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\xe3\x81\xaf\xe3\x81\x95\xe3\x82\x8c\xe3\x81\xa6\xe3\x81\x84\xe3' 28970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\x81\xbe\xe3\x81\x9b\xe3\x82\x93\xe3\x80\x82\xe4\xb8\x80\xe9\x83' 28980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\xa8\xe3\x81\xaf\xe3\x83\x89\xe3\x82\xa4\xe3\x83\x84\xe8\xaa\x9e' 28990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\xe3\x81\xa7\xe3\x81\x99\xe3\x81\x8c\xe3\x80\x81\xe3\x81\x82\xe3' 29000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\x81\xa8\xe3\x81\xaf\xe3\x81\xa7\xe3\x81\x9f\xe3\x82\x89\xe3\x82' 29010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\x81\xe3\x81\xa7\xe3\x81\x99\xe3\x80\x82\xe5\xae\x9f\xe9\x9a\x9b' 29020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\xe3\x81\xab\xe3\x81\xaf\xe3\x80\x8cWenn ist das Nunstuck git ' 29030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'und Slotermeyer? Ja! Beiherhund das Oder die Flipperwaldt ' 29040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'gersput.\xe3\x80\x8d\xe3\x81\xa8\xe8\xa8\x80\xe3\x81\xa3\xe3\x81' 29050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi '\xa6\xe3\x81\x84\xe3\x81\xbe\xe3\x81\x99\xe3\x80\x82') 29060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # Test make_header() 29070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi newh = make_header(decode_header(enc)) 29080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(newh, enc) 29090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_header_ctor_default_args(self): 29110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 29120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header() 29130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h, '') 29140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('foo', Charset('iso-8859-1')) 29150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h, '=?iso-8859-1?q?foo?=') 29160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_explicit_maxlinelen(self): 29180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 29190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hstr = 'A very long line that must get split to something other than at the 76th character boundary to test the non-default behavior' 29200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr) 29210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), '''\ 29220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiA very long line that must get split to something other than at the 76th 29230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi character boundary to test the non-default behavior''') 29240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr, header_name='Subject') 29250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), '''\ 29260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiA very long line that must get split to something other than at the 29270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 76th character boundary to test the non-default behavior''') 29280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(hstr, maxlinelen=1024, header_name='Subject') 29290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), hstr) 29300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_us_ascii_header(self): 29320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 29330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'hello' 29340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = decode_header(s) 29350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(x, [('hello', None)]) 29360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = make_header(x) 29370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, h.encode()) 29380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_string_charset(self): 29400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 29410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header() 29420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('hello', 'iso-8859-1') 29430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h, '=?iso-8859-1?q?hello?=') 29440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## def test_unicode_error(self): 29460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## raises = self.assertRaises 29470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## raises(UnicodeError, Header, u'[P\xf6stal]', 'us-ascii') 29480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## raises(UnicodeError, Header, '[P\xf6stal]', 'us-ascii') 29490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## h = Header() 29500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## raises(UnicodeError, h.append, u'[P\xf6stal]', 'us-ascii') 29510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## raises(UnicodeError, h.append, '[P\xf6stal]', 'us-ascii') 29520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi## raises(UnicodeError, Header, u'\u83ca\u5730\u6642\u592b', 'iso-8859-1') 29530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_utf8_shortest(self): 29550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 29560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(u'p\xf6stal', 'utf-8') 29570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), '=?utf-8?q?p=C3=B6stal?=') 29580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header(u'\u83ca\u5730\u6642\u592b', 'utf-8') 29590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), '=?utf-8?b?6I+K5Zyw5pmC5aSr?=') 29600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_bad_8bit_header(self): 29620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raises = self.assertRaises 29630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 29640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi x = 'Ynwp4dUEbay Auction Semiar- No Charge \x96 Earn Big' 29650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raises(UnicodeError, Header, x) 29660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header() 29670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raises(UnicodeError, h.append, x) 29680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(str(Header(x, errors='replace')), x) 29690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append(x, errors='replace') 29700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(str(h), x) 29710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_encoded_adjacent_nonencoded(self): 29730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 29740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = Header() 29750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('hello', 'iso-8859-1') 29760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h.append('world') 29770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = h.encode() 29780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, '=?iso-8859-1?q?hello?= world') 29790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi h = make_header(decode_header(s)) 29800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(h.encode(), s) 29810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_whitespace_eater(self): 29830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 29840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztk=?= =?koi8-r?q?=CA?= zz.' 29850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi parts = decode_header(s) 29860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 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)]) 29870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi hdr = make_header(parts) 29880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(hdr.encode(), 29890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'Subject: =?koi8-r?b?8NLP18XSy8EgzsEgxsnOwczYztnK?= zz.') 29900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_broken_base64_header(self): 29920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raises = self.assertRaises 29930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi s = 'Subject: =?EUC-KR?B?CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3I ?=' 29940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi raises(errors.HeaderParseError, decode_header, s) 29950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 29980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi# Test RFC 2231 header parameters (en/de)coding 29990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiclass TestRFC2231(TestEmailBase): 30000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_get_param(self): 30010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 30020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_29.txt') 30030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('title'), 30040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!')) 30050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('title', unquote=False), 30060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('us-ascii', 'en', '"This is even more ***fun*** isn\'t it!"')) 30070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_set_param(self): 30090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 30100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = Message() 30110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 30120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset='us-ascii') 30130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('title'), 30140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('us-ascii', '', 'This is even more ***fun*** isn\'t it!')) 30150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 30160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset='us-ascii', language='en') 30170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('title'), 30180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi ('us-ascii', 'en', 'This is even more ***fun*** isn\'t it!')) 30190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 30200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 30210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset='us-ascii', language='en') 30220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.ndiffAssertEqual(msg.as_string(), """\ 30230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReturn-Path: <bbb@zzz.org> 30240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDelivered-To: bbb@zzz.org 30250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived: by mail.zzz.org (Postfix, from userid 889) 30260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) 30270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 30280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 30290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMessage-ID: <15090.61304.110929.45684@aaa.zzz.org> 30300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bbb@ddd.com (John X. Doe) 30310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: bbb@zzz.org 30320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: This is a test message 30330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDate: Fri, 4 May 2001 14:05:44 -0400 30340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset=us-ascii; 30350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi title*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21" 30360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHi, 30390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDo you like this message? 30410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-Me 30430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 30440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_del_param(self): 30460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.ndiffAssertEqual 30470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_01.txt') 30480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('foo', 'bar', charset='us-ascii', language='en') 30490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.set_param('title', 'This is even more ***fun*** isn\'t it!', 30500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset='us-ascii', language='en') 30510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.del_param('foo', header='Content-Type') 30520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.as_string(), """\ 30530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReturn-Path: <bbb@zzz.org> 30540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDelivered-To: bbb@zzz.org 30550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiReceived: by mail.zzz.org (Postfix, from userid 889) 30560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) 30570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMIME-Version: 1.0 30580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 7bit 30590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiMessage-ID: <15090.61304.110929.45684@aaa.zzz.org> 30600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiFrom: bbb@ddd.com (John X. Doe) 30610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiTo: bbb@zzz.org 30620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiSubject: This is a test message 30630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDate: Fri, 4 May 2001 14:05:44 -0400 30640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset="us-ascii"; 30650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi title*="us-ascii'en'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20isn%27t%20it%21" 30660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiHi, 30690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiDo you like this message? 30710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi-Me 30730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""") 30740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_get_content_charset(self): 30760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 30770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = self._msgobj('msg_32.txt') 30780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_content_charset(), 'us-ascii') 30790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_no_language_or_charset(self): 30810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 30820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 8bit 30830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; filename="file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm" 30840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/html; NAME*0=file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEM; NAME*1=P_nsmail.htm 30850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 30870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 30880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi param = msg.get_param('NAME') 30890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertFalse(isinstance(param, tuple)) 30900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 30910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi param, 30920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'file____C__DOCUMENTS_20AND_20SETTINGS_FABIEN_LOCAL_20SETTINGS_TEMP_nsmail.htm') 30930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 30940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_no_language_or_charset_in_filename(self): 30950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 30960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; 30970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*0*="''This%20is%20even%20more%20"; 30980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 30990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*2="is it not.pdf" 31000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 31020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_filename(), 31040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is even more ***fun*** is it not.pdf') 31050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_no_language_or_charset_in_filename_encoded(self): 31070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 31080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; 31090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*0*="''This%20is%20even%20more%20"; 31100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 31110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*2="is it not.pdf" 31120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 31140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_filename(), 31160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is even more ***fun*** is it not.pdf') 31170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_partly_encoded(self): 31190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 31200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; 31210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*0="''This%20is%20even%20more%20"; 31220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 31230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*2="is it not.pdf" 31240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 31260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 31280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.get_filename(), 31290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This%20is%20even%20more%20***fun*** is it not.pdf') 31300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_partly_nonencoded(self): 31320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 31330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; 31340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*0="This%20is%20even%20more%20"; 31350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*1="%2A%2A%2Afun%2A%2A%2A%20"; 31360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*2="is it not.pdf" 31370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 31390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual( 31410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg.get_filename(), 31420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This%20is%20even%20more%20%2A%2A%2Afun%2A%2A%2A%20is it not.pdf') 31430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_no_language_or_charset_in_boundary(self): 31450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 31460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: multipart/alternative; 31470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tboundary*0*="''This%20is%20even%20more%20"; 31480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tboundary*1*="%2A%2A%2Afun%2A%2A%2A%20"; 31490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tboundary*2="is it not.pdf" 31500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 31520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_boundary(), 31540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is even more ***fun*** is it not.pdf') 31550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_no_language_or_charset_in_charset(self): 31570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This is a nonsensical charset value, but tests the code anyway 31580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 31590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; 31600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tcharset*0*="This%20is%20even%20more%20"; 31610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tcharset*1*="%2A%2A%2Afun%2A%2A%2A%20"; 31620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tcharset*2="is it not.pdf" 31630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 31650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_charset(), 31670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'this is even more ***fun*** is it not.pdf') 31680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_bad_encoding_in_filename(self): 31700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 31710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; 31720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*0*="bogus'xx'This%20is%20even%20more%20"; 31730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 31740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*2="is it not.pdf" 31750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 31770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_filename(), 31790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 'This is even more ***fun*** is it not.pdf') 31800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_bad_encoding_in_charset(self): 31820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 31830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset*=bogus''utf-8%E2%80%9D 31840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 31860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This should return None because non-ascii characters in the charset 31880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # are not allowed. 31890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_charset(), None) 31900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_bad_character_in_charset(self): 31920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 31930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: text/plain; charset*=ascii''utf-8%E2%80%9D 31940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 31950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 31960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 31970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # This should return None because non-ascii characters in the charset 31980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi # are not allowed. 31990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_content_charset(), None) 32000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_bad_character_in_filename(self): 32020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = '''\ 32030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; 32040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*0*="ascii'xx'This%20is%20even%20more%20"; 32050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*1*="%2A%2A%2Afun%2A%2A%2A%20"; 32060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tfilename*2*="is it not.pdf%E2" 32070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi''' 32090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_filename(), 32110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi u'This is even more ***fun*** is it not.pdf\ufffd') 32120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_unknown_encoding(self): 32140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Transfer-Encoding: 8bit 32160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Disposition: inline; filename*=X-UNKNOWN''myfile.txt 32170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 32190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(msg.get_filename(), 'myfile.txt') 32210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_single_tick_in_filename_extended(self): 32230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 32240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: application/x-foo; 32260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*0*=\"Frank's\"; name*1*=\" Document\" 32270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 32290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32300c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset, language, s = msg.get_param('name') 32310c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charset, None) 32320c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(language, None) 32330c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, "Frank's Document") 32340c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32350c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_single_tick_in_filename(self): 32360c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32370c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: application/x-foo; name*0=\"Frank's\"; name*1=\" Document\" 32380c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32390c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 32400c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32410c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi param = msg.get_param('name') 32420c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertFalse(isinstance(param, tuple)) 32430c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(param, "Frank's Document") 32440c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32450c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_tick_attack_extended(self): 32460c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 32470c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32480c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: application/x-foo; 32490c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*0*=\"us-ascii'en-us'Frank's\"; name*1*=\" Document\" 32500c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32510c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 32520c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32530c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset, language, s = msg.get_param('name') 32540c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charset, 'us-ascii') 32550c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(language, 'en-us') 32560c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, "Frank's Document") 32570c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32580c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_tick_attack(self): 32590c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32600c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: application/x-foo; 32610c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*0=\"us-ascii'en-us'Frank's\"; name*1=\" Document\" 32620c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32630c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 32640c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32650c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi param = msg.get_param('name') 32660c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertFalse(isinstance(param, tuple)) 32670c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi self.assertEqual(param, "us-ascii'en-us'Frank's Document") 32680c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32690c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_no_extended_values(self): 32700c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 32710c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32720c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: application/x-foo; name=\"Frank's Document\" 32730c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32740c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 32750c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32760c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(msg.get_param('name'), "Frank's Document") 32770c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32780c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_encoded_then_unencoded_segments(self): 32790c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 32800c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32810c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: application/x-foo; 32820c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*0*=\"us-ascii'en-us'My\"; 32830c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*1=\" Document\"; 32840c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*2*=\" For You\" 32850c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32860c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 32870c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 32880c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset, language, s = msg.get_param('name') 32890c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charset, 'us-ascii') 32900c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(language, 'en-us') 32910c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, 'My Document For You') 32920c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 32930c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi def test_rfc2231_unencoded_then_encoded_segments(self): 32940c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq = self.assertEqual 32950c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi m = """\ 32960c5958b1636c47ed7c284f859c8e805fd06a0e6Bill YiContent-Type: application/x-foo; 32970c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*0=\"us-ascii'en-us'My\"; 32980c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*1*=\" Document\"; 32990c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi\tname*2*=\" For You\" 33000c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33010c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi""" 33020c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi msg = email.message_from_string(m) 33030c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi charset, language, s = msg.get_param('name') 33040c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(charset, 'us-ascii') 33050c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(language, 'en-us') 33060c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi eq(s, 'My Document For You') 33070c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33080c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33090c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33100c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef _testclasses(): 33110c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi mod = sys.modules[__name__] 33120c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return [getattr(mod, name) for name in dir(mod) if name.startswith('Test')] 33130c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33140c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33150c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef suite(): 33160c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi suite = unittest.TestSuite() 33170c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for testclass in _testclasses(): 33180c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi suite.addTest(unittest.makeSuite(testclass)) 33190c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi return suite 33200c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33210c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33220c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yidef test_main(): 33230c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi for testclass in _testclasses(): 33240c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi run_unittest(testclass) 33250c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33260c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33270c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi 33280c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yiif __name__ == '__main__': 33290c5958b1636c47ed7c284f859c8e805fd06a0e6Bill Yi unittest.main(defaultTest='suite') 3330