Skip to content

Commit 89a4c74

Browse files
authored
Merge pull request #53 from adobe-apiplatform/v2
merge in changes for 2.7 release
2 parents e44d00c + 529a5c0 commit 89a4c74

File tree

12 files changed

+82
-54
lines changed

12 files changed

+82
-54
lines changed

HISTORY.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ Enhancement release:
100100
* (No Issue)
101101
* Read the wall clock to return an accurate "total time" in the `UnavailableError` (and associated logging).
102102

103-
### Version 2.6
103+
### Version 2.6, 2.7
104104

105-
Bug fix release:
105+
Bug fix releases: The first fix attempt had problems, the second is better.
106106

107107
* [Issue 50](https://github.com/adobe-apiplatform/umapi-client.py/issues/50)
108108
* Unicode input for email produced error strings that were incorrectly encoded, so clients crashed trying to use them.

tests/test_connections.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@
3232

3333
def test_remote_status_success():
3434
with mock.patch("umapi_client.connection.requests.Session.get") as mock_get:
35-
mock_get.return_value = MockResponse(200, body={"build": "2559", "version": "2.1.54", "state":"LIVE"})
35+
mock_get.return_value = MockResponse(200, body={"build": "2559", "version": "2.1.54", "state": "LIVE"})
3636
conn = Connection(**mock_connection_params)
3737
_, remote_status = conn.status(remote=True)
38-
assert remote_status == {"endpoint": "https://test/", "build": "2559", "version": "2.1.54", "state":"LIVE"}
38+
assert remote_status == {"endpoint": "https://test/", "build": "2559", "version": "2.1.54", "state": "LIVE"}
3939

4040

4141
def test_remote_status_failure():
@@ -53,6 +53,7 @@ def test_remote_status_timeout():
5353
_, remote_status = conn.status(remote=True)
5454
assert remote_status["status"].startswith("Unreachable")
5555

56+
5657
def test_ua_string():
5758
conn = Connection(**mock_connection_params)
5859
req = conn.session.prepare_request(requests.Request('GET', "http://test.com/"))
@@ -64,6 +65,7 @@ def test_ua_string():
6465
assert ua_header.startswith("umapi-client/" + umapi_version)
6566
assert " Python" in ua_header
6667

68+
6769
def test_ua_string_additional():
6870
conn = Connection(user_agent="additional/1.0", **mock_connection_params)
6971
req = conn.session.prepare_request(requests.Request('GET', "http://test.com/"))
@@ -73,6 +75,7 @@ def test_ua_string_additional():
7375
ua_header = req.headers.get("User-Agent")
7476
assert ua_header.startswith("additional/1.0 umapi-client/" + umapi_version)
7577

78+
7679
def test_get_success():
7780
with mock.patch("umapi_client.connection.requests.Session.get") as mock_get:
7881
mock_get.return_value = MockResponse(200, body=["test", "body"])

tests/test_functional.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
# SOFTWARE.
2222

2323
import pytest
24+
import six
2425

2526
from conftest import mock_connection_params
27+
from umapi_client import ArgumentError
2628
from umapi_client import Connection
2729
from umapi_client import IdentityTypes, GroupTypes, RoleTypes
2830
from umapi_client import UserAction, UserGroupAction
@@ -49,8 +51,15 @@ def test_user_adobeid_unicode():
4951

5052

5153
def test_user_adobeid_unicode_error_unicode_dot_above():
52-
with pytest.raises(ValueError):
54+
with pytest.raises(ValueError) as excinfo:
5355
UserAction(email=u"lwałę[email protected]")
56+
assert excinfo.type == ArgumentError
57+
if six.PY2:
58+
assert excinfo.match(u"lwałę[email protected]".encode('utf8'))
59+
with pytest.raises(ValueError) as excinfo:
60+
UserAction(email=u"lwałę[email protected]".encode('utf8'))
61+
assert excinfo.type == ArgumentError
62+
assert excinfo.match(u"lwałę[email protected]".encode('utf8'))
5463

5564

5665
def test_user_adobeid_unicode_error_trailing_dot():

tests/test_legacy.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
retry_response = MockResponse(429, headers={"Retry-After": "1"})
3737
not_found_response = MockResponse(404, text="404 Object Not Found")
3838

39+
3940
@mock.patch('umapi_client.legacy.requests.Session.get', return_value=success_response)
4041
def test_list_users_success(_):
4142
"""Test Users List - SUCCESS"""
@@ -173,7 +174,10 @@ def test_action_obj_multi():
173174
remove=["product3"]
174175
)
175176
assert json.dumps(action.wire_dict(), sort_keys=True) == \
176-
'{"do": [{"addAdobeID": {"email": "[email protected]"}}, {"add": {"product": ["product1", "product2"]}}, {"remove": {"product": ["product3"]}}], "user": "[email protected]"}'
177+
'{"do": [{"addAdobeID": {"email": "[email protected]"}}, ' \
178+
'{"add": {"product": ["product1", "product2"]}}, ' \
179+
'{"remove": {"product": ["product3"]}}], ' \
180+
'"user": "[email protected]"}'
177181

