Merge branch '614_multi_test_config'
This commit is contained in:
commit
fe6755f0f4
15
mediagoblin/tests/conftest.py
Normal file
15
mediagoblin/tests/conftest.py
Normal file
@ -0,0 +1,15 @@
|
||||
from mediagoblin.tests import tools
|
||||
|
||||
import pytest
|
||||
|
||||
@pytest.fixture()
|
||||
def test_app(request):
|
||||
"""
|
||||
py.test fixture to pass sandboxed mediagoblin applications into tests that
|
||||
want them.
|
||||
|
||||
You could make a local version of this method for your own tests
|
||||
to override the paste and config files being used by passing them
|
||||
in differently to get_app.
|
||||
"""
|
||||
return tools.get_app(request)
|
2
mediagoblin/tests/pytest.ini
Normal file
2
mediagoblin/tests/pytest.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[pytest]
|
||||
usefixtures = tmpdir
|
@ -20,9 +20,11 @@ import base64
|
||||
|
||||
from pkg_resources import resource_filename
|
||||
|
||||
import pytest
|
||||
|
||||
from mediagoblin import mg_globals
|
||||
from mediagoblin.tools import template, pluginapi
|
||||
from mediagoblin.tests.tools import get_app, fixture_add_user
|
||||
from mediagoblin.tests.tools import fixture_add_user
|
||||
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
@ -42,16 +44,16 @@ EVIL_PNG = resource('evil.png')
|
||||
BIG_BLUE = resource('bigblue.png')
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("test_app")
|
||||
class TestAPI(object):
|
||||
def setup(self):
|
||||
self.app = get_app(dump_old_app=False)
|
||||
self.db = mg_globals.database
|
||||
|
||||
self.user_password = u'4cc355_70k3N'
|
||||
self.user = fixture_add_user(u'joapi', self.user_password)
|
||||
|
||||
def login(self):
|
||||
self.app.post(
|
||||
def login(self, test_app):
|
||||
test_app.post(
|
||||
'/auth/login/', {
|
||||
'username': self.user.username,
|
||||
'password': self.user_password})
|
||||
@ -65,14 +67,14 @@ class TestAPI(object):
|
||||
self.user.username,
|
||||
self.user_password])))}
|
||||
|
||||
def do_post(self, data, **kwargs):
|
||||
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 = self.app.post(url, data, **kwargs)
|
||||
response = test_app.post(url, data, **kwargs)
|
||||
|
||||
if do_follow:
|
||||
response.follow()
|
||||
@ -82,21 +84,22 @@ class TestAPI(object):
|
||||
def upload_data(self, filename):
|
||||
return {'upload_files': [('file', filename)]}
|
||||
|
||||
def test_1_test_test_view(self):
|
||||
self.login()
|
||||
def test_1_test_test_view(self, test_app):
|
||||
self.login(test_app)
|
||||
|
||||
response = self.app.get(
|
||||
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):
|
||||
self.login()
|
||||
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
|
||||
|
@ -22,7 +22,7 @@ from nose.tools import assert_equal
|
||||
from mediagoblin import mg_globals
|
||||
from mediagoblin.auth import lib as auth_lib
|
||||
from mediagoblin.db.models import User
|
||||
from mediagoblin.tests.tools import setup_fresh_app, get_app, fixture_add_user
|
||||
from mediagoblin.tests.tools import fixture_add_user
|
||||
from mediagoblin.tools import template, mail
|
||||
|
||||
|
||||
@ -65,7 +65,6 @@ def test_bcrypt_gen_password_hash():
|
||||
'notthepassword', hashed_pw, '3><7R45417')
|
||||
|
||||
|
||||
@setup_fresh_app
|
||||
def test_register_views(test_app):
|
||||
"""
|
||||
Massive test function that all our registration-related views all work.
|
||||
@ -300,11 +299,10 @@ def test_register_views(test_app):
|
||||
assert 'mediagoblin/root.html' in template.TEMPLATE_TEST_CONTEXT
|
||||
|
||||
|
||||
def test_authentication_views():
|
||||
def test_authentication_views(test_app):
|
||||
"""
|
||||
Test logging in and logging out
|
||||
"""
|
||||
test_app = get_app(dump_old_app=False)
|
||||
# Make a new user
|
||||
test_user = fixture_add_user(active_user=False)
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
from mediagoblin.tests.tools import setup_fresh_app
|
||||
from mediagoblin import mg_globals
|
||||
|
||||
|
||||
@ -37,7 +36,6 @@ def _get_some_data(key):
|
||||
return value
|
||||
|
||||
|
||||
@setup_fresh_app
|
||||
def test_cache_working(test_app):
|
||||
some_data_cache = mg_globals.cache.get_cache('sum_data')
|
||||
assert not some_data_cache.has_key('herp')
|
||||
|
@ -14,17 +14,13 @@
|
||||
# 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/>.
|
||||
|
||||
from mediagoblin.tests.tools import fixture_add_collection, fixture_add_user, \
|
||||
get_app
|
||||
from mediagoblin.tests.tools import fixture_add_collection, fixture_add_user
|
||||
from mediagoblin.db.models import Collection, User
|
||||
from mediagoblin.db.base import Session
|
||||
from nose.tools import assert_equal
|
||||
|
||||
|
||||
def test_user_deletes_collection():
|
||||
def test_user_deletes_collection(test_app):
|
||||
# Setup db.
|
||||
get_app(dump_old_app=False)
|
||||
|
||||
user = fixture_add_user()
|
||||
coll = fixture_add_collection(user=user)
|
||||
# Reload into session:
|
||||
|
@ -14,12 +14,10 @@
|
||||
# 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/>.
|
||||
|
||||
from mediagoblin.tests.tools import get_app
|
||||
from mediagoblin import mg_globals
|
||||
|
||||
|
||||
def test_csrf_cookie_set():
|
||||
test_app = get_app(dump_old_app=False)
|
||||
def test_csrf_cookie_set(test_app):
|
||||
cookie_name = mg_globals.app_config['csrf_cookie_name']
|
||||
|
||||
# get login page
|
||||
@ -33,11 +31,14 @@ def test_csrf_cookie_set():
|
||||
assert response.headers.get('Vary', False) == 'Cookie'
|
||||
|
||||
|
||||
def test_csrf_token_must_match():
|
||||
# We need a fresh app for this test on webtest < 1.3.6.
|
||||
# We do not understand why, but it fixes the tests.
|
||||
# If we require webtest >= 1.3.6, we can switch to a non fresh app here.
|
||||
test_app = get_app(dump_old_app=True)
|
||||
#
|
||||
# ... this comment might be irrelevant post-pytest-fixtures, but I'm not
|
||||
# removing it yet in case we move to module-level tests :)
|
||||
# -- cwebber
|
||||
def test_csrf_token_must_match(test_app):
|
||||
|
||||
# construct a request with no cookie or form token
|
||||
assert test_app.post('/auth/login/',
|
||||
@ -67,8 +68,7 @@ def test_csrf_token_must_match():
|
||||
extra_environ={'gmg.verify_csrf': True}).\
|
||||
status_int == 200
|
||||
|
||||
def test_csrf_exempt():
|
||||
test_app = get_app(dump_old_app=False)
|
||||
def test_csrf_exempt(test_app):
|
||||
# monkey with the views to decorate a known endpoint
|
||||
import mediagoblin.auth.views
|
||||
from mediagoblin.meddleware.csrf import csrf_exempt
|
||||
|
@ -18,31 +18,31 @@ from nose.tools import assert_equal
|
||||
|
||||
from mediagoblin import mg_globals
|
||||
from mediagoblin.db.models import User
|
||||
from mediagoblin.tests.tools import get_app, fixture_add_user
|
||||
from mediagoblin.tests.tools import fixture_add_user
|
||||
from mediagoblin.tools import template
|
||||
from mediagoblin.auth.lib import bcrypt_check_password
|
||||
|
||||
class TestUserEdit(object):
|
||||
def setup(self):
|
||||
self.app = get_app(dump_old_app=False)
|
||||
# set up new user
|
||||
self.user_password = u'toast'
|
||||
self.user = fixture_add_user(password = self.user_password)
|
||||
self.login()
|
||||
|
||||
def login(self):
|
||||
self.app.post(
|
||||
def login(self, test_app):
|
||||
test_app.post(
|
||||
'/auth/login/', {
|
||||
'username': self.user.username,
|
||||
'password': self.user_password})
|
||||
|
||||
|
||||
def test_user_deletion(self):
|
||||
def test_user_deletion(self, test_app):
|
||||
"""Delete user via web interface"""
|
||||
self.login(test_app)
|
||||
|
||||
# Make sure user exists
|
||||
assert User.query.filter_by(username=u'chris').first()
|
||||
|
||||
res = self.app.post('/edit/account/delete/', {'confirmed': 'y'})
|
||||
res = test_app.post('/edit/account/delete/', {'confirmed': 'y'})
|
||||
|
||||
# Make sure user has been deleted
|
||||
assert User.query.filter_by(username=u'chris').first() == None
|
||||
@ -52,14 +52,16 @@ class TestUserEdit(object):
|
||||
|
||||
#Restore user at end of test
|
||||
self.user = fixture_add_user(password = self.user_password)
|
||||
self.login()
|
||||
self.login(test_app)
|
||||
|
||||
|
||||
def test_change_password(self):
|
||||
def test_change_password(self, test_app):
|
||||
"""Test changing password correctly and incorrectly"""
|
||||
self.login(test_app)
|
||||
|
||||
# test that the password can be changed
|
||||
# template.clear_test_template_context()
|
||||
res = self.app.post(
|
||||
res = test_app.post(
|
||||
'/edit/account/', {
|
||||
'old_password': 'toast',
|
||||
'new_password': '123456',
|
||||
@ -76,7 +78,7 @@ class TestUserEdit(object):
|
||||
|
||||
# test that the password cannot be changed if the given
|
||||
# old_password is wrong template.clear_test_template_context()
|
||||
self.app.post(
|
||||
test_app.post(
|
||||
'/edit/account/', {
|
||||
'old_password': 'toast',
|
||||
'new_password': '098765',
|
||||
@ -86,11 +88,12 @@ class TestUserEdit(object):
|
||||
assert not bcrypt_check_password('098765', test_user.pw_hash)
|
||||
|
||||
|
||||
|
||||
def test_change_bio_url(self):
|
||||
def test_change_bio_url(self, test_app):
|
||||
"""Test changing bio and URL"""
|
||||
self.login(test_app)
|
||||
|
||||
# Test if legacy profile editing URL redirects correctly
|
||||
res = self.app.post(
|
||||
res = test_app.post(
|
||||
'/edit/profile/', {
|
||||
'bio': u'I love toast!',
|
||||
'url': u'http://dustycloud.org/'}, expect_errors=True)
|
||||
@ -99,7 +102,7 @@ class TestUserEdit(object):
|
||||
assert_equal (res.status_int, 302)
|
||||
assert res.headers['Location'].endswith("/u/chris/edit/")
|
||||
|
||||
res = self.app.post(
|
||||
res = test_app.post(
|
||||
'/u/chris/edit/', {
|
||||
'bio': u'I love toast!',
|
||||
'url': u'http://dustycloud.org/'})
|
||||
@ -110,7 +113,7 @@ class TestUserEdit(object):
|
||||
|
||||
# change a different user than the logged in (should fail with 403)
|
||||
fixture_add_user(username=u"foo")
|
||||
res = self.app.post(
|
||||
res = test_app.post(
|
||||
'/u/foo/edit/', {
|
||||
'bio': u'I love toast!',
|
||||
'url': u'http://dustycloud.org/'}, expect_errors=True)
|
||||
@ -119,7 +122,7 @@ class TestUserEdit(object):
|
||||
# test changing the bio and the URL inproperly
|
||||
too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't'
|
||||
|
||||
self.app.post(
|
||||
test_app.post(
|
||||
'/u/chris/edit/', {
|
||||
# more than 500 characters
|
||||
'bio': too_long_bio,
|
||||
|
@ -20,28 +20,27 @@ from urlparse import urlparse, parse_qs
|
||||
|
||||
from mediagoblin import mg_globals
|
||||
from mediagoblin.tools import processing
|
||||
from mediagoblin.tests.tools import get_app, fixture_add_user
|
||||
from mediagoblin.tests.tools import fixture_add_user
|
||||
from mediagoblin.tests.test_submission import GOOD_PNG
|
||||
from mediagoblin.tests import test_oauth as oauth
|
||||
|
||||
|
||||
class TestHTTPCallback(object):
|
||||
def setup(self):
|
||||
self.app = get_app(dump_old_app=False)
|
||||
def _setup(self, test_app):
|
||||
self.db = mg_globals.database
|
||||
|
||||
self.user_password = u'secret'
|
||||
self.user = fixture_add_user(u'call_back', self.user_password)
|
||||
|
||||
self.login()
|
||||
self.login(test_app)
|
||||
|
||||
def login(self):
|
||||
self.app.post('/auth/login/', {
|
||||
def login(self, testapp):
|
||||
testapp.post('/auth/login/', {
|
||||
'username': self.user.username,
|
||||
'password': self.user_password})
|
||||
|
||||
def get_access_token(self, client_id, client_secret, code):
|
||||
response = self.app.get('/oauth/access_token', {
|
||||
def get_access_token(self, testapp, client_id, client_secret, code):
|
||||
response = testapp.get('/oauth/access_token', {
|
||||
'code': code,
|
||||
'client_id': client_id,
|
||||
'client_secret': client_secret})
|
||||
@ -50,13 +49,15 @@ class TestHTTPCallback(object):
|
||||
|
||||
return response_data['access_token']
|
||||
|
||||
def test_callback(self):
|
||||
def test_callback(self, test_app):
|
||||
''' Test processing HTTP callback '''
|
||||
self._setup(test_app)
|
||||
|
||||
self.oauth = oauth.TestOAuth()
|
||||
self.oauth.setup()
|
||||
self.oauth._setup(test_app)
|
||||
|
||||
redirect, client_id = self.oauth.test_4_authorize_confidential_client()
|
||||
redirect, client_id = self.oauth.test_4_authorize_confidential_client(
|
||||
test_app)
|
||||
|
||||
code = parse_qs(urlparse(redirect.location).query)['code'][0]
|
||||
|
||||
@ -65,11 +66,11 @@ class TestHTTPCallback(object):
|
||||
|
||||
client_secret = client.secret
|
||||
|
||||
access_token = self.get_access_token(client_id, client_secret, code)
|
||||
access_token = self.get_access_token(test_app, client_id, client_secret, code)
|
||||
|
||||
callback_url = 'https://foo.example?secrettestmediagoblinparam'
|
||||
|
||||
res = self.app.post('/api/submit?client_id={0}&access_token={1}\
|
||||
res = test_app.post('/api/submit?client_id={0}&access_token={1}\
|
||||
&client_secret={2}'.format(
|
||||
client_id,
|
||||
access_token,
|
||||
|
@ -15,18 +15,15 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from mediagoblin.messages import fetch_messages, add_message
|
||||
from mediagoblin.tests.tools import get_app
|
||||
from mediagoblin.tools import template
|
||||
|
||||
|
||||
|
||||
def test_messages():
|
||||
def test_messages(test_app):
|
||||
"""
|
||||
Added messages should show up in the request.session,
|
||||
fetched messages should be the same as the added ones,
|
||||
and fetching should clear the message list.
|
||||
"""
|
||||
test_app = get_app(dump_old_app=False)
|
||||
# Aquire a request object
|
||||
test_app.get('/')
|
||||
context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html']
|
||||
|
@ -18,18 +18,15 @@ from nose.tools import assert_equal
|
||||
|
||||
from mediagoblin.db.base import Session
|
||||
from mediagoblin.db.models import User, MediaEntry, MediaComment
|
||||
from mediagoblin.tests.tools import get_app, \
|
||||
fixture_add_user, fixture_media_entry
|
||||
from mediagoblin.tests.tools import fixture_add_user, fixture_media_entry
|
||||
|
||||
|
||||
def test_404_for_non_existent():
|
||||
test_app = get_app(dump_old_app=False)
|
||||
def test_404_for_non_existent(test_app):
|
||||
res = test_app.get('/does-not-exist/', expect_errors=True)
|
||||
assert_equal(res.status_int, 404)
|
||||
|
||||
|
||||
def test_user_deletes_other_comments():
|
||||
get_app() # gotta init the db and etc
|
||||
def test_user_deletes_other_comments(test_app):
|
||||
user_a = fixture_add_user(u"chris_a")
|
||||
user_b = fixture_add_user(u"chris_b")
|
||||
|
||||
@ -81,8 +78,7 @@ def test_user_deletes_other_comments():
|
||||
assert_equal(cmt_cnt2, cmt_cnt1 - 4)
|
||||
|
||||
|
||||
def test_media_deletes_broken_attachment():
|
||||
get_app() # gotta init the db and etc
|
||||
def test_media_deletes_broken_attachment(test_app):
|
||||
user_a = fixture_add_user(u"chris_a")
|
||||
|
||||
media = fixture_media_entry(uploader=user_a.id, save=False)
|
||||
|
@ -22,8 +22,7 @@ from nose.tools import assert_equal
|
||||
from mediagoblin.db.base import Session
|
||||
from mediagoblin.db.models import MediaEntry
|
||||
|
||||
from mediagoblin.tests.tools import get_app, \
|
||||
fixture_add_user
|
||||
from mediagoblin.tests.tools import fixture_add_user
|
||||
|
||||
import mock
|
||||
|
||||
@ -35,8 +34,7 @@ UUID_MOCK = mock.Mock(return_value=FakeUUID())
|
||||
|
||||
|
||||
class TestMediaEntrySlugs(object):
|
||||
def setup(self):
|
||||
self.test_app = get_app(dump_old_app=True)
|
||||
def _setup(self):
|
||||
self.chris_user = fixture_add_user(u'chris')
|
||||
self.emily_user = fixture_add_user(u'emily')
|
||||
self.existing_entry = self._insert_media_entry_fixture(
|
||||
@ -57,31 +55,44 @@ class TestMediaEntrySlugs(object):
|
||||
|
||||
return entry
|
||||
|
||||
def test_unique_slug_from_title(self):
|
||||
def test_unique_slug_from_title(self, test_app):
|
||||
self._setup()
|
||||
|
||||
entry = self._insert_media_entry_fixture(u"Totally unique slug!", save=False)
|
||||
entry.generate_slug()
|
||||
assert entry.slug == u'totally-unique-slug'
|
||||
|
||||
def test_old_good_unique_slug(self):
|
||||
def test_old_good_unique_slug(self, test_app):
|
||||
self._setup()
|
||||
|
||||
entry = self._insert_media_entry_fixture(
|
||||
u"A title here", u"a-different-slug-there", save=False)
|
||||
entry.generate_slug()
|
||||
assert entry.slug == u"a-different-slug-there"
|
||||
|
||||
def test_old_weird_slug(self):
|
||||
def test_old_weird_slug(self, test_app):
|
||||
self._setup()
|
||||
|
||||
entry = self._insert_media_entry_fixture(
|
||||
slug=u"wowee!!!!!", save=False)
|
||||
entry.generate_slug()
|
||||
assert entry.slug == u"wowee"
|
||||
|
||||
def test_existing_slug_use_id(self):
|
||||
def test_existing_slug_use_id(self, test_app):
|
||||
self._setup()
|
||||
|
||||
entry = self._insert_media_entry_fixture(
|
||||
u"Beware, I exist!!", this_id=9000, save=False)
|
||||
entry.generate_slug()
|
||||
assert entry.slug == u"beware-i-exist-9000"
|
||||
|
||||
def test_existing_slug_cant_use_id(self, test_app):
|
||||
self._setup()
|
||||
|
||||
# Getting tired of dealing with test_app and this mock.patch
|
||||
# thing conflicting, getting lazy.
|
||||
@mock.patch('uuid.uuid4', UUID_MOCK)
|
||||
def test_existing_slug_cant_use_id(self):
|
||||
def _real_test():
|
||||
# This one grabs the nine thousand slug
|
||||
self._insert_media_entry_fixture(
|
||||
slug=u"beware-i-exist-9000")
|
||||
@ -91,8 +102,15 @@ class TestMediaEntrySlugs(object):
|
||||
entry.generate_slug()
|
||||
assert entry.slug == u"beware-i-exist-test"
|
||||
|
||||
_real_test()
|
||||
|
||||
def test_existing_slug_cant_use_id_extra_junk(self, test_app):
|
||||
self._setup()
|
||||
|
||||
# Getting tired of dealing with test_app and this mock.patch
|
||||
# thing conflicting, getting lazy.
|
||||
@mock.patch('uuid.uuid4', UUID_MOCK)
|
||||
def test_existing_slug_cant_use_id_extra_junk(self):
|
||||
def _real_test():
|
||||
# This one grabs the nine thousand slug
|
||||
self._insert_media_entry_fixture(
|
||||
slug=u"beware-i-exist-9000")
|
||||
@ -106,7 +124,9 @@ class TestMediaEntrySlugs(object):
|
||||
entry.generate_slug()
|
||||
assert entry.slug == u"beware-i-exist-testtest"
|
||||
|
||||
def test_garbage_slug(self):
|
||||
_real_test()
|
||||
|
||||
def test_garbage_slug(self, test_app):
|
||||
"""
|
||||
Titles that sound totally like Q*Bert shouldn't have slugs at
|
||||
all. We'll just reference them by id.
|
||||
@ -126,14 +146,15 @@ class TestMediaEntrySlugs(object):
|
||||
| |#| |#| |#| |#|
|
||||
\|/ \|/ \|/ \|/
|
||||
"""
|
||||
self._setup()
|
||||
|
||||
qbert_entry = self._insert_media_entry_fixture(
|
||||
u"@!#?@!", save=False)
|
||||
qbert_entry.generate_slug()
|
||||
assert qbert_entry.slug is None
|
||||
|
||||
|
||||
def test_media_data_init():
|
||||
get_app() # gotta init the db and etc
|
||||
def test_media_data_init(test_app):
|
||||
Session.rollback()
|
||||
Session.remove()
|
||||
media = MediaEntry()
|
||||
|
@ -21,15 +21,14 @@ from urlparse import parse_qs, urlparse
|
||||
|
||||
from mediagoblin import mg_globals
|
||||
from mediagoblin.tools import template, pluginapi
|
||||
from mediagoblin.tests.tools import get_app, fixture_add_user
|
||||
from mediagoblin.tests.tools import fixture_add_user
|
||||
|
||||
|
||||
_log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TestOAuth(object):
|
||||
def setup(self):
|
||||
self.app = get_app()
|
||||
def _setup(self, test_app):
|
||||
self.db = mg_globals.database
|
||||
|
||||
self.pman = pluginapi.PluginManager()
|
||||
@ -37,17 +36,17 @@ class TestOAuth(object):
|
||||
self.user_password = u'4cc355_70k3N'
|
||||
self.user = fixture_add_user(u'joauth', self.user_password)
|
||||
|
||||
self.login()
|
||||
self.login(test_app)
|
||||
|
||||
def login(self):
|
||||
self.app.post(
|
||||
def login(self, test_app):
|
||||
test_app.post(
|
||||
'/auth/login/', {
|
||||
'username': self.user.username,
|
||||
'password': self.user_password})
|
||||
|
||||
def register_client(self, name, client_type, description=None,
|
||||
def register_client(self, test_app, name, client_type, description=None,
|
||||
redirect_uri=''):
|
||||
return self.app.post(
|
||||
return test_app.post(
|
||||
'/oauth/client/register', {
|
||||
'name': name,
|
||||
'description': description,
|
||||
@ -57,9 +56,11 @@ class TestOAuth(object):
|
||||
def get_context(self, template_name):
|
||||
return template.TEMPLATE_TEST_CONTEXT[template_name]
|
||||
|
||||
def test_1_public_client_registration_without_redirect_uri(self):
|
||||
def test_1_public_client_registration_without_redirect_uri(self, test_app):
|
||||
''' Test 'public' OAuth client registration without any redirect uri '''
|
||||
response = self.register_client(u'OMGOMGOMG', 'public',
|
||||
self._setup(test_app)
|
||||
|
||||
response = self.register_client(test_app, u'OMGOMGOMG', 'public',
|
||||
'OMGOMG Apache License v2')
|
||||
|
||||
ctx = self.get_context('oauth/client/register.html')
|
||||
@ -75,10 +76,10 @@ class TestOAuth(object):
|
||||
# Should not pass through
|
||||
assert not client
|
||||
|
||||
def test_2_successful_public_client_registration(self):
|
||||
def test_2_successful_public_client_registration(self, test_app):
|
||||
''' Successfully register a public client '''
|
||||
self.login()
|
||||
self.register_client(u'OMGOMG', 'public', 'OMG!',
|
||||
self._setup(test_app)
|
||||
self.register_client(test_app, u'OMGOMG', 'public', 'OMG!',
|
||||
'http://foo.example')
|
||||
|
||||
client = self.db.OAuthClient.query.filter(
|
||||
@ -87,9 +88,12 @@ class TestOAuth(object):
|
||||
# Client should have been registered
|
||||
assert client
|
||||
|
||||
def test_3_successful_confidential_client_reg(self):
|
||||
def test_3_successful_confidential_client_reg(self, test_app):
|
||||
''' Register a confidential OAuth client '''
|
||||
response = self.register_client(u'GMOGMO', 'confidential', 'NO GMO!')
|
||||
self._setup(test_app)
|
||||
|
||||
response = self.register_client(
|
||||
test_app, u'GMOGMO', 'confidential', 'NO GMO!')
|
||||
|
||||
assert response.status_int == 302
|
||||
|
||||
@ -101,15 +105,16 @@ class TestOAuth(object):
|
||||
|
||||
return client
|
||||
|
||||
def test_4_authorize_confidential_client(self):
|
||||
def test_4_authorize_confidential_client(self, test_app):
|
||||
''' Authorize a confidential client as a logged in user '''
|
||||
self._setup(test_app)
|
||||
|
||||
client = self.test_3_successful_confidential_client_reg()
|
||||
client = self.test_3_successful_confidential_client_reg(test_app)
|
||||
|
||||
client_identifier = client.identifier
|
||||
|
||||
redirect_uri = 'https://foo.example'
|
||||
response = self.app.get('/oauth/authorize', {
|
||||
response = test_app.get('/oauth/authorize', {
|
||||
'client_id': client.identifier,
|
||||
'scope': 'admin',
|
||||
'redirect_uri': redirect_uri})
|
||||
@ -122,7 +127,7 @@ class TestOAuth(object):
|
||||
form = ctx['form']
|
||||
|
||||
# Short for client authorization post reponse
|
||||
capr = self.app.post(
|
||||
capr = test_app.post(
|
||||
'/oauth/client/authorize', {
|
||||
'client_id': form.client_id.data,
|
||||
'allow': 'Allow',
|
||||
@ -139,16 +144,19 @@ class TestOAuth(object):
|
||||
def get_code_from_redirect_uri(self, uri):
|
||||
return parse_qs(urlparse(uri).query)['code'][0]
|
||||
|
||||
def test_token_endpoint_successful_confidential_request(self):
|
||||
def test_token_endpoint_successful_confidential_request(self, test_app):
|
||||
''' Successful request against token endpoint '''
|
||||
code_redirect, client_id = self.test_4_authorize_confidential_client()
|
||||
self._setup(test_app)
|
||||
|
||||
code_redirect, client_id = self.test_4_authorize_confidential_client(
|
||||
test_app)
|
||||
|
||||
code = self.get_code_from_redirect_uri(code_redirect.location)
|
||||
|
||||
client = self.db.OAuthClient.query.filter(
|
||||
self.db.OAuthClient.identifier == unicode(client_id)).first()
|
||||
|
||||
token_res = self.app.get('/oauth/access_token?client_id={0}&\
|
||||
token_res = test_app.get('/oauth/access_token?client_id={0}&\
|
||||
code={1}&client_secret={2}'.format(client_id, code, client.secret))
|
||||
|
||||
assert token_res.status_int == 200
|
||||
@ -162,16 +170,19 @@ code={1}&client_secret={2}'.format(client_id, code, client.secret))
|
||||
assert type(token_data['expires_in']) == int
|
||||
assert token_data['expires_in'] > 0
|
||||
|
||||
def test_token_endpont_missing_id_confidential_request(self):
|
||||
def test_token_endpont_missing_id_confidential_request(self, test_app):
|
||||
''' Unsuccessful request against token endpoint, missing client_id '''
|
||||
code_redirect, client_id = self.test_4_authorize_confidential_client()
|
||||
self._setup(test_app)
|
||||
|
||||
code_redirect, client_id = self.test_4_authorize_confidential_client(
|
||||
test_app)
|
||||
|
||||
code = self.get_code_from_redirect_uri(code_redirect.location)
|
||||
|
||||
client = self.db.OAuthClient.query.filter(
|
||||
self.db.OAuthClient.identifier == unicode(client_id)).first()
|
||||
|
||||
token_res = self.app.get('/oauth/access_token?\
|
||||
token_res = test_app.get('/oauth/access_token?\
|
||||
code={0}&client_secret={1}'.format(code, client.secret))
|
||||
|
||||
assert token_res.status_int == 200
|
||||
|
@ -10,7 +10,7 @@ use = egg:Paste#urlmap
|
||||
[app:mediagoblin]
|
||||
use = egg:mediagoblin#app
|
||||
filter-with = beaker
|
||||
config = %(here)s/test_mgoblin_app.ini
|
||||
config = %(here)s/mediagoblin.ini
|
||||
|
||||
[app:publicstore_serve]
|
||||
use = egg:Paste#static
|
||||
|
@ -24,8 +24,7 @@ import os
|
||||
from nose.tools import assert_equal, assert_true
|
||||
from pkg_resources import resource_filename
|
||||
|
||||
from mediagoblin.tests.tools import get_app, \
|
||||
fixture_add_user
|
||||
from mediagoblin.tests.tools import fixture_add_user
|
||||
from mediagoblin import mg_globals
|
||||
from mediagoblin.db.models import MediaEntry
|
||||
from mediagoblin.tools import template
|
||||
@ -51,8 +50,8 @@ REQUEST_CONTEXT = ['mediagoblin/user_pages/user.html', 'request']
|
||||
|
||||
|
||||
class TestSubmission:
|
||||
def setup(self):
|
||||
self.test_app = get_app(dump_old_app=False)
|
||||
def _setup(self, test_app):
|
||||
self.test_app = test_app
|
||||
|
||||
# TODO: Possibly abstract into a decorator like:
|
||||
# @as_authenticated_user('chris')
|
||||
@ -90,7 +89,9 @@ class TestSubmission:
|
||||
comments = request.db.MediaComment.find({'media_entry': media_id})
|
||||
assert_equal(count, len(list(comments)))
|
||||
|
||||
def test_missing_fields(self):
|
||||
def test_missing_fields(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
# Test blank form
|
||||
# ---------------
|
||||
response, form = self.do_post({}, *FORM_CONTEXT)
|
||||
@ -117,10 +118,12 @@ class TestSubmission:
|
||||
self.logout()
|
||||
self.test_app.get(url)
|
||||
|
||||
def test_normal_jpg(self):
|
||||
def test_normal_jpg(self, test_app):
|
||||
self._setup(test_app)
|
||||
self.check_normal_upload(u'Normal upload 1', GOOD_JPG)
|
||||
|
||||
def test_normal_png(self):
|
||||
def test_normal_png(self, test_app):
|
||||
self._setup(test_app)
|
||||
self.check_normal_upload(u'Normal upload 2', GOOD_PNG)
|
||||
|
||||
def check_media(self, request, find_data, count=None):
|
||||
@ -131,7 +134,9 @@ class TestSubmission:
|
||||
return
|
||||
return media[0]
|
||||
|
||||
def test_tags(self):
|
||||
def test_tags(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
# Good tag string
|
||||
# --------
|
||||
response, request = self.do_post({'title': u'Balanced Goblin 2',
|
||||
@ -156,7 +161,9 @@ class TestSubmission:
|
||||
'Tags that are too long: ' \
|
||||
'ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu'])
|
||||
|
||||
def test_delete(self):
|
||||
def test_delete(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
response, request = self.do_post({'title': u'Balanced Goblin'},
|
||||
*REQUEST_CONTEXT, do_follow=True,
|
||||
**self.upload_data(GOOD_JPG))
|
||||
@ -201,7 +208,9 @@ class TestSubmission:
|
||||
self.check_media(request, {'id': media_id}, 0)
|
||||
self.check_comments(request, media_id, 0)
|
||||
|
||||
def test_evil_file(self):
|
||||
def test_evil_file(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
# Test non-suppoerted file with non-supported extension
|
||||
# -----------------------------------------------------
|
||||
response, form = self.do_post({'title': u'Malicious Upload 1'},
|
||||
@ -212,9 +221,11 @@ class TestSubmission:
|
||||
str(form.file.errors[0])
|
||||
|
||||
|
||||
def test_get_media_manager(self):
|
||||
def test_get_media_manager(self, test_app):
|
||||
"""Test if the get_media_manger function returns sensible things
|
||||
"""
|
||||
self._setup(test_app)
|
||||
|
||||
response, request = self.do_post({'title': u'Balanced Goblin'},
|
||||
*REQUEST_CONTEXT, do_follow=True,
|
||||
**self.upload_data(GOOD_JPG))
|
||||
@ -224,10 +235,12 @@ class TestSubmission:
|
||||
assert_equal(media.media_manager, img_MEDIA_MANAGER)
|
||||
|
||||
|
||||
def test_sniffing(self):
|
||||
def test_sniffing(self, test_app):
|
||||
'''
|
||||
Test sniffing mechanism to assert that regular uploads work as intended
|
||||
'''
|
||||
self._setup(test_app)
|
||||
|
||||
template.clear_test_template_context()
|
||||
response = self.test_app.post(
|
||||
'/submit/', {
|
||||
@ -257,22 +270,33 @@ class TestSubmission:
|
||||
assert_equal(entry.state, 'failed')
|
||||
assert_equal(entry.fail_error, u'mediagoblin.processing:BadMediaFail')
|
||||
|
||||
def test_evil_jpg(self):
|
||||
def test_evil_jpg(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
# Test non-supported file with .jpg extension
|
||||
# -------------------------------------------
|
||||
self.check_false_image(u'Malicious Upload 2', EVIL_JPG)
|
||||
|
||||
def test_evil_png(self):
|
||||
def test_evil_png(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
# Test non-supported file with .png extension
|
||||
# -------------------------------------------
|
||||
self.check_false_image(u'Malicious Upload 3', EVIL_PNG)
|
||||
|
||||
def test_media_data(self):
|
||||
def test_media_data(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
self.check_normal_upload(u"With GPS data", GPS_JPG)
|
||||
media = self.check_media(None, {"title": u"With GPS data"}, 1)
|
||||
assert_equal(media.media_data.gps_latitude, 59.336666666666666)
|
||||
|
||||
def test_processing(self):
|
||||
def test_processing(self, test_app):
|
||||
self._setup(test_app)
|
||||
|
||||
public_store_dir = mg_globals.global_config[
|
||||
'storage:publicstore']['base_dir']
|
||||
|
||||
data = {'title': u'Big Blue'}
|
||||
response, request = self.do_post(data, *REQUEST_CONTEXT, do_follow=True,
|
||||
**self.upload_data(BIG_BLUE))
|
||||
@ -282,10 +306,9 @@ class TestSubmission:
|
||||
('medium', 'bigblue.medium.png'),
|
||||
('thumb', 'bigblue.thumbnail.png')):
|
||||
# Does the processed image have a good filename?
|
||||
filename = resource_filename(
|
||||
'mediagoblin.tests',
|
||||
os.path.join('test_user_dev/media/public',
|
||||
*media.media_files.get(key, [])))
|
||||
filename = os.path.join(
|
||||
public_store_dir,
|
||||
*media.media_files.get(key, []))
|
||||
assert_true(filename.endswith('_' + basename))
|
||||
# Is it smaller than the last processed image we looked at?
|
||||
size = os.stat(filename).st_size
|
||||
|
@ -14,17 +14,15 @@
|
||||
# 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/>.
|
||||
|
||||
from mediagoblin.tests.tools import get_app
|
||||
from mediagoblin.tools import text
|
||||
|
||||
def test_list_of_dicts_conversion():
|
||||
def test_list_of_dicts_conversion(test_app):
|
||||
"""
|
||||
When the user adds tags to a media entry, the string from the form is
|
||||
converted into a list of tags, where each tag is stored in the database
|
||||
as a dict. Each tag dict should contain the tag's name and slug. Another
|
||||
function performs the reverse operation when populating a form to edit tags.
|
||||
"""
|
||||
test_app = get_app(dump_old_app=False)
|
||||
# Leading, trailing, and internal whitespace should be removed and slugified
|
||||
assert text.convert_to_tag_list_of_dicts('sleep , 6 AM, chainsaw! ') == [
|
||||
{'name': u'sleep', 'slug': u'sleep'},
|
||||
|
@ -1,36 +0,0 @@
|
||||
# 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/>.
|
||||
|
||||
from mediagoblin import mg_globals
|
||||
from mediagoblin.tests.tools import get_app, fixture_add_user
|
||||
from mediagoblin.db.models import User
|
||||
|
||||
|
||||
def test_get_app_wipes_db():
|
||||
"""
|
||||
Make sure we get a fresh database on every wipe :)
|
||||
"""
|
||||
get_app(dump_old_app=True)
|
||||
assert User.query.count() == 0
|
||||
|
||||
fixture_add_user()
|
||||
assert User.query.count() == 1
|
||||
|
||||
get_app(dump_old_app=False)
|
||||
assert User.query.count() == 1
|
||||
|
||||
get_app(dump_old_app=True)
|
||||
assert User.query.count() == 0
|
@ -43,7 +43,7 @@ TEST_APP_CONFIG = pkg_resources.resource_filename(
|
||||
'mediagoblin.tests', 'test_mgoblin_app.ini')
|
||||
TEST_USER_DEV = pkg_resources.resource_filename(
|
||||
'mediagoblin.tests', 'test_user_dev')
|
||||
MGOBLIN_APP = None
|
||||
|
||||
|
||||
USER_DEV_DIRECTORIES_TO_SETUP = [
|
||||
'media/public', 'media/queue',
|
||||
@ -103,7 +103,30 @@ def suicide_if_bad_celery_environ():
|
||||
raise BadCeleryEnviron(BAD_CELERY_MESSAGE)
|
||||
|
||||
|
||||
def get_app(dump_old_app=True):
|
||||
def get_app(request, paste_config=None, mgoblin_config=None):
|
||||
"""Create a MediaGoblin app for testing.
|
||||
|
||||
Args:
|
||||
- request: Not an http request, but a pytest fixture request. We
|
||||
use this to make temporary directories that pytest
|
||||
automatically cleans up as needed.
|
||||
- paste_config: particular paste config used by this application.
|
||||
- mgoblin_config: particular mediagoblin config used by this
|
||||
application.
|
||||
"""
|
||||
paste_config = paste_config or TEST_SERVER_CONFIG
|
||||
mgoblin_config = mgoblin_config or TEST_APP_CONFIG
|
||||
|
||||
# This is the directory we're copying the paste/mgoblin config stuff into
|
||||
run_dir = request.config._tmpdirhandler.mktemp(
|
||||
'mgoblin_app', numbered=True)
|
||||
user_dev_dir = run_dir.mkdir('test_user_dev').strpath
|
||||
|
||||
new_paste_config = run_dir.join('paste.ini').strpath
|
||||
new_mgoblin_config = run_dir.join('mediagoblin.ini').strpath
|
||||
shutil.copyfile(paste_config, new_paste_config)
|
||||
shutil.copyfile(mgoblin_config, new_mgoblin_config)
|
||||
|
||||
suicide_if_bad_celery_environ()
|
||||
|
||||
# Make sure we've turned on testing
|
||||
@ -112,26 +135,16 @@ def get_app(dump_old_app=True):
|
||||
# Leave this imported as it sets up celery.
|
||||
from mediagoblin.init.celery import from_tests
|
||||
|
||||
global MGOBLIN_APP
|
||||
|
||||
# Just return the old app if that exists and it's okay to set up
|
||||
# and return
|
||||
if MGOBLIN_APP and not dump_old_app:
|
||||
return MGOBLIN_APP
|
||||
|
||||
Session.rollback()
|
||||
Session.remove()
|
||||
|
||||
# Remove and reinstall user_dev directories
|
||||
if os.path.exists(TEST_USER_DEV):
|
||||
shutil.rmtree(TEST_USER_DEV)
|
||||
|
||||
# install user_dev directories
|
||||
for directory in USER_DEV_DIRECTORIES_TO_SETUP:
|
||||
full_dir = os.path.join(TEST_USER_DEV, directory)
|
||||
full_dir = os.path.join(user_dev_dir, directory)
|
||||
os.makedirs(full_dir)
|
||||
|
||||
# Get app config
|
||||
global_config, validation_result = read_mediagoblin_config(TEST_APP_CONFIG)
|
||||
global_config, validation_result = read_mediagoblin_config(new_mgoblin_config)
|
||||
app_config = global_config['mediagoblin']
|
||||
|
||||
# Run database setup/migrations
|
||||
@ -139,7 +152,7 @@ def get_app(dump_old_app=True):
|
||||
|
||||
# setup app and return
|
||||
test_app = loadapp(
|
||||
'config:' + TEST_SERVER_CONFIG)
|
||||
'config:' + new_paste_config)
|
||||
|
||||
# Re-setup celery
|
||||
setup_celery_app(app_config, global_config)
|
||||
@ -151,26 +164,10 @@ def get_app(dump_old_app=True):
|
||||
mg_globals.app.meddleware.insert(0, TestingMeddleware(mg_globals.app))
|
||||
|
||||
app = TestApp(test_app)
|
||||
MGOBLIN_APP = app
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def setup_fresh_app(func):
|
||||
"""
|
||||
Decorator to setup a fresh test application for this function.
|
||||
|
||||
Cleans out test buckets and passes in a new, fresh test_app.
|
||||
"""
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
test_app = get_app()
|
||||
testing.clear_test_buckets()
|
||||
return func(test_app, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def install_fixtures_simple(db, fixtures):
|
||||
"""
|
||||
Very simply install fixtures in the database
|
||||
|
Loading…
x
Reference in New Issue
Block a user