Skip to content

Commit

Permalink
Merge branch 'release-0.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
sneakypete81 committed Nov 23, 2013
2 parents 860845a + 9769fa0 commit f75f250
Show file tree
Hide file tree
Showing 60 changed files with 2,665 additions and 1,163 deletions.
4 changes: 4 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# .coveragerc to control coverage.py
[run]
# Capture branch coverage
branch = True
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ dist
tests/tokens.py
tests.log
.tox
.coverage
htmlcov
14 changes: 11 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
language: python

install:
# Install test dependencies
- pip install tox --use-mirrors
- .travis/install_pylint
- pip install coveralls --use-mirrors

script: tox

after_success:
# Send coverage results to coveralls.io
- coveralls

after_script:
# Install dependencies for Pylint
- pip install requests requests-oauthlib
- pip install pylint-patcher --use-mirrors
- pip install requests --use-mirrors
- pip install requests-oauthlib --use-mirrors

# Run Pylint
# Uses pylint-patcher to allow exceptions to be stored in a patchfile
# (for information only, any errors don't affect the Travis result)
- pylint --use-ignore-patch=y trovebox
- pylint-patcher trovebox
10 changes: 0 additions & 10 deletions .travis/install_pylint

This file was deleted.

6 changes: 6 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
Trovebox Python Library Changelog
=================================

v0.6
======
* Support for many additional API endpoints (#56, #65)
* Code coverage reporting (#57)
* Unit test improvements (#58, #63, #64)

v0.5.1
======
* Use httpretty v0.6.5 for unit tests (#60)
Expand Down
7 changes: 7 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ Trovebox Python Library
:alt: Build Status
:target: https://travis-ci.org/photo/openphoto-python

..
(commented out until master is on coveralls.io)
.. image:: https://coveralls.io/repos/photo/openphoto-python/badge.png?branch=master
:alt: Coverage Status
:target: https://coveralls.io/r/photo/openphoto-python?branch=master
..
.. image:: https://pypip.in/v/trovebox/badge.png
:alt: Python Package Index (PyPI)
:target: https://pypi.python.org/pypi/trovebox
Expand Down
16 changes: 16 additions & 0 deletions pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[MESSAGES CONTROL]
# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
# multiple time. See also the "--disable" option for examples.
#enable=

# Disable the message, report, category or checker with the given id(s). You
# can either give multiple identifiers separated by comma (,) or put this
# option multiple times (only on the command line, not in the configuration
# file where it should appear only once).You can also use "--disable=all" to
# disable everything first and then reenable specific checks. For example, if
# you want to run only the similarities checker, you can use "--disable=all
# --enable=similarities". If you want to run only the classes checker, but have
# no Warning level messages displayed, use"--disable=all --enable=classes
# --disable=W"
disable=locally-disabled
23 changes: 13 additions & 10 deletions run_functional_tests
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,18 @@ tput setaf 3
echo
echo "Testing latest self-hosted site..."
tput sgr0
sleep 1
export TROVEBOX_TEST_CONFIG=test
unset TROVEBOX_TEST_SERVER_API
python -m unittest discover --catch tests/functional

# Test server running APIv1 Trovebox instance
# Install from photo/frontend commit 660b2ab
tput setaf 3
echo
echo "Testing APIv1 self-hosted site..."
tput sgr0
export TROVEBOX_TEST_CONFIG=test-apiv1
export TROVEBOX_TEST_SERVER_API=1
python -m unittest discover --catch tests/functional

# Test server running v3.0.8 Trovebox instance
# Install from photo/frontend commit e9d81de57b
tput setaf 3
echo
echo "Testing v3.0.8 self-hosted site..."
tput sgr0
sleep 1
export TROVEBOX_TEST_CONFIG=test-3.0.8
unset TROVEBOX_TEST_SERVER_API
python -m unittest discover --catch tests/functional
Expand All @@ -38,7 +30,18 @@ tput setaf 3
echo
echo "Testing latest hosted site..."
tput sgr0
sleep 1
export TROVEBOX_TEST_CONFIG=test-hosted
unset TROVEBOX_TEST_SERVER_API
python -m unittest discover --catch tests/functional

# Test account on hosted trovebox.com site over HTTPS
tput setaf 3
echo
echo "Testing latest hosted site over HTTPS..."
tput sgr0
sleep 1
export TROVEBOX_TEST_CONFIG=test-hosted-https
unset TROVEBOX_TEST_SERVER_API
python -m unittest discover --catch tests/functional

3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@
long_description=open("README.rst").read(),
author='Pete Burgers, James Walker',
url='https://github.com/photo/openphoto-python',
packages=['trovebox'],
data_files=['README.rst'],
packages=['trovebox', 'trovebox.objects', 'trovebox.api'],
keywords=['openphoto', 'pyopenphoto', 'openphoto-python',
'trovebox', 'pytrovebox', 'trovebox-python'],
classifiers=['Development Status :: 4 - Beta',
Expand Down
8 changes: 4 additions & 4 deletions tests/functional/README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ all supported API versions.
To use it, you must set up multiple Trovebox instances and create the following
config files containing your credentials:

test : Latest self-hosted site (from photo/frontend master branch)
test-apiv1 : APIv1 self-hosted site (from photo/frontend commit 660b2ab)
test-3.0.8 : v3.0.8 self-hosted site (from photo/frontend commit e9d81de57b)
test-hosted : Credentials for test account on trovebox.com
test : Latest self-hosted site (from photo/frontend master branch)
test-3.0.8 : v3.0.8 self-hosted site (from photo/frontend commit e9d81de57b)
test-hosted : Credentials for test account on http://<xxxx>.trovebox.com
test-hosted-https : Same as test-hosted, but with https://
2 changes: 2 additions & 0 deletions tests/functional/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# __init__.py

2 changes: 2 additions & 0 deletions tests/functional/api_versions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# __init__.py

7 changes: 7 additions & 0 deletions tests/functional/api_versions/test_v1.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
from tests.functional import test_activities, test_actions
from tests.functional import test_albums, test_photos, test_tags

class TestActivitiesV1(test_activities.TestActivities):
api_version = 1

class TestActionsV1(test_actions.TestActions):
api_version = 1

class TestAlbumsV1(test_albums.TestAlbums):
api_version = 1

Expand Down
14 changes: 13 additions & 1 deletion tests/functional/api_versions/test_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,19 @@
import unittest2 as unittest
except ImportError:
import unittest
from tests.functional import test_base, test_albums, test_photos, test_tags

from tests.functional import test_base, test_activities, test_actions
from tests.functional import test_albums, test_photos, test_tags

@unittest.skipIf(test_base.get_test_server_api() < 2,
"Don't test future API versions")
class TestActivitiesV2(test_activities.TestActivities):
api_version = 2

@unittest.skipIf(test_base.get_test_server_api() < 2,
"Don't test future API versions")
class TestActionsV2(test_actions.TestActions):
api_version = 2

@unittest.skipIf(test_base.get_test_server_api() < 2,
"Don't test future API versions")
Expand Down
23 changes: 23 additions & 0 deletions tests/functional/test_actions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
try:
import unittest2 as unittest # Python2.6
except ImportError:
import unittest

import trovebox
from tests.functional import test_base

class TestActions(test_base.TestBase):
testcase_name = "action API"

def test_create_view_delete(self):
""" Create an action on a photo, view it, then delete it """
# Create and check that the action exists
action = self.client.action.create(target=self.photos[0], type="comment", name="test")
action_id = action.id
self.assertEqual(self.client.action.view(action_id).name, "test")

# Delete and check that the action is gone
action.delete()
with self.assertRaises(trovebox.TroveboxError):
self.client.action.view(action_id)

84 changes: 84 additions & 0 deletions tests/functional/test_activities.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
try:
import unittest2 as unittest # Python2.6
except ImportError:
import unittest

from tests.functional import test_base

@unittest.skipIf(test_base.get_test_server_api() == 1,
("Activities never get deleted in v1, which makes "
"these tests too hard to write"))
class TestActivities(test_base.TestBase):
testcase_name = "activity API"

def test_list(self):
"""
Upload three photos, and check that three corresponding activities
are created.
"""
self._delete_all()
self._create_test_photos(tag=False)
photos = self.client.photos.list()

# Check that each activity is for a valid test photo
activities = self.client.activities.list()
self.assertEqual(len(activities), len(photos))
for activity in activities:
self.assertIn(activity.data.id, [photo.id for photo in photos])

# Put the environment back the way we found it
for photo in photos:
photo.update(tags=self.TEST_TAG)

def test_list_option(self):
"""
Check that the activity list options parameter works correctly
"""
self._delete_all()
self._create_test_photos(tag=False)
photos = self.client.photos.list()

# Dummy photo update activity
photos[0].update(tags=photos[0].tags)

# Check that the activities can be filtered
upload_activities = self.client.activities.list(options={"type": "photo-upload"})
update_activities = self.client.activities.list(options={"type": "photo-update"})
self.assertEqual(len(upload_activities), len(photos))
self.assertEqual(len(update_activities), 1)

# Put the environment back the way we found it
for photo in photos:
photo.update(tags=self.TEST_TAG)

# The purge endpoint currently reports a 500: Internal Server Error
# PHP Fatal error:
# Call to undefined method DatabaseMySql::postActivitiesPurge()
# in /var/www/openphoto-master/src/libraries/models/Activity.php
# on line 66
# Tracked in frontend/#1368
@unittest.expectedFailure
def test_purge(self):
""" Test that the purge endpoint deletes all activities """
activities = self.client.activities.list()
self.assertNotEqual(activities, [])
self.client.activities.purge()
activities = self.client.activities.list()
self.assertEqual(activities, [])

def test_view(self):
""" Test that the view endpoint is working correctly """
activity = self.client.activities.list()[0]
fields = activity.get_fields().copy()

# Check that the view method returns the same data as the list
activity.view()
self.assertEqual(fields, activity.get_fields())

# Check using the Trovebox class
activity = self.client.activity.view(activity)
self.assertEqual(fields, activity.get_fields())

# Check passing the activity ID to the Trovebox class
activity = self.client.activity.view(activity.id)
self.assertEqual(fields, activity.get_fields())
57 changes: 43 additions & 14 deletions tests/functional/test_albums.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
try:
import unittest2 as unittest # Python2.6
except ImportError:
import unittest

from tests.functional import test_base
from trovebox.objects.album import Album

class TestAlbums(test_base.TestBase):
testcase_name = "album API"
Expand Down Expand Up @@ -53,27 +59,50 @@ def test_update(self):
self.albums = self.client.albums.list()
self.assertEqual(self.albums[0].name, self.TEST_ALBUM)

@unittest.skipIf(test_base.get_test_server_api() == 1,
"update_cover was introduced in APIv2")
def test_update_cover(self):
""" Test that an album cover can be updated """
self.albums[0].cover_update(self.photos[0])
self.assertNotEqual(self.albums[0].cover.id, self.photos[1].id)
self.albums[0].cover_update(self.photos[1])
self.assertEqual(self.albums[0].cover.id, self.photos[1].id)

@unittest.skipIf(test_base.get_test_server_api() == 1,
"includeElements was introduced in APIv2")
def test_view(self):
""" Test the album view """
album = self.albums[0]
# Do a view() with includeElements=False, using a fresh Album object
album = Album(self.client, {"id": self.albums[0].id})
album.view()
# Make sure there are no photos reported
self.assertEqual(album.photos, None)

# Get the photos in the album using the Album object directly
# Get the photos with includeElements=True
album.view(includeElements=True)
# Make sure all photos are in the album
for photo in self.photos:
self.assertIn(photo.id, [p.id for p in album.photos])

def test_form(self):
""" If album.form gets implemented, write a test! """
with self.assertRaises(NotImplementedError):
self.client.album.form(None)
def test_add_remove(self):
""" Test that photos can be added and removed from an album """
# Make sure all photos are in the album
album = self.albums[0]
album.view(includeElements=True)
for photo in self.photos:
self.assertIn(photo.id, [p.id for p in album.photos])

# Remove two photos and check that they're gone
album.remove(self.photos[:2])
album.view(includeElements=True)
self.assertEqual([p.id for p in album.photos], [self.photos[2].id])

def test_add_photos(self):
""" If album.add_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError):
self.client.album.add_photos(None, None)
# Add a photo and check that it's there
album.add(self.photos[1])
album.view(includeElements=True)
self.assertNotIn(self.photos[0].id, [p.id for p in album.photos])
self.assertIn(self.photos[1].id, [p.id for p in album.photos])
self.assertIn(self.photos[2].id, [p.id for p in album.photos])

def test_remove_photos(self):
""" If album.remove_photos gets implemented, write a test! """
with self.assertRaises(NotImplementedError):
self.client.album.remove_photos(None, None)
# Put the environment back the way we found it
album.add(self.photos[0])
Loading

0 comments on commit f75f250

Please sign in to comment.