Skip to content

Commit

Permalink
Build and pass tests for exception handling on different return cases
Browse files Browse the repository at this point in the history
  • Loading branch information
ishiland committed Jan 25, 2019
1 parent d809ad2 commit d479f03
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ dist
docs/_build
.idea
.eggs
.cache
15 changes: 11 additions & 4 deletions geoclient/api.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import os

try:
from configparser import ConfigParser # Python 3
except ImportError:
from ConfigParser import ConfigParser # Python 2
import requests
from geoclient.config import BASE_URL, USER_CONFIG
from .error import GeoclientError
from .error import GeoclientError, _format_return_message


class Geoclient(object):
Expand Down Expand Up @@ -73,10 +74,16 @@ def _request(self, endpoint, **kwargs):
result = r.json()[key]

if isinstance(result, dict):
return_code = result['geosupportReturnCode']
if not return_code.isdigit() or int(return_code) > 1:
if 'geosupportReturnCode' in result:
return_code = result['geosupportReturnCode']
if not return_code.isdigit() or int(return_code) > 1:
raise GeoclientError(
_format_return_message(result),
result
)
else:
raise GeoclientError(
result['message'] + ' ' + result['message2'],
"No 'geosupportReturnCode' received from server.",
result
)
return result
Expand Down
21 changes: 21 additions & 0 deletions geoclient/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,24 @@ class GeoclientError(Exception):
def __init__(self, message, result=None):
super(GeoclientError, self).__init__(message)
self.result = result


def _format_return_message(results):
"""
Formats and eliminates redundant return messages from a failed geocoding result.
:param results: the returned dictionary from Geoclient API of a failed geocode.
:return: Formatted Geoclient return messages
"""
out_message = None

if 'message' in results:
out_message = results['message']

if 'message2' in results:
if out_message:
if out_message != results['message2']:
out_message = "{} {}".format(out_message, results['message2'])
else:
return results['message2']

return out_message
38 changes: 18 additions & 20 deletions tests/mock_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,22 @@
u'response': {u'message': u'350 5 AVENUE IS THE UNDERLYING ADDRESS OF EMPIRE STATE BUILDING'},
u'geosupportReturnCode': u'00'}]}

# full response
address_response_error = {
u'address': {u'streetName7': u'WORLD TRADE CENTER EAST CNCRSE', u'streetName5': u'WORLD FINANCIAL CENTER SKYBRIDGE',
u'streetCode5': u'10071901', u'streetCode4': u'10093601', u'streetCode7': u'14560116',
u'streetCode6': u'14560101', u'streetCode1': u'11191501', u'streetCode3': u'14561201',
u'streetCode2': u'14549001', u'reasonCode': u'A',
u'message': u"'WORT ST' NOT RECOGNIZED. THERE ARE 010 SIMILAR NAMES.",
u'streetName10': u'WORLD TRADE CENTER OCULUS', u'streetCode9': u'11394005',
u'streetCode8': u'14560114', u'streetCode10': u'14560118',
u'firstStreetNameNormalized': u'WORT STREET', u'streetName1In': u'WORT ST', u'boroughCode1In': u'1',
u'message2': u"'WORT ST' NOT RECOGNIZED. THERE ARE 010 SIMILAR NAMES.", u'reasonCode1e': u'A',
u'returnCode1a': u'EE', u'reasonCode1a': u'A', u'returnCode1e': u'EE',
u'geosupportFunctionCode': u'1B', u'houseNumberSortFormat': u'000125000AA', u'reasonCode2': u'A',
u'streetName6': u'WORLD TRADE CENTER', u'crossStreetNamesFlagIn': u'E',
u'streetName4': u'WORLD FINANCIAL CENTER FERRY', u'streetName3': u'WORLD FINANCIAL CENTER',
u'streetName2': u'WORTH STREET', u'streetName1': u'WORTH SQUARE', u'houseNumberIn': u'125',
u'numberOfStreetCodesAndNamesInList': u'10', u'geosupportReturnCode': u'EE',
u'streetName9': u'WORLD TRADE CENTER NORTH POOL', u'streetName8': u'WORLD TRADE CENTER NORTH CNCRSE',
u'workAreaFormatIndicatorIn': u'C', u'houseNumber': u'125', u'firstBoroughName': u'MANHATTAN',
u'geosupportReturnCode2': u'EE'}
# 'message' and 'message2' are equal
msg_equal = {
u'address': {u'message': u"'WORT ST' NOT RECOGNIZED. THERE ARE 010 SIMILAR NAMES.",
u'message2': u"'WORT ST' NOT RECOGNIZED. THERE ARE 010 SIMILAR NAMES.",
u'geosupportReturnCode': u'EE'}
}

# 'message' and 'message2' are unequal
msg_unequal = {
u'address': {u'message': u"THIS IS THE FIRST MESSAGE.",
u'message2': u"THIS IS THE SECOND MESSAGE",
u'geosupportReturnCode': u'EE'}
}

# only 'message' returned
msg_single = {
u'address': {u'message': u"'WORT ST' NOT RECOGNIZED. THERE ARE 010 SIMILAR NAMES.",
u'geosupportReturnCode': u'EE'}
}
2 changes: 0 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,3 @@ def test_search_no_result(self, fake_get):
'THIS VALUE RETURNS NO RESULT'
)
self.assertEqual(len(result), 0)


