Merge branch '614_multi_test_config'

This commit is contained in:
Christopher Allan Webber 2013-04-04 19:44:36 -05:00
commit fe6755f0f4
18 changed files with 247 additions and 224 deletions

View 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)

View File

@ -0,0 +1,2 @@
[pytest]
usefixtures = tmpdir

View File

@ -20,9 +20,11 @@ import base64
from pkg_resources import resource_filename from pkg_resources import resource_filename
import pytest
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.tools import template, pluginapi 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__) _log = logging.getLogger(__name__)
@ -42,16 +44,16 @@ EVIL_PNG = resource('evil.png')
BIG_BLUE = resource('bigblue.png') BIG_BLUE = resource('bigblue.png')
@pytest.mark.usefixtures("test_app")
class TestAPI(object): class TestAPI(object):
def setup(self): def setup(self):
self.app = get_app(dump_old_app=False)
self.db = mg_globals.database self.db = mg_globals.database
self.user_password = u'4cc355_70k3N' self.user_password = u'4cc355_70k3N'
self.user = fixture_add_user(u'joapi', self.user_password) self.user = fixture_add_user(u'joapi', self.user_password)
def login(self): def login(self, test_app):
self.app.post( test_app.post(
'/auth/login/', { '/auth/login/', {
'username': self.user.username, 'username': self.user.username,
'password': self.user_password}) 'password': self.user_password})
@ -65,14 +67,14 @@ class TestAPI(object):
self.user.username, self.user.username,
self.user_password])))} self.user_password])))}
def do_post(self, data, **kwargs): def do_post(self, data, test_app, **kwargs):
url = kwargs.pop('url', '/api/submit') url = kwargs.pop('url', '/api/submit')
do_follow = kwargs.pop('do_follow', False) do_follow = kwargs.pop('do_follow', False)
if not 'headers' in kwargs.keys(): if not 'headers' in kwargs.keys():
kwargs['headers'] = self.http_auth_headers() kwargs['headers'] = self.http_auth_headers()
response = self.app.post(url, data, **kwargs) response = test_app.post(url, data, **kwargs)
if do_follow: if do_follow:
response.follow() response.follow()
@ -82,21 +84,22 @@ class TestAPI(object):
def upload_data(self, filename): def upload_data(self, filename):
return {'upload_files': [('file', filename)]} return {'upload_files': [('file', filename)]}
def test_1_test_test_view(self): def test_1_test_test_view(self, test_app):
self.login() self.login(test_app)
response = self.app.get( response = test_app.get(
'/api/test', '/api/test',
headers=self.http_auth_headers()) headers=self.http_auth_headers())
assert response.body == \ assert response.body == \
'{"username": "joapi", "email": "joapi@example.com"}' '{"username": "joapi", "email": "joapi@example.com"}'
def test_2_test_submission(self): def test_2_test_submission(self, test_app):
self.login() self.login(test_app)
response = self.do_post( response = self.do_post(
{'title': 'Great JPG!'}, {'title': 'Great JPG!'},
test_app,
**self.upload_data(GOOD_JPG)) **self.upload_data(GOOD_JPG))
assert response.status_int == 200 assert response.status_int == 200

View File

@ -22,7 +22,7 @@ from nose.tools import assert_equal
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.auth import lib as auth_lib from mediagoblin.auth import lib as auth_lib
from mediagoblin.db.models import User 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 from mediagoblin.tools import template, mail
@ -65,7 +65,6 @@ def test_bcrypt_gen_password_hash():
'notthepassword', hashed_pw, '3><7R45417') 'notthepassword', hashed_pw, '3><7R45417')
@setup_fresh_app
def test_register_views(test_app): def test_register_views(test_app):
""" """
Massive test function that all our registration-related views all work. 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 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 logging in and logging out
""" """
test_app = get_app(dump_old_app=False)
# Make a new user # Make a new user
test_user = fixture_add_user(active_user=False) test_user = fixture_add_user(active_user=False)

View File

