Skip to content

Commit 3ffdcfa

Browse files
author
Claudio
committed
testing error checking
1 parent 748e0a9 commit 3ffdcfa

File tree

2 files changed

+85
-36
lines changed

2 files changed

+85
-36
lines changed

bitly.py

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def __init__(self, login, apikey):
4545
self.apikey = apikey
4646
self._urllib = urllib2
4747

48-
def shorten(self,longURLs,params={}):
48+
def shorten(self, longURLs, params={}):
4949
"""
5050
Takes either:
5151
A long URL string and returns shortened URL string
@@ -55,39 +55,31 @@ def shorten(self,longURLs,params={}):
5555
if not isinstance(longURLs, list):
5656
longURLs = [longURLs]
5757
want_result_list = False
58-
59-
for index,url in enumerate(longURLs):
60-
if not '://' in url:
61-
longURLs[index] = "http://" + url
6258

63-
request = self._getURL("shorten",longURLs,params)
59+
request = self._getURL("shorten", longURLs, params)
6460
result = self._fetchUrl(request)
6561
json = simplejson.loads(result)
66-
self._CheckForError(json)
62+
Api._CheckForError(json)
6763

6864
results = json['results']
69-
res = [self._extract_short_url(results[url]) for url in longURLs]
7065

66+
res = [results[url].get('shortUrl', None) for url in longURLs]
67+
7168
if want_result_list:
7269
return res
7370
else:
7471
return res[0]
7572

76-
def _extract_short_url(self,item):
77-
if item['shortKeywordUrl'] == "":
78-
return item['shortUrl']
79-
else:
80-
return item['shortKeywordUrl']
8173

82-
def expand(self,shortURL,params={}):
74+
def expand(self, shortURL, params={}):
8375
""" Given a bit.ly url or hash, return long source url """
8476
request = self._getURL("expand",shortURL,params)
8577
result = self._fetchUrl(request)
8678
json = simplejson.loads(result)
87-
self._CheckForError(json)
79+
Api._CheckForError(json)
8880
return json['results'][string.split(shortURL, '/')[-1]]['longUrl']
8981

90-
def info(self,shortURL,params={}):
82+
def info(self, shortURL, params={}):
9183
"""
9284
Given a bit.ly url or hash,
9385
return information about that page,
@@ -96,23 +88,23 @@ def info(self,shortURL,params={}):
9688
request = self._getURL("info",shortURL,params)
9789
result = self._fetchUrl(request)
9890
json = simplejson.loads(result)
99-
self._CheckForError(json)
91+
Api._CheckForError(json)
10092
return json['results'][string.split(shortURL, '/')[-1]]
10193

102-
def stats(self,shortURL,params={}):
94+
def stats(self, shortURL, params={}):
10395
""" Given a bit.ly url or hash, return traffic and referrer data. """
10496
request = self._getURL("stats",shortURL,params)
10597
result = self._fetchUrl(request)
10698
json = simplejson.loads(result)
107-
self._CheckForError(json)
99+
Api._CheckForError(json)
108100
return Stats.NewFromJsonDict(json['results'])
109101

110-
def errors(self,params={}):
102+
def errors(self, params={}):
111103
""" Get a list of bit.ly API error codes. """
112104
request = self._getURL("errors","",params)
113105
result = self._fetchUrl(request)
114106
json = simplejson.loads(result)
115-
self._CheckForError(json)
107+
Api._CheckForError(json)
116108
return json['results']
117109

118110
def setUrllib(self, urllib):
@@ -123,7 +115,7 @@ def setUrllib(self, urllib):
123115
'''
124116
self._urllib = urllib
125117

126-
def _getURL(self,verb,paramVal,more_params={}):
118+
def _getURL(self, verb, paramVal, more_params={}):
127119
if not isinstance(paramVal, list):
128120
paramVal = [paramVal]
129121

@@ -145,7 +137,7 @@ def _getURL(self,verb,paramVal,more_params={}):
145137
encoded_params = urllib.urlencode(params)
146138
return "%s%s?%s" % (BITLY_BASE_URL,verb,encoded_params)
147139

148-
def _fetchUrl(self,url):
140+
def _fetchUrl(self, url):
149141
'''Fetch a URL
150142
151143
Args:
@@ -159,7 +151,8 @@ def _fetchUrl(self,url):
159151
url_data = self._urllib.urlopen(url).read()
160152
return url_data
161153