76 changes: 72 additions & 4 deletions tests/test_error.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .testcase import TestCase
from .mock_responses import address_response_error
from .mock_responses import msg_equal, msg_unequal, msg_single
from geoclient.error import GeoclientError

try:
Expand All @@ -10,6 +10,10 @@

@mock.patch('geoclient.requests.get')
class TestResponseError(TestCase):
"""
Tests for bad responses from the Geoclient API
"""

def test_403(self, fake_get):
fake_get.return_value.status_code = 403
fake_get.return_value.reason = "Forbidden"
Expand All @@ -26,7 +30,71 @@ def test_None(self, fake_get):

@mock.patch('geoclient.requests.get')
class TestGeoclientMessageError(TestCase):
def test_address_error(self, fake_get):
"""
Tests for formatting, no key:values and de-duplication of Geoclient return messages.
"""

def test_error_msg_equal(self, fake_get):
# test for two equal messages - 'message' and 'message2'
fake_get.return_value.status_code = 200
fake_get.return_value.json.return_value = address_response_error
self.assertRaises(GeoclientError, self.geoclient.address, '125', 'Wort st', 1)
fake_get.return_value.json.return_value = msg_equal

with self.assertRaises(GeoclientError) as cm:
self.geoclient.address(
houseNumber='125',
street='Worth St',
borough='Mn',
)

self.assertEqual(
"'WORT ST' NOT RECOGNIZED. THERE ARE 010 SIMILAR NAMES.",
str(cm.exception)
)

def test_error_msg_unequal(self, fake_get):
# test for two unequal messages - 'message' and 'message2'
fake_get.return_value.status_code = 200
fake_get.return_value.json.return_value = msg_unequal

with self.assertRaises(GeoclientError) as cm:
self.geoclient.address(
houseNumber='125',
street='Worth St',
borough='Mn',
)
self.assertEqual(
"THIS IS THE FIRST MESSAGE. THIS IS THE SECOND MESSAGE",
str(cm.exception)
)

def test_error_msg_single(self, fake_get):
# test for a single message value - 'message'
fake_get.return_value.status_code = 200
fake_get.return_value.json.return_value = msg_single

with self.assertRaises(GeoclientError) as cm:
self.geoclient.address(
houseNumber='125',
street='Worth St',
borough='Mn',
)
self.assertEqual(
"'WORT ST' NOT RECOGNIZED. THERE ARE 010 SIMILAR NAMES.",
str(cm.exception)
)

def test_error_return_empty(self, fake_get):
# test for no returned key:values
fake_get.return_value.status_code = 200
fake_get.return_value.json.return_value = {u'address': {}}

with self.assertRaises(GeoclientError) as cm:
self.geoclient.address(
houseNumber='125',
street='Worth St',
borough='Mn',
)
self.assertEqual(
str(cm.exception),
"No 'geosupportReturnCode' received from server."
)

0 comments on commit d479f03

Please sign in to comment.