Merge branch 'sneakypete81-unicode_tags' into development

This commit is contained in:
sneakypete81 2014-02-02 20:55:58 +00:00
commit f536a4ef29
5 changed files with 62 additions and 38 deletions

View file

@ -70,15 +70,15 @@ class TestActivitiesList(TestActivities):
@mock.patch.object(trovebox.Trovebox, '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)
self.client.activities.list(options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
foo="bar")
# Dict element can be any order
self.assertIn(mock_get.call_args[0],
[("/activities/foo-bar/test1-test2/list.json",),
("/activities/test1-test2/foo-bar/list.json",)])
[("/activities/foo-bar/test1-%C3%BCmlaut/list.json",),
("/activities/test1-%C3%BCmlaut/foo-bar/list.json",)])
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
class TestActivitiesPurge(TestActivities):

View file

@ -57,27 +57,27 @@ class TestPhotosList(TestPhotos):
@mock.patch.object(trovebox.Trovebox, '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)
self.client.photos.list(options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
foo="bar")
# Dict element can be any order
self.assertIn(mock_get.call_args[0],
[("/photos/foo-bar/test1-test2/list.json",),
("/photos/test1-test2/foo-bar/list.json",)])
[("/photos/foo-bar/test1-%C3%BCmlaut/list.json",),
("/photos/test1-%C3%BCmlaut/foo-bar/list.json",)])
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
class TestPhotosShare(TestPhotos):
@mock.patch.object(trovebox.Trovebox, 'post')
def test_photos_share(self, mock_post):
self.client.photos.share(options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
foo="bar")
# Dict element can be any order
self.assertIn(mock_post.call_args[0],
[("/photos/foo-bar/test1-test2/share.json",),
("/photos/test1-test2/foo-bar/share.json",)])
[("/photos/foo-bar/test1-%C3%BCmlaut/share.json",),
("/photos/test1-%C3%BCmlaut/foo-bar/share.json",)])
self.assertEqual(mock_post.call_args[1], {"foo": "bar"})
class TestPhotosUpdate(TestPhotos):
@ -363,12 +363,12 @@ class TestPhotoView(TestPhotos):
mock_get.return_value = self._return_value(self.test_photos_dict[1])
result = self.client.photo.view(self.test_photos[0],
options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
returnSizes="20x20")
# Dict elemet can be in any order
self.assertIn(mock_get.call_args[0],
[("/photo/1a/foo-bar/test1-test2/view.json",),
("/photo/1a/test1-test2/foo-bar/view.json",)])
[("/photo/1a/foo-bar/test1-%C3%BCmlaut/view.json",),
("/photo/1a/test1-%C3%BCmlaut/foo-bar/view.json",)])
self.assertEqual(mock_get.call_args[1], {"returnSizes": "20x20"})
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])
result = self.client.photo.view("1a",
options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
returnSizes="20x20")
# Dict elemet can be in any order
self.assertIn(mock_get.call_args[0],
[("/photo/1a/foo-bar/test1-test2/view.json",),
("/photo/1a/test1-test2/foo-bar/view.json",)])
[("/photo/1a/foo-bar/test1-%C3%BCmlaut/view.json",),
("/photo/1a/test1-%C3%BCmlaut/foo-bar/view.json",)])
self.assertEqual(mock_get.call_args[1], {"returnSizes": "20x20"})
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
@ -455,12 +455,12 @@ class TestPhotoNextPrevious(TestPhotos):
"previous": [self.test_photos_dict[1]]})
result = self.client.photo.next_previous(self.test_photos[0],
options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
foo="bar")
# Dict elemet can be in any order
self.assertIn(mock_get.call_args[0],
[("/photo/1a/nextprevious/foo-bar/test1-test2.json",),
("/photo/1a/nextprevious/test1-test2/foo-bar.json",)])
[("/photo/1a/nextprevious/foo-bar/test1-%C3%BCmlaut.json",),
("/photo/1a/nextprevious/test1-%C3%BCmlaut/foo-bar.json",)])
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
self.assertEqual(result["next"][0].get_fields(),
self.test_photos_dict[0])
@ -478,12 +478,12 @@ class TestPhotoNextPrevious(TestPhotos):
"previous": [self.test_photos_dict[1]]})
result = self.client.photo.next_previous("1a",
options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
foo="bar")
# Dict elemet can be in any order
self.assertIn(mock_get.call_args[0],
[("/photo/1a/nextprevious/foo-bar/test1-test2.json",),
("/photo/1a/nextprevious/test1-test2/foo-bar.json",)])
[("/photo/1a/nextprevious/foo-bar/test1-%C3%BCmlaut.json",),
("/photo/1a/nextprevious/test1-%C3%BCmlaut/foo-bar.json",)])
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
self.assertEqual(result["next"][0].get_fields(),
self.test_photos_dict[0])
@ -500,12 +500,12 @@ class TestPhotoNextPrevious(TestPhotos):
{"next": [self.test_photos_dict[0]],
"previous": [self.test_photos_dict[1]]})
result = self.test_photos[0].next_previous(options={"foo": "bar",
"test1": "test2"},
"test1": "\xfcmlaut"},
foo="bar")
# Dict elemet can be in any order
self.assertIn(mock_get.call_args[0],
[("/photo/1a/nextprevious/foo-bar/test1-test2.json",),
("/photo/1a/nextprevious/test1-test2/foo-bar.json",)])
[("/photo/1a/nextprevious/foo-bar/test1-%C3%BCmlaut.json",),
("/photo/1a/nextprevious/test1-%C3%BCmlaut/foo-bar.json",)])
self.assertEqual(mock_get.call_args[1], {"foo": "bar"})
self.assertEqual(result["next"][0].get_fields(),
self.test_photos_dict[0])