162-
def _CheckForError(self, data):
154+
@classmethod
155+
def _CheckForError(cls, data):
163156
"""Raises a BitlyError if bitly returns an error message.
164157
165158
Args:
@@ -171,7 +164,7 @@ def _CheckForError(self, data):
171164
# to check first, rather than try and catch the exception
172165
if 'ERROR' in data or data['statusCode'] == 'ERROR':
173166
raise BitlyError, data['errorMessage']
174-
for key in data['results']:
167+
for key in data['results']:
175168
if type(data['results']) is dict and type(data['results'][key]) is dict:
176169
if 'statusCode' in data['results'][key] and data['results'][key]['statusCode'] == 'ERROR':
177170
raise BitlyError, data['results'][key]['errorMessage']
@@ -202,8 +195,8 @@ def NewFromJsonDict(data):
202195

203196

204197
if __name__ == '__main__':
205-
testURL1="www.yahoo.com"
206-
testURL2="www.cnn.com"
198+
testURL1="http://www.yahoo.com"
199+
testURL2="http://www.cnn.com"
207200
a=Api(login="pythonbitly",apikey="R_06871db6b7fd31a4242709acaf1b6648")
208201
short=a.shorten(testURL1)
209202
print "Short URL = %s" % short
@@ -220,6 +213,6 @@ def NewFromJsonDict(data):
220213
print "User clicks %s, total clicks: %s" % (stats.user_clicks,stats.total_clicks)
221214
errors=a.errors()
222215
print "Errors: %s" % errors
223-
testURL3=["www.google.com"]
216+
testURL3=["http://www.google.com"]
224217
short=a.shorten(testURL3)
225218
print "Short url in list = %s" % short

test/test_shortening_urls.py

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
#-*- coding:utf-8 -*-
33

44
from nose.tools import assert_raises
5+
from mox import Mox
56

67
import bitly
78

8-
def test_urls_shortening_scenario():
99

10+
def test_urls_shortening_scenario_for_plain_urls():
1011
api = bitly.Api(login='jcfigueiredo', apikey='R_1cf5dc0fa14c2df34261fb620bd256aa')
12+
1113
yield should_raise_when_an_invalid_credential_is_provided
1214
yield should_have_an_API_authenticated_by_my_credentials, api
13-
yield should_shorten_an_url_consistently_when_a_single_string_urls_is_provided, api
15+
yield should_shorten_an_url_consistently_when_a_single_string_url_is_provided, api
1416
yield should_shorten_many_urls_consistently_when_a_list_of_urls_is_provided, api
17+
yield should_shorten_an_urls_with_querystring, api
1518

1619
def should_raise_when_an_invalid_credential_is_provided():
1720
api = bitly.Api(login='inexistent_login', apikey='or_invalid_key')
@@ -20,23 +23,76 @@ def should_raise_when_an_invalid_credential_is_provided():
2023
def should_have_an_API_authenticated_by_my_credentials(api):
2124
assert api, 'Should have a valid API'
2225

23-
def should_shorten_an_url_consistently_when_a_single_string_urls_is_provided(api):
26+
def should_shorten_an_url_consistently_when_a_single_string_url_is_provided(api):
2427
url_to_be_shortened = 'http://globoesporte.globo.com/motor/formula-1/noticia/2010/10/apos-maus-resultados-ferrari-reforca-apoio-massa-no-fim-da-temporada.html'
2528
expected_url = 'http://bit.ly/9n93fw'
26-
29+
2730
shortened_url = api.shorten(longURLs=url_to_be_shortened)
28-
31+
2932
assert shortened_url == expected_url, 'The shortened version of %s url should\'ve been %s but was %s' % (url_to_be_shortened, expected_url, shortened_url)
3033

3134
def should_shorten_many_urls_consistently_when_a_list_of_urls_is_provided(api):
3235
urls_to_be_shortened = [ 'http://globoesporte.globo.com/motor/formula-1/noticia/2010/10/apos-maus-resultados-ferrari-reforca-apoio-massa-no-fim-da-temporada.html'
3336
,
3437
'http://globoesporte.globo.com/basquete/noticia/2010/10/leandrinho-faz-19-pontos-na-vitoria-do-toronto-sobre-o-philadelphia.html'
3538
]
36-
39+
3740
expected_urls = ['http://bit.ly/9n93fw','http://bit.ly/aprECg']
38-
41+
3942
shortened_urls = api.shorten(longURLs=urls_to_be_shortened)
40-
43+
4144
for expected_url in expected_urls:
4245
assert expected_url in shortened_urls, 'The list os shortened urls should contain %s but it wasn\'t found in %s' % (expected_url, shortened_urls)
46+
47+
48+
def test_urls_shortening_scenario_for_urls_with_query_string():
49+
api = bitly.Api(login='jcfigueiredo', apikey='R_1cf5dc0fa14c2df34261fb620bd256aa')
50+
51+
yield should_have_an_API_authenticated_by_my_credentials, api
52+
yield should_shorten_an_urls_with_querystring, api
53+
54+
def should_shorten_an_urls_with_querystring(api):
55+
56+
url_to_be_shortened = 'http://www.google.com/search?q=globo.com'
57+
expected_url = 'http://bit.ly/9Rc5qD'
58+
59+
shortened_url = api.shorten(longURLs=url_to_be_shortened)
60+
61+
assert shortened_url == expected_url, 'The shortened version of %s url should\'ve been %s but was %s' % (url_to_be_shortened, expected_url, shortened_url)
62+
63+
64+
def test_checking_for_errors():
65+
yield verifying_invalid_error_key
66+
yield verifying_invalid_status_code
67+
yield verifying_invalid_status_code_and_invalid_error_key
68+
yield verifying_invalid_status_code
69+
70+
def verifying_invalid_error_key():
71+
#invalid error key
72+
invalid_data = {'ERROR': 'any', 'errorMessage': 'something went wrong'}
73+
assert_raises(bitly.BitlyError, bitly.Api._CheckForError, invalid_data)
74+
75+
def verifying_invalid_status_code():
76+
#invalid status code
77+
invalid_data = {'statusCode': 'ERROR', 'errorMessage': 'something went wrong'}
78+
assert_raises(bitly.BitlyError, bitly.Api._CheckForError, invalid_data)
79+
80+
def verifying_invalid_status_code_and_invalid_error_key():
81+
#both above
82+
invalid_data = {'ERROR': 'any', 'statusCode': 'ERROR', 'errorMessage': 'something went wrong'}
83+
assert_raises(bitly.BitlyError, bitly.Api._CheckForError, invalid_data)
84+
85+
def verifying_invalid_item():
86+
#invalid item
87+
invalid_data = {'results':
88+
{'http://shorturl.com': {
89+
'statusCode': 'ERROR',
90+
'errorMessage': 'something went really wrong'
91+
}
92+
}
93+
,
94+
'statusCode': 'ANY BUT ERROR'
95+
}
96+
assert_raises(bitly.BitlyError, bitly.Api._CheckForError, invalid_data)
97+
98+

0 commit comments

Comments
 (0)