blob: 14395fed40d7ed0a1678a37d4f1d2f3cd8c5a12c [file] [log] [blame]
R David Murray0b6f6c82012-05-25 18:42:14 -04001import unittest
2from email import _encoded_words as _ew
3from email import errors
4from test.test_email import TestEmailBase
5
6
7class TestDecodeQ(TestEmailBase):
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
25class TestDecodeB(TestEmailBase):
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 self._test(b'dmk', b'vi', [errors.InvalidBase64PaddingDefect])
37
38 def test_invalid_character(self):
39 self._test(b'dm\x01k===', b'vi', [errors.InvalidBase64CharactersDefect])
40
41 def test_invalid_character_and_bad_padding(self):
42 self._test(b'dm\x01k', b'vi', [errors.InvalidBase64CharactersDefect,
43 errors.InvalidBase64PaddingDefect])
44
45
46class TestDecode(TestEmailBase):
47
48 def test_wrong_format_input_raises(self):
49 with self.assertRaises(ValueError):
50 _ew.decode('=?badone?=')
51 with self.assertRaises(ValueError):
52 _ew.decode('=?')
53 with self.assertRaises(ValueError):
54 _ew.decode('')
55
56 def _test(self, source, result, charset='us-ascii', lang='', defects=[]):
57 res, char, l, d = _ew.decode(source)
58 self.assertEqual(res, result)
59 self.assertEqual(char, charset)
60 self.assertEqual(l, lang)
61 self.assertDefectsEqual(d, defects)
62
63 def test_simple_q(self):
64 self._test('=?us-ascii?q?foo?=', 'foo')
65
66 def test_simple_b(self):
67 self._test('=?us-ascii?b?dmk=?=', 'vi')
68
69 def test_q_case_ignored(self):
70 self._test('=?us-ascii?Q?foo?=', 'foo')
71
72 def test_b_case_ignored(self):
73 self._test('=?us-ascii?B?dmk=?=', 'vi')
74
75 def test_non_trivial_q(self):
76 self._test('=?latin-1?q?=20F=fcr=20Elise=20?=', ' Für Elise ', 'latin-1')
77
78 def test_q_escpaed_bytes_preserved(self):
79 self._test(b'=?us-ascii?q?=20\xACfoo?='.decode('us-ascii',
80 'surrogateescape'),
81 ' \uDCACfoo',
82 defects = [errors.UndecodableBytesDefect])
83
84 def test_b_undecodable_bytes_ignored_with_defect(self):
85 self._test(b'=?us-ascii?b?dm\xACk?='.decode('us-ascii',
86 'surrogateescape'),
87 'vi',
88 defects = [
89 errors.InvalidBase64CharactersDefect,
90 errors.InvalidBase64PaddingDefect])
91
92 def test_b_invalid_bytes_ignored_with_defect(self):
93 self._test('=?us-ascii?b?dm\x01k===?=',
94 'vi',
95 defects = [errors.InvalidBase64CharactersDefect])
96
97 def test_b_invalid_bytes_incorrect_padding(self):
98 self._test('=?us-ascii?b?dm\x01k?=',
99 'vi',
100 defects = [
101 errors.InvalidBase64CharactersDefect,
102 errors.InvalidBase64PaddingDefect])
103
104 def test_b_padding_defect(self):
105 self._test('=?us-ascii?b?dmk?=',
106 'vi',
107 defects = [errors.InvalidBase64PaddingDefect])
108
109 def test_nonnull_lang(self):
110 self._test('=?us-ascii*jive?q?test?=', 'test', lang='jive')
111
112 def test_unknown_8bit_charset(self):
113 self._test('=?unknown-8bit?q?foo=ACbar?=',
114 b'foo\xacbar'.decode('ascii', 'surrogateescape'),
115 charset = 'unknown-8bit',
116 defects = [])
117
118 def test_unknown_charset(self):
119 self._test('=?foobar?q?foo=ACbar?=',
120 b'foo\xacbar'.decode('ascii', 'surrogateescape'),
121 charset = 'foobar',
122 # XXX Should this be a new Defect instead?
123 defects = [errors.CharsetError])
124
125
126class TestEncodeQ(TestEmailBase):
127
128 def _test(self, src, expected):
129 self.assertEqual(_ew.encode_q(src), expected)
130
131 def test_all_safe(self):
132 self._test(b'foobar', 'foobar')
133
134 def test_spaces(self):
135 self._test(b'foo bar ', 'foo_bar_')
136
137 def test_run_of_encodables(self):
138 self._test(b'foo ,,bar', 'foo__=2C=2Cbar')
139
140
141class TestEncodeB(TestEmailBase):
142
143 def test_simple(self):
144 self.assertEqual(_ew.encode_b(b'foo'), 'Zm9v')
145
146 def test_padding(self):
147 self.assertEqual(_ew.encode_b(b'vi'), 'dmk=')
148
149
150class TestEncode(TestEmailBase):
151
152 def test_q(self):
153 self.assertEqual(_ew.encode('foo', 'utf-8', 'q'), '=?utf-8?q?foo?=')
154
155 def test_b(self):
156 self.assertEqual(_ew.encode('foo', 'utf-8', 'b'), '=?utf-8?b?Zm9v?=')
157
158 def test_auto_q(self):
159 self.assertEqual(_ew.encode('foo', 'utf-8'), '=?utf-8?q?foo?=')
160
161 def test_auto_q_if_short_mostly_safe(self):
162 self.assertEqual(_ew.encode('vi.', 'utf-8'), '=?utf-8?q?vi=2E?=')
163
164 def test_auto_b_if_enough_unsafe(self):
165 self.assertEqual(_ew.encode('.....', 'utf-8'), '=?utf-8?b?Li4uLi4=?=')
166
167 def test_auto_b_if_long_unsafe(self):
168 self.assertEqual(_ew.encode('vi.vi.vi.vi.vi.', 'utf-8'),
169 '=?utf-8?b?dmkudmkudmkudmkudmku?=')
170
171 def test_auto_q_if_long_mostly_safe(self):
172 self.assertEqual(_ew.encode('vi vi vi.vi ', 'utf-8'),
173 '=?utf-8?q?vi_vi_vi=2Evi_?=')
174
175 def test_utf8_default(self):
176 self.assertEqual(_ew.encode('foo'), '=?utf-8?q?foo?=')
177
178 def test_lang(self):
179 self.assertEqual(_ew.encode('foo', lang='jive'), '=?utf-8*jive?q?foo?=')
180
181 def test_unknown_8bit(self):
182 self.assertEqual(_ew.encode('foo\uDCACbar', charset='unknown-8bit'),
183 '=?unknown-8bit?q?foo=ACbar?=')
184
185
186if __name__ == '__main__':
187 unittest.main()