@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # 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 from mediagoblin import mg_globals
@ -37,7 +36,6 @@ def _get_some_data(key):
return value return value
@setup_fresh_app
def test_cache_working(test_app): def test_cache_working(test_app):
some_data_cache = mg_globals.cache.get_cache('sum_data') some_data_cache = mg_globals.cache.get_cache('sum_data')
assert not some_data_cache.has_key('herp') assert not some_data_cache.has_key('herp')

View File

@ -14,17 +14,13 @@
# 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/>.
from mediagoblin.tests.tools import fixture_add_collection, fixture_add_user, \ from mediagoblin.tests.tools import fixture_add_collection, fixture_add_user
get_app
from mediagoblin.db.models import Collection, User from mediagoblin.db.models import Collection, User
from mediagoblin.db.base import Session
from nose.tools import assert_equal from nose.tools import assert_equal
def test_user_deletes_collection(): def test_user_deletes_collection(test_app):
# Setup db. # Setup db.
get_app(dump_old_app=False)
user = fixture_add_user() user = fixture_add_user()
coll = fixture_add_collection(user=user) coll = fixture_add_collection(user=user)
# Reload into session: # Reload into session:

View File

@ -14,12 +14,10 @@
# 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/>.
from mediagoblin.tests.tools import get_app
from mediagoblin import mg_globals from mediagoblin import mg_globals
def test_csrf_cookie_set(): def test_csrf_cookie_set(test_app):
test_app = get_app(dump_old_app=False)
cookie_name = mg_globals.app_config['csrf_cookie_name'] cookie_name = mg_globals.app_config['csrf_cookie_name']
# get login page # get login page
@ -33,11 +31,14 @@ def test_csrf_cookie_set():
assert response.headers.get('Vary', False) == 'Cookie' 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 need a fresh app for this test on webtest < 1.3.6. # We do not understand why, but it fixes the tests.
# 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.
# 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 # construct a request with no cookie or form token
assert test_app.post('/auth/login/', assert test_app.post('/auth/login/',
@ -67,8 +68,7 @@ def test_csrf_token_must_match():
extra_environ={'gmg.verify_csrf': True}).\ extra_environ={'gmg.verify_csrf': True}).\
status_int == 200 status_int == 200
def test_csrf_exempt(): def test_csrf_exempt(test_app):
test_app = get_app(dump_old_app=False)
# monkey with the views to decorate a known endpoint # monkey with the views to decorate a known endpoint
import mediagoblin.auth.views import mediagoblin.auth.views
from mediagoblin.meddleware.csrf import csrf_exempt from mediagoblin.meddleware.csrf import csrf_exempt

View File

