Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overhaul many things #11

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Return USPSError, not ValueError
See #10

- still allows you to catch ValueErrors
- still acts just like a ValueError
- Differentiates between errors from USPS,
  and the ValueError you get if you supply more than 5 addresses
NickCrews committed Apr 6, 2022
commit 3f28f07c6b9098f61e75d13e660aa078173f35f0
24 changes: 23 additions & 1 deletion pyusps/address_information.py
Original file line number Diff line number Diff line change
@@ -7,11 +7,33 @@

ADDRESS_MAX = 5

class USPSError(ValueError):
"""
An error from the USPS API, such as a bad `user_id` or when an address is not found.

Inherits from ValueError. Also has attributes `code: str` and `description: str`.
"""
code: str
description: str

def __init__(self, code: str, description: str) -> None:
self.code = code
self.description = description
super().__init__(f"{code}: {description}")

def __eq__(self, o: object) -> bool:
return (
isinstance(o, USPSError) and
self.code == o.code and
self.description == o.description
)

def _get_error(node):
if node.tag != 'Error':
return None
return ValueError(f"{node.find('Number').text}: {node.find('Description').text}")
code = node.find('Number').text
description = node.find('Description').text
return USPSError(code, description)

def _get_address_error(address):
error_node = address.find('Error')
63 changes: 36 additions & 27 deletions pyusps/test/test_address_information.py
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
from nose.tools import eq_ as eq
from io import StringIO

from pyusps.address_information import verify
from pyusps.address_information import verify, USPSError
from pyusps.test.util import assert_raises, assert_errors_equal

@fudge.patch('pyusps.urlutil.urlopen')
@@ -292,14 +292,27 @@ def test_verify_more_than_5(fake_urlopen):
])
addresses = [inp] * 6

msg = assert_raises(
err = assert_raises(
ValueError,
verify,
'foo_id',
addresses
)
expected = ValueError('Only 5 addresses are allowed per request')
assert_errors_equal(err, expected)


def test_error_properties():
"""We can treat these pretty much like a ValueError."""
err = USPSError("code", "description")
err2 = USPSError("code", "description")
eq(err.code, "code")
eq(err.description, "description")
eq(err.args, ("code: description", ))
eq(str(err), "code: description")
assert isinstance(err, ValueError)
eq(err, err2)

eq(str(msg), 'Only 5 addresses are allowed per request')

@fudge.patch('pyusps.urlutil.urlopen')
def test_verify_api_root_error(fake_urlopen):
@@ -318,17 +331,18 @@ def test_verify_api_root_error(fake_urlopen):
('city', 'Greenbelt'),
('state', 'MD'),
])
msg = assert_raises(
ValueError,
err = assert_raises(
USPSError,
verify,
'foo_id',
[address]
)

expected = ('80040b1a: Authorization failure. Perhaps username '
'and/or password is incorrect.'
)
eq(str(msg), expected)
expected = USPSError(
"80040b1a",
"Authorization failure. Perhaps username and/or password is incorrect."
)
eq(err, expected)

@fudge.patch('pyusps.urlutil.urlopen')
def test_verify_api_address_error_single(fake_urlopen):
@@ -347,10 +361,8 @@ def test_verify_api_address_error_single(fake_urlopen):
res = verify('foo_id', address)

eq(len(res), 1)
assert_errors_equal(
res[0],
ValueError('-2147219401: Address Not Found.'),
)
expected = USPSError("-2147219401", "Address Not Found.")
eq(res[0], expected)

@fudge.patch('pyusps.urlutil.urlopen')
def test_verify_api_address_error_multiple(fake_urlopen):
@@ -386,11 +398,9 @@ def test_verify_api_address_error_multiple(fake_urlopen):
('zip5', '20770'),
('zip4', '1441'),
]),
)
assert_errors_equal(
res[1],
ValueError('-2147219400: Invalid City.'),
)
)
expected = USPSError("-2147219400", "Invalid City.")
eq(res[1], expected)

@fudge.patch('pyusps.urlutil.urlopen')
def test_verify_api_empty_error(fake_urlopen):
@@ -406,15 +416,15 @@ def test_verify_api_empty_error(fake_urlopen):
('city', 'Greenbelt'),
('state', 'NJ'),
])]
msg = assert_raises(
err = assert_raises(
TypeError,
verify,
'foo_id',
address
)

expected = 'Could not find any address or error information'
eq(str(msg), expected)
expected = TypeError('Could not find any address or error information')
assert_errors_equal(err, expected)

@fudge.patch('pyusps.urlutil.urlopen')
def test_verify_api_order_error(fake_urlopen):
@@ -437,14 +447,13 @@ def test_verify_api_order_error(fake_urlopen):
('state', 'CT'),
]),
]
msg = assert_raises(
err = assert_raises(
IndexError,
verify,
'foo_id',
addresses
)

expected = ('The addresses returned are not in the same order '
'they were requested'
)
eq(str(msg), expected)
expected = IndexError(
'The addresses returned are not in the same order they were requested'
)
assert_errors_equal(err, expected)