Skip to content
This repository has been archived by the owner on Aug 29, 2019. It is now read-only.

Commit

Permalink
refactored client library to raise exceptions when 40x and 50x errors…
Browse files Browse the repository at this point in the history
… are returned from the api.
  • Loading branch information
Edward F. Long, Jr committed Aug 24, 2011
1 parent 119dc17 commit 309d9f1
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 64 deletions.
12 changes: 6 additions & 6 deletions aweber_api/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from urllib import urlencode
from aweber_api.response import AWeberResponse
from aweber_api.base import API_BASE
import aweber_api


class AWeberCollection(AWeberResponse):
"""
Expand Down Expand Up @@ -57,12 +59,10 @@ def create(self, **kwargs):

response = self.adapter.request('POST', self.url, params,
response='headers')
if response['status'] != '201':
return False
new_resource = response['location']
self._diff = {}
self._data = self.adapter.request('GET', new_resource)
return True

resource_url = response['location']
data = self.adapter.request('GET', resource_url)
return aweber_api.entry.AWeberEntry(resource_url, data, self.adapter)

def find(self, **kwargs):
params = {'ws.op': 'find'}
Expand Down
10 changes: 5 additions & 5 deletions aweber_api/entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ def get_parent_entry(self):
size = len(url_parts)
url = self.url[:-len(url_parts[size-1])-1]
url = url[:-len(url_parts[size-2])-1]
data = self.adapter.request('GET', url)
try:
entry = AWeberEntry(url, data, self.adapter)
except TypeError:

if url == '':
return None
return entry

data = self.adapter.request('GET', url)
return AWeberEntry(url, data, self.adapter)

def get_web_forms(self):
self._method_for('account')
Expand Down
60 changes: 37 additions & 23 deletions aweber_api/oauth.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,43 @@ def request(self, method, url, data={}, response='body'):
client = self._get_client()
url = self._expand_url(url)
body = self._prepare_request_body(method, url, data)
try:
# need a test for the next 4 lines below
content_type = 'application/json'
if method == 'GET' and body is not None and body is not '':
# todo: need a better way to do this!
if '?' in url:
url = '{0}&{1}'.format(url, body)
else:
url = '{0}?{1}'.format(url, body)
if method == 'POST':
content_type = 'application/x-www-form-urlencoded'
headers = {'Content-Type' : content_type}
resp, content = client.request(url, method, body=body,
headers=headers)
if response == 'body' and isinstance(content, str):
return self._parse(content)
if response == 'status':
return resp['status']
if response == 'headers':
return resp
except Exception:
# TODO: refactor this for better error handling
pass

# need a test for the next 4 lines below
content_type = 'application/json'
if method == 'GET' and body is not None and body is not '':
# todo: need a better way to do this!
if '?' in url:
url = '{0}&{1}'.format(url, body)
else:
url = '{0}?{1}'.format(url, body)
if method == 'POST':
content_type = 'application/x-www-form-urlencoded'
headers = {'Content-Type' : content_type}

resp, content = client.request(url, method, body=body,
headers=headers)
if int(resp['status']) >= 400:
"""
API Service Errors:
Please review the Exception that is raised it should indicate
what the error is.
refer to https://labs.aweber.com/docs/troubleshooting for more
details.
"""
content = json.loads(content)
error = content.get('error', {})
error_type = error.get('type')
error_msg = error.get('message')
raise Exception('{0}: {1}'.format(error_type, error_msg))

if response == 'body' and isinstance(content, str):
return self._parse(content)
if response == 'status':
return resp['status']
if response == 'headers':
return resp
return None

def _expand_url(self, url):
Expand Down
1 change: 1 addition & 0 deletions tests/data/custom_fields/505454.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"total_size": 0, "start": 0, "resource_type_link": "https://api.aweber.com/1.0/#custom_field-page-resource", "entries": []}
1 change: 1 addition & 0 deletions tests/data/custom_fields/error.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"error": {"message": "name: must be unique.", "type": "BadRequestError"}}
2 changes: 1 addition & 1 deletion tests/data/error.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"error": {"message": "Missing required parameter 'oauth_consumer_key'.", "type": "MissingRequiredOAuthParameterError"}}
{"error": {"message": "Simulated Exception", "type": "BadRequestError"}}
1 change: 1 addition & 0 deletions tests/data/subscribers/get_activity_ts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
17 changes: 14 additions & 3 deletions tests/mock_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,21 @@
'/accounts/1/lists/505454': ({}, 'lists/505454'),
'/accounts/1/lists/303449/campaigns': ({}, 'campaigns/303449'),
'/accounts/1/lists/303449/custom_fields': ({}, 'custom_fields/303449'),
'/accounts/1/lists/505454/custom_fields': ({}, 'custom_fields/505454'),
'/accounts/1/lists/303449/custom_fields/1': ({}, 'custom_fields/1'),
'/accounts/1/lists/303449/custom_fields/2': ({}, 'custom_fields/2'),
'/accounts/1/lists/303449/subscribers': ({}, 'subscribers/page1'),
'/accounts/1/lists/303449/subscribers/1': ({}, 'subscribers/1'),
'/accounts/1/lists/303449/subscribers/2': ({}, 'subscribers/2'),
'/accounts/1/lists/505454/subscribers/3': ({}, 'subscribers/3'),
'/accounts/1/lists/303449/subscribers/1?ws.op=getActivity': (
{}, 'subscribers/get_activity'),
'/accounts/1/lists/303449/subscribers/1?ws.op=getActivity&ws.show=total_size': (
{}, 'subscribers/get_activity_ts'),
'/accounts/1/lists/303449/subscribers?ws.op=find&name=joe': (
{'status': '400'}, 'error'),
'/accounts/1?ws.op=findSubscribers&name=bob': (
{'status': '400'}, 'error'),
'/accounts/1/lists/303449/subscribers?ws.op=find&' \
'email=joe%40example.com': ({}, 'subscribers/find'),
'/accounts/1/lists/303449/subscribers?ws.op=find&' \
Expand All @@ -42,17 +51,19 @@
'/accounts/1/lists/303449/custom_fields': ({
'status': '201',
'location': '/accounts/1/lists/303449/custom_fields/2'}, None),
'/accounts/1/lists/505454/custom_fields': ({
'status': '400'}, 'custom_fields/error'),
'/accounts/1/lists/303449/subscribers/1': ({
'status': '201',
'location': '/accounts/1/lists/505454/subscribers/3'}, None),
},
'PATCH' : {
'/accounts/1/lists/303449/subscribers/1': ({}, None),
'/accounts/1/lists/303449/subscribers/2': ({'status': '403'}, None),
'/accounts/1/lists/303449/subscribers/2': ({'status': '400'}, 'error'),
},
'DELETE' : {
'/accounts/1/lists/303449/subscribers/1': ({}, None),
'/accounts/1/lists/303449/subscribers/2': ({'status': '403'}, None),
'/accounts/1/lists/303449/subscribers/1': ({'status': '200'}, None),
'/accounts/1/lists/303449/subscribers/2': ({'status': '400'}, 'error'),
}
}

Expand Down
29 changes: 20 additions & 9 deletions tests/test_aweber_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,7 @@ def test_should_support_find_method(self):
def test_find_should_handle_errors(self):
base_url = '/accounts/1/lists/303449/subscribers'
subscriber_collection = self.aweber.load_from_url(base_url)
self.aweber.adapter.requests = []
subscribers = subscriber_collection.find(name='joe')
request = self.aweber.adapter.requests[0]

assert subscribers == False
assert request['url'] == \
'{0}?ws.op=find&name=joe'.format(base_url)
self.assertRaises(Exception, subscriber_collection.find, name='joe')

def test_should_create_entries_with_correct_url(self):
base_url = '/accounts/1'
Expand All @@ -72,6 +66,19 @@ def test_should_create_entries_with_correct_url(self):
assert subscriber.url == subscriber.self_link.replace(API_BASE, '')


class TestWhenCreatingCustomFieldsFails(TestCase):

def setUp(self):
self.aweber = AWeberAPI('1', '2')
self.aweber.adapter = MockAdapter()
cf_url = '/accounts/1/lists/505454/custom_fields'
self.cf = self.aweber.load_from_url(cf_url)
self.aweber.adapter.requests = []

def test_should_raise_exception(self):
self.assertRaises(Exception, self.cf.create, name='Duplicate Name')


class TestCreatingCustomFields(TestCase):

def setUp(self):
Expand All @@ -85,8 +92,12 @@ def setUp(self):
self.create_req = self.aweber.adapter.requests[0]
self.get_req = self.aweber.adapter.requests[1]

def test_returned_true(self):
self.assertTrue(self.resp)
def test_should_return_new_resource_entry_object(self):
assert isinstance(self.resp, AWeberEntry)
assert self.resp.name == u'COLOR'
assert self.resp.is_subscriber_updateable == True
assert self.resp.id == 2
assert self.resp.url == '/accounts/1/lists/303449/custom_fields/2'

def test_should_have_requested_create_with_post(self):
self.assertEqual(self.create_req['method'], 'POST')
Expand Down
24 changes: 7 additions & 17 deletions tests/test_aweber_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,8 @@ def test_should_have_child_collections(self):
self.assertEqual(type(campaigns), AWeberCollection)

def test_findSubscribers_should_handle_errors(self):
base_url = '/accounts/1'
account = self.aweber.load_from_url(base_url)
self.aweber.adapter.requests = []
subscribers = account.findSubscribers(name='bob')
request = self.aweber.adapter.requests[0]

assert subscribers == False
assert request['url'] == \
'{0}?ws.op=findSubscribers&name=bob'.format(base_url)
account = self.aweber.load_from_url('/accounts/1')
self.assertRaises(Exception, account.findSubscribers, name='bob')


class AccountTestCase(TestCase):
Expand Down Expand Up @@ -232,11 +225,9 @@ def setUp(self):
self.subscriber = self.aweber.load_from_url(sub_url)
self.subscriber.name = 'Gary Oldman'
self.subscriber.custom_fields['New Custom Field'] = 'Cookies'
self.resp = self.subscriber.save()
self.req = self.aweber.adapter.requests[0]

def test_save_failed(self):
self.assertFalse(self.resp)
self.assertRaises(Exception, self.subscriber.save)


class TestDeletingSubscriberData(SubscriberTestCase):
Expand Down Expand Up @@ -264,12 +255,9 @@ def setUp(self):
self.aweber.adapter = MockAdapter()
sub_url = '/accounts/1/lists/303449/subscribers/2'
self.subscriber = self.aweber.load_from_url(sub_url)
self.aweber.adapter.requests = []
self.response = self.subscriber.delete()
self.req = self.aweber.adapter.requests[0]

def test_should_have_failed(self):
self.assertFalse(self.response)
def test_should_raise_exception_when_failing(self):
self.assertRaises(Exception, self.subscriber.delete)


class TestGettingParentEntry(TestCase):
Expand All @@ -279,6 +267,8 @@ def setUp(self):
self.aweber.adapter = MockAdapter()
self.list = self.aweber.load_from_url('/accounts/1/lists/303449')
self.account = self.aweber.load_from_url('/accounts/1')
#print self.account._data
#1/0
self.custom_field = self.aweber.load_from_url('/accounts/1/lists/303449/custom_fields/1')

def test_should_be_able_get_parent_entry(self):
Expand Down

0 comments on commit 309d9f1

Please sign in to comment.