From 5304803f0955b1d0f4ef8457334f500402b60dee Mon Sep 17 00:00:00 2001 From: cash Date: Sat, 11 Jan 2014 11:13:55 -0500 Subject: [PATCH] added docstrings for new tests and finished testing input arguments of request() --- tests/test_core.py | 95 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/tests/test_core.py b/tests/test_core.py index d63d40d..b0cdc8d 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -11,6 +11,11 @@ import time import unittest import responses +try: + import io.StringIO as StringIO +except ImportError: + import StringIO + class TwythonAPITestCase(unittest.TestCase): def setUp(self): @@ -33,8 +38,13 @@ class TwythonAPITestCase(unittest.TestCase): self.oauth2_api = Twython(app_key, access_token=access_token, client_args=oauth2_client_args) + def get_url(self, endpoint): + """Convenience function for mapping from endpoint to URL""" + return '%s/%s.json' % (self.api.api_url % self.api.api_version, endpoint) + @responses.activate def test_request_should_handle_full_endpoint(self): + """Test that request() accepts a full URL for the endpoint argument""" url = 'https://api.twitter.com/1.1/search/tweets.json' responses.add(responses.GET, url) @@ -45,16 +55,18 @@ class TwythonAPITestCase(unittest.TestCase): @responses.activate def test_request_should_handle_relative_endpoint(self): - url = 'https://api.twitter.com/1.1/search/tweets.json' + """Test that request() accepts a twitter endpoint name for the endpoint argument""" + url = 'https://api.twitter.com/2.0/search/tweets.json' responses.add(responses.GET, url) - self.api.request('search/tweets', version='1.1') + self.api.request('search/tweets', version='2.0') self.assertEqual(1, len(responses.calls)) self.assertEqual(url, responses.calls[0].request.url) @responses.activate def test_request_should_post_request_regardless_of_case(self): + """Test that request() accepts the HTTP method name regardless of case""" url = 'https://api.twitter.com/1.1/statuses/update.json' responses.add(responses.POST, url) @@ -62,70 +74,101 @@ class TwythonAPITestCase(unittest.TestCase): self.api.request(url, method='post') self.assertEqual(2, len(responses.calls)) - self.assertEqual(url, responses.calls[0].request.url) - self.assertEqual(url, responses.calls[1].request.url) + self.assertEqual('POST', responses.calls[0].request.method) + self.assertEqual('POST', responses.calls[1].request.method) @responses.activate def test_request_should_throw_exception_with_invalid_http_method(self): + """Test that request() throws an exception when an invalid HTTP method is passed""" #TODO(cash): should Twython catch the AttributeError and throw a TwythonError self.assertRaises(AttributeError, self.api.request, endpoint='search/tweets', method='INVALID') @responses.activate def test_request_should_encode_boolean_as_lowercase_string(self): - url = 'https://api.twitter.com/1.1/search/tweets.json' + """Test that request() encodes a boolean parameter as a lowercase string""" + endpoint = 'search/tweets' + url = self.get_url(endpoint) responses.add(responses.GET, url) - self.api.request('search/tweets', params={'include_entities': True}) - self.api.request('search/tweets', params={'include_entities': False}) + self.api.request(endpoint, params={'include_entities': True}) + self.api.request(endpoint, params={'include_entities': False}) self.assertEqual(url + '?include_entities=true', responses.calls[0].request.url) self.assertEqual(url + '?include_entities=false', responses.calls[1].request.url) @responses.activate def test_request_should_handle_string_or_number_parameter(self): - url = 'https://api.twitter.com/1.1/search/tweets.json' + """Test that request() encodes a numeric or string parameter correctly""" + endpoint = 'search/tweets' + url = self.get_url(endpoint) responses.add(responses.GET, url) - self.api.request('search/tweets', params={'lang': 'es'}) - self.api.request('search/tweets', params={'count': 50}) + self.api.request(endpoint, params={'lang': 'es'}) + self.api.request(endpoint, params={'count': 50}) self.assertEqual(url + '?lang=es', responses.calls[0].request.url) self.assertEqual(url + '?count=50', responses.calls[1].request.url) @responses.activate - def test_request_should_encode_string_list_as_string(self): - url = 'https://api.twitter.com/1.1/search/tweets.json' + def test_request_should_encode_list_of_strings_as_string(self): + """Test that request() encodes a list of strings as a comma-separated string""" + endpoint = 'search/tweets' + url = self.get_url(endpoint) location = ['37.781157', '-122.39872', '1mi'] responses.add(responses.GET, url) - self.api.request('search/tweets', params={'geocode': location}) + self.api.request(endpoint, params={'geocode': location}) + # requests url encodes the parameters so , is %2C self.assertEqual(url + '?geocode=37.781157%2C-122.39872%2C1mi', responses.calls[0].request.url) @responses.activate - def test_request_should_encode_number_list_as_string(self): - url = 'https://api.twitter.com/1.1/search/tweets.json' + def test_request_should_encode_numeric_list_as_string(self): + """Test that request() encodes a list of numbers as a comma-separated string""" + endpoint = 'search/tweets' + url = self.get_url(endpoint) location = [37.781157, -122.39872, '1mi'] responses.add(responses.GET, url) - self.api.request('search/tweets', params={'geocode': location}) + self.api.request(endpoint, params={'geocode': location}) self.assertEqual(url + '?geocode=37.781157%2C-122.39872%2C1mi', responses.calls[0].request.url) @responses.activate def test_request_should_ignore_bad_parameter(self): - url = 'https://api.twitter.com/1.1/search/tweets.json' + """Test that request() ignores unexpected parameter types""" + endpoint = 'search/tweets' + url = self.get_url(endpoint) responses.add(responses.GET, url) - self.api.request('search/tweets', params={'geocode': self}) + self.api.request(endpoint, params={'geocode': self}) self.assertEqual(url, responses.calls[0].request.url) - def test_construct_api_url(self): - """Test constructing a Twitter API url works as we expect""" - url = 'https://api.twitter.com/1.1/search/tweets.json' - constructed_url = self.api.construct_api_url(url, q='#twitter') - self.assertEqual(constructed_url, 'https://api.twitter.com/1.1/search/tweets.json?q=%23twitter') + @responses.activate + def test_request_should_handle_file_as_parameter(self): + """Test that request() pulls a file out of params for requests lib""" + endpoint = 'account/update_profile_image' + url = self.get_url(endpoint) + responses.add(responses.POST, url) + + mock_file = StringIO.StringIO("Twython test image") + self.api.request(endpoint, method='POST', params={'image': mock_file}) + + self.assertIn('filename="image"', responses.calls[0].request.body) + self.assertIn("Twython test image", responses.calls[0].request.body) + + @responses.activate + def test_request_should_put_params_in_body_when_post(self): + """Test that request() passes params as data when the request is a POST""" + endpoint = 'statuses/update' + url = self.get_url(endpoint) + responses.add(responses.POST, url) + + self.api.request(endpoint, method='POST', params={'status': 'this is a test'}) + + self.assertIn('status=this+is+a+test', responses.calls[0].request.body) + self.assertNotIn('status=this+is+a+test', responses.calls[0].request.url) def test_get(self): """Test Twython generic GET request works""" @@ -138,6 +181,12 @@ class TwythonAPITestCase(unittest.TestCase): status = self.api.post(update_url, params={'status': 'I love Twython! %s' % int(time.time())}) self.api.post('statuses/destroy/%s' % status['id_str']) + def test_construct_api_url(self): + """Test constructing a Twitter API url works as we expect""" + url = 'https://api.twitter.com/1.1/search/tweets.json' + constructed_url = self.api.construct_api_url(url, q='#twitter') + self.assertEqual(constructed_url, 'https://api.twitter.com/1.1/search/tweets.json?q=%23twitter') + def test_get_lastfunction_header(self): """Test getting last specific header of the last API call works""" self.api.get('statuses/home_timeline')