@ -18,31 +18,31 @@ from nose.tools import assert_equal
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.db.models import User 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.tools import template
from mediagoblin.auth.lib import bcrypt_check_password from mediagoblin.auth.lib import bcrypt_check_password
class TestUserEdit(object): class TestUserEdit(object):
def setup(self): def setup(self):
self.app = get_app(dump_old_app=False)
# set up new user # set up new user
self.user_password = u'toast' self.user_password = u'toast'
self.user = fixture_add_user(password = self.user_password) self.user = fixture_add_user(password = self.user_password)
self.login()
def login(self): def login(self, test_app):
self.app.post( test_app.post(
'/auth/login/', { '/auth/login/', {
'username': self.user.username, 'username': self.user.username,
'password': self.user_password}) 'password': self.user_password})
def test_user_deletion(self): def test_user_deletion(self, test_app):
"""Delete user via web interface""" """Delete user via web interface"""
self.login(test_app)
# Make sure user exists # Make sure user exists
assert User.query.filter_by(username=u'chris').first() 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 # Make sure user has been deleted
assert User.query.filter_by(username=u'chris').first() == None assert User.query.filter_by(username=u'chris').first() == None
@ -52,14 +52,16 @@ class TestUserEdit(object):
#Restore user at end of test #Restore user at end of test
self.user = fixture_add_user(password = self.user_password) 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""" """Test changing password correctly and incorrectly"""
self.login(test_app)
# test that the password can be changed # test that the password can be changed
# template.clear_test_template_context() # template.clear_test_template_context()
res = self.app.post( res = test_app.post(
'/edit/account/', { '/edit/account/', {
'old_password': 'toast', 'old_password': 'toast',
'new_password': '123456', 'new_password': '123456',
@ -76,7 +78,7 @@ class TestUserEdit(object):
# test that the password cannot be changed if the given # test that the password cannot be changed if the given
# old_password is wrong template.clear_test_template_context() # old_password is wrong template.clear_test_template_context()
self.app.post( test_app.post(
'/edit/account/', { '/edit/account/', {
'old_password': 'toast', 'old_password': 'toast',
'new_password': '098765', 'new_password': '098765',
@ -86,11 +88,12 @@ class TestUserEdit(object):
assert not bcrypt_check_password('098765', test_user.pw_hash) assert not bcrypt_check_password('098765', test_user.pw_hash)
def test_change_bio_url(self, test_app):
def test_change_bio_url(self):
"""Test changing bio and URL""" """Test changing bio and URL"""
self.login(test_app)
# Test if legacy profile editing URL redirects correctly # Test if legacy profile editing URL redirects correctly
res = self.app.post( res = test_app.post(
'/edit/profile/', { '/edit/profile/', {
'bio': u'I love toast!', 'bio': u'I love toast!',
'url': u'http://dustycloud.org/'}, expect_errors=True) 'url': u'http://dustycloud.org/'}, expect_errors=True)
@ -99,7 +102,7 @@ class TestUserEdit(object):
assert_equal (res.status_int, 302) assert_equal (res.status_int, 302)
assert res.headers['Location'].endswith("/u/chris/edit/") assert res.headers['Location'].endswith("/u/chris/edit/")
res = self.app.post( res = test_app.post(
'/u/chris/edit/', { '/u/chris/edit/', {
'bio': u'I love toast!', 'bio': u'I love toast!',
'url': u'http://dustycloud.org/'}) 'url': u'http://dustycloud.org/'})
@ -110,7 +113,7 @@ class TestUserEdit(object):
# change a different user than the logged in (should fail with 403) # change a different user than the logged in (should fail with 403)
fixture_add_user(username=u"foo") fixture_add_user(username=u"foo")
res = self.app.post( res = test_app.post(
'/u/foo/edit/', { '/u/foo/edit/', {
'bio': u'I love toast!', 'bio': u'I love toast!',
'url': u'http://dustycloud.org/'}, expect_errors=True) 'url': u'http://dustycloud.org/'}, expect_errors=True)
@ -119,7 +122,7 @@ class TestUserEdit(object):
# test changing the bio and the URL inproperly # test changing the bio and the URL inproperly
too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't' too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't'
self.app.post( test_app.post(
'/u/chris/edit/', { '/u/chris/edit/', {
# more than 500 characters # more than 500 characters
'bio': too_long_bio, 'bio': too_long_bio,

View File

@ -20,28 +20,27 @@ from urlparse import urlparse, parse_qs
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.tools import processing 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.test_submission import GOOD_PNG
from mediagoblin.tests import test_oauth as oauth from mediagoblin.tests import test_oauth as oauth
class TestHTTPCallback(object): class TestHTTPCallback(object):
def setup(self): def _setup(self, test_app):
self.app = get_app(dump_old_app=False)
self.db = mg_globals.database self.db = mg_globals.database
self.user_password = u'secret' self.user_password = u'secret'
self.user = fixture_add_user(u'call_back', self.user_password) self.user = fixture_add_user(u'call_back', self.user_password)
self.login() self.login(test_app)
def login(self): def login(self, testapp):
self.app.post('/auth/login/', { testapp.post('/auth/login/', {
'username': self.user.username, 'username': self.user.username,
'password': self.user_password}) 'password': self.user_password})
def get_access_token(self, client_id, client_secret, code): def get_access_token(self, testapp, client_id, client_secret, code):
response = self.app.get('/oauth/access_token', { response = testapp.get('/oauth/access_token', {
'code': code, 'code': code,
'client_id': client_id, 'client_id': client_id,
'client_secret': client_secret}) 'client_secret': client_secret})
@ -50,13 +49,15 @@ class TestHTTPCallback(object):
return response_data['access_token'] return response_data['access_token']
def test_callback(self): def test_callback(self, test_app):
''' Test processing HTTP callback ''' ''' Test processing HTTP callback '''
self._setup(test_app)
self.oauth = oauth.TestOAuth() 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] code = parse_qs(urlparse(redirect.location).query)['code'][0]
@ -65,11 +66,11 @@ class TestHTTPCallback(object):
client_secret = client.secret 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' 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_secret={2}'.format(
client_id, client_id,
access_token, access_token,

View File

@ -15,18 +15,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from mediagoblin.messages import fetch_messages, add_message from mediagoblin.messages import fetch_messages, add_message
from mediagoblin.tests.tools import get_app
from mediagoblin.tools import template from mediagoblin.tools import template
def test_messages(test_app):
def test_messages():
""" """
Added messages should show up in the request.session, Added messages should show up in the request.session,
fetched messages should be the same as the added ones, fetched messages should be the same as the added ones,
and fetching should clear the message list. and fetching should clear the message list.
""" """
test_app = get_app(dump_old_app=False)
# Aquire a request object # Aquire a request object
test_app.get('/') test_app.get('/')
context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html'] context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html']

View File

@ -18,18 +18,15 @@ from nose.tools import assert_equal
from mediagoblin.db.base import Session from mediagoblin.db.base import Session
from mediagoblin.db.models import User, MediaEntry, MediaComment from mediagoblin.db.models import User, MediaEntry, MediaComment
from mediagoblin.tests.tools import get_app, \ from mediagoblin.tests.tools import fixture_add_user, fixture_media_entry
fixture_add_user, fixture_media_entry
def test_404_for_non_existent(): def test_404_for_non_existent(test_app):
test_app = get_app(dump_old_app=False)
res = test_app.get('/does-not-exist/', expect_errors=True) res = test_app.get('/does-not-exist/', expect_errors=True)
assert_equal(res.status_int, 404) assert_equal(res.status_int, 404)
def test_user_deletes_other_comments(): def test_user_deletes_other_comments(test_app):
get_app() # gotta init the db and etc
user_a = fixture_add_user(u"chris_a") user_a = fixture_add_user(u"chris_a")
user_b = fixture_add_user(u"chris_b") 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) assert_equal(cmt_cnt2, cmt_cnt1 - 4)
def test_media_deletes_broken_attachment(): def test_media_deletes_broken_attachment(test_app):
get_app() # gotta init the db and etc
user_a = fixture_add_user(u"chris_a") user_a = fixture_add_user(u"chris_a")
media = fixture_media_entry(uploader=user_a.id, save=False) media = fixture_media_entry(uploader=user_a.id, save=False)

View File

@ -22,8 +22,7 @@ from nose.tools import assert_equal
from mediagoblin.db.base import Session from mediagoblin.db.base import Session
from mediagoblin.db.models import MediaEntry from mediagoblin.db.models import MediaEntry
from mediagoblin.tests.tools import get_app, \ from mediagoblin.tests.tools import fixture_add_user
fixture_add_user
import mock import mock
@ -35,8 +34,7 @@ UUID_MOCK = mock.Mock(return_value=FakeUUID())
class TestMediaEntrySlugs(object): class TestMediaEntrySlugs(object):
def setup(self): def _setup(self):
self.test_app = get_app(dump_old_app=True)
self.chris_user = fixture_add_user(u'chris') self.chris_user = fixture_add_user(u'chris')
self.emily_user = fixture_add_user(u'emily') self.emily_user = fixture_add_user(u'emily')
self.existing_entry = self._insert_media_entry_fixture( self.existing_entry = self._insert_media_entry_fixture(
@ -57,56 +55,78 @@ class TestMediaEntrySlugs(object):
return entry 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 = self._insert_media_entry_fixture(u"Totally unique slug!", save=False)
entry.generate_slug() entry.generate_slug()
assert entry.slug == u'totally-unique-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( entry = self._insert_media_entry_fixture(
u"A title here", u"a-different-slug-there", save=False) u"A title here", u"a-different-slug-there", save=False)
entry.generate_slug() entry.generate_slug()
assert entry.slug == u"a-different-slug-there" 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( entry = self._insert_media_entry_fixture(
slug=u"wowee!!!!!", save=False) slug=u"wowee!!!!!", save=False)
entry.generate_slug() entry.generate_slug()
assert entry.slug == u"wowee" 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( entry = self._insert_media_entry_fixture(
u"Beware, I exist!!", this_id=9000, save=False) u"Beware, I exist!!", this_id=9000, save=False)
entry.generate_slug() entry.generate_slug()
assert entry.slug == u"beware-i-exist-9000" assert entry.slug == u"beware-i-exist-9000"
@mock.patch('uuid.uuid4', UUID_MOCK) def test_existing_slug_cant_use_id(self, test_app):
def test_existing_slug_cant_use_id(self): self._setup()
# This one grabs the nine thousand slug
self._insert_media_entry_fixture(
slug=u"beware-i-exist-9000")
entry = self._insert_media_entry_fixture( # Getting tired of dealing with test_app and this mock.patch
u"Beware, I exist!!", this_id=9000, save=False) # thing conflicting, getting lazy.
entry.generate_slug() @mock.patch('uuid.uuid4', UUID_MOCK)
assert entry.slug == u"beware-i-exist-test" def _real_test():
# This one grabs the nine thousand slug
self._insert_media_entry_fixture(
slug=u"beware-i-exist-9000")
@mock.patch('uuid.uuid4', UUID_MOCK) entry = self._insert_media_entry_fixture(
def test_existing_slug_cant_use_id_extra_junk(self): u"Beware, I exist!!", this_id=9000, save=False)
# This one grabs the nine thousand slug entry.generate_slug()
self._insert_media_entry_fixture( assert entry.slug == u"beware-i-exist-test"
slug=u"beware-i-exist-9000")
_real_test()
# This one grabs makes sure the annoyance doesn't stop def test_existing_slug_cant_use_id_extra_junk(self, test_app):
self._insert_media_entry_fixture( self._setup()
slug=u"beware-i-exist-test")
entry = self._insert_media_entry_fixture( # Getting tired of dealing with test_app and this mock.patch
u"Beware, I exist!!", this_id=9000, save=False) # thing conflicting, getting lazy.
entry.generate_slug() @mock.patch('uuid.uuid4', UUID_MOCK)
assert entry.slug == u"beware-i-exist-testtest" def _real_test():
# This one grabs the nine thousand slug
self._insert_media_entry_fixture(
slug=u"beware-i-exist-9000")
def test_garbage_slug(self): # This one grabs makes sure the annoyance doesn't stop
self._insert_media_entry_fixture(
slug=u"beware-i-exist-test")
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-testtest"
_real_test()
def test_garbage_slug(self, test_app):
""" """
Titles that sound totally like Q*Bert shouldn't have slugs at Titles that sound totally like Q*Bert shouldn't have slugs at
all. We'll just reference them by id. all. We'll just reference them by id.
@ -126,14 +146,15 @@ class TestMediaEntrySlugs(object):
| |#| |#| |#| |#| | |#| |#| |#| |#|
\|/ \|/ \|/ \|/ \|/ \|/ \|/ \|/
""" """
self._setup()
qbert_entry = self._insert_media_entry_fixture( qbert_entry = self._insert_media_entry_fixture(
u"@!#?@!", save=False) u"@!#?@!", save=False)
qbert_entry.generate_slug() qbert_entry.generate_slug()
assert qbert_entry.slug is None assert qbert_entry.slug is None
def test_media_data_init(): def test_media_data_init(test_app):
get_app() # gotta init the db and etc
Session.rollback() Session.rollback()
Session.remove() Session.remove()
media = MediaEntry() media = MediaEntry()

View File

@ -21,15 +21,14 @@ from urlparse import parse_qs, urlparse
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.tools import template, pluginapi 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__) _log = logging.getLogger(__name__)
class TestOAuth(object): class TestOAuth(object):
def setup(self): def _setup(self, test_app):
self.app = get_app()
self.db = mg_globals.database self.db = mg_globals.database
self.pman = pluginapi.PluginManager() self.pman = pluginapi.PluginManager()
@ -37,17 +36,17 @@ class TestOAuth(object):
self.user_password = u'4cc355_70k3N' self.user_password = u'4cc355_70k3N'
self.user = fixture_add_user(u'joauth', self.user_password) self.user = fixture_add_user(u'joauth', self.user_password)
self.login() self.login(test_app)
def login(self): def login(self, test_app):
self.app.post( test_app.post(
'/auth/login/', { '/auth/login/', {
'username': self.user.username, 'username': self.user.username,
'password': self.user_password}) '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=''): redirect_uri=''):
return self.app.post( return test_app.post(
'/oauth/client/register', { '/oauth/client/register', {
'name': name, 'name': name,
'description': description, 'description': description,
@ -57,9 +56,11 @@ class TestOAuth(object):
def get_context(self, template_name): def get_context(self, template_name):
return template.TEMPLATE_TEST_CONTEXT[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 ''' ''' 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') 'OMGOMG Apache License v2')
ctx = self.get_context('oauth/client/register.html') ctx = self.get_context('oauth/client/register.html')
@ -75,10 +76,10 @@ class TestOAuth(object):
# Should not pass through # Should not pass through
assert not client 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 ''' ''' Successfully register a public client '''
self.login() self._setup(test_app)
self.register_client(u'OMGOMG', 'public', 'OMG!', self.register_client(test_app, u'OMGOMG', 'public', 'OMG!',
'http://foo.example') 'http://foo.example')
client = self.db.OAuthClient.query.filter( client = self.db.OAuthClient.query.filter(
@ -87,9 +88,12 @@ class TestOAuth(object):
# Client should have been registered # Client should have been registered
assert client 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 ''' ''' 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 assert response.status_int == 302
@ -101,15 +105,16 @@ class TestOAuth(object):
return client 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 ''' ''' 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 client_identifier = client.identifier
redirect_uri = 'https://foo.example' redirect_uri = 'https://foo.example'
response = self.app.get('/oauth/authorize', { response = test_app.get('/oauth/authorize', {
'client_id': client.identifier, 'client_id': client.identifier,
'scope': 'admin', 'scope': 'admin',
'redirect_uri': redirect_uri}) 'redirect_uri': redirect_uri})
@ -122,7 +127,7 @@ class TestOAuth(object):
form = ctx['form'] form = ctx['form']
# Short for client authorization post reponse # Short for client authorization post reponse
capr = self.app.post( capr = test_app.post(
'/oauth/client/authorize', { '/oauth/client/authorize', {
'client_id': form.client_id.data, 'client_id': form.client_id.data,
'allow': 'Allow', 'allow': 'Allow',
@ -139,16 +144,19 @@ class TestOAuth(object):
def get_code_from_redirect_uri(self, uri): def get_code_from_redirect_uri(self, uri):
return parse_qs(urlparse(uri).query)['code'][0] 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 ''' ''' 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) code = self.get_code_from_redirect_uri(code_redirect.location)
client = self.db.OAuthClient.query.filter( client = self.db.OAuthClient.query.filter(
self.db.OAuthClient.identifier == unicode(client_id)).first() 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)) code={1}&client_secret={2}'.format(client_id, code, client.secret))
assert token_res.status_int == 200 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 type(token_data['expires_in']) == int
assert token_data['expires_in'] > 0 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 ''' ''' 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) code = self.get_code_from_redirect_uri(code_redirect.location)
client = self.db.OAuthClient.query.filter( client = self.db.OAuthClient.query.filter(
self.db.OAuthClient.identifier == unicode(client_id)).first() 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)) code={0}&client_secret={1}'.format(code, client.secret))
assert token_res.status_int == 200 assert token_res.status_int == 200

View File

@ -10,7 +10,7 @@ use = egg:Paste#urlmap
[app:mediagoblin] [app:mediagoblin]
use = egg:mediagoblin#app use = egg:mediagoblin#app
filter-with = beaker filter-with = beaker
config = %(here)s/test_mgoblin_app.ini config = %(here)s/mediagoblin.ini
[app:publicstore_serve] [app:publicstore_serve]
use = egg:Paste#static use = egg:Paste#static

View File

@ -24,8 +24,7 @@ import os
from nose.tools import assert_equal, assert_true from nose.tools import assert_equal, assert_true
from pkg_resources import resource_filename from pkg_resources import resource_filename
from mediagoblin.tests.tools import get_app, \ from mediagoblin.tests.tools import fixture_add_user
fixture_add_user
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.db.models import MediaEntry from mediagoblin.db.models import MediaEntry
from mediagoblin.tools import template from mediagoblin.tools import template
@ -51,8 +50,8 @@ REQUEST_CONTEXT = ['mediagoblin/user_pages/user.html', 'request']
class TestSubmission: class TestSubmission:
def setup(self): def _setup(self, test_app):
self.test_app = get_app(dump_old_app=False) self.test_app = test_app
# TODO: Possibly abstract into a decorator like: # TODO: Possibly abstract into a decorator like:
# @as_authenticated_user('chris') # @as_authenticated_user('chris')
@ -90,7 +89,9 @@ class TestSubmission:
comments = request.db.MediaComment.find({'media_entry': media_id}) comments = request.db.MediaComment.find({'media_entry': media_id})
assert_equal(count, len(list(comments))) 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 # Test blank form
# --------------- # ---------------
response, form = self.do_post({}, *FORM_CONTEXT) response, form = self.do_post({}, *FORM_CONTEXT)
@ -117,10 +118,12 @@ class TestSubmission:
self.logout() self.logout()
self.test_app.get(url) 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) 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) self.check_normal_upload(u'Normal upload 2', GOOD_PNG)
def check_media(self, request, find_data, count=None): def check_media(self, request, find_data, count=None):
@ -131,7 +134,9 @@ class TestSubmission:
return return
return media[0] return media[0]
def test_tags(self): def test_tags(self, test_app):
self._setup(test_app)
# Good tag string # Good tag string
# -------- # --------
response, request = self.do_post({'title': u'Balanced Goblin 2', response, request = self.do_post({'title': u'Balanced Goblin 2',
@ -156,7 +161,9 @@ class TestSubmission:
'Tags that are too long: ' \ 'Tags that are too long: ' \
'ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu']) 'ffffffffffffffffffffffffffuuuuuuuuuuuuuuuuuuuuuuuuuu'])
def test_delete(self): def test_delete(self, test_app):
self._setup(test_app)
response, request = self.do_post({'title': u'Balanced Goblin'}, response, request = self.do_post({'title': u'Balanced Goblin'},
*REQUEST_CONTEXT, do_follow=True, *REQUEST_CONTEXT, do_follow=True,
**self.upload_data(GOOD_JPG)) **self.upload_data(GOOD_JPG))
@ -201,7 +208,9 @@ class TestSubmission:
self.check_media(request, {'id': media_id}, 0) self.check_media(request, {'id': media_id}, 0)
self.check_comments(request, 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 # Test non-suppoerted file with non-supported extension
# ----------------------------------------------------- # -----------------------------------------------------
response, form = self.do_post({'title': u'Malicious Upload 1'}, response, form = self.do_post({'title': u'Malicious Upload 1'},
@ -212,9 +221,11 @@ class TestSubmission:
str(form.file.errors[0]) 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 """Test if the get_media_manger function returns sensible things
""" """
self._setup(test_app)
response, request = self.do_post({'title': u'Balanced Goblin'}, response, request = self.do_post({'title': u'Balanced Goblin'},
*REQUEST_CONTEXT, do_follow=True, *REQUEST_CONTEXT, do_follow=True,
**self.upload_data(GOOD_JPG)) **self.upload_data(GOOD_JPG))
@ -224,10 +235,12 @@ class TestSubmission:
assert_equal(media.media_manager, img_MEDIA_MANAGER) 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 Test sniffing mechanism to assert that regular uploads work as intended
''' '''
self._setup(test_app)
template.clear_test_template_context() template.clear_test_template_context()
response = self.test_app.post( response = self.test_app.post(
'/submit/', { '/submit/', {
@ -257,22 +270,33 @@ class TestSubmission:
assert_equal(entry.state, 'failed') assert_equal(entry.state, 'failed')
assert_equal(entry.fail_error, u'mediagoblin.processing:BadMediaFail') 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 # Test non-supported file with .jpg extension
# ------------------------------------------- # -------------------------------------------
self.check_false_image(u'Malicious Upload 2', EVIL_JPG) 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 # Test non-supported file with .png extension
# ------------------------------------------- # -------------------------------------------
self.check_false_image(u'Malicious Upload 3', EVIL_PNG) 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) self.check_normal_upload(u"With GPS data", GPS_JPG)
media = self.check_media(None, {"title": u"With GPS data"}, 1) media = self.check_media(None, {"title": u"With GPS data"}, 1)
assert_equal(media.media_data.gps_latitude, 59.336666666666666) 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'} data = {'title': u'Big Blue'}
response, request = self.do_post(data, *REQUEST_CONTEXT, do_follow=True, response, request = self.do_post(data, *REQUEST_CONTEXT, do_follow=True,
**self.upload_data(BIG_BLUE)) **self.upload_data(BIG_BLUE))
@ -282,10 +306,9 @@ class TestSubmission:
('medium', 'bigblue.medium.png'), ('medium', 'bigblue.medium.png'),
('thumb', 'bigblue.thumbnail.png')): ('thumb', 'bigblue.thumbnail.png')):
# Does the processed image have a good filename? # Does the processed image have a good filename?
filename = resource_filename( filename = os.path.join(
'mediagoblin.tests', public_store_dir,
os.path.join('test_user_dev/media/public', *media.media_files.get(key, []))
*media.media_files.get(key, [])))
assert_true(filename.endswith('_' + basename)) assert_true(filename.endswith('_' + basename))
# Is it smaller than the last processed image we looked at? # Is it smaller than the last processed image we looked at?
size = os.stat(filename).st_size size = os.stat(filename).st_size

View File

@ -14,17 +14,15 @@
# 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/>.
from mediagoblin.tests.tools import get_app
from mediagoblin.tools import text 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 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 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 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. 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 # Leading, trailing, and internal whitespace should be removed and slugified
assert text.convert_to_tag_list_of_dicts('sleep , 6 AM, chainsaw! ') == [ assert text.convert_to_tag_list_of_dicts('sleep , 6 AM, chainsaw! ') == [
{'name': u'sleep', 'slug': u'sleep'}, {'name': u'sleep', 'slug': u'sleep'},

View File

@ -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

View File

@ -43,7 +43,7 @@ TEST_APP_CONFIG = pkg_resources.resource_filename(
'mediagoblin.tests', 'test_mgoblin_app.ini') 'mediagoblin.tests', 'test_mgoblin_app.ini')
TEST_USER_DEV = pkg_resources.resource_filename( TEST_USER_DEV = pkg_resources.resource_filename(
'mediagoblin.tests', 'test_user_dev') 'mediagoblin.tests', 'test_user_dev')
MGOBLIN_APP = None
USER_DEV_DIRECTORIES_TO_SETUP = [ USER_DEV_DIRECTORIES_TO_SETUP = [
'media/public', 'media/queue', 'media/public', 'media/queue',
@ -103,7 +103,30 @@ def suicide_if_bad_celery_environ():
raise BadCeleryEnviron(BAD_CELERY_MESSAGE) 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() suicide_if_bad_celery_environ()
# Make sure we've turned on testing # 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. # Leave this imported as it sets up celery.
from mediagoblin.init.celery import from_tests 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.rollback()
Session.remove() Session.remove()
# Remove and reinstall user_dev directories # install user_dev directories
if os.path.exists(TEST_USER_DEV):
shutil.rmtree(TEST_USER_DEV)
for directory in USER_DEV_DIRECTORIES_TO_SETUP: 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) os.makedirs(full_dir)
# Get app config # 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'] app_config = global_config['mediagoblin']
# Run database setup/migrations # Run database setup/migrations
@ -139,7 +152,7 @@ def get_app(dump_old_app=True):
# setup app and return # setup app and return
test_app = loadapp( test_app = loadapp(
'config:' + TEST_SERVER_CONFIG) 'config:' + new_paste_config)
# Re-setup celery # Re-setup celery
setup_celery_app(app_config, global_config) 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)) mg_globals.app.meddleware.insert(0, TestingMeddleware(mg_globals.app))
app = TestApp(test_app) app = TestApp(test_app)
MGOBLIN_APP = app
return 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): def install_fixtures_simple(db, fixtures):
""" """
Very simply install fixtures in the database Very simply install fixtures in the database