View file

@ -10,13 +10,17 @@ import trovebox
class TestTags(unittest.TestCase):
test_host = "test.example.com"
test_tags = None
test_tags_dict = [{"count": 11, "id":"tag1"},
{"count": 5, "id":"tag2"}]
test_tags_dict = [{"count": 11, "id": "tag1"},
{"count": 5, "id": "tag2"}]
test_tag_unicode_dict = {"id": "\xfcmlaut"}
def setUp(self):
self.client = trovebox.Trovebox(host=self.test_host)
self.test_tags = [trovebox.objects.tag.Tag(self.client, tag)
for tag in self.test_tags_dict]
self.test_tag_unicode = trovebox.objects.tag.Tag(self.client,
self.test_tag_unicode_dict)
@staticmethod
def _return_value(result, message="", code=200):
@ -89,6 +93,14 @@ class TestTagDelete(TestTags):
self.assertEqual(tag.get_fields(), {})
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):
@mock.patch.object(trovebox.Trovebox, 'post')
def test_tag_update(self, mock_post):
@ -118,3 +130,11 @@ class TestTagUpdate(TestTags):
self.assertEqual(tag.id, "tag2")
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")

View file

@ -1,14 +1,18 @@
"""
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):
""" Base class for all API objects """
def __init__(self, client):
self._client = client
@staticmethod
def _build_option_string(options):
def _build_option_string(self, options):
"""
:param options: dictionary containing the options
:returns: option_string formatted for an API endpoint
@ -17,7 +21,7 @@ class ApiBase(object):
if options is not None:
for key in options:
option_string += "/%s-%s" % (key, options[key])
return option_string
return self._quote_url(option_string)
@staticmethod
def _extract_id(obj):
@ -27,6 +31,11 @@ class ApiBase(object):
except AttributeError:
return obj
@staticmethod
def _quote_url(string):
""" Make a string suitable for insertion into a URL """
return quote(string.encode('utf-8'))
@staticmethod
def _result_to_list(result):
""" Handle the case where the result contains no items """

View file

@ -1,11 +1,6 @@
"""
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 .api_base import ApiBase
@ -42,7 +37,7 @@ class ApiTag(ApiBase):
Raises a TroveboxError if not.
"""
return self._client.post("/tag/%s/delete.json" %
quote(self._extract_id(tag)),
self._quote_url(self._extract_id(tag)),
**kwds)["result"]
def update(self, tag, **kwds):
@ -53,7 +48,7 @@ class ApiTag(ApiBase):
Returns the updated tag object.
"""
result = self._client.post("/tag/%s/update.json" %
quote(self._extract_id(tag)),
self._quote_url(self._extract_id(tag)),
**kwds)["result"]
return Tag(self._client, result)