mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			199 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import io
 | 
						|
import textwrap
 | 
						|
import unittest
 | 
						|
from email import message_from_string, message_from_bytes
 | 
						|
from email.generator import Generator, BytesGenerator
 | 
						|
from email import policy
 | 
						|
from test.test_email import TestEmailBase, parameterize
 | 
						|
 | 
						|
 | 
						|
@parameterize
 | 
						|
class TestGeneratorBase:
 | 
						|
 | 
						|
    policy = policy.default
 | 
						|
 | 
						|
    def msgmaker(self, msg, policy=None):
 | 
						|
        policy = self.policy if policy is None else policy
 | 
						|
        return self.msgfunc(msg, policy=policy)
 | 
						|
 | 
						|
    refold_long_expected = {
 | 
						|
        0: textwrap.dedent("""\
 | 
						|
            To: whom_it_may_concern@example.com
 | 
						|
            From: nobody_you_want_to_know@example.com
 | 
						|
            Subject: We the willing led by the unknowing are doing the
 | 
						|
             impossible for the ungrateful. We have done so much for so long with so little
 | 
						|
             we are now qualified to do anything with nothing.
 | 
						|
 | 
						|
            None
 | 
						|
            """),
 | 
						|
        # From is wrapped because wrapped it fits in 40.
 | 
						|
        40: textwrap.dedent("""\
 | 
						|
            To: whom_it_may_concern@example.com
 | 
						|
            From:
 | 
						|
             nobody_you_want_to_know@example.com
 | 
						|
            Subject: We the willing led by the
 | 
						|
             unknowing are doing the impossible for
 | 
						|
             the ungrateful. We have done so much
 | 
						|
             for so long with so little we are now
 | 
						|
             qualified to do anything with nothing.
 | 
						|
 | 
						|
            None
 | 
						|
            """),
 | 
						|
        # Neither to nor from fit even if put on a new line,
 | 
						|
        # so we leave them sticking out on the first line.
 | 
						|
        20: textwrap.dedent("""\
 | 
						|
            To: whom_it_may_concern@example.com
 | 
						|
            From: nobody_you_want_to_know@example.com
 | 
						|
            Subject: We the
 | 
						|
             willing led by the
 | 
						|
             unknowing are doing
 | 
						|
             the impossible for
 | 
						|
             the ungrateful. We
 | 
						|
             have done so much
 | 
						|
             for so long with so
 | 
						|
             little we are now
 | 
						|
             qualified to do
 | 
						|
             anything with
 | 
						|
             nothing.
 | 
						|
 | 
						|
            None
 | 
						|
            """),
 | 
						|
        }
 | 
						|
    refold_long_expected[100] = refold_long_expected[0]
 | 
						|
 | 
						|
    refold_all_expected = refold_long_expected.copy()
 | 
						|
    refold_all_expected[0] = (
 | 
						|
            "To: whom_it_may_concern@example.com\n"
 | 
						|
            "From: nobody_you_want_to_know@example.com\n"
 | 
						|
            "Subject: We the willing led by the unknowing are doing the "
 | 
						|
              "impossible for the ungrateful. We have done so much for "
 | 
						|
              "so long with so little we are now qualified to do anything "
 | 
						|
              "with nothing.\n"
 | 
						|
              "\n"
 | 
						|
              "None\n")
 | 
						|
    refold_all_expected[100] = (
 | 
						|
            "To: whom_it_may_concern@example.com\n"
 | 
						|
            "From: nobody_you_want_to_know@example.com\n"
 | 
						|
            "Subject: We the willing led by the unknowing are doing the "
 | 
						|
                "impossible for the ungrateful. We have\n"
 | 
						|
              " done so much for so long with so little we are now qualified "
 | 
						|
                "to do anything with nothing.\n"
 | 
						|
              "\n"
 | 
						|
              "None\n")
 | 
						|
 | 
						|
    length_params = [n for n in refold_long_expected]
 | 
						|
 | 
						|
    def length_as_maxheaderlen_parameter(self, n):
 | 
						|
        msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
 | 
						|
        s = self.ioclass()
 | 
						|
        g = self.genclass(s, maxheaderlen=n, policy=self.policy)
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[n]))
 | 
						|
 | 
						|
    def length_as_max_line_length_policy(self, n):
 | 
						|
        msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
 | 
						|
        s = self.ioclass()
 | 
						|
        g = self.genclass(s, policy=self.policy.clone(max_line_length=n))
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[n]))
 | 
						|
 | 
						|
    def length_as_maxheaderlen_parm_overrides_policy(self, n):
 | 
						|
        msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
 | 
						|
        s = self.ioclass()
 | 
						|
        g = self.genclass(s, maxheaderlen=n,
 | 
						|
                          policy=self.policy.clone(max_line_length=10))
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[n]))
 | 
						|
 | 
						|
    def length_as_max_line_length_with_refold_none_does_not_fold(self, n):
 | 
						|
        msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
 | 
						|
        s = self.ioclass()
 | 
						|
        g = self.genclass(s, policy=self.policy.clone(refold_source='none',
 | 
						|
                                                      max_line_length=n))
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[0]))
 | 
						|
 | 
						|
    def length_as_max_line_length_with_refold_all_folds(self, n):
 | 
						|
        msg = self.msgmaker(self.typ(self.refold_long_expected[0]))
 | 
						|
        s = self.ioclass()
 | 
						|
        g = self.genclass(s, policy=self.policy.clone(refold_source='all',
 | 
						|
                                                      max_line_length=n))
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), self.typ(self.refold_all_expected[n]))
 | 
						|
 | 
						|
    def test_crlf_control_via_policy(self):
 | 
						|
        source = "Subject: test\r\n\r\ntest body\r\n"
 | 
						|
        expected = source
 | 
						|
        msg = self.msgmaker(self.typ(source))
 | 
						|
        s = self.ioclass()
 | 
						|
        g = self.genclass(s, policy=policy.SMTP)
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), self.typ(expected))
 | 
						|
 | 
						|
    def test_flatten_linesep_overrides_policy(self):
 | 
						|
        source = "Subject: test\n\ntest body\n"
 | 
						|
        expected = source
 | 
						|
        msg = self.msgmaker(self.typ(source))
 | 
						|
        s = self.ioclass()
 | 
						|
        g = self.genclass(s, policy=policy.SMTP)
 | 
						|
        g.flatten(msg, linesep='\n')
 | 
						|
        self.assertEqual(s.getvalue(), self.typ(expected))
 | 
						|
 | 
						|
 | 
						|
