comparison test/test_multipart.py @ 1975:30a444b7b212

*** empty log message ***
author Johannes Gijsbers <jlgijsbers@users.sourceforge.net>
date Sat, 17 Jan 2004 13:49:06 +0000
parents f63aa57386b0
children 6b3919328381
comparison
equal deleted inserted replaced
1973:b019d0194d27 1975:30a444b7b212
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" 14 # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17 # 17 #
18 # $Id: test_multipart.py,v 1.6 2003-10-25 22:53:26 richard Exp $ 18 # $Id: test_multipart.py,v 1.7 2004-01-17 13:49:06 jlgijsbers Exp $
19 19
20 import unittest, cStringIO 20 import unittest
21 from cStringIO import StringIO
21 22
22 from roundup.mailgw import Message 23 from roundup.mailgw import Message
24
25 class TestMessage(Message):
26 table = {'multipart/signed': ' boundary="boundary-%(indent)s";\n',
27 'multipart/mixed': ' boundary="boundary-%(indent)s";\n',
28 'multipart/alternative': ' boundary="boundary-%(indent)s";\n',
29 'text/plain': ' name="foo.txt"\nfoo\n',
30 'application/pgp-signature': ' name="foo.gpg"\nfoo\n',
31 'application/pdf': ' name="foo.pdf"\nfoo\n',
32 'message/rfc822': 'Subject: foo\n\nfoo\n'}
33
34 def __init__(self, spec):
35 """Create a basic MIME message according to 'spec'.
36
37 Each line of a spec has one content-type, which is optionally indented.
38 The indentation signifies how deep in the MIME hierarchy the
39 content-type is.
40
41 """
42 parts = []
43 for line in spec.splitlines():
44 content_type = line.strip()
45 if not content_type:
46 continue
47
48 indent = self.getIndent(line)
49 if indent:
50 parts.append('--boundary-%s\n' % indent)
51 parts.append('Content-type: %s;\n' % content_type)
52 parts.append(self.table[content_type] % {'indent': indent + 1})
53
54 Message.__init__(self, StringIO(''.join(parts)))
55
56 def getIndent(self, line):
57 """Get the current line's indentation, using four-space indents."""
58 count = 0
59 for char in line:
60 if char != ' ':
61 break
62 count += 1
63 return count / 4
23 64
24 class MultipartTestCase(unittest.TestCase): 65 class MultipartTestCase(unittest.TestCase):
25 def setUp(self): 66 def setUp(self):
26 self.fp = cStringIO.StringIO() 67 self.fp = StringIO()
27 w = self.fp.write 68 w = self.fp.write
28 w('Content-Type: multipart/mixed; boundary="foo"\r\n\r\n') 69 w('Content-Type: multipart/mixed; boundary="foo"\r\n\r\n')
29 w('This is a multipart message. Ignore this bit.\r\n') 70 w('This is a multipart message. Ignore this bit.\r\n')
30 w('--foo\r\n') 71 w('--foo\r\n')
31 72
60 def testMultipart(self): 101 def testMultipart(self):
61 m = Message(self.fp) 102 m = Message(self.fp)
62 self.assert_(m is not None) 103 self.assert_(m is not None)
63 104
64 # skip the first bit 105 # skip the first bit
65 p = m.getPart() 106 p = m.getpart()
66 self.assert_(p is not None) 107 self.assert_(p is not None)
67 self.assertEqual(p.fp.read(), 108 self.assertEqual(p.fp.read(),
68 'This is a multipart message. Ignore this bit.\r\n') 109 'This is a multipart message. Ignore this bit.\r\n')
69 110
70 # first text/plain 111 # first text/plain
71 p = m.getPart() 112 p = m.getpart()
72 self.assert_(p is not None) 113 self.assert_(p is not None)
73 self.assertEqual(p.gettype(), 'text/plain') 114 self.assertEqual(p.gettype(), 'text/plain')
74 self.assertEqual(p.fp.read(), 115 self.assertEqual(p.fp.read(),
75 'Hello, world!\r\n\r\nBlah blah\r\nfoo\r\n-foo\r\n') 116 'Hello, world!\r\n\r\nBlah blah\r\nfoo\r\n-foo\r\n')
76 117
77 # sub-multipart 118 # sub-multipart
78 p = m.getPart() 119 p = m.getpart()
79 self.assert_(p is not None) 120 self.assert_(p is not None)
80 self.assertEqual(p.gettype(), 'multipart/alternative') 121 self.assertEqual(p.gettype(), 'multipart/alternative')
81 122
82 # sub-multipart text/plain 123 # sub-multipart text/plain
83 q = p.getPart() 124 q = p.getpart()
84 self.assert_(q is not None) 125 self.assert_(q is not None)
85 q = p.getPart() 126 q = p.getpart()
86 self.assert_(q is not None) 127 self.assert_(q is not None)
87 self.assertEqual(q.gettype(), 'text/plain') 128 self.assertEqual(q.gettype(), 'text/plain')
88 self.assertEqual(q.fp.read(), 'Hello, world!\r\n\r\nBlah blah\r\n') 129 self.assertEqual(q.fp.read(), 'Hello, world!\r\n\r\nBlah blah\r\n')
89 130
90 # sub-multipart text/html 131 # sub-multipart text/html
91 q = p.getPart() 132 q = p.getpart()
92 self.assert_(q is not None) 133 self.assert_(q is not None)
93 self.assertEqual(q.gettype(), 'text/html') 134 self.assertEqual(q.gettype(), 'text/html')
94 self.assertEqual(q.fp.read(), '<b>Hello, world!</b>\r\n') 135 self.assertEqual(q.fp.read(), '<b>Hello, world!</b>\r\n')
95 136
96 # sub-multipart end 137 # sub-multipart end
97 q = p.getPart() 138 q = p.getpart()
98 self.assert_(q is None) 139 self.assert_(q is None)
99 140
100 # final text/plain 141 # final text/plain
101 p = m.getPart() 142 p = m.getpart()
102 self.assert_(p is not None) 143 self.assert_(p is not None)
103 self.assertEqual(p.gettype(), 'text/plain') 144 self.assertEqual(p.gettype(), 'text/plain')
104 self.assertEqual(p.fp.read(), 145 self.assertEqual(p.fp.read(),
105 'Last bit\n') 146 'Last bit\n')
106 147
107 # end 148 # end
108 p = m.getPart() 149 p = m.getpart()
109 self.assert_(p is None) 150 self.assert_(p is None)
151
152 def TestExtraction(self, spec, expected):
153 self.assertEqual(TestMessage(spec).extract_content(), expected)
154
155 def testTextPlain(self):
156 self.TestExtraction('text/plain', ('foo\n', []))
157
158 def testAttachedTextPlain(self):
159 self.TestExtraction("""
160 multipart/mixed
161 text/plain
162 text/plain""",
163 ('foo\n',
164 [('foo.txt', 'text/plain', 'foo\n')]))
165
166 def testMultipartMixed(self):
167 self.TestExtraction("""
168 multipart/mixed
169 text/plain
170 application/pdf""",
171 ('foo\n',
172 [('foo.pdf', 'application/pdf', 'foo\n')]))
173
174 def testMultipartAlternative(self):
175 self.TestExtraction("""
176 multipart/alternative
177 text/plain
178 application/pdf
179 """, ('foo\n', [('foo.pdf', 'application/pdf', 'foo\n')]))
180
181 def testDeepMultipartAlternative(self):
182 self.TestExtraction("""
183 multipart/mixed
184 multipart/alternative
185 text/plain
186 application/pdf
187 """, ('foo\n', [('foo.pdf', 'application/pdf', 'foo\n')]))
188
189 def testSignedText(self):
190 self.TestExtraction("""
191 multipart/signed
192 text/plain
193 application/pgp-signature""", ('foo\n', []))
194
195 def testSignedAttachments(self):
196 self.TestExtraction("""
197 multipart/signed
198 multipart/mixed
199 text/plain
200 application/pdf
201 application/pgp-signature""",
202 ('foo\n',
203 [('foo.pdf', 'application/pdf', 'foo\n')]))
204
205 def testAttachedSignature(self):
206 self.TestExtraction("""
207 multipart/mixed
208 text/plain
209 application/pgp-signature""",
210 ('foo\n',
211 [('foo.gpg', 'application/pgp-signature', 'foo\n')]))
212
213 def testMessageRfc822(self):
214 self.TestExtraction("""
215 multipart/mixed
216 message/rfc822""",
217 (None,
218 [('foo', 'message/rfc822', 'foo\n')]))
110 219
111 def test_suite(): 220 def test_suite():
112 suite = unittest.TestSuite() 221 suite = unittest.TestSuite()
113 suite.addTest(unittest.makeSuite(MultipartTestCase)) 222 suite.addTest(unittest.makeSuite(MultipartTestCase))
114 return suite 223 return suite

Roundup Issue Tracker: http://roundup-tracker.org/