diff options
Diffstat (limited to 'mediagoblin/tests')
-rw-r--r-- | mediagoblin/tests/__init__.py | 4 | ||||
-rw-r--r-- | mediagoblin/tests/test_api.py | 104 | ||||
-rw-r--r-- | mediagoblin/tests/test_auth.py | 31 | ||||
-rw-r--r-- | mediagoblin/tests/test_csrf_middleware.py | 25 | ||||
-rw-r--r-- | mediagoblin/tests/test_edit.py | 191 | ||||
-rw-r--r-- | mediagoblin/tests/test_exif.py | 19 | ||||
-rw-r--r-- | mediagoblin/tests/test_globals.py | 5 | ||||
-rw-r--r-- | mediagoblin/tests/test_http_callback.py | 6 | ||||
-rw-r--r-- | mediagoblin/tests/test_messages.py | 13 | ||||
-rw-r--r-- | mediagoblin/tests/test_mgoblin_app.ini | 2 | ||||
-rw-r--r-- | mediagoblin/tests/test_misc.py | 12 | ||||
-rw-r--r-- | mediagoblin/tests/test_oauth.py | 17 | ||||
-rw-r--r-- | mediagoblin/tests/test_sql_migrations.py | 33 | ||||
-rw-r--r-- | mediagoblin/tests/test_storage.py | 9 | ||||
-rw-r--r-- | mediagoblin/tests/test_submission.py | 35 | ||||
-rw-r--r-- | mediagoblin/tests/test_tags.py | 6 | ||||
-rw-r--r-- | mediagoblin/tests/test_tests.py | 22 | ||||
-rw-r--r-- | mediagoblin/tests/test_util.py | 14 | ||||
-rw-r--r-- | mediagoblin/tests/test_workbench.py | 34 | ||||
-rw-r--r-- | mediagoblin/tests/tools.py | 23 |
20 files changed, 402 insertions, 203 deletions
diff --git a/mediagoblin/tests/__init__.py b/mediagoblin/tests/__init__.py index 4e84914a..5a3235c6 100644 --- a/mediagoblin/tests/__init__.py +++ b/mediagoblin/tests/__init__.py @@ -25,6 +25,10 @@ from mediagoblin.tests.tools import ( def setup_package(): suicide_if_bad_celery_environ() + import warnings + from sqlalchemy.exc import SAWarning + warnings.simplefilter("error", SAWarning) + def teardown_package(): # Remove and reinstall user_dev directories diff --git a/mediagoblin/tests/test_api.py b/mediagoblin/tests/test_api.py new file mode 100644 index 00000000..4b784da3 --- /dev/null +++ b/mediagoblin/tests/test_api.py @@ -0,0 +1,104 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +import logging +import base64 + +from pkg_resources import resource_filename + +from mediagoblin import mg_globals +from mediagoblin.tools import template, pluginapi +from mediagoblin.tests.tools import get_test_app, fixture_add_user + + +_log = logging.getLogger(__name__) + +def resource(filename): + ''' + Borrowed from the submission tests + ''' + return resource_filename('mediagoblin.tests', 'test_submission/' + filename) + + +GOOD_JPG = resource('good.jpg') +GOOD_PNG = resource('good.png') +EVIL_FILE = resource('evil') +EVIL_JPG = resource('evil.jpg') +EVIL_PNG = resource('evil.png') +BIG_BLUE = resource('bigblue.png') + + +class TestAPI(object): + def setUp(self): + self.app = get_test_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( + '/auth/login/', { + 'username': self.user.username, + 'password': self.user_password}) + + def get_context(self, template_name): + return template.TEMPLATE_TEST_CONTEXT[template_name] + + def http_auth_headers(self): + return {'Authorization': 'Basic {0}'.format( + base64.b64encode(':'.join([ + self.user.username, + self.user_password])))} + + def do_post(self, data, **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) + + if do_follow: + response.follow() + + return response + + def upload_data(self, filename): + return {'upload_files': [('file', filename)]} + + def test_1_test_test_view(self): + self.login() + + response = self.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() + + response = self.do_post( + {'title': 'Great JPG!'}, + **self.upload_data(GOOD_JPG)) + + assert response.status_int == 200 + + assert self.db.MediaEntry.query.filter_by(title=u'Great JPG!').first() diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 1b84b435..a40c9cbc 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -19,9 +19,10 @@ import datetime from nose.tools import assert_equal -from mediagoblin.auth import lib as auth_lib -from mediagoblin.tests.tools import setup_fresh_app, fixture_add_user from mediagoblin import mg_globals +from mediagoblin.auth import lib as auth_lib +from mediagoblin.db.models import User +from mediagoblin.tests.tools import get_test_app, fixture_add_user from mediagoblin.tools import template, mail @@ -66,11 +67,11 @@ def test_bcrypt_gen_password_hash(): 'notthepassword', hashed_pw, '3><7R45417') -@setup_fresh_app -def test_register_views(test_app): +def test_register_views(): """ Massive test function that all our registration-related views all work. """ + test_app = get_test_app(dump_old_app=False) # Test doing a simple GET on the page # ----------------------------------- @@ -124,7 +125,7 @@ def test_register_views(test_app): u'Invalid email address.'] ## At this point there should be no users in the database ;) - assert not mg_globals.database.User.find().count() + assert not User.query.count() # Successful register # ------------------- @@ -153,7 +154,7 @@ def test_register_views(test_app): ## Make sure user is logged in request = template.TEMPLATE_TEST_CONTEXT[ 'mediagoblin/user_pages/user.html']['request'] - assert request.session['user_id'] == unicode(new_user._id) + assert request.session['user_id'] == unicode(new_user.id) ## Make sure we get email confirmation, and try verifying assert len(mail.EMAIL_TEST_INBOX) == 1 @@ -170,7 +171,7 @@ def test_register_views(test_app): ### user should have these same parameters assert parsed_get_params['userid'] == [ - unicode(new_user._id)] + unicode(new_user.id)] assert parsed_get_params['token'] == [ new_user.verification_key] @@ -178,7 +179,7 @@ def test_register_views(test_app): template.clear_test_template_context() response = test_app.get( "/auth/verify_email/?userid=%s&token=total_bs" % unicode( - new_user._id)) + new_user.id)) response.follow() context = template.TEMPLATE_TEST_CONTEXT[ 'mediagoblin/user_pages/user.html'] @@ -253,7 +254,7 @@ def test_register_views(test_app): # user should have matching parameters new_user = mg_globals.database.User.find_one({'username': u'happygirl'}) - assert parsed_get_params['userid'] == [unicode(new_user._id)] + assert parsed_get_params['userid'] == [unicode(new_user.id)] assert parsed_get_params['token'] == [new_user.fp_verification_key] ### The forgotten password token should be set to expire in ~ 10 days @@ -264,8 +265,8 @@ def test_register_views(test_app): template.clear_test_template_context() response = test_app.get( "/auth/forgot_password/verify/?userid=%s&token=total_bs" % unicode( - new_user._id), status=404) - assert_equal(response.status, '404 Not Found') + new_user.id), status=404) + assert_equal(response.status.split()[0], u'404') # status="404 NOT FOUND" ## Try using an expired token to change password, shouldn't work template.clear_test_template_context() @@ -274,7 +275,7 @@ def test_register_views(test_app): new_user.fp_token_expire = datetime.datetime.now() new_user.save() response = test_app.get("%s?%s" % (path, get_params), status=404) - assert_equal(response.status, '404 Not Found') + assert_equal(response.status.split()[0], u'404') # status="404 NOT FOUND" new_user.fp_token_expire = real_token_expiration new_user.save() @@ -310,11 +311,11 @@ def test_register_views(test_app): 'mediagoblin/root.html') -@setup_fresh_app -def test_authentication_views(test_app): +def test_authentication_views(): """ Test logging in and logging out """ + test_app = get_test_app(dump_old_app=False) # Make a new user test_user = fixture_add_user(active_user=False) @@ -392,7 +393,7 @@ def test_authentication_views(test_app): # Make sure user is in the session context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html'] session = context['request'].session - assert session['user_id'] == unicode(test_user._id) + assert session['user_id'] == unicode(test_user.id) # Successful logout # ----------------- diff --git a/mediagoblin/tests/test_csrf_middleware.py b/mediagoblin/tests/test_csrf_middleware.py index ad433fe8..22a0eb04 100644 --- a/mediagoblin/tests/test_csrf_middleware.py +++ b/mediagoblin/tests/test_csrf_middleware.py @@ -14,13 +14,12 @@ # 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 setup_fresh_app +from mediagoblin.tests.tools import get_test_app from mediagoblin import mg_globals -@setup_fresh_app -def test_csrf_cookie_set(test_app): - +def test_csrf_cookie_set(): + test_app = get_test_app(dump_old_app=False) cookie_name = mg_globals.app_config['csrf_cookie_name'] # get login page @@ -34,8 +33,11 @@ def test_csrf_cookie_set(test_app): assert response.headers.get('Vary', False) == 'Cookie' -@setup_fresh_app -def test_csrf_token_must_match(test_app): +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_test_app(dump_old_app=True) # construct a request with no cookie or form token assert test_app.post('/auth/login/', @@ -44,7 +46,7 @@ def test_csrf_token_must_match(test_app): # construct a request with a cookie, but no form token assert test_app.post('/auth/login/', - headers={'Cookie': str('%s=foo; ' % + headers={'Cookie': str('%s=foo' % mg_globals.app_config['csrf_cookie_name'])}, extra_environ={'gmg.verify_csrf': True}, expect_errors=True).status_int == 403 @@ -52,7 +54,7 @@ def test_csrf_token_must_match(test_app): # if both the cookie and form token are provided, they must match assert test_app.post('/auth/login/', {'csrf_token': 'blarf'}, - headers={'Cookie': str('%s=foo; ' % + headers={'Cookie': str('%s=foo' % mg_globals.app_config['csrf_cookie_name'])}, extra_environ={'gmg.verify_csrf': True}, expect_errors=True).\ @@ -60,14 +62,13 @@ def test_csrf_token_must_match(test_app): assert test_app.post('/auth/login/', {'csrf_token': 'foo'}, - headers={'Cookie': str('%s=foo; ' % + headers={'Cookie': str('%s=foo' % mg_globals.app_config['csrf_cookie_name'])}, extra_environ={'gmg.verify_csrf': True}).\ status_int == 200 -@setup_fresh_app -def test_csrf_exempt(test_app): - +def test_csrf_exempt(): + test_app = get_test_app(dump_old_app=False) # monkey with the views to decorate a known endpoint import mediagoblin.auth.views from mediagoblin.meddleware.csrf import csrf_exempt diff --git a/mediagoblin/tests/test_edit.py b/mediagoblin/tests/test_edit.py index 353a7eb9..4bea9243 100644 --- a/mediagoblin/tests/test_edit.py +++ b/mediagoblin/tests/test_edit.py @@ -14,83 +14,122 @@ # 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 nose.tools import assert_equal + from mediagoblin import mg_globals -from mediagoblin.tests.tools import setup_fresh_app, fixture_add_user +from mediagoblin.db.models import User +from mediagoblin.tests.tools import get_test_app, fixture_add_user from mediagoblin.tools import template from mediagoblin.auth.lib import bcrypt_check_password - -@setup_fresh_app -def test_change_password(test_app): - """Test changing password correctly and incorrectly""" - # set up new user - test_user = fixture_add_user() - - test_app.post( - '/auth/login/', { - 'username': u'chris', - 'password': 'toast'}) - - # test that the password can be changed - # template.clear_test_template_context() - test_app.post( - '/edit/account/', { - 'old_password': 'toast', - 'new_password': '123456', - 'wants_comment_notification': 'y' - }) - - # test_user has to be fetched again in order to have the current values - test_user = mg_globals.database.User.one({'username': u'chris'}) - - assert bcrypt_check_password('123456', test_user.pw_hash) - - # test that the password cannot be changed if the given old_password - # is wrong - # template.clear_test_template_context() - test_app.post( - '/edit/account/', { - 'old_password': 'toast', - 'new_password': '098765', - }) - - test_user = mg_globals.database.User.one({'username': u'chris'}) - - assert not bcrypt_check_password('098765', test_user.pw_hash) - - -@setup_fresh_app -def change_bio_url(test_app): - """Test changing bio and URL""" - # set up new user - test_user = fixture_add_user() - - # test changing the bio and the URL properly - test_app.post( - '/edit/profile/', { - 'bio': u'I love toast!', - 'url': u'http://dustycloud.org/'}) - - test_user = mg_globals.database.User.one({'username': u'chris'}) - - assert test_user.bio == u'I love toast!' - assert test_user.url == u'http://dustycloud.org/' - - # test changing the bio and the URL inproperly - too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't' - - test_app.post( - '/edit/profile/', { - # more than 500 characters - 'bio': too_long_bio, - 'url': 'this-is-no-url'}) - - test_user = mg_globals.database.User.one({'username': u'chris'}) - - context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/edit/edit_profile.html'] - form = context['edit_profile_form'] - - assert form.bio.errors == [u'Field must be between 0 and 500 characters long.'] - assert form.url.errors == [u'Improperly formed URL'] - - # test changing the url inproperly +class TestUserEdit(object): + def setUp(self): + self.app = get_test_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( + '/auth/login/', { + 'username': self.user.username, + 'password': self.user_password}) + + + def test_user_deletion(self): + """Delete user via web interface""" + # Make sure user exists + assert User.query.filter_by(username=u'chris').first() + + res = self.app.post('/edit/account/delete/', {'confirmed': 'y'}) + + # Make sure user has been deleted + assert User.query.filter_by(username=u'chris').first() == None + + #TODO: make sure all corresponding items comments etc have been + # deleted too. Perhaps in submission test? + + #Restore user at end of test + self.user = fixture_add_user(password = self.user_password) + self.login() + + + def test_change_password(self): + """Test changing password correctly and incorrectly""" + # test that the password can be changed + # template.clear_test_template_context() + res = self.app.post( + '/edit/account/', { + 'old_password': 'toast', + 'new_password': '123456', + 'wants_comment_notification': 'y' + }) + + # Check for redirect on success + assert_equal(res.status_int, 302) + # test_user has to be fetched again in order to have the current values + test_user = User.query.filter_by(username=u'chris').first() + assert bcrypt_check_password('123456', test_user.pw_hash) + # Update current user passwd + self.user_password = '123456' + + # test that the password cannot be changed if the given + # old_password is wrong template.clear_test_template_context() + self.app.post( + '/edit/account/', { + 'old_password': 'toast', + 'new_password': '098765', + }) + + test_user = User.query.filter_by(username=u'chris').first() + assert not bcrypt_check_password('098765', test_user.pw_hash) + + + + def test_change_bio_url(self): + """Test changing bio and URL""" + # Test if legacy profile editing URL redirects correctly + res = self.app.post( + '/edit/profile/', { + 'bio': u'I love toast!', + 'url': u'http://dustycloud.org/'}, expect_errors=True) + + # Should redirect to /u/chris/edit/ + assert_equal (res.status_int, 302) + assert res.headers['Location'].endswith("/u/chris/edit/") + + res = self.app.post( + '/u/chris/edit/', { + 'bio': u'I love toast!', + 'url': u'http://dustycloud.org/'}) + + test_user = User.query.filter_by(username=u'chris').first() + assert_equal(test_user.bio, u'I love toast!') + assert_equal(test_user.url, u'http://dustycloud.org/') + + # change a different user than the logged in (should fail with 403) + fixture_add_user(username=u"foo") + res = self.app.post( + '/u/foo/edit/', { + 'bio': u'I love toast!', + 'url': u'http://dustycloud.org/'}, expect_errors=True) + assert_equal(res.status_int, 403) + + # test changing the bio and the URL inproperly + too_long_bio = 150 * 'T' + 150 * 'o' + 150 * 'a' + 150 * 's' + 150* 't' + + self.app.post( + '/u/chris/edit/', { + # more than 500 characters + 'bio': too_long_bio, + 'url': 'this-is-no-url'}) + + # Check form errors + context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/edit/edit_profile.html'] + form = context['form'] + + assert_equal(form.bio.errors, [u'Field must be between 0 and 500 characters long.']) + assert_equal(form.url.errors, [u'This address contains errors']) + +# test changing the url inproperly diff --git a/mediagoblin/tests/test_exif.py b/mediagoblin/tests/test_exif.py index ed95045c..100d17f0 100644 --- a/mediagoblin/tests/test_exif.py +++ b/mediagoblin/tests/test_exif.py @@ -58,10 +58,10 @@ def test_exif_extraction(): gps = get_gps_data(result) # Do we have the result? - assert len(result) == 108 + assert len(result) == 56 # Do we have clean data? - assert len(clean) == 105 + assert len(clean) == 53 # GPS data? assert gps == {} @@ -70,7 +70,7 @@ def test_exif_extraction(): assert useful == { 'EXIF Flash': { 'field_type': 3, - 'printable': 'No', + 'printable': u'Flash did not fire', 'field_offset': 380, 'tag': 37385, 'values': [0], @@ -123,18 +123,7 @@ def test_exif_extraction(): 'field_offset': 708, 'tag': 33437, 'values': [[10, 1]], - 'field_length': 8}, - 'EXIF UserComment': { - 'field_type': 7, - 'printable': 'Joar Wandborg ', - 'field_offset': 26180, - 'tag': 37510, - 'values': [ - 65, 83, 67, 73, 73, 0, 0, 0, 74, 111, 97, 114, 32, 87, - 97, 110, 100, 98, 111, 114, 103, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32], - 'field_length': 44}} + 'field_length': 8}} def test_exif_image_orientation(): diff --git a/mediagoblin/tests/test_globals.py b/mediagoblin/tests/test_globals.py index 98f6a436..303f89e2 100644 --- a/mediagoblin/tests/test_globals.py +++ b/mediagoblin/tests/test_globals.py @@ -18,23 +18,20 @@ from nose.tools import assert_raises from mediagoblin import mg_globals + class TestGlobals(object): def setUp(self): - self.old_connection = mg_globals.db_connection self.old_database = mg_globals.database def tearDown(self): - mg_globals.db_connection = self.old_connection mg_globals.database = self.old_database def test_setup_globals(self): mg_globals.setup_globals( - db_connection='my favorite db_connection!', database='my favorite database!', public_store='my favorite public_store!', queue_store='my favorite queue_store!') - assert mg_globals.db_connection == 'my favorite db_connection!' assert mg_globals.database == 'my favorite database!' assert mg_globals.public_store == 'my favorite public_store!' assert mg_globals.queue_store == 'my favorite queue_store!' diff --git a/mediagoblin/tests/test_http_callback.py b/mediagoblin/tests/test_http_callback.py index d769af1e..0f6e489f 100644 --- a/mediagoblin/tests/test_http_callback.py +++ b/mediagoblin/tests/test_http_callback.py @@ -27,11 +27,11 @@ from mediagoblin.tests import test_oauth as oauth class TestHTTPCallback(object): def setUp(self): - self.app = get_test_app() + self.app = get_test_app(dump_old_app=False) self.db = mg_globals.database - self.user_password = 'secret' - self.user = fixture_add_user('call_back', self.user_password) + self.user_password = u'secret' + self.user = fixture_add_user(u'call_back', self.user_password) self.login() diff --git a/mediagoblin/tests/test_messages.py b/mediagoblin/tests/test_messages.py index d3b84828..c587e599 100644 --- a/mediagoblin/tests/test_messages.py +++ b/mediagoblin/tests/test_messages.py @@ -15,30 +15,31 @@ # 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 setup_fresh_app +from mediagoblin.tests.tools import get_test_app from mediagoblin.tools import template -@setup_fresh_app -def test_messages(test_app): + +def test_messages(): """ 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_test_app(dump_old_app=False) # Aquire a request object test_app.get('/') context = template.TEMPLATE_TEST_CONTEXT['mediagoblin/root.html'] request = context['request'] - + # The message queue should be empty assert request.session.get('messages', []) == [] - + # Adding a message should modify the session accordingly add_message(request, 'herp_derp', 'First!') test_msg_queue = [{'text': 'First!', 'level': 'herp_derp'}] assert request.session['messages'] == test_msg_queue - + # fetch_messages should return and empty the queue assert fetch_messages(request) == test_msg_queue assert request.session.get('messages') == [] diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini index cde61a70..42d3785a 100644 --- a/mediagoblin/tests/test_mgoblin_app.ini +++ b/mediagoblin/tests/test_mgoblin_app.ini @@ -35,3 +35,5 @@ BROKER_HOST = "sqlite:///%(here)s/test_user_dev/kombu.db" [plugins] [[mediagoblin.plugins.api]] [[mediagoblin.plugins.oauth]] +[[mediagoblin.plugins.httpapiauth]] + diff --git a/mediagoblin/tests/test_misc.py b/mediagoblin/tests/test_misc.py index 94ae5a51..8a96e7d0 100644 --- a/mediagoblin/tests/test_misc.py +++ b/mediagoblin/tests/test_misc.py @@ -16,11 +16,9 @@ from nose.tools import assert_equal -from mediagoblin.tests.tools import setup_fresh_app +from mediagoblin.tests.tools import get_test_app - -@setup_fresh_app -def test_404_for_non_existent(test_app): - assert_equal(test_app.get('/does-not-exist/', - expect_errors=True).status_int, - 404) +def test_404_for_non_existent(): + test_app = get_test_app(dump_old_app=False) + res = test_app.get('/does-not-exist/', expect_errors=True) + assert_equal(res.status_int, 404) diff --git a/mediagoblin/tests/test_oauth.py b/mediagoblin/tests/test_oauth.py index db4e226a..a72f766e 100644 --- a/mediagoblin/tests/test_oauth.py +++ b/mediagoblin/tests/test_oauth.py @@ -34,8 +34,8 @@ class TestOAuth(object): self.pman = pluginapi.PluginManager() - self.user_password = '4cc355_70k3N' - self.user = fixture_add_user('joauth', self.user_password) + self.user_password = u'4cc355_70k3N' + self.user = fixture_add_user(u'joauth', self.user_password) self.login() @@ -59,13 +59,13 @@ class TestOAuth(object): def test_1_public_client_registration_without_redirect_uri(self): ''' Test 'public' OAuth client registration without any redirect uri ''' - response = self.register_client('OMGOMGOMG', 'public', + response = self.register_client(u'OMGOMGOMG', 'public', 'OMGOMG Apache License v2') ctx = self.get_context('oauth/client/register.html') client = self.db.OAuthClient.query.filter( - self.db.OAuthClient.name == 'OMGOMGOMG').first() + self.db.OAuthClient.name == u'OMGOMGOMG').first() assert response.status_int == 200 @@ -78,23 +78,23 @@ class TestOAuth(object): def test_2_successful_public_client_registration(self): ''' Successfully register a public client ''' self.login() - self.register_client('OMGOMG', 'public', 'OMG!', + self.register_client(u'OMGOMG', 'public', 'OMG!', 'http://foo.example') client = self.db.OAuthClient.query.filter( - self.db.OAuthClient.name == 'OMGOMG').first() + self.db.OAuthClient.name == u'OMGOMG').first() # Client should have been registered assert client def test_3_successful_confidential_client_reg(self): ''' Register a confidential OAuth client ''' - response = self.register_client('GMOGMO', 'confidential', 'NO GMO!') + response = self.register_client(u'GMOGMO', 'confidential', 'NO GMO!') assert response.status_int == 302 client = self.db.OAuthClient.query.filter( - self.db.OAuthClient.name == 'GMOGMO').first() + self.db.OAuthClient.name == u'GMOGMO').first() # Client should have been registered assert client @@ -103,6 +103,7 @@ class TestOAuth(object): def test_4_authorize_confidential_client(self): ''' Authorize a confidential client as a logged in user ''' + client = self.test_3_successful_confidential_client_reg() client_identifier = client.identifier diff --git a/mediagoblin/tests/test_sql_migrations.py b/mediagoblin/tests/test_sql_migrations.py index e3b55634..2fc4c043 100644 --- a/mediagoblin/tests/test_sql_migrations.py +++ b/mediagoblin/tests/test_sql_migrations.py @@ -25,8 +25,8 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.sql import select, insert from migrate import changeset -from mediagoblin.db.sql.base import GMGTableBase -from mediagoblin.db.sql.util import MigrationManager, RegisterMigration +from mediagoblin.db.base import GMGTableBase +from mediagoblin.db.migration_tools import MigrationManager, RegisterMigration from mediagoblin.tools.common import CollectingPrinter @@ -322,6 +322,28 @@ def creature_power_hitpower_to_float(db_conn): creature_power.c.hitpower.alter(type=Float) +@RegisterMigration(8, FULL_MIGRATIONS) +def creature_power_name_creature_unique(db_conn): + """ + Add a unique constraint to name and creature on creature_power. + + We don't want multiple creature powers with the same name per creature! + """ + # Note: We don't actually check to see if this constraint is set + # up because at present there's no way to do so in sqlalchemy :\ + + metadata = MetaData(bind=db_conn.bind) + + creature_power = Table( + 'creature_power', metadata, + autoload=True, autoload_with=db_conn.bind) + + cons = changeset.constraint.UniqueConstraint( + 'name', 'creature', table=creature_power) + + cons.create() + + def _insert_migration1_objects(session): """ Test objects to insert for the first set of things @@ -660,7 +682,7 @@ def test_set1_to_set3(): u'__main__', SET3_MODELS, SET3_MIGRATIONS, Session(), printer) - assert migration_manager.latest_migration == 7 + assert migration_manager.latest_migration == 8 assert migration_manager.database_current_migration == 0 # Migrate @@ -679,14 +701,15 @@ def test_set1_to_set3(): + Running migration 5, "level_exit_index_from_and_to_level"... done. + Running migration 6, "creature_power_index_creature"... done. + Running migration 7, "creature_power_hitpower_to_float"... done. + + Running migration 8, "creature_power_name_creature_unique"... done. """ # Make sure version matches expected migration_manager = MigrationManager( u'__main__', SET3_MODELS, SET3_MIGRATIONS, Session(), printer) - assert migration_manager.latest_migration == 7 - assert migration_manager.database_current_migration == 7 + assert migration_manager.latest_migration == 8 + assert migration_manager.database_current_migration == 8 # Check all things in database match expected diff --git a/mediagoblin/tests/test_storage.py b/mediagoblin/tests/test_storage.py index 6fc2e57c..61326ae9 100644 --- a/mediagoblin/tests/test_storage.py +++ b/mediagoblin/tests/test_storage.py @@ -18,7 +18,7 @@ import os import tempfile -from nose.tools import assert_raises +from nose.tools import assert_raises, assert_equal, assert_true from werkzeug.utils import secure_filename from mediagoblin import storage @@ -78,9 +78,10 @@ def test_storage_system_from_config(): 'garbage_arg': 'garbage_arg', 'storage_class': 'mediagoblin.tests.test_storage:FakeStorageSystem'}) - assert this_storage.foobie == 'eiboof' - assert this_storage.blech == 'hcelb' - assert this_storage.__class__ is FakeStorageSystem + assert_equal(this_storage.foobie, 'eiboof') + assert_equal(this_storage.blech, 'hcelb') + assert_equal(unicode(this_storage.__class__), + u'mediagoblin.tests.test_storage.FakeStorageSystem') ########################## diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index b7b0e574..53330c48 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -28,7 +28,7 @@ from mediagoblin.tests.tools import get_test_app, \ fixture_add_user from mediagoblin import mg_globals from mediagoblin.tools import template - +from mediagoblin.media_types.image import MEDIA_MANAGER as img_MEDIA_MANAGER def resource(filename): return resource_filename('mediagoblin.tests', 'test_submission/' + filename) @@ -50,7 +50,7 @@ REQUEST_CONTEXT = ['mediagoblin/user_pages/user.html', 'request'] class TestSubmission: def setUp(self): - self.test_app = get_test_app() + self.test_app = get_test_app(dump_old_app=False) # TODO: Possibly abstract into a decorator like: # @as_authenticated_user('chris') @@ -132,11 +132,11 @@ class TestSubmission: def test_tags(self): # Good tag string # -------- - response, request = self.do_post({'title': u'Balanced Goblin', + response, request = self.do_post({'title': u'Balanced Goblin 2', 'tags': GOOD_TAG_STRING}, *REQUEST_CONTEXT, do_follow=True, **self.upload_data(GOOD_JPG)) - media = self.check_media(request, {'title': u'Balanced Goblin'}, 1) + media = self.check_media(request, {'title': u'Balanced Goblin 2'}, 1) assert media.tags[0]['name'] == u'yin' assert media.tags[0]['slug'] == u'yin' @@ -145,7 +145,7 @@ class TestSubmission: # Test tags that are too long # --------------- - response, form = self.do_post({'title': u'Balanced Goblin', + response, form = self.do_post({'title': u'Balanced Goblin 2', 'tags': BAD_TAG_STRING}, *FORM_CONTEXT, **self.upload_data(GOOD_JPG)) @@ -161,11 +161,17 @@ class TestSubmission: media = self.check_media(request, {'title': u'Balanced Goblin'}, 1) media_id = media.id + # At least render the edit page + edit_url = request.urlgen( + 'mediagoblin.edit.edit_media', + user=self.test_user.username, media_id=media_id) + self.test_app.get(edit_url) + # Add a comment, so we can test for its deletion later. self.check_comments(request, media_id, 0) comment_url = request.urlgen( 'mediagoblin.user_pages.media_post_comment', - user=self.test_user.username, media=media_id) + user=self.test_user.username, media_id=media_id) response = self.do_post({'comment_content': 'i love this test'}, url=comment_url, do_follow=True)[0] self.check_comments(request, media_id, 1) @@ -174,7 +180,7 @@ class TestSubmission: # --------------------------------------------------- delete_url = request.urlgen( 'mediagoblin.user_pages.media_confirm_delete', - user=self.test_user.username, media=media_id) + user=self.test_user.username, media_id=media_id) # Empty data means don't confirm response = self.do_post({}, do_follow=True, url=delete_url)[0] media = self.check_media(request, {'title': u'Balanced Goblin'}, 1) @@ -184,7 +190,7 @@ class TestSubmission: # --------------------------------------------------- response, request = self.do_post({'confirm': 'y'}, *REQUEST_CONTEXT, do_follow=True, url=delete_url) - self.check_media(request, {'_id': media_id}, 0) + self.check_media(request, {'id': media_id}, 0) self.check_comments(request, media_id, 0) def test_evil_file(self): @@ -197,6 +203,19 @@ class TestSubmission: assert 'Sorry, I don\'t support that file type :(' == \ str(form.file.errors[0]) + + def test_get_media_manager(self): + """Test if the get_media_manger function returns sensible things + """ + response, request = self.do_post({'title': u'Balanced Goblin'}, + *REQUEST_CONTEXT, do_follow=True, + **self.upload_data(GOOD_JPG)) + media = self.check_media(request, {'title': u'Balanced Goblin'}, 1) + + assert_equal(media.media_type, u'mediagoblin.media_types.image') + assert_equal(media.media_manager, img_MEDIA_MANAGER) + + def test_sniffing(self): ''' Test sniffing mechanism to assert that regular uploads work as intended diff --git a/mediagoblin/tests/test_tags.py b/mediagoblin/tests/test_tags.py index bc657660..73af2eea 100644 --- a/mediagoblin/tests/test_tags.py +++ b/mediagoblin/tests/test_tags.py @@ -14,17 +14,17 @@ # 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 setup_fresh_app +from mediagoblin.tests.tools import get_test_app from mediagoblin.tools import text -@setup_fresh_app -def test_list_of_dicts_conversion(test_app): +def test_list_of_dicts_conversion(): """ 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_test_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'}, diff --git a/mediagoblin/tests/test_tests.py b/mediagoblin/tests/test_tests.py index 20832ac7..d09e8f28 100644 --- a/mediagoblin/tests/test_tests.py +++ b/mediagoblin/tests/test_tests.py @@ -14,25 +14,23 @@ # 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_test_app - from mediagoblin import mg_globals +from mediagoblin.tests.tools import get_test_app, fixture_add_user +from mediagoblin.db.models import User def test_get_test_app_wipes_db(): """ Make sure we get a fresh database on every wipe :) """ - get_test_app() - assert mg_globals.database.User.find().count() == 0 + get_test_app(dump_old_app=True) + assert User.query.count() == 0 - new_user = mg_globals.database.User() - new_user.username = u'lolcat' - new_user.email = u'lol@cats.example.org' - new_user.pw_hash = u'pretend_this_is_a_hash' - new_user.save() - assert mg_globals.database.User.find().count() == 1 + fixture_add_user() + assert User.query.count() == 1 - get_test_app() + get_test_app(dump_old_app=False) + assert User.query.count() == 1 - assert mg_globals.database.User.find().count() == 0 + get_test_app(dump_old_app=True) + assert User.query.count() == 0 diff --git a/mediagoblin/tests/test_util.py b/mediagoblin/tests/test_util.py index 452090e1..e4c04b7a 100644 --- a/mediagoblin/tests/test_util.py +++ b/mediagoblin/tests/test_util.py @@ -70,13 +70,13 @@ I hope you like unit tests JUST AS MUCH AS I DO!""" I hope you like unit tests JUST AS MUCH AS I DO!""" def test_slugify(): - assert url.slugify('a walk in the park') == 'a-walk-in-the-park' - assert url.slugify('A Walk in the Park') == 'a-walk-in-the-park' - assert url.slugify('a walk in the park') == 'a-walk-in-the-park' - assert url.slugify('a walk in-the-park') == 'a-walk-in-the-park' - assert url.slugify('a w@lk in the park?') == 'a-w-lk-in-the-park' - assert url.slugify(u'a walk in the par\u0107') == 'a-walk-in-the-parc' - assert url.slugify(u'\u00E0\u0042\u00E7\u010F\u00EB\u0066') == 'abcdef' + assert url.slugify(u'a walk in the park') == u'a-walk-in-the-park' + assert url.slugify(u'A Walk in the Park') == u'a-walk-in-the-park' + assert url.slugify(u'a walk in the park') == u'a-walk-in-the-park' + assert url.slugify(u'a walk in-the-park') == u'a-walk-in-the-park' + assert url.slugify(u'a w@lk in the park?') == u'a-w-lk-in-the-park' + assert url.slugify(u'a walk in the par\u0107') == u'a-walk-in-the-parc' + assert url.slugify(u'\u00E0\u0042\u00E7\u010F\u00EB\u0066') == u'abcdef' def test_locale_to_lower_upper(): """ diff --git a/mediagoblin/tests/test_workbench.py b/mediagoblin/tests/test_workbench.py index 04a74653..9da8eea0 100644 --- a/mediagoblin/tests/test_workbench.py +++ b/mediagoblin/tests/test_workbench.py @@ -19,6 +19,8 @@ import tempfile from mediagoblin import workbench +from mediagoblin.mg_globals import setup_globals +from mediagoblin.decorators import get_workbench from mediagoblin.tests.test_storage import get_tmp_filestorage @@ -28,19 +30,20 @@ class TestWorkbench(object): os.path.join(tempfile.gettempdir(), u'mgoblin_workbench_testing')) def test_create_workbench(self): - workbench = self.workbench_manager.create_workbench() + workbench = self.workbench_manager.create() assert os.path.isdir(workbench.dir) assert workbench.dir.startswith(self.workbench_manager.base_workbench_dir) + workbench.destroy() def test_joinpath(self): - this_workbench = self.workbench_manager.create_workbench() + this_workbench = self.workbench_manager.create() tmpname = this_workbench.joinpath('temp.txt') assert tmpname == os.path.join(this_workbench.dir, 'temp.txt') - this_workbench.destroy_self() + this_workbench.destroy() def test_destroy_workbench(self): # kill a workbench - this_workbench = self.workbench_manager.create_workbench() + this_workbench = self.workbench_manager.create() tmpfile_name = this_workbench.joinpath('temp.txt') tmpfile = file(tmpfile_name, 'w') with tmpfile: @@ -49,14 +52,14 @@ class TestWorkbench(object): assert os.path.exists(tmpfile_name) wb_dir = this_workbench.dir - this_workbench.destroy_self() + this_workbench.destroy() assert not os.path.exists(tmpfile_name) assert not os.path.exists(wb_dir) def test_localized_file(self): tmpdir, this_storage = get_tmp_filestorage() - this_workbench = self.workbench_manager.create_workbench() - + this_workbench = self.workbench_manager.create() + # Write a brand new file filepath = ['dir1', 'dir2', 'ourfile.txt'] @@ -78,7 +81,7 @@ class TestWorkbench(object): filename = this_workbench.localized_file(this_storage, filepath) assert filename == os.path.join( this_workbench.dir, 'ourfile.txt') - + # fake remote file storage, filename_if_copying set filename = this_workbench.localized_file( this_storage, filepath, 'thisfile') @@ -91,3 +94,18 @@ class TestWorkbench(object): this_storage, filepath, 'thisfile.text', False) assert filename == os.path.join( this_workbench.dir, 'thisfile.text') + + def test_workbench_decorator(self): + """Test @get_workbench decorator and automatic cleanup""" + # The decorator needs mg_globals.workbench_manager + setup_globals(workbench_manager=self.workbench_manager) + + @get_workbench + def create_it(workbench=None): + # workbench dir exists? + assert os.path.isdir(workbench.dir) + return workbench.dir + + benchdir = create_it() + # workbench dir has been cleaned up automatically? + assert not os.path.isdir(benchdir) diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index d3369831..3e78b2e3 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -25,10 +25,11 @@ from paste.deploy import loadapp from webtest import TestApp from mediagoblin import mg_globals +from mediagoblin.db.models import User from mediagoblin.tools import testing from mediagoblin.init.config import read_mediagoblin_config from mediagoblin.db.open import setup_connection_and_db_from_config -from mediagoblin.db.sql.base import Session +from mediagoblin.db.base import Session from mediagoblin.meddleware import BaseMeddleware from mediagoblin.auth.lib import bcrypt_gen_password_hash from mediagoblin.gmg_commands.dbupdate import run_dbupdate @@ -78,7 +79,7 @@ class TestingMeddleware(BaseMeddleware): def process_response(self, request, response): # All following tests should be for html only! - if response.content_type != "text/html": + if getattr(response, 'content_type', None) != "text/html": # Get out early return @@ -184,27 +185,30 @@ 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. + 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', + {'id': 'foo', 'some_field': 'some_value'},]} """ for collection_name, collection_data in expected.iteritems(): collection = db[collection_name] for expected_document in collection_data: - document = collection.find_one({'_id': expected_document['_id']}) + document = collection.find_one({'id': expected_document['id']}) 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='toast', +def fixture_add_user(username=u'chris', password=u'toast', active_user=True): - test_user = mg_globals.database.User() + # Reuse existing user or create a new one + test_user = User.query.filter_by(username=username).first() + if test_user is None: + test_user = User() test_user.username = username test_user.email = username + u'@example.com' if password is not None: @@ -216,10 +220,9 @@ def fixture_add_user(username=u'chris', password='toast', test_user.save() # Reload - test_user = mg_globals.database.User.find_one({'username': username}) + test_user = User.query.filter_by(username=username).first() # ... and detach from session: - from mediagoblin.db.sql.base import Session Session.expunge(test_user) return test_user |