class TestGenerator(TestGeneratorBase, TestEmailBase):
 | 
						|
 | 
						|
    msgfunc = staticmethod(message_from_string)
 | 
						|
    genclass = Generator
 | 
						|
    ioclass = io.StringIO
 | 
						|
    typ = str
 | 
						|
 | 
						|
 | 
						|
class TestBytesGenerator(TestGeneratorBase, TestEmailBase):
 | 
						|
 | 
						|
    msgfunc = staticmethod(message_from_bytes)
 | 
						|
    genclass = BytesGenerator
 | 
						|
    ioclass = io.BytesIO
 | 
						|
    typ = lambda self, x: x.encode('ascii')
 | 
						|
 | 
						|
    def test_cte_type_7bit_handles_unknown_8bit(self):
 | 
						|
        source = ("Subject: Maintenant je vous présente mon "
 | 
						|
                 "collègue\n\n").encode('utf-8')
 | 
						|
        expected = ('Subject: Maintenant je vous =?unknown-8bit?q?'
 | 
						|
                    'pr=C3=A9sente_mon_coll=C3=A8gue?=\n\n').encode('ascii')
 | 
						|
        msg = message_from_bytes(source)
 | 
						|
        s = io.BytesIO()
 | 
						|
        g = BytesGenerator(s, policy=self.policy.clone(cte_type='7bit'))
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), expected)
 | 
						|
 | 
						|
    def test_cte_type_7bit_transforms_8bit_cte(self):
 | 
						|
        source = textwrap.dedent("""\
 | 
						|
            From: foo@bar.com
 | 
						|
            To: Dinsdale
 | 
						|
            Subject: Nudge nudge, wink, wink
 | 
						|
            Mime-Version: 1.0
 | 
						|
            Content-Type: text/plain; charset="latin-1"
 | 
						|
            Content-Transfer-Encoding: 8bit
 | 
						|
 | 
						|
            oh là là, know what I mean, know what I mean?
 | 
						|
            """).encode('latin1')
 | 
						|
        msg = message_from_bytes(source)
 | 
						|
        expected =  textwrap.dedent("""\
 | 
						|
            From: foo@bar.com
 | 
						|
            To: Dinsdale
 | 
						|
            Subject: Nudge nudge, wink, wink
 | 
						|
            Mime-Version: 1.0
 | 
						|
            Content-Type: text/plain; charset="iso-8859-1"
 | 
						|
            Content-Transfer-Encoding: quoted-printable
 | 
						|
 | 
						|
            oh l=E0 l=E0, know what I mean, know what I mean?
 | 
						|
            """).encode('ascii')
 | 
						|
        s = io.BytesIO()
 | 
						|
        g = BytesGenerator(s, policy=self.policy.clone(cte_type='7bit',
 | 
						|
                                                       linesep='\n'))
 | 
						|
        g.flatten(msg)
 | 
						|
        self.assertEqual(s.getvalue(), expected)
 | 
						|
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    unittest.main()
 |