178182

179183
def test_action_obj_requestid():

tests/test_live.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def test_list_users(config):
7878
break
7979
logging.info("Found %d users.", user_count)
8080

81+
8182
def test_list_groups(config):
8283
conn, params = config
8384
groups = umapi_client.GroupsQuery(connection=conn)
@@ -93,6 +94,7 @@ def test_list_groups(config):
9394
group_count_2 = len(groups.all_results())
9495
assert group_count == group_count_2
9596

97+
9698
def test_get_user(config):
9799
conn, params = config
98100
user_query = umapi_client.UserQuery(conn, params["test_user"]["email"])
@@ -101,6 +103,7 @@ def test_get_user(config):
101103
for k, v in six.iteritems(params["test_user"]):
102104
assert user[k].lower() == v.lower()
103105

106+
104107
def test_rename_user(config):
105108
conn, params = config
106109
user = umapi_client.UserAction(id_type=params["test_user"]["type"],

umapi_client/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1919
# SOFTWARE.
2020

21-
from .connection import Connection
2221
from .api import Action, QuerySingle, QueryMultiple
23-
from .error import BatchError, ClientError, RequestError, ServerError, UnavailableError
22+
from .connection import Connection
23+
from .error import BatchError, ClientError, RequestError, ServerError, UnavailableError, ArgumentError
2424
from .functional import IdentityTypes, GroupTypes, RoleTypes, IfAlreadyExistsOptions
2525
from .functional import UserAction, UserQuery, UsersQuery
2626
from .functional import UserGroupAction, GroupsQuery

umapi_client/auth.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import datetime as dt
2222
import time
2323

24-
import jwt # package name is PyJWT in setup
24+
import jwt # package name is PyJWT in setup
2525
import requests
2626
import six.moves.urllib.parse as urlparse
2727

umapi_client/connection.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import six.moves.urllib.parse as urlparse
3131

3232
from .auth import JWT, Auth, AccessRequest
33-
from .error import BatchError, UnavailableError, ClientError, RequestError, ServerError
33+
from .error import BatchError, UnavailableError, ClientError, RequestError, ServerError, ArgumentError
3434
from .version import __version__ as umapi_version
3535

3636

@@ -119,7 +119,7 @@ def __init__(self,
119119
elif auth_dict:
120120
self.auth = self._get_auth(ims_host=ims_host, ims_endpoint_jwt=ims_endpoint_jwt, **auth_dict)
121121
else:
122-
raise ValueError("Connector create: either auth (an Auth object) or auth_dict (a dictionary) is required")
122+
raise ArgumentError("Connector create: either auth (an Auth object) or auth_dict (a dict) is required")
123123
self.session = requests.Session()
124124
ua_string = "umapi-client/" + umapi_version + " Python/" + python_version() + " (" + platform_version() + ")"
125125
if user_agent and user_agent.strip():
@@ -133,7 +133,7 @@ def _get_auth(self, ims_host, ims_endpoint_jwt,
133133
tech_acct_id = tech_acct_id or kwargs.get("tech_acct")
134134
private_key_file = private_key_file or kwargs.get("priv_key_path")
135135
if not (tech_acct_id and api_key and client_secret and (private_key_data or private_key_file)):
136-
raise ValueError("Connector create: not all required auth parameters were supplied; please see docs")
136+
raise ArgumentError("Connector create: not all required auth parameters were supplied; please see docs")
137137
if private_key_data:
138138
jwt = JWT(self.org_id, tech_acct_id, ims_host, api_key, six.StringIO(private_key_data))
139139
else:
@@ -196,7 +196,7 @@ def query_single(self, object_type, url_params, query_params=None):
196196
query_type = object_type + "s" # poor man's plural
197197
query_path = "/organizations/{}/{}".format(self.org_id, query_type)
198198
for component in url_params if url_params else []:
199-
query_path += "/" + urlparse.quote(component)
199+
query_path += "/" + urlparse.quote(component, safe='/@')
200200
if query_params: query_path += "?" + urlparse.urlencode(query_params)
201201
try:
202202
result = self.make_call(query_path)

umapi_client/error.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1919
# SOFTWARE.
2020

21+
import six
22+
2123

2224
class UnavailableError(Exception):
2325
def __init__(self, attempts, seconds, result):
@@ -52,3 +54,10 @@ def __init__(self, causes, queued, sent, completed):
5254
Exception.__init__(self, prefix + tail)
5355
self.causes = causes
5456
self.statistics = (queued, sent, completed)
57+
58+
59+
class ArgumentError(ValueError):
60+
def __init__(self, message):
61+
if six.PY2 and isinstance(message, unicode):
62+
message = message.encode('utf8')
63+
ValueError.__init__(self, message)

0 commit comments

Comments
 (0)