Merge branch 'sneakypete81-unicode_tags' into development
This commit is contained in:
commit
f536a4ef29
5 changed files with 62 additions and 38 deletions
|
@ -70,15 +70,15 @@ class TestActivitiesList(TestActivities):
|
||||||
|
|
||||||
@mock.patch.object(trovebox.Trovebox, 'get')
|
@mock.patch.object(trovebox.Trovebox, 'get')
|
||||||
def test_options(self, mock_get):
|
def test_options(self, mock_get):
|
||||||
"""Check that the activity list optionss are applied properly"""
|
"""Check that the activity list options are applied properly"""
|
||||||
mock_get.return_value = self._return_value(self.test_activities_dict)
|
mock_get.return_value = self._return_value(self.test_activities_dict)
|
||||||
self.client.activities.list(options={"foo": "bar",
|
self.client.activities.list(options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
foo="bar")
|
foo="bar")
|
||||||
# Dict element can be any order
|
# Dict element can be any order
|
||||||
self.assertIn(mock_get.call_args[0],
|
self.assertIn(mock_get.call_args[0],
|
||||||
[("/activities/foo-bar/test1-test2/list.json",),
|
[("/activities/foo-bar/test1-%C3%BCmlaut/list.json",),
|
||||||
("/activities/test1-test2/foo-bar/list.json",)])
|
("/activities/test1-%C3%BCmlaut/foo-bar/list.json",)])
|
||||||
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
||||||
|
|
||||||
class TestActivitiesPurge(TestActivities):
|
class TestActivitiesPurge(TestActivities):
|
||||||
|
|
|
@ -57,27 +57,27 @@ class TestPhotosList(TestPhotos):
|
||||||
|
|
||||||
@mock.patch.object(trovebox.Trovebox, 'get')
|
@mock.patch.object(trovebox.Trovebox, 'get')
|
||||||
def test_options(self, mock_get):
|
def test_options(self, mock_get):
|
||||||
"""Check that the activity list options are applied properly"""
|
"""Check that the photo list options are applied properly"""
|
||||||
mock_get.return_value = self._return_value(self.test_photos_dict)
|
mock_get.return_value = self._return_value(self.test_photos_dict)
|
||||||
self.client.photos.list(options={"foo": "bar",
|
self.client.photos.list(options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
foo="bar")
|
foo="bar")
|
||||||
# Dict element can be any order
|
# Dict element can be any order
|
||||||
self.assertIn(mock_get.call_args[0],
|
self.assertIn(mock_get.call_args[0],
|
||||||
[("/photos/foo-bar/test1-test2/list.json",),
|
[("/photos/foo-bar/test1-%C3%BCmlaut/list.json",),
|
||||||
("/photos/test1-test2/foo-bar/list.json",)])
|
("/photos/test1-%C3%BCmlaut/foo-bar/list.json",)])
|
||||||
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
||||||
|
|
||||||
class TestPhotosShare(TestPhotos):
|
class TestPhotosShare(TestPhotos):
|
||||||
@mock.patch.object(trovebox.Trovebox, 'post')
|
@mock.patch.object(trovebox.Trovebox, 'post')
|
||||||
def test_photos_share(self, mock_post):
|
def test_photos_share(self, mock_post):
|
||||||
self.client.photos.share(options={"foo": "bar",
|
self.client.photos.share(options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
foo="bar")
|
foo="bar")
|
||||||
# Dict element can be any order
|
# Dict element can be any order
|
||||||
self.assertIn(mock_post.call_args[0],
|
self.assertIn(mock_post.call_args[0],
|
||||||
[("/photos/foo-bar/test1-test2/share.json",),
|
[("/photos/foo-bar/test1-%C3%BCmlaut/share.json",),
|
||||||
("/photos/test1-test2/foo-bar/share.json",)])
|
("/photos/test1-%C3%BCmlaut/foo-bar/share.json",)])
|
||||||
self.assertEqual(mock_post.call_args[1], {"foo": "bar"})
|
self.assertEqual(mock_post.call_args[1], {"foo": "bar"})
|
||||||
|
|
||||||
class TestPhotosUpdate(TestPhotos):
|
class TestPhotosUpdate(TestPhotos):
|
||||||
|
@ -363,12 +363,12 @@ class TestPhotoView(TestPhotos):
|
||||||
mock_get.return_value = self._return_value(self.test_photos_dict[1])
|
mock_get.return_value = self._return_value(self.test_photos_dict[1])
|
||||||
result = self.client.photo.view(self.test_photos[0],
|
result = self.client.photo.view(self.test_photos[0],
|
||||||
options={"foo": "bar",
|
options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
returnSizes="20x20")
|
returnSizes="20x20")
|
||||||
# Dict elemet can be in any order
|
# Dict elemet can be in any order
|
||||||
self.assertIn(mock_get.call_args[0],
|
self.assertIn(mock_get.call_args[0],
|
||||||
[("/photo/1a/foo-bar/test1-test2/view.json",),
|
[("/photo/1a/foo-bar/test1-%C3%BCmlaut/view.json",),
|
||||||
("/photo/1a/test1-test2/foo-bar/view.json",)])
|
("/photo/1a/test1-%C3%BCmlaut/foo-bar/view.json",)])
|
||||||
self.assertEqual(mock_get.call_args[1], {"returnSizes": "20x20"})
|
self.assertEqual(mock_get.call_args[1], {"returnSizes": "20x20"})
|
||||||
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
|
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
|
||||||
|
|
||||||
|
@ -378,13 +378,13 @@ class TestPhotoView(TestPhotos):
|
||||||
mock_get.return_value = self._return_value(self.test_photos_dict[1])
|
mock_get.return_value = self._return_value(self.test_photos_dict[1])
|
||||||
result = self.client.photo.view("1a",
|
result = self.client.photo.view("1a",
|
||||||
options={"foo": "bar",
|
options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
returnSizes="20x20")
|
returnSizes="20x20")
|
||||||
|
|
||||||
# Dict elemet can be in any order
|
# Dict elemet can be in any order
|
||||||
self.assertIn(mock_get.call_args[0],
|
self.assertIn(mock_get.call_args[0],
|
||||||
[("/photo/1a/foo-bar/test1-test2/view.json",),
|
[("/photo/1a/foo-bar/test1-%C3%BCmlaut/view.json",),
|
||||||
("/photo/1a/test1-test2/foo-bar/view.json",)])
|
("/photo/1a/test1-%C3%BCmlaut/foo-bar/view.json",)])
|
||||||
self.assertEqual(mock_get.call_args[1], {"returnSizes": "20x20"})
|
self.assertEqual(mock_get.call_args[1], {"returnSizes": "20x20"})
|
||||||
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
|
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
|
||||||
|
|
||||||
|
@ -455,12 +455,12 @@ class TestPhotoNextPrevious(TestPhotos):
|
||||||
"previous": [self.test_photos_dict[1]]})
|
"previous": [self.test_photos_dict[1]]})
|
||||||
result = self.client.photo.next_previous(self.test_photos[0],
|
result = self.client.photo.next_previous(self.test_photos[0],
|
||||||
options={"foo": "bar",
|
options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
foo="bar")
|
foo="bar")
|
||||||
# Dict elemet can be in any order
|
# Dict elemet can be in any order
|
||||||
self.assertIn(mock_get.call_args[0],
|
self.assertIn(mock_get.call_args[0],
|
||||||
[("/photo/1a/nextprevious/foo-bar/test1-test2.json",),
|
[("/photo/1a/nextprevious/foo-bar/test1-%C3%BCmlaut.json",),
|
||||||
("/photo/1a/nextprevious/test1-test2/foo-bar.json",)])
|
("/photo/1a/nextprevious/test1-%C3%BCmlaut/foo-bar.json",)])
|
||||||
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
||||||
self.assertEqual(result["next"][0].get_fields(),
|
self.assertEqual(result["next"][0].get_fields(),
|
||||||
self.test_photos_dict[0])
|
self.test_photos_dict[0])
|
||||||
|
@ -478,12 +478,12 @@ class TestPhotoNextPrevious(TestPhotos):
|
||||||
"previous": [self.test_photos_dict[1]]})
|
"previous": [self.test_photos_dict[1]]})
|
||||||
result = self.client.photo.next_previous("1a",
|
result = self.client.photo.next_previous("1a",
|
||||||
options={"foo": "bar",
|
options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
foo="bar")
|
foo="bar")
|
||||||
# Dict elemet can be in any order
|
# Dict elemet can be in any order
|
||||||
self.assertIn(mock_get.call_args[0],
|
self.assertIn(mock_get.call_args[0],
|
||||||
[("/photo/1a/nextprevious/foo-bar/test1-test2.json",),
|
[("/photo/1a/nextprevious/foo-bar/test1-%C3%BCmlaut.json",),
|
||||||
("/photo/1a/nextprevious/test1-test2/foo-bar.json",)])
|
("/photo/1a/nextprevious/test1-%C3%BCmlaut/foo-bar.json",)])
|
||||||
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
||||||
self.assertEqual(result["next"][0].get_fields(),
|
self.assertEqual(result["next"][0].get_fields(),
|
||||||
self.test_photos_dict[0])
|
self.test_photos_dict[0])
|
||||||
|
@ -500,12 +500,12 @@ class TestPhotoNextPrevious(TestPhotos):
|
||||||
{"next": [self.test_photos_dict[0]],
|
{"next": [self.test_photos_dict[0]],
|
||||||
"previous": [self.test_photos_dict[1]]})
|
"previous": [self.test_photos_dict[1]]})
|
||||||
result = self.test_photos[0].next_previous(options={"foo": "bar",
|
result = self.test_photos[0].next_previous(options={"foo": "bar",
|
||||||
"test1": "test2"},
|
"test1": "\xfcmlaut"},
|
||||||
foo="bar")
|
foo="bar")
|
||||||
# Dict elemet can be in any order
|
# Dict elemet can be in any order
|
||||||
self.assertIn(mock_get.call_args[0],
|
self.assertIn(mock_get.call_args[0],
|
||||||
[("/photo/1a/nextprevious/foo-bar/test1-test2.json",),
|
[("/photo/1a/nextprevious/foo-bar/test1-%C3%BCmlaut.json",),
|
||||||
("/photo/1a/nextprevious/test1-test2/foo-bar.json",)])
|
("/photo/1a/nextprevious/test1-%C3%BCmlaut/foo-bar.json",)])
|
||||||
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
|
||||||
self.assertEqual(result["next"][0].get_fields(),
|
self.assertEqual(result["next"][0].get_fields(),
|
||||||
self.test_photos_dict[0])
|
self.test_photos_dict[0])
|
||||||
|
|
|
@ -10,13 +10,17 @@ import trovebox
|
||||||
class TestTags(unittest.TestCase):
|
class TestTags(unittest.TestCase):
|
||||||
test_host = "test.example.com"
|
test_host = "test.example.com"
|
||||||
test_tags = None
|
test_tags = None
|
||||||
test_tags_dict = [{"count": 11, "id":"tag1"},
|
test_tags_dict = [{"count": 11, "id": "tag1"},
|
||||||
{"count": 5, "id":"tag2"}]
|
{"count": 5, "id": "tag2"}]
|
||||||
|
|
||||||
|
test_tag_unicode_dict = {"id": "\xfcmlaut"}
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = trovebox.Trovebox(host=self.test_host)
|
self.client = trovebox.Trovebox(host=self.test_host)
|
||||||
self.test_tags = [trovebox.objects.tag.Tag(self.client, tag)
|
self.test_tags = [trovebox.objects.tag.Tag(self.client, tag)
|
||||||
for tag in self.test_tags_dict]
|
for tag in self.test_tags_dict]
|
||||||
|
self.test_tag_unicode = trovebox.objects.tag.Tag(self.client,
|
||||||
|
self.test_tag_unicode_dict)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _return_value(result, message="", code=200):
|
def _return_value(result, message="", code=200):
|
||||||
|
@ -89,6 +93,14 @@ class TestTagDelete(TestTags):
|
||||||
self.assertEqual(tag.get_fields(), {})
|
self.assertEqual(tag.get_fields(), {})
|
||||||
self.assertEqual(tag.id, None)
|
self.assertEqual(tag.id, None)
|
||||||
|
|
||||||
|
@mock.patch.object(trovebox.Trovebox, 'post')
|
||||||
|
def test_tag_object_delete_unicode(self, mock_post):
|
||||||
|
"""Check that a unicode tag can be deleted using its ID"""
|
||||||
|
mock_post.return_value = self._return_value(True)
|
||||||
|
result = self.client.tag.delete(self.test_tag_unicode)
|
||||||
|
mock_post.assert_called_with("/tag/%C3%BCmlaut/delete.json")
|
||||||
|
self.assertEqual(result, True)
|
||||||
|
|
||||||
class TestTagUpdate(TestTags):
|
class TestTagUpdate(TestTags):
|
||||||
@mock.patch.object(trovebox.Trovebox, 'post')
|
@mock.patch.object(trovebox.Trovebox, 'post')
|
||||||
def test_tag_update(self, mock_post):
|
def test_tag_update(self, mock_post):
|
||||||
|
@ -118,3 +130,11 @@ class TestTagUpdate(TestTags):
|
||||||
self.assertEqual(tag.id, "tag2")
|
self.assertEqual(tag.id, "tag2")
|
||||||
self.assertEqual(tag.count, 5)
|
self.assertEqual(tag.count, 5)
|
||||||
|
|
||||||
|
@mock.patch.object(trovebox.Trovebox, 'post')
|
||||||
|
def test_tag_object_update_unicode(self, mock_post):
|
||||||
|
"""Check that a unicode tag can be updated using its ID"""
|
||||||
|
mock_post.return_value = self._return_value(self.test_tag_unicode_dict)
|
||||||
|
result = self.client.tag.update(self.test_tag_unicode, name="Test")
|
||||||
|
mock_post.assert_called_with("/tag/%C3%BCmlaut/update.json", name="Test")
|
||||||
|
self.assertEqual(result.id, "\xfcmlaut")
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
"""
|
"""
|
||||||
api_base.py: Base class for all API classes
|
api_base.py: Base class for all API classes
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
from urllib.parse import quote # Python3
|
||||||
|
except ImportError:
|
||||||
|
from urllib import quote # Python2
|
||||||
|
|
||||||
|
|
||||||
class ApiBase(object):
|
class ApiBase(object):
|
||||||
""" Base class for all API objects """
|
""" Base class for all API objects """
|
||||||
def __init__(self, client):
|
def __init__(self, client):
|
||||||
self._client = client
|
self._client = client
|
||||||
|
|
||||||
@staticmethod
|
def _build_option_string(self, options):
|
||||||
def _build_option_string(options):
|
|
||||||
"""
|
"""
|
||||||
:param options: dictionary containing the options
|
:param options: dictionary containing the options
|
||||||
:returns: option_string formatted for an API endpoint
|
:returns: option_string formatted for an API endpoint
|
||||||
|
@ -17,7 +21,7 @@ class ApiBase(object):
|
||||||
if options is not None:
|
if options is not None:
|
||||||
for key in options:
|
for key in options:
|
||||||
option_string += "/%s-%s" % (key, options[key])
|
option_string += "/%s-%s" % (key, options[key])
|
||||||
return option_string
|
return self._quote_url(option_string)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _extract_id(obj):
|
def _extract_id(obj):
|
||||||
|
@ -27,6 +31,11 @@ class ApiBase(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _quote_url(string):
|
||||||
|
""" Make a string suitable for insertion into a URL """
|
||||||
|
return quote(string.encode('utf-8'))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _result_to_list(result):
|
def _result_to_list(result):
|
||||||
""" Handle the case where the result contains no items """
|
""" Handle the case where the result contains no items """
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
"""
|
"""
|
||||||
api_tag.py : Trovebox Tag API Classes
|
api_tag.py : Trovebox Tag API Classes
|
||||||
"""
|
"""
|
||||||
try:
|
|
||||||
from urllib.parse import quote # Python3
|
|
||||||
except ImportError:
|
|
||||||
from urllib import quote # Python2
|
|
||||||
|
|
||||||
from trovebox.objects.tag import Tag
|
from trovebox.objects.tag import Tag
|
||||||
from .api_base import ApiBase
|
from .api_base import ApiBase
|
||||||
|
|
||||||
|
@ -42,7 +37,7 @@ class ApiTag(ApiBase):
|
||||||
Raises a TroveboxError if not.
|
Raises a TroveboxError if not.
|
||||||
"""
|
"""
|
||||||
return self._client.post("/tag/%s/delete.json" %
|
return self._client.post("/tag/%s/delete.json" %
|
||||||
quote(self._extract_id(tag)),
|
self._quote_url(self._extract_id(tag)),
|
||||||
**kwds)["result"]
|
**kwds)["result"]
|
||||||
|
|
||||||
def update(self, tag, **kwds):
|
def update(self, tag, **kwds):
|
||||||
|
@ -53,7 +48,7 @@ class ApiTag(ApiBase):
|
||||||
Returns the updated tag object.
|
Returns the updated tag object.
|
||||||
"""
|
"""
|
||||||
result = self._client.post("/tag/%s/update.json" %
|
result = self._client.post("/tag/%s/update.json" %
|
||||||
quote(self._extract_id(tag)),
|
self._quote_url(self._extract_id(tag)),
|
||||||
**kwds)["result"]
|
**kwds)["result"]
|
||||||
return Tag(self._client, result)
|
return Tag(self._client, result)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue