Adds the unit-tests for API and cleans up API

This commit is contained in:
xray7224 2013-11-14 22:42:07 +00:00 committed by Jessica Tallon
parent c64fc16b13
commit 247a3b788f
4 changed files with 176 additions and 64 deletions

View File

@ -0,0 +1,41 @@
.. MediaGoblin Documentation
Written in 2011, 2012 by MediaGoblin contributors
To the extent possible under law, the author(s) have dedicated all
copyright and related and neighboring rights to this software to
the public domain worldwide. This software is distributed without
any warranty.
You should have received a copy of the CC0 Public Domain
Dedication along with this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
==================
Uploading an Image
==================
You must have fully authenticated with oauth to upload an image.
The endpoint is: ``/api/user/<username>/uploads/`` (POST endpoint)
There are four GET parameters available to use, if they're not specified the defaults (listed below) will be used, the parameters are:
+-------------+-----------+---------------------+--------------------+
| Parameter | Required | Default | Example |
+=============+===========+=====================+====================+
| qqfile | No | unknown | my_picture.jpg |
+-------------+-----------+---------------------+--------------------+
| title | No | <qqfile> | My Picture! |
+-------------+-----------+---------------------+--------------------+
| description | No | None | My awesome picture |
+-------------+-----------+---------------------+--------------------+
| licence | No | All rights reserved | CC BY-SA 3.0 |
+-------------+-----------+---------------------+--------------------+
*Note: licence is not part of the pump.io spec and is a GNU MediaGoblin specific parameter*
Example URL (with parameters): /api/user/tsyesika/uploads/?qqfile=river.jpg&title=The%20River&description=The%20river%20that%20I%20use%20to%20visit%20as%20a%20child%20licence=CC%20BY-SA%203.0
Submit the binary image data in the POST parameter.

View File

@ -10,7 +10,7 @@ from mediagoblin.tools.response import redirect, json_response
from mediagoblin.meddleware.csrf import csrf_exempt from mediagoblin.meddleware.csrf import csrf_exempt
from mediagoblin.submit.lib import new_upload_entry from mediagoblin.submit.lib import new_upload_entry
#@oauth_required @oauth_required
def profile(request, raw=False): def profile(request, raw=False):
""" This is /api/user/<username>/profile - This will give profile info """ """ This is /api/user/<username>/profile - This will give profile info """
user = request.matchdict["username"] user = request.matchdict["username"]
@ -29,6 +29,7 @@ def profile(request, raw=False):
# user profiles are public so return information # user profiles are public so return information
return json_response(user.serialize(request)) return json_response(user.serialize(request))
@oauth_required
def user(request): def user(request):
""" This is /api/user/<username> - This will get the user """ """ This is /api/user/<username> - This will get the user """
user, user_profile = profile(request, raw=True) user, user_profile = profile(request, raw=True)
@ -41,7 +42,7 @@ def user(request):
return json_response(data) return json_response(data)
#@oauth_required @oauth_required
@csrf_exempt @csrf_exempt
def uploads(request): def uploads(request):
""" Endpoint for file uploads """ """ Endpoint for file uploads """
@ -57,7 +58,7 @@ def uploads(request):
# Wrap the data in the werkzeug file wrapper # Wrap the data in the werkzeug file wrapper
file_data = FileStorage( file_data = FileStorage(
stream=io.BytesIO(request.data), stream=io.BytesIO(request.data),
filename=request.args.get("qqfile", "unknown.jpg"), filename=request.args.get("qqfile", "unknown"),
content_type=request.headers.get("Content-Type", "application/octal-stream") content_type=request.headers.get("Content-Type", "application/octal-stream")
) )
@ -71,7 +72,7 @@ def uploads(request):
return json_response({"error": "Not yet implemented"}, status=400) return json_response({"error": "Not yet implemented"}, status=400)
#@oauth_required @oauth_required
@csrf_exempt @csrf_exempt
def feed(request): def feed(request):
""" Handles the user's outbox - /api/user/<username>/feed """ """ Handles the user's outbox - /api/user/<username>/feed """
@ -200,6 +201,7 @@ def object(request, raw_obj=False):
return json_response(media.serialize(request)) return json_response(media.serialize(request))
@oauth_required
def object_comments(request): def object_comments(request):
""" Looks up for the comments on a object """ """ Looks up for the comments on a object """
media = object(request, raw_obj=True) media = object(request, raw_obj=True)

View File

