1 import unittest
2 from email import _encoded_words as _ew
3 from email import errors
4 from test.test_email import TestEmailBase
5
6
7 class ESC[4;38;5;81mTestDecodeQ(ESC[4;38;5;149mTestEmailBase):
8
9 def _test(self, source, ex_result, ex_defects=[]):
10 result, defects = _ew.decode_q(source)
11 self.assertEqual(result, ex_result)
12 self.assertDefectsEqual(defects, ex_defects)
13
14 def test_no_encoded(self):
15 self._test(b'foobar', b'foobar')
16
17 def test_spaces(self):
18 self._test(b'foo=20bar=20', b'foo bar ')
19 self._test(b'foo_bar_', b'foo bar ')
20
21 def test_run_of_encoded(self):
22 self._test(b'foo=20=20=21=2Cbar', b'foo !,bar')
23
24
25 class ESC[4;38;5;81mTestDecodeB(ESC[4;38;5;149mTestEmailBase):
26
27 def _test(self, source, ex_result, ex_defects=[]):
28 result, defects = _ew.decode_b(source)
29 self.assertEqual(result, ex_result)
30 self.assertDefectsEqual(defects, ex_defects)
31
32 def test_simple(self):
33 self._test(b'Zm9v', b'foo')
34
35 def test_missing_padding(self):
36 # 1 missing padding character
37 self._test(b'dmk', b'vi', [errors.InvalidBase64PaddingDefect])
38 # 2 missing padding characters
39 self._test(b'dg', b'v', [errors.InvalidBase64PaddingDefect])
40
41 def test_invalid_character(self):
42 self._test(b'dm\x01k===', b'vi', [errors.InvalidBase64CharactersDefect])
43
44 def test_invalid_character_and_bad_padding(self):
45 self._test(b'dm\x01k', b'vi', [errors.InvalidBase64CharactersDefect,
46 errors.InvalidBase64PaddingDefect])
47
48 def test_invalid_length(self):
49 self._test(b'abcde', b'abcde', [errors.InvalidBase64LengthDefect])
50
51
52 class ESC[4;38;5;81mTestDecode(ESC[4;38;5;149mTestEmailBase):
53
54 def test_wrong_format_input_raises(self):
55 with self.assertRaises(ValueError):
56 _ew.decode('=?badone?=')
57 with self.assertRaises(ValueError):
58 _ew.decode('=?')
59 with self.assertRaises(ValueError):
60 _ew.decode('')
61 with self.assertRaises(KeyError):
62 _ew.decode('=?utf-8?X?somevalue?=')
63
64 def _test(self, source, result, charset='us-ascii', lang='', defects=[]):
65 res, char, l, d = _ew.decode(source)
66 self.assertEqual(res, result)
67 self.assertEqual(char, charset)
68 self.assertEqual(l, lang)
69 self.assertDefectsEqual(d, defects)
70
71 def test_simple_q(self):
72 self._test('=?us-ascii?q?foo?=', 'foo')
73
74 def test_simple_b(self):
75 self._test('=?us-ascii?b?dmk=?=', 'vi')
76
77 def test_q_case_ignored(self):
78 self._test('=?us-ascii?Q?foo?=', 'foo')
79
80 def test_b_case_ignored(self):
81 self._test('=?us-ascii?B?dmk=?=', 'vi')
82
83 def test_non_trivial_q(self):
84 self._test('=?latin-1?q?=20F=fcr=20Elise=20?=', ' Für Elise ', 'latin-1')
85
86 def test_q_escaped_bytes_preserved(self):
87 self._test(b'=?us-ascii?q?=20\xACfoo?='.decode('us-ascii',
88 'surrogateescape'),
89 ' \uDCACfoo',
90 defects = [errors.UndecodableBytesDefect])
91
92 def test_b_undecodable_bytes_ignored_with_defect(self):
93 self._test(b'=?us-ascii?b?dm\xACk?='.decode('us-ascii',
94 'surrogateescape'),
95 'vi',
96 defects = [
97 errors.InvalidBase64CharactersDefect,
98 errors.InvalidBase64PaddingDefect])
99
100 def test_b_invalid_bytes_ignored_with_defect(self):
101 self._test('=?us-ascii?b?dm\x01k===?=',
102 'vi',
103 defects = [errors.InvalidBase64CharactersDefect])
104
105 def test_b_invalid_bytes_incorrect_padding(self):
106 self._test('=?us-ascii?b?dm\x01k?=',
107 'vi',
108 defects = [
109 errors.InvalidBase64CharactersDefect,
110 errors.InvalidBase64PaddingDefect])
111
112 def test_b_padding_defect(self):
113 self._test('=?us-ascii?b?dmk?=',
114 'vi',
115 defects = [errors.InvalidBase64PaddingDefect])
116
117 def test_nonnull_lang(self):
118 self._test('=?us-ascii*jive?q?test?=', 'test', lang='jive')
119
120 def test_unknown_8bit_charset(self):
121 self._test('=?unknown-8bit?q?foo=ACbar?=',
122 b'foo\xacbar'.decode('ascii', 'surrogateescape'),
123 charset = 'unknown-8bit',
124 defects = [])
125
126 def test_unknown_charset(self):
127 self._test('=?foobar?q?foo=ACbar?=',
128 b'foo\xacbar'.decode('ascii', 'surrogateescape'),
129 charset = 'foobar',
130 # XXX Should this be a new Defect instead?
131 defects = [errors.CharsetError])
132
133 def test_invalid_character_in_charset(self):
134 self._test('=?utf-8\udce2\udc80\udc9d?q?foo=ACbar?=',
135 b'foo\xacbar'.decode('ascii', 'surrogateescape'),
136 charset = 'utf-8\udce2\udc80\udc9d',
137 # XXX Should this be a new Defect instead?
138 defects = [errors.CharsetError])
139
140 def test_q_nonascii(self):
141 self._test('=?utf-8?q?=C3=89ric?=',
142 'Éric',
143 charset='utf-8')
144
145
146 class ESC[4;38;5;81mTestEncodeQ(ESC[4;38;5;149mTestEmailBase):
147
148 def _test(self, src, expected):
149 self.assertEqual(_ew.encode_q(src), expected)
150
151 def test_all_safe(self):
152 self._test(b'foobar', 'foobar')
153
154 def test_spaces(self):
155 self._test(b'foo bar ', 'foo_bar_')
156
157 def test_run_of_encodables(self):
158 self._test(b'foo ,,bar', 'foo__=2C=2Cbar')
159
160
161 class ESC[4;38;5;81mTestEncodeB(ESC[4;38;5;149mTestEmailBase):
162
163 def test_simple(self):
164 self.assertEqual(_ew.encode_b(b'foo'), 'Zm9v')
165
166 def test_padding(self):
167 self.assertEqual(_ew.encode_b(b'vi'), 'dmk=')
168
169
170 class ESC[4;38;5;81mTestEncode(ESC[4;38;5;149mTestEmailBase):
171
172 def test_q(self):
173 self.assertEqual(_ew.encode('foo', 'utf-8', 'q'), '=?utf-8?q?foo?=')
174
175 def test_b(self):
176 self.assertEqual(_ew.encode('foo', 'utf-8', 'b'), '=?utf-8?b?Zm9v?=')
177
178 def test_auto_q(self):
179 self.assertEqual(_ew.encode('foo', 'utf-8'), '=?utf-8?q?foo?=')
180
181 def test_auto_q_if_short_mostly_safe(self):
182 self.assertEqual(_ew.encode('vi.', 'utf-8'), '=?utf-8?q?vi=2E?=')
183
184 def test_auto_b_if_enough_unsafe(self):
185 self.assertEqual(_ew.encode('.....', 'utf-8'), '=?utf-8?b?Li4uLi4=?=')
186
187 def test_auto_b_if_long_unsafe(self):
188 self.assertEqual(_ew.encode('vi.vi.vi.vi.vi.', 'utf-8'),
189 '=?utf-8?b?dmkudmkudmkudmkudmku?=')
190
191 def test_auto_q_if_long_mostly_safe(self):
192 self.assertEqual(_ew.encode('vi vi vi.vi ', 'utf-8'),
193 '=?utf-8?q?vi_vi_vi=2Evi_?=')
194
195 def test_utf8_default(self):
196 self.assertEqual(_ew.encode('foo'), '=?utf-8?q?foo?=')
197
198 def test_lang(self):
199 self.assertEqual(_ew.encode('foo', lang='jive'), '=?utf-8*jive?q?foo?=')
200
201 def test_unknown_8bit(self):
202 self.assertEqual(_ew.encode('foo\uDCACbar', charset='unknown-8bit'),
203 '=?unknown-8bit?q?foo=ACbar?=')
204
205
206 if __name__ == '__main__':
207 unittest.main()