PyLint fixes

This commit is contained in:
sneakypete81 2013-06-29 18:57:12 +01:00
parent 5825a751c3
commit 77fef49c64
7 changed files with 593 additions and 388 deletions

View file

@ -8,8 +8,8 @@ except ImportError:
import openphoto import openphoto
class TestAlbums(unittest.TestCase): class TestAlbums(unittest.TestCase):
TEST_HOST = "test.example.com" test_host = "test.example.com"
TEST_ALBUMS_DICT = [{"cover": {"id": "1a", "tags": ["tag1", "tag2"]}, test_albums_dict = [{"cover": {"id": "1a", "tags": ["tag1", "tag2"]},
"id": "1", "id": "1",
"name": "Album 1", "name": "Album 1",
"totalRows": 2}, "totalRows": 2},
@ -18,9 +18,9 @@ class TestAlbums(unittest.TestCase):
"name": "Album 2", "name": "Album 2",
"totalRows": 2}] "totalRows": 2}]
def setUp(self): def setUp(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST) self.client = openphoto.OpenPhoto(host=self.test_host)
self.TEST_ALBUMS = [openphoto.objects.Album(self.client, album) self.test_albums = [openphoto.objects.Album(self.client, album)
for album in self.TEST_ALBUMS_DICT] for album in self.test_albums_dict]
@staticmethod @staticmethod
def _return_value(result, message="", code=200): def _return_value(result, message="", code=200):
@ -28,10 +28,11 @@ class TestAlbums(unittest.TestCase):
class TestAlbumsList(TestAlbums): class TestAlbumsList(TestAlbums):
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_albums_list(self, mock): def test_albums_list(self, mock_get):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT) """Check that the album list is returned correctly"""
mock_get.return_value = self._return_value(self.test_albums_dict)
result = self.client.albums.list() result = self.client.albums.list()
mock.assert_called_with("/albums/list.json") mock_get.assert_called_with("/albums/list.json")
self.assertEqual(len(result), 2) self.assertEqual(len(result), 2)
self.assertEqual(result[0].id, "1") self.assertEqual(result[0].id, "1")
self.assertEqual(result[0].name, "Album 1") self.assertEqual(result[0].name, "Album 1")
@ -41,10 +42,11 @@ class TestAlbumsList(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_albums_list_returns_cover_photos(self, mock): def test_albums_list_returns_cover_photos(self, mock_get):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT) """Check that the album list returns cover photo objects"""
mock_get.return_value = self._return_value(self.test_albums_dict)
result = self.client.albums.list() result = self.client.albums.list()
mock.assert_called_with("/albums/list.json") mock_get.assert_called_with("/albums/list.json")
self.assertEqual(len(result), 2) self.assertEqual(len(result), 2)
self.assertEqual(result[0].id, "1") self.assertEqual(result[0].id, "1")
self.assertEqual(result[0].name, "Album 1") self.assertEqual(result[0].name, "Album 1")
@ -58,10 +60,12 @@ class TestAlbumsList(TestAlbums):
class TestAlbumCreate(TestAlbums): class TestAlbumCreate(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_create(self, mock): def test_album_create(self, mock_post):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT[0]) """Check that an album can be created"""
mock_post.return_value = self._return_value(self.test_albums_dict[0])
result = self.client.album.create(name="Test", foo="bar") result = self.client.album.create(name="Test", foo="bar")
mock.assert_called_with("/album/create.json", name="Test", foo="bar") mock_post.assert_called_with("/album/create.json", name="Test",
foo="bar")
self.assertEqual(result.id, "1") self.assertEqual(result.id, "1")
self.assertEqual(result.name, "Album 1") self.assertEqual(result.name, "Album 1")
# self.assertEqual(result.cover.id, "1a") # self.assertEqual(result.cover.id, "1a")
@ -69,34 +73,38 @@ class TestAlbumCreate(TestAlbums):
class TestAlbumDelete(TestAlbums): class TestAlbumDelete(TestAlbums):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_delete(self, mock): def test_album_delete(self, mock_post):
mock.return_value = self._return_value(True) """Check that an album can be deleted"""
result = self.client.album.delete(self.TEST_ALBUMS[0]) mock_post.return_value = self._return_value(True)
mock.assert_called_with("/album/1/delete.json") result = self.client.album.delete(self.test_albums[0])
mock_post.assert_called_with("/album/1/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_delete_id(self, mock): def test_album_delete_id(self, mock_post):
mock.return_value = self._return_value(True) """Check that an album can be deleted using its ID"""
mock_post.return_value = self._return_value(True)
result = self.client.album.delete("1") result = self.client.album.delete("1")
mock.assert_called_with("/album/1/delete.json") mock_post.assert_called_with("/album/1/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
# TODO: album.delete should raise exception on failure # TODO: album.delete should raise exception on failure
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_delete_failure_raises_exception(self, mock): def test_album_delete_failure(self, mock_post):
mock.return_value = self._return_value(False) """Check that an exception is raised if an album cannot be deleted"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.album.delete(self.TEST_ALBUMS[0]) self.client.album.delete(self.test_albums[0])
# TODO: after deleting object fields, name and id should be set to None # TODO: after deleting object fields, name and id should be set to None
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_object_delete(self, mock): def test_album_object_delete(self, mock_post):
mock.return_value = self._return_value(True) """Check that an album can be deleted using the album object directly"""
album = self.TEST_ALBUMS[0] mock_post.return_value = self._return_value(True)
album = self.test_albums[0]
result = album.delete() result = album.delete()
mock.assert_called_with("/album/1/delete.json") mock_post.assert_called_with("/album/1/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
self.assertEqual(album.get_fields(), {}) self.assertEqual(album.get_fields(), {})
# self.assertEqual(album.id, None) # self.assertEqual(album.id, None)
@ -105,70 +113,85 @@ class TestAlbumDelete(TestAlbums):
# TODO: album.delete should raise exception on failure # TODO: album.delete should raise exception on failure
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_object_delete_failure_raises_exception(self, mock): def test_album_object_delete_failure(self, mock_post):
mock.return_value = self._return_value(False) """
Check that an exception is raised if an album cannot be deleted
when using the album object directly
"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.TEST_ALBUMS[0].delete() self.test_albums[0].delete()
class TestAlbumForm(TestAlbums): class TestAlbumForm(TestAlbums):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_form(self, mock): def test_album_form(self, _):
""" If album.form gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.album.form(self.TEST_ALBUMS[0]) self.client.album.form(self.test_albums[0])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_form_id(self, mock): def test_album_form_id(self, _):
""" If album.form gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.album.form("1") self.client.album.form("1")
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_object_form(self, mock): def test_album_object_form(self, _):
""" If album.form gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.TEST_ALBUMS[0].form() self.test_albums[0].form()
class TestAlbumAddPhotos(TestAlbums): class TestAlbumAddPhotos(TestAlbums):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_add_photos(self, mock): def test_album_add_photos(self, _):
""" If album.add_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.album.add_photos(self.TEST_ALBUMS[0], ["Photo Objects"]) self.client.album.add_photos(self.test_albums[0], ["Photo Objects"])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_add_photos_id(self, mock): def test_album_add_photos_id(self, _):
""" If album.add_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.album.add_photos("1", ["Photo Objects"]) self.client.album.add_photos("1", ["Photo Objects"])
# TODO: object.add_photos should accept photos list as first parameter # TODO: object.add_photos should accept photos list as first parameter
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_object_add_photos(self, mock): def test_album_object_add_photos(self, _):
""" If album.add_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.TEST_ALBUMS[0].add_photos(["Photo Objects"]) self.test_albums[0].add_photos(["Photo Objects"])
class TestAlbumRemovePhotos(TestAlbums): class TestAlbumRemovePhotos(TestAlbums):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_remove_photos(self, mock): def test_album_remove_photos(self, _):
""" If album.remove_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.album.remove_photos(self.TEST_ALBUMS[0], ["Photo Objects"]) self.client.album.remove_photos(self.test_albums[0],
["Photo Objects"])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_remove_photos_id(self, mock): def test_album_remove_photos_id(self, _):
""" If album.remove_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.album.remove_photos("1", ["Photo Objects"]) self.client.album.remove_photos("1", ["Photo Objects"])
# TODO: object.remove_photos should accept photos list as first parameter # TODO: object.remove_photos should accept photos list as first parameter
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_object_remove_photos(self, mock): def test_album_object_remove_photos(self, _):
""" If album.remove_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.TEST_ALBUMS[0].remove_photos(["Photo Objects"]) self.test_albums[0].remove_photos(["Photo Objects"])
class TestAlbumUpdate(TestAlbums): class TestAlbumUpdate(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_update(self, mock): def test_album_update(self, mock_post):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT[1]) """Check that an album can be updated"""
result = self.client.album.update(self.TEST_ALBUMS[0], name="Test") mock_post.return_value = self._return_value(self.test_albums_dict[1])
mock.assert_called_with("/album/1/update.json", name="Test") result = self.client.album.update(self.test_albums[0], name="Test")
mock_post.assert_called_with("/album/1/update.json", name="Test")
self.assertEqual(result.id, "2") self.assertEqual(result.id, "2")
self.assertEqual(result.name, "Album 2") self.assertEqual(result.name, "Album 2")
# self.assertEqual(result.cover.id, "2b") # self.assertEqual(result.cover.id, "2b")
@ -176,10 +199,11 @@ class TestAlbumUpdate(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_update_id(self, mock): def test_album_update_id(self, mock_post):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT[1]) """Check that an album can be updated using its ID"""
mock_post.return_value = self._return_value(self.test_albums_dict[1])
result = self.client.album.update("1", name="Test") result = self.client.album.update("1", name="Test")
mock.assert_called_with("/album/1/update.json", name="Test") mock_post.assert_called_with("/album/1/update.json", name="Test")
self.assertEqual(result.id, "2") self.assertEqual(result.id, "2")
self.assertEqual(result.name, "Album 2") self.assertEqual(result.name, "Album 2")
# self.assertEqual(result.cover.id, "2b") # self.assertEqual(result.cover.id, "2b")
@ -187,11 +211,12 @@ class TestAlbumUpdate(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_album_object_update(self, mock): def test_album_object_update(self, mock_post):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT[1]) """Check that an album can be updated using the album object directly"""
album = self.TEST_ALBUMS[0] mock_post.return_value = self._return_value(self.test_albums_dict[1])
album = self.test_albums[0]
album.update(name="Test") album.update(name="Test")
mock.assert_called_with("/album/1/update.json", name="Test") mock_post.assert_called_with("/album/1/update.json", name="Test")
self.assertEqual(album.id, "2") self.assertEqual(album.id, "2")
self.assertEqual(album.name, "Album 2") self.assertEqual(album.name, "Album 2")
# self.assertEqual(album.cover.id, "2b") # self.assertEqual(album.cover.id, "2b")
@ -200,10 +225,11 @@ class TestAlbumUpdate(TestAlbums):
class TestAlbumView(TestAlbums): class TestAlbumView(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_album_view(self, mock): def test_album_view(self, mock_get):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT[1]) """Check that an album can be viewed"""
result = self.client.album.view(self.TEST_ALBUMS[0], name="Test") mock_get.return_value = self._return_value(self.test_albums_dict[1])
mock.assert_called_with("/album/1/view.json", name="Test") result = self.client.album.view(self.test_albums[0], name="Test")
mock_get.assert_called_with("/album/1/view.json", name="Test")
self.assertEqual(result.id, "2") self.assertEqual(result.id, "2")
self.assertEqual(result.name, "Album 2") self.assertEqual(result.name, "Album 2")
# self.assertEqual(result.cover.id, "2b") # self.assertEqual(result.cover.id, "2b")
@ -211,10 +237,11 @@ class TestAlbumView(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_album_view_id(self, mock): def test_album_view_id(self, mock_get):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT[1]) """Check that an album can be viewed using its ID"""
mock_get.return_value = self._return_value(self.test_albums_dict[1])
result = self.client.album.view("1", name="Test") result = self.client.album.view("1", name="Test")
mock.assert_called_with("/album/1/view.json", name="Test") mock_get.assert_called_with("/album/1/view.json", name="Test")
self.assertEqual(result.id, "2") self.assertEqual(result.id, "2")
self.assertEqual(result.name, "Album 2") self.assertEqual(result.name, "Album 2")
# self.assertEqual(result.cover.id, "2b") # self.assertEqual(result.cover.id, "2b")
@ -222,11 +249,12 @@ class TestAlbumView(TestAlbums):
# TODO: cover should be updated to Photo object # TODO: cover should be updated to Photo object
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_album_object_view(self, mock): def test_album_object_view(self, mock_get):
mock.return_value = self._return_value(self.TEST_ALBUMS_DICT[1]) """Check that an album can be viewed using the album object directly"""
album = self.TEST_ALBUMS[0] mock_get.return_value = self._return_value(self.test_albums_dict[1])
album = self.test_albums[0]
album.view(name="Test") album.view(name="Test")
mock.assert_called_with("/album/1/view.json", name="Test") mock_get.assert_called_with("/album/1/view.json", name="Test")
self.assertEqual(album.id, "2") self.assertEqual(album.id, "2")
self.assertEqual(album.name, "Album 2") self.assertEqual(album.name, "Album 2")
# self.assertEqual(album.cover.id, "2b") # self.assertEqual(album.cover.id, "2b")

View file

@ -17,59 +17,66 @@ def raise_exception(_):
raise TestException() raise TestException()
class TestCli(unittest.TestCase): class TestCli(unittest.TestCase):
TEST_FILE = os.path.join("tests", "unit", "data", "test_file.txt") test_file = os.path.join("tests", "unit", "data", "test_file.txt")
@mock.patch.object(openphoto.main, "OpenPhoto") @mock.patch.object(openphoto.main, "OpenPhoto")
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_defaults(self, _, MockOpenPhoto): def test_defaults(self, _, mock_openphoto):
get = MockOpenPhoto.return_value.get """Check that the default behaviour is correct"""
get = mock_openphoto.return_value.get
main([]) main([])
MockOpenPhoto.assert_called_with(config_file=None) mock_openphoto.assert_called_with(config_file=None)
get.assert_called_with("/photos/list.json", process_response=False) get.assert_called_with("/photos/list.json", process_response=False)
@mock.patch.object(openphoto.main, "OpenPhoto") @mock.patch.object(openphoto.main, "OpenPhoto")
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_config(self, _, MockOpenPhoto): def test_config(self, _, mock_openphoto):
"""Check that a config file can be specified"""
main(["--config=test"]) main(["--config=test"])
MockOpenPhoto.assert_called_with(config_file="test") mock_openphoto.assert_called_with(config_file="test")
@mock.patch.object(openphoto.main, "OpenPhoto") @mock.patch.object(openphoto.main, "OpenPhoto")
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_get(self, mock_stdout, MockOpenPhoto): def test_get(self, mock_stdout, mock_openphoto):
get = MockOpenPhoto.return_value.get """Check that the get operation is working"""
get = mock_openphoto.return_value.get
get.return_value = "Result" get.return_value = "Result"
main(["-X", "GET", "-h", "test_host", "-e", "test_endpoint", "-F", main(["-X", "GET", "-h", "test_host", "-e", "test_endpoint", "-F",
"field1=1", "-F", "field2=2"]) "field1=1", "-F", "field2=2"])
MockOpenPhoto.assert_called_with(host="test_host") mock_openphoto.assert_called_with(host="test_host")
get.assert_called_with("test_endpoint", field1="1", field2="2", get.assert_called_with("test_endpoint", field1="1", field2="2",
process_response=False) process_response=False)
self.assertEqual(mock_stdout.getvalue(), "Result\n") self.assertEqual(mock_stdout.getvalue(), "Result\n")
@mock.patch.object(openphoto.main, "OpenPhoto") @mock.patch.object(openphoto.main, "OpenPhoto")
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_post(self, mock_stdout, MockOpenPhoto): def test_post(self, mock_stdout, mock_openphoto):
post = MockOpenPhoto.return_value.post """Check that the post operation is working"""
post = mock_openphoto.return_value.post
post.return_value = "Result" post.return_value = "Result"
main(["-X", "POST", "-h", "test_host", "-e", "test_endpoint", "-F", main(["-X", "POST", "-h", "test_host", "-e", "test_endpoint", "-F",
"field1=1", "-F", "field2=2"]) "field1=1", "-F", "field2=2"])
MockOpenPhoto.assert_called_with(host="test_host") mock_openphoto.assert_called_with(host="test_host")
post.assert_called_with("test_endpoint", field1="1", field2="2", files={}, post.assert_called_with("test_endpoint", field1="1", field2="2",
process_response=False) files={}, process_response=False)
self.assertEqual(mock_stdout.getvalue(), "Result\n") self.assertEqual(mock_stdout.getvalue(), "Result\n")
@mock.patch.object(openphoto.main, "OpenPhoto") @mock.patch.object(openphoto.main, "OpenPhoto")
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_post_files(self, _, MockOpenPhoto): def test_post_files(self, _, mock_openphoto):
post = MockOpenPhoto.return_value.post """Check that files are posted correctly"""
main(["-X", "POST", "-F", "photo=@%s" % self.TEST_FILE]) post = mock_openphoto.return_value.post
# It's not possible to directly compare the file object, so check it manually main(["-X", "POST", "-F", "photo=@%s" % self.test_file])
# It's not possible to directly compare the file object,
# so check it manually
files = post.call_args[1]["files"] files = post.call_args[1]["files"]
self.assertEqual(files.keys(), ["photo"]) self.assertEqual(files.keys(), ["photo"])
self.assertEqual(files["photo"].name, self.TEST_FILE) self.assertEqual(files["photo"].name, self.test_file)
@mock.patch.object(sys, "exit", raise_exception) @mock.patch.object(sys, "exit", raise_exception)
@mock.patch('sys.stderr', new_callable=StringIO) @mock.patch('sys.stderr', new_callable=StringIO)
def test_unknown_arg(self, mock_stderr): def test_unknown_arg(self, mock_stderr):
"""Check that an unknown argument produces an error"""
with self.assertRaises(TestException): with self.assertRaises(TestException):
main(["hello"]) main(["hello"])
self.assertIn("error: Unknown argument", mock_stderr.getvalue()) self.assertIn("error: Unknown argument", mock_stderr.getvalue())
@ -77,6 +84,7 @@ class TestCli(unittest.TestCase):
@mock.patch.object(sys, "exit", raise_exception) @mock.patch.object(sys, "exit", raise_exception)
@mock.patch('sys.stderr', new_callable=StringIO) @mock.patch('sys.stderr', new_callable=StringIO)
def test_unknown_option(self, mock_stderr): def test_unknown_option(self, mock_stderr):
"""Check that an unknown option produces an error"""
with self.assertRaises(TestException): with self.assertRaises(TestException):
main(["--hello"]) main(["--hello"])
self.assertIn("error: no such option", mock_stderr.getvalue()) self.assertIn("error: no such option", mock_stderr.getvalue())
@ -84,23 +92,27 @@ class TestCli(unittest.TestCase):
@mock.patch.object(sys, "exit", raise_exception) @mock.patch.object(sys, "exit", raise_exception)
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_unknown_config(self, mock_stdout): def test_unknown_config(self, mock_stdout):
"""Check that an unknown config file produces an error"""
with self.assertRaises(TestException): with self.assertRaises(TestException):
main(["--config=this_config_doesnt_exist"]) main(["--config=this_config_doesnt_exist"])
self.assertIn("No such file or directory", mock_stdout.getvalue()) self.assertIn("No such file or directory", mock_stdout.getvalue())
self.assertIn("You must create a configuration file", mock_stdout.getvalue()) self.assertIn("You must create a configuration file",
mock_stdout.getvalue())
self.assertIn("To get your credentials", mock_stdout.getvalue()) self.assertIn("To get your credentials", mock_stdout.getvalue())
@mock.patch.object(openphoto.main, "OpenPhoto") @mock.patch.object(openphoto.main, "OpenPhoto")
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_verbose(self, mock_stdout, _): def test_verbose(self, mock_stdout, _):
"""Check that the verbose option is working"""
main(["-v"]) main(["-v"])
self.assertIn("Method: GET", mock_stdout.getvalue()) self.assertIn("Method: GET", mock_stdout.getvalue())
self.assertIn("Endpoint: /photos/list.json", mock_stdout.getvalue()) self.assertIn("Endpoint: /photos/list.json", mock_stdout.getvalue())
@mock.patch.object(openphoto.main, "OpenPhoto") @mock.patch.object(openphoto.main, "OpenPhoto")
@mock.patch('sys.stdout', new_callable=StringIO) @mock.patch('sys.stdout', new_callable=StringIO)
def test_pretty_print(self, mock_stdout, MockOpenPhoto): def test_pretty_print(self, mock_stdout, mock_openphoto):
get = MockOpenPhoto.return_value.get """Check that the pretty-print option is working"""
get = mock_openphoto.return_value.get
get.return_value = '{"test":1}' get.return_value = '{"test":1}'
main(["-p"]) main(["-p"])
self.assertEqual(mock_stdout.getvalue(), '{\n "test":1\n}\n') self.assertEqual(mock_stdout.getvalue(), '{\n "test":1\n}\n')

View file

@ -29,6 +29,7 @@ class TestConfig(unittest.TestCase):
@staticmethod @staticmethod
def create_config(config_file, host): def create_config(config_file, host):
"""Create a dummy config file"""
with open(os.path.join(CONFIG_PATH, config_file), "w") as conf: with open(os.path.join(CONFIG_PATH, config_file), "w") as conf:
conf.write("host = %s\n" % host) conf.write("host = %s\n" % host)
conf.write("# Comment\n\n") conf.write("# Comment\n\n")

View file

@ -10,25 +10,28 @@ except ImportError:
import openphoto import openphoto
class TestHttp(unittest.TestCase): class TestHttp(unittest.TestCase):
TEST_HOST = "test.example.com" test_host = "test.example.com"
TEST_ENDPOINT = "test.json" test_endpoint = "test.json"
TEST_URI = "http://%s/%s" % (TEST_HOST, TEST_ENDPOINT) test_uri = "http://%s/%s" % (test_host, test_endpoint)
TEST_DATA = {"message": "Test Message", test_data = {"message": "Test Message",
"code": 200, "code": 200,
"result": "Test Result"} "result": "Test Result"}
TEST_OAUTH = {"consumer_key": "dummy", test_oauth = {"consumer_key": "dummy",
"consumer_secret": "dummy", "consumer_secret": "dummy",
"token": "dummy", "token": "dummy",
"token_secret": "dummy"} "token_secret": "dummy"}
TEST_FILE = os.path.join("tests", "unit", "data", "test_file.txt") test_file = os.path.join("tests", "unit", "data", "test_file.txt")
def setUp(self): def setUp(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST, **self.TEST_OAUTH) self.client = openphoto.OpenPhoto(host=self.test_host,
**self.test_oauth)
def _register_uri(self, method, uri=TEST_URI, data=TEST_DATA, body=None, def _register_uri(self, method, uri=test_uri, data=None, body=None,
**kwds): **kwds):
"""Convenience wrapper around httpretty.register_uri""" """Convenience wrapper around httpretty.register_uri"""
if data is None:
data = self.test_data
if body is None: if body is None:
body = json.dumps(data) body = json.dumps(data)
httpretty.register_uri(method, uri=uri, body=body, **kwds) httpretty.register_uri(method, uri=uri, body=body, **kwds)
@ -39,67 +42,77 @@ class TestHttp(unittest.TestCase):
return httpretty.httpretty.last_request return httpretty.httpretty.last_request
def test_attributes(self): def test_attributes(self):
self.assertEqual(self.client.host, self.TEST_HOST) """Check that the host attribute has been set correctly"""
self.assertEqual(self.client.config.host, self.TEST_HOST) self.assertEqual(self.client.host, self.test_host)
self.assertEqual(self.client.config.host, self.test_host)
@httpretty.activate @httpretty.activate
def test_get_with_parameters(self): def test_get_with_parameters(self):
"""Check that the get method accepts parameters correctly"""
self._register_uri(httpretty.GET) self._register_uri(httpretty.GET)
response = self.client.get(self.TEST_ENDPOINT, response = self.client.get(self.test_endpoint,
foo="bar", spam="eggs") foo="bar", spam="eggs")
self.assertIn("OAuth", self._last_request().headers["authorization"]) self.assertIn("OAuth", self._last_request().headers["authorization"])
self.assertEqual(self._last_request().querystring["foo"], ["bar"]) self.assertEqual(self._last_request().querystring["foo"], ["bar"])
self.assertEqual(self._last_request().querystring["spam"], ["eggs"]) self.assertEqual(self._last_request().querystring["spam"], ["eggs"])
self.assertEqual(response, self.TEST_DATA) self.assertEqual(response, self.test_data)
self.assertEqual(self.client.last_url, self.TEST_URI) self.assertEqual(self.client.last_url, self.test_uri)
self.assertEqual(self.client.last_params, {"foo": "bar", "spam": "eggs"}) self.assertEqual(self.client.last_params, {"foo": "bar",
self.assertEqual(self.client.last_response.json(), self.TEST_DATA) "spam": "eggs"})
self.assertEqual(self.client.last_response.json(), self.test_data)
@httpretty.activate @httpretty.activate
def test_post_with_parameters(self): def test_post_with_parameters(self):
"""Check that the post method accepts parameters correctly"""
self._register_uri(httpretty.POST) self._register_uri(httpretty.POST)
response = self.client.post(self.TEST_ENDPOINT, response = self.client.post(self.test_endpoint,
foo="bar", spam="eggs") foo="bar", spam="eggs")
self.assertEqual(self._last_request().body, "foo=bar&spam=eggs") self.assertEqual(self._last_request().body, "foo=bar&spam=eggs")
self.assertEqual(response, self.TEST_DATA) self.assertEqual(response, self.test_data)
self.assertEqual(self.client.last_url, self.TEST_URI) self.assertEqual(self.client.last_url, self.test_uri)
self.assertEqual(self.client.last_params, {"foo": "bar", "spam": "eggs"}) self.assertEqual(self.client.last_params, {"foo": "bar",
self.assertEqual(self.client.last_response.json(), self.TEST_DATA) "spam": "eggs"})
self.assertEqual(self.client.last_response.json(), self.test_data)
@httpretty.activate @httpretty.activate
def test_get_without_oauth(self): def test_get_without_oauth(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST) """Check that the get method works without OAuth parameters"""
self.client = openphoto.OpenPhoto(host=self.test_host)
self._register_uri(httpretty.GET) self._register_uri(httpretty.GET)
response = self.client.get(self.TEST_ENDPOINT) response = self.client.get(self.test_endpoint)
self.assertNotIn("authorization", self._last_request().headers) self.assertNotIn("authorization", self._last_request().headers)
self.assertEqual(response, self.TEST_DATA) self.assertEqual(response, self.test_data)
@httpretty.activate @httpretty.activate
def test_post_without_oauth_raises_exception(self): def test_post_without_oauth(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST) """Check that the post method fails without OAuth parameters"""
self.client = openphoto.OpenPhoto(host=self.test_host)
self._register_uri(httpretty.POST) self._register_uri(httpretty.POST)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_get_without_response_processing(self): def test_get_without_response_processing(self):
"""Check that the get method works with response processing disabled"""
self._register_uri(httpretty.GET) self._register_uri(httpretty.GET)
response = self.client.get(self.TEST_ENDPOINT, process_response=False) response = self.client.get(self.test_endpoint, process_response=False)
self.assertEqual(response, json.dumps(self.TEST_DATA)) self.assertEqual(response, json.dumps(self.test_data))
@httpretty.activate @httpretty.activate
def test_post_without_response_processing(self): def test_post_without_response_processing(self):
"""Check that the post method works with response processing disabled"""
self._register_uri(httpretty.POST) self._register_uri(httpretty.POST)
response = self.client.post(self.TEST_ENDPOINT, process_response=False) response = self.client.post(self.test_endpoint, process_response=False)
self.assertEqual(response, json.dumps(self.TEST_DATA)) self.assertEqual(response, json.dumps(self.test_data))
@httpretty.activate @httpretty.activate
def test_get_parameter_processing(self): def test_get_parameter_processing(self):
"""Check that the parameter processing function is working"""
self._register_uri(httpretty.GET) self._register_uri(httpretty.GET)
photo = openphoto.objects.Photo(None, {"id": "photo_id"}) photo = openphoto.objects.Photo(None, {"id": "photo_id"})
album = openphoto.objects.Album(None, {"id": "album_id"}) album = openphoto.objects.Album(None, {"id": "album_id"})
tag = openphoto.objects.Tag(None, {"id": "tag_id"}) tag = openphoto.objects.Tag(None, {"id": "tag_id"})
self.client.get(self.TEST_ENDPOINT, self.client.get(self.test_endpoint,
photo=photo, album=album, tag=tag, photo=photo, album=album, tag=tag,
list_=[photo, album, tag], list_=[photo, album, tag],
boolean=True, boolean=True,
@ -114,28 +127,31 @@ class TestHttp(unittest.TestCase):
@httpretty.activate @httpretty.activate
def test_get_with_api_version(self): def test_get_with_api_version(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST, api_version=1) """Check that an API version can be specified for the get method"""
self.client = openphoto.OpenPhoto(host=self.test_host, api_version=1)
self._register_uri(httpretty.GET, self._register_uri(httpretty.GET,
uri="http://%s/v1/%s" % (self.TEST_HOST, uri="http://%s/v1/%s" % (self.test_host,
self.TEST_ENDPOINT)) self.test_endpoint))
self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_post_with_api_version(self): def test_post_with_api_version(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST, api_version=1, """Check that an API version can be specified for the post method"""
**self.TEST_OAUTH) self.client = openphoto.OpenPhoto(host=self.test_host, api_version=1,
**self.test_oauth)
self._register_uri(httpretty.POST, self._register_uri(httpretty.POST,
uri="http://%s/v1/%s" % (self.TEST_HOST, uri="http://%s/v1/%s" % (self.test_host,
self.TEST_ENDPOINT)) self.test_endpoint))
self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_post_file(self): def test_post_file(self):
"""Check that a file can be posted"""
self._register_uri(httpretty.POST) self._register_uri(httpretty.POST)
with open(self.TEST_FILE, 'rb') as in_file: with open(self.test_file, 'rb') as in_file:
response = self.client.post(self.TEST_ENDPOINT, response = self.client.post(self.test_endpoint,
files={"file": in_file}) files={"file": in_file})
self.assertEqual(response, self.TEST_DATA) self.assertEqual(response, self.test_data)
body = self._last_request().body body = self._last_request().body
self.assertIn("Content-Disposition: form-data; "+ self.assertIn("Content-Disposition: form-data; "+
"name=\"file\"; filename=\"test_file.txt\"", body) "name=\"file\"; filename=\"test_file.txt\"", body)
@ -144,9 +160,13 @@ class TestHttp(unittest.TestCase):
@httpretty.activate @httpretty.activate
def test_post_file_parameters_are_sent_as_querystring(self): def test_post_file_parameters_are_sent_as_querystring(self):
"""
Check that parameters are send as a query string
when a file is posted
"""
self._register_uri(httpretty.POST) self._register_uri(httpretty.POST)
with open(self.TEST_FILE, 'rb') as in_file: with open(self.test_file, 'rb') as in_file:
response = self.client.post(self.TEST_ENDPOINT, foo="bar", response = self.client.post(self.test_endpoint, foo="bar",
files={"file": in_file}) files={"file": in_file})
self.assertEqual(response, self.TEST_DATA) self.assertEqual(response, self.test_data)
self.assertEqual(self._last_request().querystring["foo"], ["bar"]) self.assertEqual(self._last_request().querystring["foo"], ["bar"])

View file

@ -9,25 +9,26 @@ except ImportError:
import openphoto import openphoto
class TestHttpErrors(unittest.TestCase): class TestHttpErrors(unittest.TestCase):
TEST_HOST = "test.example.com" test_host = "test.example.com"
TEST_ENDPOINT = "test.json" test_endpoint = "test.json"
TEST_URI = "http://%s/%s" % (TEST_HOST, TEST_ENDPOINT) test_uri = "http://%s/%s" % (test_host, test_endpoint)
TEST_DATA = {"message": "Test Message", test_data = {"message": "Test Message",
"code": 200, "code": 200,
"result": "Test Result"} "result": "Test Result"}
TEST_OAUTH = {"consumer_key": "dummy", test_oauth = {"consumer_key": "dummy",
"consumer_secret": "dummy", "consumer_secret": "dummy",
"token": "dummy", "token": "dummy",
"token_secret": "dummy"} "token_secret": "dummy"}
def setUp(self): def setUp(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST, **self.TEST_OAUTH) self.client = openphoto.OpenPhoto(host=self.test_host,
**self.test_oauth)
def _register_uri(self, method, uri=TEST_URI, def _register_uri(self, method, uri=test_uri,
data=None, body=None, status=200, **kwds): data=None, body=None, status=200, **kwds):
"""Convenience wrapper around httpretty.register_uri""" """Convenience wrapper around httpretty.register_uri"""
if data is None: if data is None:
data = self.TEST_DATA data = self.test_data
# Set the JSON return code to match the HTTP status # Set the JSON return code to match the HTTP status
data["code"] = status data["code"] = status
if body is None: if body is None:
@ -36,98 +37,154 @@ class TestHttpErrors(unittest.TestCase):
**kwds) **kwds)
@httpretty.activate @httpretty.activate
def test_get_with_error_status_raises_openphoto_exception(self): def test_get_with_error_status(self):
"""
Check that an error status causes the get method
to raise an exception
"""
self._register_uri(httpretty.GET, status=500) self._register_uri(httpretty.GET, status=500)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_post_with_error_status_raises_openphoto_exception(self): def test_post_with_error_status(self):
"""
Check that an error status causes the post method
to raise an exception
"""
self._register_uri(httpretty.POST, status=500) self._register_uri(httpretty.POST, status=500)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
# TODO: 404 status should raise 404 error, even if JSON is valid # TODO: 404 status should raise 404 error, even if JSON is valid
@unittest.expectedFailure @unittest.expectedFailure
@httpretty.activate @httpretty.activate
def test_get_with_404_status_raises_404_exception(self): def test_get_with_404_status(self):
"""
Check that a 404 status causes the get method
to raise a 404 exception
"""
self._register_uri(httpretty.GET, status=404) self._register_uri(httpretty.GET, status=404)
with self.assertRaises(openphoto.OpenPhoto404Error): with self.assertRaises(openphoto.OpenPhoto404Error):
response = self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
# TODO: 404 status should raise 404 error, even if JSON is valid # TODO: 404 status should raise 404 error, even if JSON is valid
@unittest.expectedFailure @unittest.expectedFailure
@httpretty.activate @httpretty.activate
def test_post_with_404_status_raises_404_exception(self): def test_post_with_404_status(self):
"""
Check that a 404 status causes the post method
to raise a 404 exception
"""
self._register_uri(httpretty.POST, status=404) self._register_uri(httpretty.POST, status=404)
with self.assertRaises(openphoto.OpenPhoto404Error): with self.assertRaises(openphoto.OpenPhoto404Error):
response = self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_get_with_invalid_json_raises_exception(self): def test_get_with_invalid_json(self):
"""
Check that invalid JSON causes the get method to
raise an exception
"""
self._register_uri(httpretty.GET, body="Invalid JSON") self._register_uri(httpretty.GET, body="Invalid JSON")
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_post_with_invalid_json_raises_exception(self): def test_post_with_invalid_json(self):
"""
Check that invalid JSON causes the post method to
raise an exception
"""
self._register_uri(httpretty.POST, body="Invalid JSON") self._register_uri(httpretty.POST, body="Invalid JSON")
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_get_with_error_status_and_invalid_json_raises_openphoto_exception(self): def test_get_with_error_status_and_invalid_json(self):
"""
Check that invalid JSON causes the get method to raise an exception,
even with an error status is returned
"""
self._register_uri(httpretty.GET, body="Invalid JSON", status=500) self._register_uri(httpretty.GET, body="Invalid JSON", status=500)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
response = self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_post_with_error_status_and_invalid_json_raises_openphoto_exception(self): def test_post_with_error_status_and_invalid_json(self):
"""
Check that invalid JSON causes the post method to raise an exception,
even with an error status is returned
"""
self._register_uri(httpretty.POST, body="Invalid JSON", status=500) self._register_uri(httpretty.POST, body="Invalid JSON", status=500)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
response = self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_get_with_404_status_and_invalid_json_raises_404_exception(self): def test_get_with_404_status_and_invalid_json(self):
"""
Check that invalid JSON causes the get method to raise an exception,
even with a 404 status is returned
"""
self._register_uri(httpretty.GET, body="Invalid JSON", status=404) self._register_uri(httpretty.GET, body="Invalid JSON", status=404)
with self.assertRaises(openphoto.OpenPhoto404Error): with self.assertRaises(openphoto.OpenPhoto404Error):
response = self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_post_with_404_status_and_invalid_json_raises_404_exception(self): def test_post_with_404_status_and_invalid_json(self):
"""
Check that invalid JSON causes the post method to raise an exception,
even with a 404 status is returned
"""
self._register_uri(httpretty.POST, body="Invalid JSON", status=404) self._register_uri(httpretty.POST, body="Invalid JSON", status=404)
with self.assertRaises(openphoto.OpenPhoto404Error): with self.assertRaises(openphoto.OpenPhoto404Error):
response = self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_get_with_duplicate_status_raises_duplicate_exception(self): def test_get_with_duplicate_status(self):
"""
Check that a get with a duplicate status
raises a duplicate exception
"""
data = {"message": "This photo already exists", "code": 409} data = {"message": "This photo already exists", "code": 409}
self._register_uri(httpretty.GET, data=data, status=409) self._register_uri(httpretty.GET, data=data, status=409)
with self.assertRaises(openphoto.OpenPhotoDuplicateError): with self.assertRaises(openphoto.OpenPhotoDuplicateError):
response = self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
@httpretty.activate @httpretty.activate
def test_post_with_duplicate_status_raises_duplicate_exception(self): def test_post_with_duplicate_status(self):
"""
Check that a post with a duplicate status
raises a duplicate exception
"""
data = {"message": "This photo already exists", "code": 409} data = {"message": "This photo already exists", "code": 409}
self._register_uri(httpretty.POST, data=data, status=409) self._register_uri(httpretty.POST, data=data, status=409)
with self.assertRaises(openphoto.OpenPhotoDuplicateError): with self.assertRaises(openphoto.OpenPhotoDuplicateError):
response = self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)
# TODO: Status code mismatch should raise an exception # TODO: Status code mismatch should raise an exception
@unittest.expectedFailure @unittest.expectedFailure
@httpretty.activate @httpretty.activate
def test_get_with_status_code_mismatch_raises_openphoto_exception(self): def test_get_with_status_code_mismatch(self):
"""
Check that an exception is raised if a get returns a
status code that doesn't match the JSON code
"""
data = {"message": "Test Message", "code": 200} data = {"message": "Test Message", "code": 200}
self._register_uri(httpretty.GET, data=data, status=202) self._register_uri(httpretty.GET, data=data, status=202)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
response = self.client.get(self.TEST_ENDPOINT) self.client.get(self.test_endpoint)
# TODO: Status code mismatch should raise an exception # TODO: Status code mismatch should raise an exception
@unittest.expectedFailure @unittest.expectedFailure
@httpretty.activate @httpretty.activate
def test_post_with_status_code_mismatch_raises_openphoto_exception(self): def test_post_with_status_code_mismatch(self):
"""
Check that an exception is raised if a post returns a
status code that doesn't match the JSON code
"""
data = {"message": "Test Message", "code": 200} data = {"message": "Test Message", "code": 200}
self._register_uri(httpretty.POST, data=data, status=202) self._register_uri(httpretty.POST, data=data, status=202)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
response = self.client.post(self.TEST_ENDPOINT) self.client.post(self.test_endpoint)

View file

@ -10,16 +10,16 @@ except ImportError:
import openphoto import openphoto
class TestPhotos(unittest.TestCase): class TestPhotos(unittest.TestCase):
TEST_HOST = "test.example.com" test_host = "test.example.com"
TEST_FILE = os.path.join("tests", "unit", "data", "test_file.txt") test_file = os.path.join("tests", "unit", "data", "test_file.txt")
TEST_PHOTOS_DICT = [{"id": "1a", "tags": ["tag1", "tag2"], test_photos_dict = [{"id": "1a", "tags": ["tag1", "tag2"],
"totalPages": 1, "totalRows": 2}, "totalPages": 1, "totalRows": 2},
{"id": "2b", "tags": ["tag3", "tag4"], {"id": "2b", "tags": ["tag3", "tag4"],
"totalPages": 1, "totalRows": 2}] "totalPages": 1, "totalRows": 2}]
def setUp(self): def setUp(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST) self.client = openphoto.OpenPhoto(host=self.test_host)
self.TEST_PHOTOS = [openphoto.objects.Photo(self.client, photo) self.test_photos = [openphoto.objects.Photo(self.client, photo)
for photo in self.TEST_PHOTOS_DICT] for photo in self.test_photos_dict]
@staticmethod @staticmethod
def _return_value(result, message="", code=200): def _return_value(result, message="", code=200):
@ -27,11 +27,12 @@ class TestPhotos(unittest.TestCase):
class TestPhotosList(TestPhotos): class TestPhotosList(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photos_list(self, mock): def test_photos_list(self, mock_get):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT) """Check that the photo list is returned correctly"""
mock_get.return_value = self._return_value(self.test_photos_dict)
result = self.client.photos.list() result = self.client.photos.list()
mock.assert_called_with("/photos/list.json") mock_get.assert_called_with("/photos/list.json")
self.assertEqual(len(result), 2) self.assertEqual(len(result), 2)
self.assertEqual(result[0].id, "1a") self.assertEqual(result[0].id, "1a")
self.assertEqual(result[0].tags, ["tag1", "tag2"]) self.assertEqual(result[0].tags, ["tag1", "tag2"])
@ -42,80 +43,99 @@ class TestPhotosUpdate(TestPhotos):
# TODO: photos.update should accept a list of Photo objects # TODO: photos.update should accept a list of Photo objects
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photos_update(self, mock): def test_photos_update(self, mock_post):
mock.return_value = self._return_value(True) """Check that multiple photos can be updated"""
result = self.client.photos.update(self.TEST_PHOTOS, title="Test") mock_post.return_value = self._return_value(True)
mock.assert_called_with("/photos/update.json", result = self.client.photos.update(self.test_photos, title="Test")
mock_post.assert_called_with("/photos/update.json",
ids=["1a", "2b"], title="Test") ids=["1a", "2b"], title="Test")
self.assertEqual(result, True) self.assertEqual(result, True)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photos_update_ids(self, mock): def test_photos_update_ids(self, mock_post):
mock.return_value = self._return_value(True) """Check that multiple photos can be updated using their IDs"""
mock_post.return_value = self._return_value(True)
result = self.client.photos.update(["1a", "2b"], title="Test") result = self.client.photos.update(["1a", "2b"], title="Test")
mock.assert_called_with("/photos/update.json", mock_post.assert_called_with("/photos/update.json",
ids=["1a", "2b"], title="Test") ids=["1a", "2b"], title="Test")
self.assertEqual(result, True) self.assertEqual(result, True)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photos_update_failure_raises_exception(self, mock): def test_photos_update_failure(self, mock_post):
mock.return_value = self._return_value(False) """
Check that an exception is raised if multiple photos
cannot be updated
"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.photos.update(self.TEST_PHOTOS, title="Test") self.client.photos.update(self.test_photos, title="Test")
class TestPhotosDelete(TestPhotos): class TestPhotosDelete(TestPhotos):
# TODO: photos.delete should accept a list of Photo objects # TODO: photos.delete should accept a list of Photo objects
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photos_delete(self, mock): def test_photos_delete(self, mock_post):
mock.return_value = self._return_value(True) """Check that multiple photos can be deleted"""
result = self.client.photos.delete(self.TEST_PHOTOS) mock_post.return_value = self._return_value(True)
mock.assert_called_with("/photos/delete.json", ids=["1a", "2b"]) result = self.client.photos.delete(self.test_photos)
mock_post.assert_called_with("/photos/delete.json", ids=["1a", "2b"])
self.assertEqual(result, True) self.assertEqual(result, True)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photos_delete_ids(self, mock): def test_photos_delete_ids(self, mock_post):
mock.return_value = self._return_value(True) """Check that multiple photos can be deleted using their IDs"""
mock_post.return_value = self._return_value(True)
result = self.client.photos.delete(["1a", "2b"]) result = self.client.photos.delete(["1a", "2b"])
mock.assert_called_with("/photos/delete.json", ids=["1a", "2b"]) mock_post.assert_called_with("/photos/delete.json", ids=["1a", "2b"])
self.assertEqual(result, True) self.assertEqual(result, True)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photos_delete_failure_raises_exception(self, mock): def test_photos_delete_failure(self, mock_post):
mock.return_value = self._return_value(False) """
Check that an exception is raised if multiple photos
cannot be deleted
"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.photos.delete(self.TEST_PHOTOS) self.client.photos.delete(self.test_photos)
class TestPhotoDelete(TestPhotos): class TestPhotoDelete(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_delete(self, mock): def test_photo_delete(self, mock_post):
mock.return_value = self._return_value(True) """Check that a photo can be deleted"""
result = self.client.photo.delete(self.TEST_PHOTOS[0]) mock_post.return_value = self._return_value(True)
mock.assert_called_with("/photo/1a/delete.json") result = self.client.photo.delete(self.test_photos[0])
mock_post.assert_called_with("/photo/1a/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_delete_id(self, mock): def test_photo_delete_id(self, mock_post):
mock.return_value = self._return_value(True) """Check that a photo can be deleted using its ID"""
mock_post.return_value = self._return_value(True)
result = self.client.photo.delete("1a") result = self.client.photo.delete("1a")
mock.assert_called_with("/photo/1a/delete.json") mock_post.assert_called_with("/photo/1a/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
# TODO: photo.delete should raise exception on failure # TODO: photo.delete should raise exception on failure
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_delete_failure_raises_exception(self, mock): def test_photo_delete_failure(self, mock_post):
mock.return_value = self._return_value(False) """Check that an exception is raised if a photo cannot be deleted"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.photo.delete(self.TEST_PHOTOS[0]) self.client.photo.delete(self.test_photos[0])
# TODO: after deleting object fields, name and id should be set to None # TODO: after deleting object fields, name and id should be set to None
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_object_delete(self, mock): def test_photo_object_delete(self, mock_post):
mock.return_value = self._return_value(True) """
photo = self.TEST_PHOTOS[0] Check that a photo can be deleted when using
the photo object directly
"""
mock_post.return_value = self._return_value(True)
photo = self.test_photos[0]
result = photo.delete() result = photo.delete()
mock.assert_called_with("/photo/1a/delete.json") mock_post.assert_called_with("/photo/1a/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
self.assertEqual(photo.get_fields(), {}) self.assertEqual(photo.get_fields(), {})
# self.assertEqual(photo.id, None) # self.assertEqual(photo.id, None)
@ -123,245 +143,298 @@ class TestPhotoDelete(TestPhotos):
# TODO: photo.delete should raise exception on failure # TODO: photo.delete should raise exception on failure
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_object_delete_failure_raises_exception(self, mock): def test_photo_object_delete_failure(self, mock_post):
mock.return_value = self._return_value(False) """
Check that an exception is raised if a photo cannot be deleted
when using the photo object directly
"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.TEST_PHOTOS[0].delete() self.test_photos[0].delete()
class TestPhotoEdit(TestPhotos): class TestPhotoEdit(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_edit(self, mock): def test_photo_edit(self, mock_get):
mock.return_value = self._return_value({"markup": "<form/>"}) """Check that a the photo edit endpoint is working"""
result = self.client.photo.edit(self.TEST_PHOTOS[0]) mock_get.return_value = self._return_value({"markup": "<form/>"})
mock.assert_called_with("/photo/1a/edit.json") result = self.client.photo.edit(self.test_photos[0])
mock_get.assert_called_with("/photo/1a/edit.json")
self.assertEqual(result, "<form/>") self.assertEqual(result, "<form/>")
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_edit_id(self, mock): def test_photo_edit_id(self, mock_get):
mock.return_value = self._return_value({"markup": "<form/>"}) """Check that a the photo edit endpoint is working when using an ID"""
mock_get.return_value = self._return_value({"markup": "<form/>"})
result = self.client.photo.edit("1a") result = self.client.photo.edit("1a")
mock.assert_called_with("/photo/1a/edit.json") mock_get.assert_called_with("/photo/1a/edit.json")
self.assertEqual(result, "<form/>") self.assertEqual(result, "<form/>")
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_object_edit(self, mock): def test_photo_object_edit(self, mock_get):
mock.return_value = self._return_value({"markup": "<form/>"}) """
result = self.TEST_PHOTOS[0].edit() Check that a the photo edit endpoint is working
mock.assert_called_with("/photo/1a/edit.json") when using the photo object directly
"""
mock_get.return_value = self._return_value({"markup": "<form/>"})
result = self.test_photos[0].edit()
mock_get.assert_called_with("/photo/1a/edit.json")
self.assertEqual(result, "<form/>") self.assertEqual(result, "<form/>")
class TestPhotoReplace(TestPhotos): class TestPhotoReplace(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_replace(self, mock): def test_photo_replace(self, _):
""" If photo.replace gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.photo.replace(self.TEST_PHOTOS[0], self.TEST_FILE) self.client.photo.replace(self.test_photos[0], self.test_file)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_replace_id(self, mock): def test_photo_replace_id(self, _):
""" If photo.replace gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.photo.replace("1a", self.TEST_FILE) self.client.photo.replace("1a", self.test_file)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_object_replace(self, mock): def test_photo_object_replace(self, _):
""" If photo.replace gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.TEST_PHOTOS[0].replace(self.TEST_FILE) self.test_photos[0].replace(self.test_file)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_replace_encoded(self, mock): def test_photo_replace_encoded(self, _):
""" If photo.replace_encoded gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.photo.replace_encoded(self.TEST_PHOTOS[0], self.TEST_FILE) self.client.photo.replace_encoded(self.test_photos[0],
self.test_file)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_replace_encoded_id(self, mock): def test_photo_replace_encoded_id(self, _):
""" If photo.replace_encoded gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.photo.replace_encoded("1a", self.TEST_FILE) self.client.photo.replace_encoded("1a", self.test_file)
# TODO: replace_encoded parameter should be called photo_file, # TODO: replace_encoded parameter should be called photo_file,
# not encoded_photo # not encoded_photo
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_object_replace_encoded(self, mock): def test_photo_object_replace_encoded(self, _):
""" If photo.replace_encoded gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.TEST_PHOTOS[0].replace_encoded(photo_file=self.TEST_FILE) self.test_photos[0].replace_encoded(photo_file=self.test_file)
class TestPhotoUpdate(TestPhotos): class TestPhotoUpdate(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_update(self, mock): def test_photo_update(self, mock_post):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """Check that a photo can be updated"""
result = self.client.photo.update(self.TEST_PHOTOS[0], title="Test") mock_post.return_value = self._return_value(self.test_photos_dict[1])
mock.assert_called_with("/photo/1a/update.json", title="Test") result = self.client.photo.update(self.test_photos[0], title="Test")
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[1]) mock_post.assert_called_with("/photo/1a/update.json", title="Test")
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_update_id(self, mock): def test_photo_update_id(self, mock_post):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """Check that a photo can be updated using its ID"""
mock_post.return_value = self._return_value(self.test_photos_dict[1])
result = self.client.photo.update("1a", title="Test") result = self.client.photo.update("1a", title="Test")
mock.assert_called_with("/photo/1a/update.json", title="Test") mock_post.assert_called_with("/photo/1a/update.json", title="Test")
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[1]) self.assertEqual(result.get_fields(), self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_object_update(self, mock): def test_photo_object_update(self, mock_post):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """
photo = self.TEST_PHOTOS[0] Check that a photo can be updated
when using the photo object directly
"""
mock_post.return_value = self._return_value(self.test_photos_dict[1])
photo = self.test_photos[0]
photo.update(title="Test") photo.update(title="Test")
mock.assert_called_with("/photo/1a/update.json", title="Test") mock_post.assert_called_with("/photo/1a/update.json", title="Test")
self.assertEqual(photo.get_fields(), self.TEST_PHOTOS_DICT[1]) self.assertEqual(photo.get_fields(), self.test_photos_dict[1])
class TestPhotoView(TestPhotos): class TestPhotoView(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_view(self, mock): def test_photo_view(self, mock_get):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """Check that a photo can be viewed"""
result = self.client.photo.view(self.TEST_PHOTOS[0], returnSizes="20x20") mock_get.return_value = self._return_value(self.test_photos_dict[1])
mock.assert_called_with("/photo/1a/view.json", returnSizes="20x20") result = self.client.photo.view(self.test_photos[0],
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[1]) returnSizes="20x20")
mock_get.assert_called_with("/photo/1a/view.json", returnSizes="20x20")
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_view_id(self, mock): def test_photo_view_id(self, mock_get):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """Check that a photo can be viewed using its ID"""
mock_get.return_value = self._return_value(self.test_photos_dict[1])
result = self.client.photo.view("1a", returnSizes="20x20") result = self.client.photo.view("1a", returnSizes="20x20")
mock.assert_called_with("/photo/1a/view.json", returnSizes="20x20") mock_get.assert_called_with("/photo/1a/view.json", returnSizes="20x20")
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[1]) self.assertEqual(result.get_fields(), self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_object_view(self, mock): def test_photo_object_view(self, mock_get):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """
photo = self.TEST_PHOTOS[0] Check that a photo can be viewed
when using the photo object directly
"""
mock_get.return_value = self._return_value(self.test_photos_dict[1])
photo = self.test_photos[0]
photo.view(returnSizes="20x20") photo.view(returnSizes="20x20")
mock.assert_called_with("/photo/1a/view.json", returnSizes="20x20") mock_get.assert_called_with("/photo/1a/view.json", returnSizes="20x20")
self.assertEqual(photo.get_fields(), self.TEST_PHOTOS_DICT[1]) self.assertEqual(photo.get_fields(), self.test_photos_dict[1])
class TestPhotoUpload(TestPhotos): class TestPhotoUpload(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_upload(self, mock): def test_photo_upload(self, mock_post):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[0]) """Check that a photo can be uploaded"""
result = self.client.photo.upload(self.TEST_FILE, title="Test") mock_post.return_value = self._return_value(self.test_photos_dict[0])
result = self.client.photo.upload(self.test_file, title="Test")
# It's not possible to compare the file object, # It's not possible to compare the file object,
# so check each parameter individually # so check each parameter individually
endpoint = mock.call_args[0] endpoint = mock_post.call_args[0]
title = mock.call_args[1]["title"] title = mock_post.call_args[1]["title"]
files = mock.call_args[1]["files"] files = mock_post.call_args[1]["files"]
self.assertEqual(endpoint, ("/photo/upload.json",)) self.assertEqual(endpoint, ("/photo/upload.json",))
self.assertEqual(title, "Test") self.assertEqual(title, "Test")
self.assertIn("photo", files) self.assertIn("photo", files)
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[0]) self.assertEqual(result.get_fields(), self.test_photos_dict[0])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_upload_encoded(self, mock): def test_photo_upload_encoded(self, mock_post):
encoded_file = base64.b64encode(open(self.TEST_FILE, "rb").read()) """Check that a photo can be uploaded using Base64 encoding"""
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[0]) encoded_file = base64.b64encode(open(self.test_file, "rb").read())
result = self.client.photo.upload_encoded(self.TEST_FILE, title="Test") mock_post.return_value = self._return_value(self.test_photos_dict[0])
mock.assert_called_with("/photo/upload.json", result = self.client.photo.upload_encoded(self.test_file, title="Test")
mock_post.assert_called_with("/photo/upload.json",
photo=encoded_file, title="Test") photo=encoded_file, title="Test")
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[0]) self.assertEqual(result.get_fields(), self.test_photos_dict[0])
class TestPhotoDynamicUrl(TestPhotos): class TestPhotoDynamicUrl(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_dynamic_url(self, mock): def test_photo_dynamic_url(self, _):
""" If photo.dynamic_url gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.photo.dynamic_url(self.TEST_PHOTOS[0]) self.client.photo.dynamic_url(self.test_photos[0])
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_dynamic_url_id(self, mock): def test_photo_dynamic_url_id(self, _):
""" If photo.dynamic_url gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.client.photo.dynamic_url("1a") self.client.photo.dynamic_url("1a")
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_object_dynamic_url(self, mock): def test_photo_object_dynamic_url(self, _):
""" If photo.dynamic_url gets implemented, write a test! """
with self.assertRaises(NotImplementedError): with self.assertRaises(NotImplementedError):
self.TEST_PHOTOS[0].dynamic_url() self.test_photos[0].dynamic_url()
class TestPhotoNextPrevious(TestPhotos): class TestPhotoNextPrevious(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_next_previous(self, mock): def test_photo_next_previous(self, mock_get):
mock.return_value = self._return_value( """Check that the next/previous photos are returned"""
{"next": [self.TEST_PHOTOS_DICT[0]], mock_get.return_value = self._return_value(
"previous": [self.TEST_PHOTOS_DICT[1]]}) {"next": [self.test_photos_dict[0]],
result = self.client.photo.next_previous(self.TEST_PHOTOS[0]) "previous": [self.test_photos_dict[1]]})
mock.assert_called_with("/photo/1a/nextprevious.json") result = self.client.photo.next_previous(self.test_photos[0])
mock_get.assert_called_with("/photo/1a/nextprevious.json")
self.assertEqual(result["next"][0].get_fields(), self.assertEqual(result["next"][0].get_fields(),
self.TEST_PHOTOS_DICT[0]) self.test_photos_dict[0])
self.assertEqual(result["previous"][0].get_fields(), self.assertEqual(result["previous"][0].get_fields(),
self.TEST_PHOTOS_DICT[1]) self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_next_previous_id(self, mock): def test_photo_next_previous_id(self, mock_get):
mock.return_value = self._return_value( """
{"next": [self.TEST_PHOTOS_DICT[0]], Check that the next/previous photos are returned
"previous": [self.TEST_PHOTOS_DICT[1]]}) when using the photo ID
"""
mock_get.return_value = self._return_value(
{"next": [self.test_photos_dict[0]],
"previous": [self.test_photos_dict[1]]})
result = self.client.photo.next_previous("1a") result = self.client.photo.next_previous("1a")
mock.assert_called_with("/photo/1a/nextprevious.json") mock_get.assert_called_with("/photo/1a/nextprevious.json")
self.assertEqual(result["next"][0].get_fields(), self.assertEqual(result["next"][0].get_fields(),
self.TEST_PHOTOS_DICT[0]) self.test_photos_dict[0])
self.assertEqual(result["previous"][0].get_fields(), self.assertEqual(result["previous"][0].get_fields(),
self.TEST_PHOTOS_DICT[1]) self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_object_next_previous(self, mock): def test_photo_object_next_previous(self, mock_get):
mock.return_value = self._return_value( """
{"next": [self.TEST_PHOTOS_DICT[0]], Check that the next/previous photos are returned
"previous": [self.TEST_PHOTOS_DICT[1]]}) when using the photo object directly
result = self.TEST_PHOTOS[0].next_previous() """
mock.assert_called_with("/photo/1a/nextprevious.json") mock_get.return_value = self._return_value(
{"next": [self.test_photos_dict[0]],
"previous": [self.test_photos_dict[1]]})
result = self.test_photos[0].next_previous()
mock_get.assert_called_with("/photo/1a/nextprevious.json")
self.assertEqual(result["next"][0].get_fields(), self.assertEqual(result["next"][0].get_fields(),
self.TEST_PHOTOS_DICT[0]) self.test_photos_dict[0])
self.assertEqual(result["previous"][0].get_fields(), self.assertEqual(result["previous"][0].get_fields(),
self.TEST_PHOTOS_DICT[1]) self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_next(self, mock): def test_photo_next(self, mock_get):
mock.return_value = self._return_value( """Check that the next photos are returned"""
{"next": [self.TEST_PHOTOS_DICT[0]]}) mock_get.return_value = self._return_value(
result = self.client.photo.next_previous(self.TEST_PHOTOS[0]) {"next": [self.test_photos_dict[0]]})
mock.assert_called_with("/photo/1a/nextprevious.json") result = self.client.photo.next_previous(self.test_photos[0])
mock_get.assert_called_with("/photo/1a/nextprevious.json")
self.assertEqual(result["next"][0].get_fields(), self.assertEqual(result["next"][0].get_fields(),
self.TEST_PHOTOS_DICT[0]) self.test_photos_dict[0])
self.assertNotIn("previous", result) self.assertNotIn("previous", result)
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_previous(self, mock): def test_photo_previous(self, mock_get):
mock.return_value = self._return_value( """Check that the previous photos are returned"""
{"previous": [self.TEST_PHOTOS_DICT[1]]}) mock_get.return_value = self._return_value(
result = self.client.photo.next_previous(self.TEST_PHOTOS[0]) {"previous": [self.test_photos_dict[1]]})
mock.assert_called_with("/photo/1a/nextprevious.json") result = self.client.photo.next_previous(self.test_photos[0])
mock_get.assert_called_with("/photo/1a/nextprevious.json")
self.assertEqual(result["previous"][0].get_fields(), self.assertEqual(result["previous"][0].get_fields(),
self.TEST_PHOTOS_DICT[1]) self.test_photos_dict[1])
self.assertNotIn("next", result) self.assertNotIn("next", result)
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_photo_multiple_next_previous(self, mock): def test_photo_multiple_next_previous(self, mock_get):
mock.return_value = self._return_value( """Check that multiple next/previous photos are returned"""
{"next": [self.TEST_PHOTOS_DICT[0], self.TEST_PHOTOS_DICT[0]], mock_get.return_value = self._return_value(
"previous": [self.TEST_PHOTOS_DICT[1], self.TEST_PHOTOS_DICT[1]]}) {"next": [self.test_photos_dict[0], self.test_photos_dict[0]],
result = self.client.photo.next_previous(self.TEST_PHOTOS[0]) "previous": [self.test_photos_dict[1], self.test_photos_dict[1]]})
mock.assert_called_with("/photo/1a/nextprevious.json") result = self.client.photo.next_previous(self.test_photos[0])
mock_get.assert_called_with("/photo/1a/nextprevious.json")
self.assertEqual(result["next"][0].get_fields(), self.assertEqual(result["next"][0].get_fields(),
self.TEST_PHOTOS_DICT[0]) self.test_photos_dict[0])
self.assertEqual(result["next"][1].get_fields(), self.assertEqual(result["next"][1].get_fields(),
self.TEST_PHOTOS_DICT[0]) self.test_photos_dict[0])
self.assertEqual(result["previous"][0].get_fields(), self.assertEqual(result["previous"][0].get_fields(),
self.TEST_PHOTOS_DICT[1]) self.test_photos_dict[1])
self.assertEqual(result["previous"][1].get_fields(), self.assertEqual(result["previous"][1].get_fields(),
self.TEST_PHOTOS_DICT[1]) self.test_photos_dict[1])
class TestPhotoTransform(TestPhotos): class TestPhotoTransform(TestPhotos):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_transform(self, mock): def test_photo_transform(self, mock_post):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """Check that a photo can be transformed"""
result = self.client.photo.transform(self.TEST_PHOTOS[0], rotate="90") mock_post.return_value = self._return_value(self.test_photos_dict[1])
mock.assert_called_with("/photo/1a/transform.json", rotate="90") result = self.client.photo.transform(self.test_photos[0], rotate="90")
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[1]) mock_post.assert_called_with("/photo/1a/transform.json", rotate="90")
self.assertEqual(result.get_fields(), self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_transform_id(self, mock): def test_photo_transform_id(self, mock_post):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """Check that a photo can be transformed using its ID"""
mock_post.return_value = self._return_value(self.test_photos_dict[1])
result = self.client.photo.transform("1a", rotate="90") result = self.client.photo.transform("1a", rotate="90")
mock.assert_called_with("/photo/1a/transform.json", rotate="90") mock_post.assert_called_with("/photo/1a/transform.json", rotate="90")
self.assertEqual(result.get_fields(), self.TEST_PHOTOS_DICT[1]) self.assertEqual(result.get_fields(), self.test_photos_dict[1])
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_photo_object_transform(self, mock): def test_photo_object_transform(self, mock_post):
mock.return_value = self._return_value(self.TEST_PHOTOS_DICT[1]) """
photo = self.TEST_PHOTOS[0] Check that a photo can be transformed
when using the photo object directly
"""
mock_post.return_value = self._return_value(self.test_photos_dict[1])
photo = self.test_photos[0]
photo.transform(rotate="90") photo.transform(rotate="90")
mock.assert_called_with("/photo/1a/transform.json", rotate="90") mock_post.assert_called_with("/photo/1a/transform.json", rotate="90")
self.assertEqual(photo.get_fields(), self.TEST_PHOTOS_DICT[1]) self.assertEqual(photo.get_fields(), self.test_photos_dict[1])

View file

@ -8,14 +8,15 @@ except ImportError:
import openphoto import openphoto
class TestTags(unittest.TestCase): class TestTags(unittest.TestCase):
TEST_HOST = "test.example.com" test_host = "test.example.com"
TEST_TAGS_DICT = [{"count": 11, "id":"tag1"}, test_tags = None
test_tags_dict = [{"count": 11, "id":"tag1"},
{"count": 5, "id":"tag2"}] {"count": 5, "id":"tag2"}]
def setUp(self): def setUp(self):
self.client = openphoto.OpenPhoto(host=self.TEST_HOST) self.client = openphoto.OpenPhoto(host=self.test_host)
self.TEST_TAGS = [openphoto.objects.Tag(self.client, tag) self.test_tags = [openphoto.objects.Tag(self.client, tag)
for tag in self.TEST_TAGS_DICT] for tag in self.test_tags_dict]
@staticmethod @staticmethod
def _return_value(result, message="", code=200): def _return_value(result, message="", code=200):
@ -23,10 +24,11 @@ class TestTags(unittest.TestCase):
class TestTagsList(TestTags): class TestTagsList(TestTags):
@mock.patch.object(openphoto.OpenPhoto, 'get') @mock.patch.object(openphoto.OpenPhoto, 'get')
def test_tags_list(self, mock): def test_tags_list(self, mock_get):
mock.return_value = self._return_value(self.TEST_TAGS_DICT) """Check that the the tag list is returned correctly"""
mock_get.return_value = self._return_value(self.test_tags_dict)
result = self.client.tags.list() result = self.client.tags.list()
mock.assert_called_with("/tags/list.json") mock_get.assert_called_with("/tags/list.json")
self.assertEqual(len(result), 2) self.assertEqual(len(result), 2)
self.assertEqual(result[0].id, "tag1") self.assertEqual(result[0].id, "tag1")
self.assertEqual(result[0].count, 11) self.assertEqual(result[0].count, 11)
@ -37,43 +39,48 @@ class TestTagCreate(TestTags):
# TODO: should return a tag object, not a result dict # TODO: should return a tag object, not a result dict
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_create(self, mock): def test_tag_create(self, mock_post):
mock.return_value = self._return_value(self.TEST_TAGS_DICT[0]) """Check that a tag can be created"""
mock_post.return_value = self._return_value(self.test_tags_dict[0])
result = self.client.tag.create(tag="Test", foo="bar") result = self.client.tag.create(tag="Test", foo="bar")
mock.assert_called_with("/tag/create.json", tag="Test", foo="bar") mock_post.assert_called_with("/tag/create.json", tag="Test", foo="bar")
self.assertEqual(result.id, "tag1") self.assertEqual(result.id, "tag1")
self.assertEqual(result.count, 11) self.assertEqual(result.count, 11)
class TestTagDelete(TestTags): class TestTagDelete(TestTags):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_delete(self, mock): def test_tag_delete(self, mock_post):
mock.return_value = self._return_value(True) """Check that a tag can be deleted"""
result = self.client.tag.delete(self.TEST_TAGS[0]) mock_post.return_value = self._return_value(True)
mock.assert_called_with("/tag/tag1/delete.json") result = self.client.tag.delete(self.test_tags[0])
mock_post.assert_called_with("/tag/tag1/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_delete_id(self, mock): def test_tag_delete_id(self, mock_post):
mock.return_value = self._return_value(True) """Check that a tag can be deleted using its ID"""
mock_post.return_value = self._return_value(True)
result = self.client.tag.delete("tag1") result = self.client.tag.delete("tag1")
mock.assert_called_with("/tag/tag1/delete.json") mock_post.assert_called_with("/tag/tag1/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
# TODO: tag.delete should raise exception on failure # TODO: tag.delete should raise exception on failure
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_delete_failure_raises_exception(self, mock): def test_tag_delete_failure(self, mock_post):
mock.return_value = self._return_value(False) """Check that an exception is raised if a tag cannot be deleted"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.client.tag.delete(self.TEST_TAGS[0]) self.client.tag.delete(self.test_tags[0])
# TODO: after deleting object fields, id should be set to None # TODO: after deleting object fields, id should be set to None
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_object_delete(self, mock): def test_tag_object_delete(self, mock_post):
mock.return_value = self._return_value(True) """Check that a tag can be deleted when using the tag object directly"""
tag = self.TEST_TAGS[0] mock_post.return_value = self._return_value(True)
tag = self.test_tags[0]
result = tag.delete() result = tag.delete()
mock.assert_called_with("/tag/tag1/delete.json") mock_post.assert_called_with("/tag/tag1/delete.json")
self.assertEqual(result, True) self.assertEqual(result, True)
self.assertEqual(tag.get_fields(), {}) self.assertEqual(tag.get_fields(), {})
# self.assertEqual(tag.id, None) # self.assertEqual(tag.id, None)
@ -81,34 +88,41 @@ class TestTagDelete(TestTags):
# TODO: tag.delete should raise exception on failure # TODO: tag.delete should raise exception on failure
@unittest.expectedFailure @unittest.expectedFailure
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_object_delete_failure_raises_exception(self, mock): def test_tag_object_delete_failure(self, mock_post):
mock.return_value = self._return_value(False) """
Check that an exception is raised if a tag cannot be deleted
when using the tag object directly
"""
mock_post.return_value = self._return_value(False)
with self.assertRaises(openphoto.OpenPhotoError): with self.assertRaises(openphoto.OpenPhotoError):
self.TEST_TAGS[0].delete() self.test_tags[0].delete()
class TestTagUpdate(TestTags): class TestTagUpdate(TestTags):
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_update(self, mock): def test_tag_update(self, mock_post):
mock.return_value = self._return_value(self.TEST_TAGS_DICT[1]) """Check that a tag can be updated"""
result = self.client.tag.update(self.TEST_TAGS[0], name="Test") mock_post.return_value = self._return_value(self.test_tags_dict[1])
mock.assert_called_with("/tag/tag1/update.json", name="Test") result = self.client.tag.update(self.test_tags[0], name="Test")
mock_post.assert_called_with("/tag/tag1/update.json", name="Test")
self.assertEqual(result.id, "tag2") self.assertEqual(result.id, "tag2")
self.assertEqual(result.count, 5) self.assertEqual(result.count, 5)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_update_id(self, mock): def test_tag_update_id(self, mock_post):
mock.return_value = self._return_value(self.TEST_TAGS_DICT[1]) """Check that a tag can be updated using its ID"""
mock_post.return_value = self._return_value(self.test_tags_dict[1])
result = self.client.tag.update("tag1", name="Test") result = self.client.tag.update("tag1", name="Test")
mock.assert_called_with("/tag/tag1/update.json", name="Test") mock_post.assert_called_with("/tag/tag1/update.json", name="Test")
self.assertEqual(result.id, "tag2") self.assertEqual(result.id, "tag2")
self.assertEqual(result.count, 5) self.assertEqual(result.count, 5)
@mock.patch.object(openphoto.OpenPhoto, 'post') @mock.patch.object(openphoto.OpenPhoto, 'post')
def test_tag_object_update(self, mock): def test_tag_object_update(self, mock_post):
mock.return_value = self._return_value(self.TEST_TAGS_DICT[1]) """Check that a tag can be updated when using the tag object directly"""
tag = self.TEST_TAGS[0] mock_post.return_value = self._return_value(self.test_tags_dict[1])
tag = self.test_tags[0]
tag.update(name="Test") tag.update(name="Test")
mock.assert_called_with("/tag/tag1/update.json", name="Test") mock_post.assert_called_with("/tag/tag1/update.json", name="Test")
self.assertEqual(tag.id, "tag2") self.assertEqual(tag.id, "tag2")
self.assertEqual(tag.count, 5) self.assertEqual(tag.count, 5)