@ -14,80 +14,57 @@
# You should have received a copy of the GNU Affero General Public License # You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import urllib
import logging
import base64
import pytest import pytest
import mock
from oauthlib.oauth1 import Client
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.tools import template, pluginapi
from mediagoblin.tests.tools import fixture_add_user from mediagoblin.tests.tools import fixture_add_user
from .resources import GOOD_JPG, GOOD_PNG, EVIL_FILE, EVIL_JPG, EVIL_PNG, \ from .resources import GOOD_JPG
BIG_BLUE
_log = logging.getLogger(__name__)
class TestAPI(object): class TestAPI(object):
def setup(self): def setup(self):
self.db = mg_globals.database self.db = mg_globals.database
self.user = fixture_add_user()
self.user_password = u'4cc355_70k3N' def test_profile_endpoint(self, test_app):
self.user = fixture_add_user(u'joapi', self.user_password, """ Test that you can successfully get the profile of a user """
privileges=[u'active',u'uploader']) @mock.patch("mediagoblin.decorators.oauth_required")
def _real_test(*args, **kwargs):
profile = test_app.get(
"/api/user/{0}/profile".format(self.user.username)
).json
def login(self, test_app): assert profile["preferredUsername"] == self.user.username
test_app.post( assert profile["objectType"] == "person"
'/auth/login/', {
'username': self.user.username,
'password': self.user_password})
def get_context(self, template_name): _real_test()
return template.TEMPLATE_TEST_CONTEXT[template_name]
def http_auth_headers(self): def test_upload_file(self, test_app):
return {'Authorization': 'Basic {0}'.format( """ Test that i can upload a file """
base64.b64encode(':'.join([ context = {
"title": "Rel",
"description": "ayRel sunu oeru",
"qqfile": "my_picture.jpg",
}
encoded_context = urllib.urlencode(context)
response = test_app.post(
"/api/user/{0}/uploads?{1}".format(
self.user.username, self.user.username,
self.user_password])))} encoded_context[1:]
)
)
def do_post(self, data, test_app, **kwargs): picture = self.db.MediaEntry.query.filter_by(title=context["title"])
url = kwargs.pop('url', '/api/submit') picture = picture.first()
do_follow = kwargs.pop('do_follow', False)
if not 'headers' in kwargs.keys():
kwargs['headers'] = self.http_auth_headers()
response = test_app.post(url, data, **kwargs)
if do_follow:
response.follow()
return response
def upload_data(self, filename):
return {'upload_files': [('file', filename)]}
def test_1_test_test_view(self, test_app):
self.login(test_app)
response = test_app.get(
'/api/test',
headers=self.http_auth_headers())
assert response.body == \
'{"username": "joapi", "email": "joapi@example.com"}'
def test_2_test_submission(self, test_app):
self.login(test_app)
response = self.do_post(
{'title': 'Great JPG!'},
test_app,
**self.upload_data(GOOD_JPG))
assert response.status_int == 200 assert response.status_int == 200
assert picture
raise Exception(str(dir(picture)))
assert picture.description == context["description"]
assert self.db.MediaEntry.query.filter_by(title=u'Great JPG!').first()

View File

@ -0,0 +1,92 @@
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import base64
import pytest
from mediagoblin import mg_globals
from mediagoblin.tools import template, pluginapi
from mediagoblin.tests.tools import fixture_add_user
from .resources import GOOD_JPG, GOOD_PNG, EVIL_FILE, EVIL_JPG, EVIL_PNG, \
BIG_BLUE
_log = logging.getLogger(__name__)
class TestAPI(object):
def setup(self):
self.db = mg_globals.database
self.user_password = u'4cc355_70k3N'
self.user = fixture_add_user(u'joapi', self.user_password)
def login(self, test_app):
test_app.post(
'/auth/login/', {
'username': self.user.username,
'password': self.user_password})
def get_context(self, template_name):
return template.TEMPLATE_TEST_CONTEXT[template_name]
def http_auth_headers(self):
return {'Authorization': 'Basic {0}'.format(
base64.b64encode(':'.join([
self.user.username,
self.user_password])))}
def do_post(self, data, test_app, **kwargs):
url = kwargs.pop('url', '/api/submit')
do_follow = kwargs.pop('do_follow', False)
if not 'headers' in kwargs.keys():
kwargs['headers'] = self.http_auth_headers()
response = test_app.post(url, data, **kwargs)
if do_follow:
response.follow()
return response
def upload_data(self, filename):
return {'upload_files': [('file', filename)]}
def test_1_test_test_view(self, test_app):
self.login(test_app)
response = test_app.get(
'/api/test',
headers=self.http_auth_headers())
assert response.body == \
'{"username": "joapi", "email": "joapi@example.com"}'
def test_2_test_submission(self, test_app):
self.login(test_app)
response = self.do_post(
{'title': 'Great JPG!'},
test_app,
**self.upload_data(GOOD_JPG))
assert response.status_int == 200
assert self.db.MediaEntry.query.filter_by(title=u'Great JPG!').first()