diff options
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/test_cookies.py | 207 | ||||
-rwxr-xr-x | tests/test_requests.py | 83 | ||||
-rwxr-xr-x | tests/test_requests_async.py | 1 | ||||
-rw-r--r-- | tests/test_requests_ext.py | 23 |
4 files changed, 300 insertions, 14 deletions
diff --git a/tests/test_cookies.py b/tests/test_cookies.py new file mode 100755 index 0000000..dca7d2c --- /dev/null +++ b/tests/test_cookies.py @@ -0,0 +1,207 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import sys +import json +import os +import tempfile +import unittest + +# Path hack. +sys.path.insert(0, os.path.abspath('..')) +import requests +from requests.compat import cookielib + +# More hacks +sys.path.append('.') +from test_requests import httpbin, TestBaseMixin + +class CookieTests(TestBaseMixin, unittest.TestCase): + + def test_cookies_from_response(self): + """Basic test that we correctly parse received cookies in the Response object.""" + r = requests.get(httpbin('cookies', 'set', 'myname', 'myvalue')) + + # test deprecated dictionary interface + self.assertEqual(r.cookies['myname'], 'myvalue') + # test CookieJar interface + jar = r.cookies + self.assertEqual(len(jar), 1) + cookie_from_jar = list(jar)[0] + self.assertCookieHas(cookie_from_jar, name='myname', value='myvalue') + + q = requests.get(httpbin('cookies'), cookies=jar) + self.assertEqual(json.loads(q.text)['cookies'], {'myname': 'myvalue'}) + + def test_crossdomain_cookies(self): + """Cookies should not be sent to domains they didn't originate from.""" + r = requests.get("http://github.com") + c = r.cookies + # github should send us cookies + self.assertTrue(len(c) >= 1) + + # github cookies should not be sent to httpbin.org: + r2 = requests.get(httpbin('cookies'), cookies=c) + self.assertEqual(json.loads(r2.text)['cookies'], {}) + + # let's do this again using the session object + s = requests.session() + s.get("http://github.com") + self.assertTrue(len(s.cookies) >= 1) + r = s.get(httpbin('cookies')) + self.assertEqual(json.loads(r.text)['cookies'], {}) + # we can set a cookie and get exactly that same-domain cookie back: + r = s.get(httpbin('cookies', 'set', 'myname', 'myvalue')) + self.assertEqual(json.loads(r.text)['cookies'], {'myname': 'myvalue'}) + + def test_overwrite(self): + """Cookies should get overwritten when appropriate.""" + r = requests.get(httpbin('cookies', 'set', 'shimon', 'yochai')) + cookies = r.cookies + requests.get(httpbin('cookies', 'set', 'elazar', 'shimon'), cookies=cookies) + r = requests.get(httpbin('cookies'), cookies=cookies) + self.assertEqual(json.loads(r.text)['cookies'], + {'shimon': 'yochai', 'elazar': 'shimon'}) + # overwrite the value of 'shimon' + r = requests.get(httpbin('cookies', 'set', 'shimon', 'gamaliel'), cookies=cookies) + self.assertEqual(len(cookies), 2) + r = requests.get(httpbin('cookies'), cookies=cookies) + self.assertEqual(json.loads(r.text)['cookies'], + {'shimon': 'gamaliel', 'elazar': 'shimon'}) + + def test_redirects(self): + """Test that cookies set by a 302 page are correctly processed.""" + r = requests.get(httpbin('cookies', 'set', 'redirects', 'work')) + self.assertEqual(r.history[0].status_code, 302) + expected_cookies = {'redirects': 'work'} + self.assertEqual(json.loads(r.text)['cookies'], expected_cookies) + + r2 = requests.get(httpbin('cookies', 'set', 'very', 'well'), cookies=r.cookies) + expected_cookies = {'redirects': 'work', 'very': 'well'} + self.assertEqual(json.loads(r2.text)['cookies'], expected_cookies) + self.assertTrue(r.cookies is r2.cookies) + + def test_none_cookie(self): + """Regression test: don't send a Cookie header with a string value of 'None'!""" + page = json.loads(requests.get(httpbin('headers')).text) + self.assertTrue('Cookie' not in page['headers']) + + def test_secure_cookies(self): + """Test that secure cookies can only be sent via https.""" + header = "Set-Cookie: ThisIsA=SecureCookie; Path=/; Secure; HttpOnly" + url = 'https://httpbin.org/response-headers?%s' % (requests.utils.quote(header),) + cookies = requests.get(url, verify=False).cookies + self.assertEqual(len(cookies), 1) + self.assertEqual(list(cookies)[0].secure, True) + + secure_resp = requests.get('https://httpbin.org/cookies', cookies=cookies, verify=False) + secure_cookies_sent = json.loads(secure_resp.text)['cookies'] + self.assertEqual(secure_cookies_sent, {'ThisIsA': 'SecureCookie'}) + + insecure_resp = requests.get('http://httpbin.org/cookies', cookies=cookies) + insecure_cookies_sent = json.loads(insecure_resp.text)['cookies'] + self.assertEqual(insecure_cookies_sent, {}) + +class LWPCookieJarTest(TestBaseMixin, unittest.TestCase): + """Check store/load of cookies to FileCookieJar's, specifically LWPCookieJar's.""" + + COOKIEJAR_CLASS = cookielib.LWPCookieJar + + def setUp(self): + # blank the file + self.cookiejar_file = tempfile.NamedTemporaryFile() + self.cookiejar_filename = self.cookiejar_file.name + cookiejar = self.COOKIEJAR_CLASS(self.cookiejar_filename) + cookiejar.save() + + def tearDown(self): + try: + self.cookiejar_file.close() + except OSError: + pass + + def test_cookiejar_persistence(self): + """Test that we can save cookies to a FileCookieJar.""" + cookiejar = self.COOKIEJAR_CLASS(self.cookiejar_filename) + cookiejar.load() + # initially should be blank + self.assertEqual(len(cookiejar), 0) + + response = requests.get(httpbin('cookies', 'set', 'key', 'value'), cookies=cookiejar) + self.assertEqual(len(cookiejar), 1) + cookie = list(cookiejar)[0] + self.assertEqual(json.loads(response.text)['cookies'], {'key': 'value'}) + self.assertCookieHas(cookie, name='key', value='value') + + # save and reload the cookies from the file: + cookiejar.save(ignore_discard=True) + cookiejar_2 = self.COOKIEJAR_CLASS(self.cookiejar_filename) + cookiejar_2.load(ignore_discard=True) + self.assertEqual(len(cookiejar_2), 1) + cookie_2 = list(cookiejar_2)[0] + # this cookie should have been saved with the correct domain restriction: + self.assertCookieHas(cookie_2, name='key', value='value', + domain='httpbin.org', path='/') + + # httpbin sets session cookies, so if we don't ignore the discard attribute, + # there should be no cookie: + cookiejar_3 = self.COOKIEJAR_CLASS(self.cookiejar_filename) + cookiejar_3.load() + self.assertEqual(len(cookiejar_3), 0) + + def test_crossdomain(self): + """Test persistence of the domains associated with the cookies.""" + cookiejar = self.COOKIEJAR_CLASS(self.cookiejar_filename) + cookiejar.load() + self.assertEqual(len(cookiejar), 0) + + # github sets a cookie + requests.get("http://github.com", cookies=cookiejar) + num_github_cookies = len(cookiejar) + self.assertTrue(num_github_cookies >= 1) + # httpbin sets another + requests.get(httpbin('cookies', 'set', 'key', 'value'), cookies=cookiejar) + num_total_cookies = len(cookiejar) + self.assertTrue(num_total_cookies >= 2) + self.assertTrue(num_total_cookies > num_github_cookies) + + # save and load + cookiejar.save(ignore_discard=True) + cookiejar_2 = self.COOKIEJAR_CLASS(self.cookiejar_filename) + cookiejar_2.load(ignore_discard=True) + self.assertEqual(len(cookiejar_2), num_total_cookies) + r = requests.get(httpbin('cookies'), cookies=cookiejar_2) + self.assertEqual(json.loads(r.text)['cookies'], {'key': 'value'}) + + def test_persistent_cookies(self): + """Test that we correctly interpret persistent cookies.""" + # httpbin's normal cookie methods don't send persistent cookies, + # so cook up the appropriate header and force it to send + header = "Set-Cookie: Persistent=CookiesAreScary; expires=Sun, 04-May-2032 04:56:50 GMT; path=/" + url = httpbin('response-headers?%s' % (requests.utils.quote(header),)) + cookiejar = self.COOKIEJAR_CLASS(self.cookiejar_filename) + + requests.get(url, cookies=cookiejar) + self.assertEqual(len(cookiejar), 1) + self.assertCookieHas(list(cookiejar)[0], name='Persistent', value='CookiesAreScary') + + requests.get(httpbin('cookies', 'set', 'ThisCookieIs', 'SessionOnly'), cookies=cookiejar) + self.assertEqual(len(cookiejar), 2) + self.assertEqual(len([c for c in cookiejar if c.name == 'Persistent']), 1) + self.assertEqual(len([c for c in cookiejar if c.name == 'ThisCookieIs']), 1) + + # save and load + cookiejar.save() + cookiejar_2 = self.COOKIEJAR_CLASS(self.cookiejar_filename) + cookiejar_2.load() + # we should only load the persistent cookie + self.assertEqual(len(cookiejar_2), 1) + self.assertCookieHas(list(cookiejar_2)[0], name='Persistent', value='CookiesAreScary') + +class MozCookieJarTest(LWPCookieJarTest): + """Same test, but substitute MozillaCookieJar.""" + + COOKIEJAR_CLASS = cookielib.MozillaCookieJar + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_requests.py b/tests/test_requests.py index ac8329e..530008a 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -10,7 +10,6 @@ sys.path.insert(0, os.path.abspath('..')) import json import os -import sys import unittest import pickle @@ -52,8 +51,16 @@ class TestSetup(object): # time.sleep(1) _httpbin = True +class TestBaseMixin(object): + + def assertCookieHas(self, cookie, **kwargs): + """Assert that a cookie has various specified properties.""" + for attr, expected_value in kwargs.items(): + cookie_attr = getattr(cookie, attr) + message = 'Failed comparison for %s: %s != %s' % (attr, cookie_attr, expected_value) + self.assertEqual(cookie_attr, expected_value, message) -class RequestsTestSuite(TestSetup, unittest.TestCase): +class RequestsTestSuite(TestSetup, TestBaseMixin, unittest.TestCase): """Requests test cases.""" def test_entry_points(self): @@ -322,6 +329,37 @@ class RequestsTestSuite(TestSetup, unittest.TestCase): self.assertEqual(post2.status_code, 200) + def test_POSTBIN_GET_POST_FILES_STRINGS(self): + + for service in SERVICES: + + url = service('post') + + post1 = post(url, files={'fname.txt': 'fdata'}) + self.assertEqual(post1.status_code, 200) + + post2 = post(url, files={'fname.txt': 'fdata', 'fname2.txt':'more fdata'}) + self.assertEqual(post2.status_code, 200) + + post3 = post(url, files={'fname.txt': 'fdata', 'fname2.txt':open(__file__,'rb')}) + self.assertEqual(post3.status_code, 200) + + post4 = post(url, files={'fname.txt': 'fdata'}) + self.assertEqual(post4.status_code, 200) + + post5 = post(url, files={'file': ('file.txt', 'more fdata')}) + self.assertEqual(post5.status_code, 200) + + post6 = post(url, files={'fname.txt': '\xe9'}) + self.assertEqual(post6.status_code, 200) + + post7 = post(url, files={'fname.txt': 'fdata to verify'}) + rbody = json.loads(post7.text) + self.assertTrue(rbody.get('files', None)) + self.assertTrue(rbody['files'].get('fname.txt'), None) + self.assertEqual(rbody['files']['fname.txt'], 'fdata to verify') + + def test_nonzero_evaluation(self): for service in SERVICES: @@ -632,24 +670,24 @@ class RequestsTestSuite(TestSetup, unittest.TestCase): # Those cookies persist transparently. c = json.loads(r.text).get('cookies') - assert c == _c + self.assertEqual(c, _c) # Double check. r = get(httpbin('cookies'), cookies={}, session=s) c = json.loads(r.text).get('cookies') - assert c == _c + self.assertEqual(c, _c) # Remove a cookie by setting it's value to None. r = get(httpbin('cookies'), cookies={'bessie': None}, session=s) c = json.loads(r.text).get('cookies') del _c['bessie'] - assert c == _c + self.assertEqual(c, _c) # Test session-level cookies. s = requests.session(cookies=_c) r = get(httpbin('cookies'), session=s) c = json.loads(r.text).get('cookies') - assert c == _c + self.assertEqual(c, _c) # Have the server set a cookie. r = get(httpbin('cookies', 'set', 'k', 'v'), allow_redirects=True, session=s) @@ -698,9 +736,13 @@ class RequestsTestSuite(TestSetup, unittest.TestCase): ds = pickle.loads(pickle.dumps(s)) self.assertEqual(s.headers, ds.headers) - self.assertEqual(s.cookies, ds.cookies) self.assertEqual(s.auth, ds.auth) + # Cookie doesn't have a good __eq__, so verify manually: + self.assertEqual(len(ds.cookies), 1) + for cookie in ds.cookies: + self.assertCookieHas(cookie, name='a-cookie', value='cookie-value') + def test_unpickled_session_requests(self): s = requests.session() r = get(httpbin('cookies', 'set', 'k', 'v'), allow_redirects=True, session=s) @@ -837,10 +879,29 @@ class RequestsTestSuite(TestSetup, unittest.TestCase): r = requests.get(httpbin('status', '404')) r.text - def test_no_content(self): - r = requests.get(httpbin('status', "0"), config={"safe_mode":True}) - r.content - r.content + def test_max_redirects(self): + """Test the max_redirects config variable, normally and under safe_mode.""" + def unsafe_callable(): + requests.get(httpbin('redirect', '3'), config=dict(max_redirects=2)) + self.assertRaises(requests.exceptions.TooManyRedirects, unsafe_callable) + + # add safe mode + response = requests.get(httpbin('redirect', '3'), config=dict(safe_mode=True, max_redirects=2)) + self.assertTrue(response.content is None) + self.assertTrue(isinstance(response.error, requests.exceptions.TooManyRedirects)) + + def test_connection_keepalive_and_close(self): + """Test that we send 'Connection: close' when keep_alive is disabled.""" + # keep-alive should be on by default + r1 = requests.get(httpbin('get')) + # XXX due to proxying issues, test the header sent back by httpbin, rather than + # the header reported in its message body. See kennethreitz/httpbin#46 + self.assertEqual(r1.headers['Connection'].lower(), 'keep-alive') + + # but when we disable it, we should send a 'Connection: close' + # and get the same back: + r2 = requests.get(httpbin('get'), config=dict(keep_alive=False)) + self.assertEqual(r2.headers['Connection'].lower(), 'close') if __name__ == '__main__': unittest.main() diff --git a/tests/test_requests_async.py b/tests/test_requests_async.py index 1d28261..3a5a762 100755 --- a/tests/test_requests_async.py +++ b/tests/test_requests_async.py @@ -12,7 +12,6 @@ import select has_poll = hasattr(select, "poll") from requests import async -import envoy sys.path.append('.') from test_requests import httpbin, RequestsTestSuite, SERVICES diff --git a/tests/test_requests_ext.py b/tests/test_requests_ext.py index 1e4d89b..883bdce 100644 --- a/tests/test_requests_ext.py +++ b/tests/test_requests_ext.py @@ -104,8 +104,27 @@ class RequestsTestSuite(unittest.TestCase): 'php') assert r.ok - - + def test_cookies_on_redirects(self): + """Test interaction between cookie handling and redirection.""" + # get a cookie for tinyurl.com ONLY + s = requests.session() + s.get(url='http://tinyurl.com/preview.php?disable=1') + # we should have set a cookie for tinyurl: preview=0 + self.assertIn('preview', s.cookies) + self.assertEqual(s.cookies['preview'], '0') + self.assertEqual(list(s.cookies)[0].name, 'preview') + self.assertEqual(list(s.cookies)[0].domain, 'tinyurl.com') + + # get cookies on another domain + r2 = s.get(url='http://httpbin.org/cookies') + # the cookie is not there + self.assertNotIn('preview', json.loads(r2.text)['cookies']) + + # this redirects to another domain, httpbin.org + # cookies of the first domain should NOT be sent to the next one + r3 = s.get(url='http://tinyurl.com/7zp3jnr') + assert r3.url == 'http://httpbin.org/cookies' + self.assertNotIn('preview', json.loads(r2.text)['cookies']) if __name__ == '__main__': unittest.main() |