python (3.12.0)
1 """Test the parser and generator are inverses.
2
3 Note that this is only strictly true if we are parsing RFC valid messages and
4 producing RFC valid messages.
5 """
6
7 import io
8 import unittest
9 from email import policy, message_from_bytes
10 from email.message import EmailMessage
11 from email.generator import BytesGenerator
12 from test.test_email import TestEmailBase, parameterize
13
14 # This is like textwrap.dedent for bytes, except that it uses \r\n for the line
15 # separators on the rebuilt string.
16 def dedent(bstr):
17 lines = bstr.splitlines()
18 if not lines[0].strip():
19 raise ValueError("First line must contain text")
20 stripamt = len(lines[0]) - len(lines[0].lstrip())
21 return b'\r\n'.join(
22 [x[stripamt:] if len(x)>=stripamt else b''
23 for x in lines])
24
25
26 @parameterize
27 class ESC[4;38;5;81mTestInversion(ESC[4;38;5;149mTestEmailBase):
28
29 policy = policy.default
30 message = EmailMessage
31
32 def msg_as_input(self, msg):
33 m = message_from_bytes(msg, policy=policy.SMTP)
34 b = io.BytesIO()
35 g = BytesGenerator(b)
36 g.flatten(m)
37 self.assertEqual(b.getvalue(), msg)
38
39 # XXX: spaces are not preserved correctly here yet in the general case.
40 msg_params = {
41 'header_with_one_space_body': (dedent(b"""\
42 From: abc@xyz.com
43 X-Status:\x20
44 Subject: test
45
46 foo
47 """),),
48
49 'header_with_invalid_date': (dedent(b"""\
50 Date: Tue, 06 Jun 2017 27:39:33 +0600
51 From: abc@xyz.com
52 Subject: timezones
53
54 How do they work even?
55 """),),
56
57 }
58
59 payload_params = {
60 'plain_text': dict(payload='This is a test\n'*20),
61 'base64_text': dict(payload=(('xy a'*40+'\n')*5), cte='base64'),
62 'qp_text': dict(payload=(('xy a'*40+'\n')*5), cte='quoted-printable'),
63 }
64
65 def payload_as_body(self, payload, **kw):
66 msg = self._make_message()
67 msg['From'] = 'foo'
68 msg['To'] = 'bar'
69 msg['Subject'] = 'payload round trip test'
70 msg.set_content(payload, **kw)
71 b = bytes(msg)
72 msg2 = message_from_bytes(b, policy=self.policy)
73 self.assertEqual(bytes(msg2), b)
74 self.assertEqual(msg2.get_content(), payload)
75
76
77 if __name__ == '__main__':
78 unittest.main()