| OLD | NEW |
| (Empty) |
| 1 # coding: utf-8 | |
| 2 from io import BytesIO | |
| 3 | |
| 4 import pytest | |
| 5 from requests import compat | |
| 6 from requests.structures import CaseInsensitiveDict | |
| 7 from requests.utils import ( | |
| 8 address_in_network, dotted_netmask, | |
| 9 get_auth_from_url, get_encoding_from_headers, | |
| 10 get_encodings_from_content, get_environ_proxies, | |
| 11 guess_filename, guess_json_utf, is_ipv4_address, | |
| 12 is_valid_cidr, iter_slices, parse_dict_header, | |
| 13 parse_header_links, prepend_scheme_if_needed, | |
| 14 requote_uri, select_proxy, super_len, | |
| 15 to_key_val_list, to_native_string, | |
| 16 unquote_header_value, unquote_unreserved, | |
| 17 urldefragauth) | |
| 18 | |
| 19 from .compat import StringIO, cStringIO | |
| 20 | |
| 21 | |
| 22 class TestSuperLen: | |
| 23 | |
| 24 @pytest.mark.parametrize( | |
| 25 'stream, value', ( | |
| 26 (StringIO.StringIO, 'Test'), | |
| 27 (BytesIO, b'Test'), | |
| 28 pytest.mark.skipif('cStringIO is None')((cStringIO, 'Test')), | |
| 29 )) | |
| 30 def test_io_streams(self, stream, value): | |
| 31 """Ensures that we properly deal with different kinds of IO streams.""" | |
| 32 assert super_len(stream()) == 0 | |
| 33 assert super_len(stream(value)) == 4 | |
| 34 | |
| 35 def test_super_len_correctly_calculates_len_of_partially_read_file(self): | |
| 36 """Ensure that we handle partially consumed file like objects.""" | |
| 37 s = StringIO.StringIO() | |
| 38 s.write('foobarbogus') | |
| 39 assert super_len(s) == 0 | |
| 40 | |
| 41 @pytest.mark.parametrize('error', [IOError, OSError]) | |
| 42 def test_super_len_handles_files_raising_weird_errors_in_tell(self, error): | |
| 43 """ | |
| 44 If tell() raises errors, assume the cursor is at position zero. | |
| 45 """ | |
| 46 class BoomFile(object): | |
| 47 def __len__(self): | |
| 48 return 5 | |
| 49 | |
| 50 def tell(self): | |
| 51 raise error() | |
| 52 | |
| 53 assert super_len(BoomFile()) == 0 | |
| 54 | |
| 55 def test_string(self): | |
| 56 assert super_len('Test') == 4 | |
| 57 | |
| 58 @pytest.mark.parametrize( | |
| 59 'mode, warnings_num', ( | |
| 60 ('r', 1), | |
| 61 ('rb', 0), | |
| 62 )) | |
| 63 def test_file(self, tmpdir, mode, warnings_num, recwarn): | |
| 64 file_obj = tmpdir.join('test.txt') | |
| 65 file_obj.write('Test') | |
| 66 with file_obj.open(mode) as fd: | |
| 67 assert super_len(fd) == 4 | |
| 68 assert len(recwarn) == warnings_num | |
| 69 | |
| 70 | |
| 71 class TestToKeyValList: | |
| 72 | |
| 73 @pytest.mark.parametrize( | |
| 74 'value, expected', ( | |
| 75 ([('key', 'val')], [('key', 'val')]), | |
| 76 ((('key', 'val'), ), [('key', 'val')]), | |
| 77 ({'key': 'val'}, [('key', 'val')]), | |
| 78 (None, None) | |
| 79 )) | |
| 80 def test_valid(self, value, expected): | |
| 81 assert to_key_val_list(value) == expected | |
| 82 | |
| 83 def test_invalid(self): | |
| 84 with pytest.raises(ValueError): | |
| 85 to_key_val_list('string') | |
| 86 | |
| 87 | |
| 88 class TestUnquoteHeaderValue: | |
| 89 | |
| 90 @pytest.mark.parametrize( | |
| 91 'value, expected', ( | |
| 92 (None, None), | |
| 93 ('Test', 'Test'), | |
| 94 ('"Test"', 'Test'), | |
| 95 ('"Test\\\\"', 'Test\\'), | |
| 96 ('"\\\\Comp\\Res"', '\\Comp\\Res'), | |
| 97 )) | |
| 98 def test_valid(self, value, expected): | |
| 99 assert unquote_header_value(value) == expected | |
| 100 | |
| 101 def test_is_filename(self): | |
| 102 assert unquote_header_value('"\\\\Comp\\Res"', True) == '\\\\Comp\\Res' | |
| 103 | |
| 104 | |
| 105 class TestGetEnvironProxies: | |
| 106 """Ensures that IP addresses are correctly matches with ranges | |
| 107 in no_proxy variable.""" | |
| 108 | |
| 109 @pytest.fixture(autouse=True, params=['no_proxy', 'NO_PROXY']) | |
| 110 def no_proxy(self, request, monkeypatch): | |
| 111 monkeypatch.setenv(request.param, '192.168.0.0/24,127.0.0.1,localhost.lo
caldomain,172.16.1.1') | |
| 112 | |
| 113 @pytest.mark.parametrize( | |
| 114 'url', ( | |
| 115 'http://192.168.0.1:5000/', | |
| 116 'http://192.168.0.1/', | |
| 117 'http://172.16.1.1/', | |
| 118 'http://172.16.1.1:5000/', | |
| 119 'http://localhost.localdomain:5000/v1.0/', | |
| 120 )) | |
| 121 def test_bypass(self, url): | |
| 122 assert get_environ_proxies(url) == {} | |
| 123 | |
| 124 @pytest.mark.parametrize( | |
| 125 'url', ( | |
| 126 'http://192.168.1.1:5000/', | |
| 127 'http://192.168.1.1/', | |
| 128 'http://www.requests.com/', | |
| 129 )) | |
| 130 def test_not_bypass(self, url): | |
| 131 assert get_environ_proxies(url) != {} | |
| 132 | |
| 133 | |
| 134 class TestIsIPv4Address: | |
| 135 | |
| 136 def test_valid(self): | |
| 137 assert is_ipv4_address('8.8.8.8') | |
| 138 | |
| 139 @pytest.mark.parametrize('value', ('8.8.8.8.8', 'localhost.localdomain')) | |
| 140 def test_invalid(self, value): | |
| 141 assert not is_ipv4_address(value) | |
| 142 | |
| 143 | |
| 144 class TestIsValidCIDR: | |
| 145 | |
| 146 def test_valid(self): | |
| 147 assert is_valid_cidr('192.168.1.0/24') | |
| 148 | |
| 149 @pytest.mark.parametrize( | |
| 150 'value', ( | |
| 151 '8.8.8.8', | |
| 152 '192.168.1.0/a', | |
| 153 '192.168.1.0/128', | |
| 154 '192.168.1.0/-1', | |
| 155 '192.168.1.999/24', | |
| 156 )) | |
| 157 def test_invalid(self, value): | |
| 158 assert not is_valid_cidr(value) | |
| 159 | |
| 160 | |
| 161 class TestAddressInNetwork: | |
| 162 | |
| 163 def test_valid(self): | |
| 164 assert address_in_network('192.168.1.1', '192.168.1.0/24') | |
| 165 | |
| 166 def test_invalid(self): | |
| 167 assert not address_in_network('172.16.0.1', '192.168.1.0/24') | |
| 168 | |
| 169 | |
| 170 class TestGuessFilename: | |
| 171 | |
| 172 @pytest.mark.parametrize( | |
| 173 'value', (1, type('Fake', (object,), {'name': 1})()), | |
| 174 ) | |
| 175 def test_guess_filename_invalid(self, value): | |
| 176 assert guess_filename(value) is None | |
| 177 | |
| 178 @pytest.mark.parametrize( | |
| 179 'value, expected_type', ( | |
| 180 (b'value', compat.bytes), | |
| 181 (b'value'.decode('utf-8'), compat.str) | |
| 182 )) | |
| 183 def test_guess_filename_valid(self, value, expected_type): | |
| 184 obj = type('Fake', (object,), {'name': value})() | |
| 185 result = guess_filename(obj) | |
| 186 assert result == value | |
| 187 assert isinstance(result, expected_type) | |
| 188 | |
| 189 | |
| 190 class TestContentEncodingDetection: | |
| 191 | |
| 192 def test_none(self): | |
| 193 encodings = get_encodings_from_content('') | |
| 194 assert not len(encodings) | |
| 195 | |
| 196 @pytest.mark.parametrize( | |
| 197 'content', ( | |
| 198 # HTML5 meta charset attribute | |
| 199 '<meta charset="UTF-8">', | |
| 200 # HTML4 pragma directive | |
| 201 '<meta http-equiv="Content-type" content="text/html;charset=UTF-8">'
, | |
| 202 # XHTML 1.x served with text/html MIME type | |
| 203 '<meta http-equiv="Content-type" content="text/html;charset=UTF-8" /
>', | |
| 204 # XHTML 1.x served as XML | |
| 205 '<?xml version="1.0" encoding="UTF-8"?>', | |
| 206 )) | |
| 207 def test_pragmas(self, content): | |
| 208 encodings = get_encodings_from_content(content) | |
| 209 assert len(encodings) == 1 | |
| 210 assert encodings[0] == 'UTF-8' | |
| 211 | |
| 212 def test_precedence(self): | |
| 213 content = ''' | |
| 214 <?xml version="1.0" encoding="XML"?> | |
| 215 <meta charset="HTML5"> | |
| 216 <meta http-equiv="Content-type" content="text/html;charset=HTML4" /> | |
| 217 '''.strip() | |
| 218 assert get_encodings_from_content(content) == ['HTML5', 'HTML4', 'XML'] | |
| 219 | |
| 220 | |
| 221 class TestGuessJSONUTF: | |
| 222 | |
| 223 @pytest.mark.parametrize( | |
| 224 'encoding', ( | |
| 225 'utf-32', 'utf-8-sig', 'utf-16', 'utf-8', 'utf-16-be', 'utf-16-le', | |
| 226 'utf-32-be', 'utf-32-le' | |
| 227 )) | |
| 228 def test_encoded(self, encoding): | |
| 229 data = '{}'.encode(encoding) | |
| 230 assert guess_json_utf(data) == encoding | |
| 231 | |
| 232 def test_bad_utf_like_encoding(self): | |
| 233 assert guess_json_utf(b'\x00\x00\x00\x00') is None | |
| 234 | |
| 235 | |
| 236 USER = PASSWORD = "%!*'();:@&=+$,/?#[] " | |
| 237 ENCODED_USER = compat.quote(USER, '') | |
| 238 ENCODED_PASSWORD = compat.quote(PASSWORD, '') | |
| 239 | |
| 240 | |
| 241 @pytest.mark.parametrize( | |
| 242 'url, auth', ( | |
| 243 ( | |
| 244 'http://' + ENCODED_USER + ':' + ENCODED_PASSWORD + '@' + | |
| 245 'request.com/url.html#test', | |
| 246 (USER, PASSWORD) | |
| 247 ), | |
| 248 ( | |
| 249 'http://user:pass@complex.url.com/path?query=yes', | |
| 250 ('user', 'pass') | |
| 251 ), | |
| 252 ( | |
| 253 'http://user:pass%20pass@complex.url.com/path?query=yes', | |
| 254 ('user', 'pass pass') | |
| 255 ), | |
| 256 ( | |
| 257 'http://user:pass pass@complex.url.com/path?query=yes', | |
| 258 ('user', 'pass pass') | |
| 259 ), | |
| 260 ( | |
| 261 'http://user%25user:pass@complex.url.com/path?query=yes', | |
| 262 ('user%user', 'pass') | |
| 263 ), | |
| 264 ( | |
| 265 'http://user:pass%23pass@complex.url.com/path?query=yes', | |
| 266 ('user', 'pass#pass') | |
| 267 ), | |
| 268 ( | |
| 269 'http://complex.url.com/path?query=yes', | |
| 270 ('', '') | |
| 271 ), | |
| 272 )) | |
| 273 def test_get_auth_from_url(url, auth): | |
| 274 assert get_auth_from_url(url) == auth | |
| 275 | |
| 276 | |
| 277 @pytest.mark.parametrize( | |
| 278 'uri, expected', ( | |
| 279 ( | |
| 280 # Ensure requoting doesn't break expectations | |
| 281 'http://example.com/fiz?buz=%25ppicture', | |
| 282 'http://example.com/fiz?buz=%25ppicture', | |
| 283 ), | |
| 284 ( | |
| 285 # Ensure we handle unquoted percent signs in redirects | |
| 286 'http://example.com/fiz?buz=%ppicture', | |
| 287 'http://example.com/fiz?buz=%25ppicture', | |
| 288 ), | |
| 289 )) | |
| 290 def test_requote_uri_with_unquoted_percents(uri, expected): | |
| 291 """See: https://github.com/kennethreitz/requests/issues/2356 | |
| 292 """ | |
| 293 assert requote_uri(uri) == expected | |
| 294 | |
| 295 | |
| 296 @pytest.mark.parametrize( | |
| 297 'uri, expected', ( | |
| 298 ( | |
| 299 # Illegal bytes | |
| 300 'http://example.com/?a=%--', | |
| 301 'http://example.com/?a=%--', | |
| 302 ), | |
| 303 ( | |
| 304 # Reserved characters | |
| 305 'http://example.com/?a=%300', | |
| 306 'http://example.com/?a=00', | |
| 307 ) | |
| 308 )) | |
| 309 def test_unquote_unreserved(uri, expected): | |
| 310 assert unquote_unreserved(uri) == expected | |
| 311 | |
| 312 | |
| 313 @pytest.mark.parametrize( | |
| 314 'mask, expected', ( | |
| 315 (8, '255.0.0.0'), | |
| 316 (24, '255.255.255.0'), | |
| 317 (25, '255.255.255.128'), | |
| 318 )) | |
| 319 def test_dotted_netmask(mask, expected): | |
| 320 assert dotted_netmask(mask) == expected | |
| 321 | |
| 322 | |
| 323 @pytest.mark.parametrize( | |
| 324 'url, expected', ( | |
| 325 ('hTTp://u:p@Some.Host/path', 'http://some.host.proxy'), | |
| 326 ('hTTp://u:p@Other.Host/path', 'http://http.proxy'), | |
| 327 ('hTTps://Other.Host', None), | |
| 328 ('file:///etc/motd', None), | |
| 329 )) | |
| 330 def test_select_proxies(url, expected): | |
| 331 """Make sure we can select per-host proxies correctly.""" | |
| 332 proxies = {'http': 'http://http.proxy', | |
| 333 'http://some.host': 'http://some.host.proxy'} | |
| 334 assert select_proxy(url, proxies) == expected | |
| 335 | |
| 336 | |
| 337 @pytest.mark.parametrize( | |
| 338 'value, expected', ( | |
| 339 ('foo="is a fish", bar="as well"', {'foo': 'is a fish', 'bar': 'as well'
}), | |
| 340 ('key_without_value', {'key_without_value': None}) | |
| 341 )) | |
| 342 def test_parse_dict_header(value, expected): | |
| 343 assert parse_dict_header(value) == expected | |
| 344 | |
| 345 | |
| 346 @pytest.mark.parametrize( | |
| 347 'value, expected', ( | |
| 348 ( | |
| 349 CaseInsensitiveDict(), | |
| 350 None | |
| 351 ), | |
| 352 ( | |
| 353 CaseInsensitiveDict({'content-type': 'application/json; charset=utf-
8'}), | |
| 354 'utf-8' | |
| 355 ), | |
| 356 ( | |
| 357 CaseInsensitiveDict({'content-type': 'text/plain'}), | |
| 358 'ISO-8859-1' | |
| 359 ), | |
| 360 )) | |
| 361 def test_get_encoding_from_headers(value, expected): | |
| 362 assert get_encoding_from_headers(value) == expected | |
| 363 | |
| 364 | |
| 365 @pytest.mark.parametrize( | |
| 366 'value, length', ( | |
| 367 ('', 0), | |
| 368 ('T', 1), | |
| 369 ('Test', 4), | |
| 370 )) | |
| 371 def test_iter_slices(value, length): | |
| 372 assert len(list(iter_slices(value, 1))) == length | |
| 373 | |
| 374 | |
| 375 @pytest.mark.parametrize( | |
| 376 'value, expected', ( | |
| 377 ( | |
| 378 '<http:/.../front.jpeg>; rel=front; type="image/jpeg"', | |
| 379 [{'url': 'http:/.../front.jpeg', 'rel': 'front', 'type': 'image/jpeg
'}] | |
| 380 ), | |
| 381 ( | |
| 382 '<http:/.../front.jpeg>', | |
| 383 [{'url': 'http:/.../front.jpeg'}] | |
| 384 ), | |
| 385 ( | |
| 386 '<http:/.../front.jpeg>;', | |
| 387 [{'url': 'http:/.../front.jpeg'}] | |
| 388 ), | |
| 389 ( | |
| 390 '<http:/.../front.jpeg>; type="image/jpeg",<http://.../back.jpeg>;', | |
| 391 [ | |
| 392 {'url': 'http:/.../front.jpeg', 'type': 'image/jpeg'}, | |
| 393 {'url': 'http://.../back.jpeg'} | |
| 394 ] | |
| 395 ), | |
| 396 )) | |
| 397 def test_parse_header_links(value, expected): | |
| 398 assert parse_header_links(value) == expected | |
| 399 | |
| 400 | |
| 401 @pytest.mark.parametrize( | |
| 402 'value, expected', ( | |
| 403 ('example.com/path', 'http://example.com/path'), | |
| 404 ('//example.com/path', 'http://example.com/path'), | |
| 405 )) | |
| 406 def test_prepend_scheme_if_needed(value, expected): | |
| 407 assert prepend_scheme_if_needed(value, 'http') == expected | |
| 408 | |
| 409 | |
| 410 @pytest.mark.parametrize( | |
| 411 'value, expected', ( | |
| 412 ('T', 'T'), | |
| 413 (b'T', 'T'), | |
| 414 (u'T', 'T'), | |
| 415 )) | |
| 416 def test_to_native_string(value, expected): | |
| 417 assert to_native_string(value) == expected | |
| 418 | |
| 419 | |
| 420 @pytest.mark.parametrize( | |
| 421 'url, expected', ( | |
| 422 ('http://u:p@example.com/path?a=1#test', 'http://example.com/path?a=1'), | |
| 423 ('http://example.com/path', 'http://example.com/path'), | |
| 424 ('//u:p@example.com/path', '//example.com/path'), | |
| 425 ('//example.com/path', '//example.com/path'), | |
| 426 ('example.com/path', '//example.com/path'), | |
| 427 ('scheme:u:p@example.com/path', 'scheme://example.com/path'), | |
| 428 )) | |
| 429 def test_urldefragauth(url, expected): | |
| 430 assert urldefragauth(url) == expected | |
| OLD | NEW |