aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin/tests
diff options
context:
space:
mode:
Diffstat (limited to 'mediagoblin/tests')
-rw-r--r--mediagoblin/tests/.gitignore1
-rw-r--r--mediagoblin/tests/fake_carrot_conf_good.ini2
-rw-r--r--mediagoblin/tests/resources.py1
-rw-r--r--mediagoblin/tests/test_api.py90
-rw-r--r--mediagoblin/tests/test_auth.py50
-rw-r--r--mediagoblin/tests/test_celery_setup.py5
-rw-r--r--mediagoblin/tests/test_config.py4
-rw-r--r--mediagoblin/tests/test_exif.py17
-rw-r--r--mediagoblin/tests/test_exif/bad-gps.jpgbin0 -> 141096 bytes
-rw-r--r--mediagoblin/tests/test_tools.py57
-rw-r--r--mediagoblin/tests/test_util.py29
-rw-r--r--mediagoblin/tests/tools.py22
12 files changed, 230 insertions, 48 deletions
diff --git a/mediagoblin/tests/.gitignore b/mediagoblin/tests/.gitignore
new file mode 100644
index 00000000..16d3c4db
--- /dev/null
+++ b/mediagoblin/tests/.gitignore
@@ -0,0 +1 @@
+.cache
diff --git a/mediagoblin/tests/fake_carrot_conf_good.ini b/mediagoblin/tests/fake_carrot_conf_good.ini
index 1377907b..8dc32525 100644
--- a/mediagoblin/tests/fake_carrot_conf_good.ini
+++ b/mediagoblin/tests/fake_carrot_conf_good.ini
@@ -7,7 +7,7 @@ num_carrots = 88
encouragement_phrase = "I'd love it if you eat your carrots!"
# Something extra!
-blah_blah = "blah!"
+blah_blah = "blæh!"
[celery]
EAT_CELERY_WITH_CARROTS = False
diff --git a/mediagoblin/tests/resources.py b/mediagoblin/tests/resources.py
index 480f6d9a..38406d62 100644
--- a/mediagoblin/tests/resources.py
+++ b/mediagoblin/tests/resources.py
@@ -41,3 +41,4 @@ GOOD_JPG = resource_exif('good.jpg')
EMPTY_JPG = resource_exif('empty.jpg')
BAD_JPG = resource_exif('bad.jpg')
GPS_JPG = resource_exif('has-gps.jpg')
+BAD_GPS_JPG = resource_exif('bad-gps.jpg')
diff --git a/mediagoblin/tests/test_api.py b/mediagoblin/tests/test_api.py
index 90873cb9..f4741fd1 100644
--- a/mediagoblin/tests/test_api.py
+++ b/mediagoblin/tests/test_api.py
@@ -25,11 +25,11 @@ from webtest import AppError
from .resources import GOOD_JPG
from mediagoblin import mg_globals
-from mediagoblin.db.models import User, Activity, MediaEntry, TextComment
-from mediagoblin.tools.routing import extract_url_arguments
+from mediagoblin.db.models import User, MediaEntry, TextComment
from mediagoblin.tests.tools import fixture_add_user
from mediagoblin.moderation.tools import take_away_privileges
+
class TestAPI(object):
""" Test mediagoblin's pump.io complient APIs """
@@ -38,7 +38,8 @@ class TestAPI(object):
self.test_app = test_app
self.db = mg_globals.database
- self.user = fixture_add_user(privileges=[u'active', u'uploader', u'commenter'])
+ self.user = fixture_add_user(privileges=[u'active', u'uploader',
+ u'commenter'])
self.other_user = fixture_add_user(
username="otheruser",
privileges=[u'active', u'uploader', u'commenter']
@@ -61,7 +62,7 @@ class TestAPI(object):
return response, json.loads(response.body.decode())
- def _upload_image(self, test_app, image):
+ def _upload_image(self, test_app, image, custom_filename=None):
""" Uploads and image to MediaGoblin via pump.io API """
data = open(image, "rb").read()
headers = {
@@ -69,6 +70,8 @@ class TestAPI(object):
"Content-Length": str(len(data))
}
+ if custom_filename is not None:
+ headers["X-File-Name"] = custom_filename
with self.mock_oauth():
response = test_app.post(
@@ -126,9 +129,48 @@ class TestAPI(object):
assert image["objectType"] == "image"
# Check that we got the response we're expecting
- response, _ = self._post_image_to_feed(test_app, image)
+ response, data = self._post_image_to_feed(test_app, image)
+ assert response.status_code == 200
+ assert data["object"]["fullImage"]["url"].endswith("unknown.jpe")
+ assert data["object"]["image"]["url"].endswith("unknown.thumbnail.jpe")
+
+ def test_can_post_image_custom_filename(self, test_app):
+ """ Tests an image can be posted to the API with custom filename """
+ # First request we need to do is to upload the image
+ response, image = self._upload_image(test_app, GOOD_JPG,
+ custom_filename="hello.jpg")
+
+ # I should have got certain things back
+ assert response.status_code == 200
+
+ assert "id" in image
+ assert "fullImage" in image
+ assert "url" in image["fullImage"]
+ assert "url" in image
+ assert "author" in image
+ assert "published" in image
+ assert "updated" in image
+ assert image["objectType"] == "image"
+
+ # Check that we got the response we're expecting
+ response, data = self._post_image_to_feed(test_app, image)
+ assert response.status_code == 200
+ assert data["object"]["fullImage"]["url"].endswith("hello.jpg")
+ assert data["object"]["image"]["url"].endswith("hello.thumbnail.jpg")
+
+ def test_can_post_image_tags(self, test_app):
+ """ Tests that an image can be posted to the API """
+ # First request we need to do is to upload the image
+ response, image = self._upload_image(test_app, GOOD_JPG)
assert response.status_code == 200
+ image["tags"] = ["hello", "world"]
+
+ # Check that we got the response we're expecting
+ response, data = self._post_image_to_feed(test_app, image)
+ assert response.status_code == 200
+ assert data["object"]["tags"] == ["hello", "world"]
+
def test_unable_to_upload_as_someone_else(self, test_app):
""" Test that can't upload as someoen else """
data = open(GOOD_JPG, "rb").read()
@@ -172,7 +214,7 @@ class TestAPI(object):
assert "403 FORBIDDEN" in excinfo.value.args[0]
def test_only_able_to_update_own_image(self, test_app):
- """ Test's that the uploader is the only person who can update an image """
+ """ Test uploader is the only person who can update an image """
response, data = self._upload_image(test_app, GOOD_JPG)
response, data = self._post_image_to_feed(test_app, data)
@@ -186,13 +228,16 @@ class TestAPI(object):
}
# Lets change the image uploader to be self.other_user, this is easier
- # than uploading the image as someone else as the way self.mocked_oauth_required
- # and self._upload_image.
- media = MediaEntry.query.filter_by(public_id=data["object"]["id"]).first()
+ # than uploading the image as someone else as the way
+ # self.mocked_oauth_required and self._upload_image.
+ media = MediaEntry.query \
+ .filter_by(public_id=data["object"]["id"]) \
+ .first()
media.actor = self.other_user.id
media.save()
- # Now lets try and edit the image as self.user, this should produce a 403 error.
+ # Now lets try and edit the image as self.user, this should produce a
+ # 403 error.
with self.mock_oauth():
with pytest.raises(AppError) as excinfo:
test_app.post(
@@ -242,7 +287,6 @@ class TestAPI(object):
assert image["content"] == description
assert image["license"] == license
-
def test_only_uploaders_post_image(self, test_app):
""" Test that only uploaders can upload images """
# Remove uploader permissions from user
@@ -288,12 +332,15 @@ class TestAPI(object):
image = json.loads(request.body.decode())
entry = MediaEntry.query.filter_by(public_id=image["id"]).first()
+ assert entry is not None
+
assert request.status_code == 200
assert "image" in image
assert "fullImage" in image
assert "pump_io" in image
assert "links" in image
+ assert "tags" in image
def test_post_comment(self, test_app):
""" Tests that I can post an comment media """
@@ -316,7 +363,9 @@ class TestAPI(object):
assert response.status_code == 200
# Find the objects in the database
- media = MediaEntry.query.filter_by(public_id=data["object"]["id"]).first()
+ media = MediaEntry.query \
+ .filter_by(public_id=data["object"]["id"]) \
+ .first()
comment = media.get_comments()[0].comment()
# Tests that it matches in the database
@@ -378,7 +427,9 @@ class TestAPI(object):
response, comment_data = self._activity_to_feed(test_app, activity)
# change who uploaded the comment as it's easier than changing
- comment = TextComment.query.filter_by(public_id=comment_data["object"]["id"]).first()
+ comment = TextComment.query \
+ .filter_by(public_id=comment_data["object"]["id"]) \
+ .first()
comment.actor = self.other_user.id
comment.save()
@@ -432,7 +483,7 @@ class TestAPI(object):
def test_whoami_without_login(self, test_app):
""" Test that whoami endpoint returns error when not logged in """
with pytest.raises(AppError) as excinfo:
- response = test_app.get("/api/whoami")
+ test_app.get("/api/whoami")
assert "401 UNAUTHORIZED" in excinfo.value.args[0]
@@ -621,8 +672,11 @@ class TestAPI(object):
delete = self._activity_to_feed(test_app, activity)[1]
# Verify the comment no longer exists
- assert TextComment.query.filter_by(public_id=comment["object"]["id"]).first() is None
- comment_id = comment["object"]["id"]
+ assert TextComment.query \
+ .filter_by(public_id=comment["object"]["id"]) \
+ .first() is None
+
+ assert "id" in comment["object"]
# Check we've got a delete activity back
assert "id" in delete
@@ -662,6 +716,8 @@ class TestAPI(object):
comment = self._activity_to_feed(test_app, activity)[1]
# Verify the comment reflects the changes
- model = TextComment.query.filter_by(public_id=comment["object"]["id"]).first()
+ model = TextComment.query \
+ .filter_by(public_id=comment["object"]["id"]) \
+ .first()
assert model.content == activity["object"]["content"]
diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py
index cb971fdb..9cf5ccb0 100644
--- a/mediagoblin/tests/test_auth.py
+++ b/mediagoblin/tests/test_auth.py
@@ -1,4 +1,3 @@
-
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
@@ -102,7 +101,7 @@ def test_register_views(test_app):
'password': 'iamsohappy',
'email': 'easter@egg.com'})
- ## At this point there should on user in the database
+ ## At this point there should be one user in the database
assert User.query.count() == 1
# Successful register
@@ -373,6 +372,53 @@ def test_authentication_views(test_app):
assert not form.username.data == u'ANDREW'
assert form.username.data == u'andrew'
+ # Successful login with short user
+ # --------------------------------
+ short_user = fixture_add_user(username=u'me', password=u'sho')
+ template.clear_test_template_context()
+ response = test_app.post(
+ '/auth/login/', {
+ 'username': u'me',
+ 'password': 'sho'})
+
+ # User should be redirected
+ response.follow()
+
+ assert urlparse.urlsplit(response.location)[2] == '/'
+ assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT
+
+ # Make sure user is in the session
+ context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html']
+ session = context['request'].session
+ assert session['user_id'] == six.text_type(short_user.id)
+
+ # Must logout
+ template.clear_test_template_context()
+ response = test_app.get('/auth/logout/')
+
+ # Successful login with long user
+ # ----------------
+ long_user = fixture_add_user(
+ username=u'realllylonguser@reallylongdomain.com.co', password=u'sho')
+ template.clear_test_template_context()
+ response = test_app.post(
+ '/auth/login/', {
+ 'username': u'realllylonguser@reallylongdomain.com.co',
+ 'password': 'sho'})
+
+ # User should be redirected
+ response.follow()
+ assert urlparse.urlsplit(response.location)[2] == '/'
+ assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT
+
+ # Make sure user is in the session
+ context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html']
+ session = context['request'].session
+ assert session['user_id'] == six.text_type(long_user.id)
+
+ template.clear_test_template_context()
+ response = test_app.get('/auth/logout/')
+
@pytest.fixture()
def authentication_disabled_app(request):
return get_app(
diff --git a/mediagoblin/tests/test_celery_setup.py b/mediagoblin/tests/test_celery_setup.py
index df0d04b0..0749c7f4 100644
--- a/mediagoblin/tests/test_celery_setup.py
+++ b/mediagoblin/tests/test_celery_setup.py
@@ -55,7 +55,4 @@ def test_setup_celery_from_config():
'sqlite:///' +
pkg_resources.resource_filename('mediagoblin.tests', 'celery.db'))
- assert fake_celery_module.BROKER_TRANSPORT == 'sqlalchemy'
- assert fake_celery_module.BROKER_URL == (
- 'sqlite:///' +
- pkg_resources.resource_filename('mediagoblin.tests', 'kombu.db'))
+ assert fake_celery_module.BROKER_URL == 'amqp://'
diff --git a/mediagoblin/tests/test_config.py b/mediagoblin/tests/test_config.py
index b13adae6..c3527418 100644
--- a/mediagoblin/tests/test_config.py
+++ b/mediagoblin/tests/test_config.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+#
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
@@ -47,7 +49,7 @@ def test_read_mediagoblin_config():
assert this_conf['carrotapp']['num_carrots'] == 88
assert this_conf['carrotapp']['encouragement_phrase'] == \
"I'd love it if you eat your carrots!"
- assert this_conf['carrotapp']['blah_blah'] == "blah!"
+ assert this_conf['carrotapp']['blah_blah'] == u"blæh!"
assert this_conf['celery']['EAT_CELERY_WITH_CARROTS'] == False
# A bad file
diff --git a/mediagoblin/tests/test_exif.py b/mediagoblin/tests/test_exif.py
index d0495a7a..ad771cca 100644
--- a/mediagoblin/tests/test_exif.py
+++ b/mediagoblin/tests/test_exif.py
@@ -24,7 +24,7 @@ from collections import OrderedDict
from mediagoblin.tools.exif import exif_fix_image_orientation, \
extract_exif, clean_exif, get_gps_data, get_useful
-from .resources import GOOD_JPG, EMPTY_JPG, BAD_JPG, GPS_JPG
+from .resources import GOOD_JPG, EMPTY_JPG, BAD_JPG, GPS_JPG, BAD_GPS_JPG
def assert_in(a, b):
@@ -437,3 +437,18 @@ def test_exif_gps_data():
'direction': 25.674046740467404,
'altitude': 37.64365671641791,
'longitude': 18.016166666666667}
+
+
+def test_exif_bad_gps_data():
+ '''
+ Test extraction of GPS data from an image with bad GPS data
+ '''
+ result = extract_exif(BAD_GPS_JPG)
+ gps = get_gps_data(result)
+ print(gps)
+
+ assert gps == {
+ 'latitude': 0.0,
+ 'direction': 0.0,
+ 'altitude': 0.0,
+ 'longitude': 0.0}
diff --git a/mediagoblin/tests/test_exif/bad-gps.jpg b/mediagoblin/tests/test_exif/bad-gps.jpg
new file mode 100644
index 00000000..bd6c7bf2
--- /dev/null
+++ b/mediagoblin/tests/test_exif/bad-gps.jpg
Binary files differ
diff --git a/mediagoblin/tests/test_tools.py b/mediagoblin/tests/test_tools.py
index 6d3dd475..5f916400 100644
--- a/mediagoblin/tests/test_tools.py
+++ b/mediagoblin/tests/test_tools.py
@@ -16,10 +16,16 @@
from __future__ import absolute_import, unicode_literals
+try:
+ import mock
+except ImportError:
+ import unittest.mock as mock
+
from werkzeug.wrappers import Request
from werkzeug.test import EnvironBuilder
from mediagoblin.tools.request import decode_request
+from mediagoblin.tools.pagination import Pagination
class TestDecodeRequest(object):
"""Test the decode_request function."""
@@ -59,3 +65,54 @@ class TestDecodeRequest(object):
request.form = {'foo': 'bar'}
data = decode_request(request)
assert data['foo'] == 'bar'
+
+
+class TestPagination(object):
+ def _create_paginator(self, num_items, page, per_page):
+ """Create a Paginator with a mock database cursor."""
+ mock_cursor = mock.MagicMock()
+ mock_cursor.count.return_value = num_items
+ return Pagination(page, mock_cursor, per_page)
+
+ def test_creates_valid_page_url_from_explicit_base_url(self):
+ """Check that test_page_url_explicit runs.
+
+ This is a regression test for a Python 2/3 compatibility fix.
+
+ """
+ paginator = self._create_paginator(num_items=1, page=1, per_page=30)
+ url = paginator.get_page_url_explicit('http://example.com', [], 1)
+ assert url == 'http://example.com?page=1'
+
+ def test_iter_pages_handles_single_page(self):
+ """Check that iter_pages produces the expected result for single page.
+
+ This is a regression test for a Python 2/3 compatibility fix.
+
+ """
+ paginator = self._create_paginator(num_items=1, page=1, per_page=30)
+ assert list(paginator.iter_pages()) == [1]
+
+ def test_zero_items(self):
+ """Check that no items produces no pages."""
+ paginator = self._create_paginator(num_items=0, page=1, per_page=30)
+ assert paginator.total_count == 0
+ assert paginator.pages == 0
+
+ def test_single_item(self):
+ """Check that one item produces one page."""
+ paginator = self._create_paginator(num_items=1, page=1, per_page=30)
+ assert paginator.total_count == 1
+ assert paginator.pages == 1
+
+ def test_full_page(self):
+ """Check that a full page of items produces one page."""
+ paginator = self._create_paginator(num_items=30, page=1, per_page=30)
+ assert paginator.total_count == 30
+ assert paginator.pages == 1
+
+ def test_multiple_pages(self):
+ """Check that more than a full page produces two pages."""
+ paginator = self._create_paginator(num_items=31, page=1, per_page=30)
+ assert paginator.total_count == 31
+ assert paginator.pages == 2
diff --git a/mediagoblin/tests/test_util.py b/mediagoblin/tests/test_util.py
index 8193233f..02976405 100644
--- a/mediagoblin/tests/test_util.py
+++ b/mediagoblin/tests/test_util.py
@@ -19,6 +19,7 @@ try:
except ImportError:
import unittest.mock as mock
import email
+import socket
import pytest
import smtplib
import pkg_resources
@@ -26,6 +27,7 @@ import pkg_resources
import six
from mediagoblin.tests.tools import get_app
+from mediagoblin import mg_globals
from mediagoblin.tools import common, url, translate, mail, text, testing
testing._activate_testing()
@@ -181,3 +183,30 @@ def test_html_cleaner():
'<p><a href="javascript:nasty_surprise">innocent link!</a></p>')
assert result == (
'<p><a href="">innocent link!</a></p>')
+
+
+class TestMail(object):
+ """ Test mediagoblin's mail tool """
+ def test_no_mail_server(self):
+ """ Tests that no smtp server is available """
+ with pytest.raises(mail.NoSMTPServerError), mock.patch("smtplib.SMTP") as smtp_mock:
+ smtp_mock.side_effect = socket.error
+ mg_globals.app_config = {
+ "email_debug_mode": False,
+ "email_smtp_use_ssl": False,
+ "email_smtp_host": "127.0.0.1",
+ "email_smtp_port": 0}
+ common.TESTS_ENABLED = False
+ mail.send_email("", "", "", "")
+
+ def test_no_smtp_host(self):
+ """ Empty email_smtp_host """
+ with pytest.raises(mail.NoSMTPServerError), mock.patch("smtplib.SMTP") as smtp_mock:
+ smtp_mock.return_value.connect.side_effect = socket.error
+ mg_globals.app_config = {
+ "email_debug_mode": False,
+ "email_smtp_use_ssl": False,
+ "email_smtp_host": "",
+ "email_smtp_port": 0}
+ common.TESTS_ENABLED = False
+ mail.send_email("", "", "", "")
diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py
index 39b9ac50..82def02c 100644
--- a/mediagoblin/tests/tools.py
+++ b/mediagoblin/tests/tools.py
@@ -153,28 +153,6 @@ def install_fixtures_simple(db, fixtures):
collection.insert(fixture)
-def assert_db_meets_expected(db, expected):
- """
- Assert a database contains the things we expect it to.
-
- Objects are found via 'id', so you should make sure your document
- has an id.
-
- Args:
- - db: pymongo or mongokit database connection
- - expected: the data we expect. Formatted like:
- {'collection_name': [
- {'id': 'foo',
- 'some_field': 'some_value'},]}
- """
- for collection_name, collection_data in six.iteritems(expected):
- collection = db[collection_name]
- for expected_document in collection_data:
- document = collection.query.filter_by(id=expected_document['id']).first()
- assert document is not None # make sure it exists
- assert document == expected_document # make sure it matches
-
-
def fixture_add_user(username=u'chris', password=u'toast',
privileges=[], wants_comment_notification=True):
# Reuse existing user or create a new one