Mercurial > p > roundup > code
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 |
