diff options
Diffstat (limited to 'mediagoblin/tests')
-rw-r--r-- | mediagoblin/tests/__init__.py | 11 | ||||
-rw-r--r-- | mediagoblin/tests/test_auth.py | 172 | ||||
-rw-r--r-- | mediagoblin/tests/test_globals.py | 2 | ||||
-rw-r--r-- | mediagoblin/tests/test_storage.py | 45 | ||||
-rw-r--r-- | mediagoblin/tests/test_tests.py | 38 | ||||
-rw-r--r-- | mediagoblin/tests/test_workbench.py | 96 | ||||
-rw-r--r-- | mediagoblin/tests/tools.py | 23 |
7 files changed, 380 insertions, 7 deletions
diff --git a/mediagoblin/tests/__init__.py b/mediagoblin/tests/__init__.py index c129cbf8..e9e2a59a 100644 --- a/mediagoblin/tests/__init__.py +++ b/mediagoblin/tests/__init__.py @@ -13,3 +13,14 @@ # # 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 + + +def setup_package(): + pass + +def teardown_package(): + print "Killing db ..." + mg_globals.db_connection.drop_database(mg_globals.database.name) + print "... done" diff --git a/mediagoblin/tests/test_auth.py b/mediagoblin/tests/test_auth.py index 94ce6bba..3d569093 100644 --- a/mediagoblin/tests/test_auth.py +++ b/mediagoblin/tests/test_auth.py @@ -14,8 +14,14 @@ # 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 urlparse + +from nose.tools import assert_equal from mediagoblin.auth import lib as auth_lib +from mediagoblin.tests.tools import setup_fresh_app +from mediagoblin import mg_globals +from mediagoblin import util ######################## @@ -57,3 +63,169 @@ def test_bcrypt_gen_password_hash(): pw, hashed_pw, '3><7R45417') assert not auth_lib.bcrypt_check_password( '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. + """ + # Test doing a simple GET on the page + # ----------------------------------- + + test_app.get('/auth/register/') + # Make sure it rendered with the appropriate template + assert util.TEMPLATE_TEST_CONTEXT.has_key( + 'mediagoblin/auth/register.html') + + # Try to register without providing anything, should error + # -------------------------------------------------------- + + util.clear_test_template_context() + test_app.post( + '/auth/register/', {}) + context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] + form = context['register_form'] + assert form.username.errors == [u'This field is required.'] + assert form.password.errors == [u'This field is required.'] + assert form.confirm_password.errors == [u'This field is required.'] + assert form.email.errors == [u'This field is required.'] + + # Try to register with fields that are known to be invalid + # -------------------------------------------------------- + + ## too short + util.clear_test_template_context() + test_app.post( + '/auth/register/', { + 'username': 'l', + 'password': 'o', + 'confirm_password': 'o', + 'email': 'l'}) + context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] + form = context['register_form'] + + assert form.username.errors == [ + u'Field must be between 3 and 30 characters long.'] + assert form.password.errors == [ + u'Field must be between 6 and 30 characters long.'] + + ## bad form + util.clear_test_template_context() + test_app.post( + '/auth/register/', { + 'username': '@_@', + 'email': 'lollerskates'}) + context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] + form = context['register_form'] + + assert form.username.errors == [ + u'Invalid input.'] + assert form.email.errors == [ + u'Invalid email address.'] + + ## mismatching passwords + util.clear_test_template_context() + test_app.post( + '/auth/register/', { + 'password': 'herpderp', + 'confirm_password': 'derpherp'}) + context = util.TEMPLATE_TEST_CONTEXT['mediagoblin/auth/register.html'] + form = context['register_form'] + + assert form.password.errors == [ + u'Passwords must match.'] + + ## At this point there should be no users in the database ;) + assert not mg_globals.database.User.find().count() + + # Successful register + # ------------------- + util.clear_test_template_context() + response = test_app.post( + '/auth/register/', { + 'username': 'happygirl', + 'password': 'iamsohappy', + 'confirm_password': 'iamsohappy', + 'email': 'happygrrl@example.org'}) + response.follow() + + ## Did we redirect to the proper page? Use the right template? + assert_equal( + urlparse.urlsplit(response.location)[2], + '/auth/register/success/') + assert util.TEMPLATE_TEST_CONTEXT.has_key( + 'mediagoblin/auth/register_success.html') + + ## Make sure user is in place + new_user = mg_globals.database.User.find_one( + {'username': 'happygirl'}) + assert new_user + assert new_user['status'] == u'needs_email_verification' + assert new_user['email_verified'] == False + + ## Make sure we get email confirmation, and try verifying + assert len(util.EMAIL_TEST_INBOX) == 1 + message = util.EMAIL_TEST_INBOX.pop() + assert message['To'] == 'happygrrl@example.org' + email_context = util.TEMPLATE_TEST_CONTEXT[ + 'mediagoblin/auth/verification_email.txt'] + assert email_context['verification_url'] in message.get_payload(decode=True) + + path = urlparse.urlsplit(email_context['verification_url'])[2] + get_params = urlparse.urlsplit(email_context['verification_url'])[3] + assert path == u'/auth/verify_email/' + parsed_get_params = urlparse.parse_qs(get_params) + + ### user should have these same parameters + assert parsed_get_params['userid'] == [ + unicode(new_user['_id'])] + assert parsed_get_params['token'] == [ + new_user['verification_key']] + + ## Try verifying with bs verification key, shouldn't work + util.clear_test_template_context() + test_app.get( + "/auth/verify_email/?userid=%s&token=total_bs" % unicode( + new_user['_id'])) + context = util.TEMPLATE_TEST_CONTEXT[ + 'mediagoblin/auth/verify_email.html'] + assert context['verification_successful'] == False + new_user = mg_globals.database.User.find_one( + {'username': 'happygirl'}) + assert new_user + assert new_user['status'] == u'needs_email_verification' + assert new_user['email_verified'] == False + + ## Verify the email activation works + util.clear_test_template_context() + test_app.get("%s?%s" % (path, get_params)) + context = util.TEMPLATE_TEST_CONTEXT[ + 'mediagoblin/auth/verify_email.html'] + assert context['verification_successful'] == True + new_user = mg_globals.database.User.find_one( + {'username': 'happygirl'}) + assert new_user + assert new_user['status'] == u'active' + assert new_user['email_verified'] == True + + ## TODO: Try logging in + + # Uniqueness checks + # ----------------- + ## We shouldn't be able to register with that user twice + util.clear_test_template_context() + response = test_app.post( + '/auth/register/', { + 'username': 'happygirl', + 'password': 'iamsohappy2', + 'confirm_password': 'iamsohappy2', + 'email': 'happygrrl2@example.org'}) + + context = util.TEMPLATE_TEST_CONTEXT[ + 'mediagoblin/auth/register.html'] + form = context['register_form'] + assert form.username.errors == [ + u'Sorry, a user with that name already exists.'] + + ## TODO: Also check for double instances of an email address? diff --git a/mediagoblin/tests/test_globals.py b/mediagoblin/tests/test_globals.py index 6d2e01da..59d217f3 100644 --- a/mediagoblin/tests/test_globals.py +++ b/mediagoblin/tests/test_globals.py @@ -14,7 +14,7 @@ # 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 globals as mg_globals +from mediagoblin import mg_globals def test_setup_globals(): mg_globals.setup_globals( diff --git a/mediagoblin/tests/test_storage.py b/mediagoblin/tests/test_storage.py index 61dd5dca..55b66e84 100644 --- a/mediagoblin/tests/test_storage.py +++ b/mediagoblin/tests/test_storage.py @@ -52,6 +52,11 @@ class FakeStorageSystem(): self.foobie = foobie self.blech = blech +class FakeRemoteStorage(storage.BasicFileStorage): + # Theoretically despite this, all the methods should work but it + # should force copying to the workbench + local_storage = False + def test_storage_system_from_paste_config(): this_storage = storage.storage_system_from_paste_config( @@ -81,9 +86,12 @@ def test_storage_system_from_paste_config(): # Basic file storage tests ########################## -def get_tmp_filestorage(mount_url=None): +def get_tmp_filestorage(mount_url=None, fake_remote=False): tmpdir = tempfile.mkdtemp() - this_storage = storage.BasicFileStorage(tmpdir, mount_url) + if fake_remote: + this_storage = FakeRemoteStorage(tmpdir, mount_url) + else: + this_storage = storage.BasicFileStorage(tmpdir, mount_url) return tmpdir, this_storage @@ -214,3 +222,36 @@ def test_basic_storage_url_for_file(): ['dir1', 'dir2', 'filename.txt']) expected = 'http://media.example.org/ourmedia/dir1/dir2/filename.txt' assert result == expected + + +def test_basic_storage_get_local_path(): + tmpdir, this_storage = get_tmp_filestorage() + + result = this_storage.get_local_path( + ['dir1', 'dir2', 'filename.txt']) + + expected = os.path.join( + tmpdir, 'dir1/dir2/filename.txt') + + assert result == expected + + +def test_basic_storage_is_local(): + tmpdir, this_storage = get_tmp_filestorage() + assert this_storage.local_storage is True + + +def test_basic_storage_copy_locally(): + tmpdir, this_storage = get_tmp_filestorage() + + dest_tmpdir = tempfile.mkdtemp() + + filepath = ['dir1', 'dir2', 'ourfile.txt'] + with this_storage.get_file(filepath, 'w') as our_file: + our_file.write('Testing this file') + + new_file_dest = os.path.join(dest_tmpdir, 'file2.txt') + + this_storage.copy_locally(filepath, new_file_dest) + + assert file(new_file_dest).read() == 'Testing this file' diff --git a/mediagoblin/tests/test_tests.py b/mediagoblin/tests/test_tests.py new file mode 100644 index 00000000..8ac7f0a4 --- /dev/null +++ b/mediagoblin/tests/test_tests.py @@ -0,0 +1,38 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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.tests.tools import get_test_app + +from mediagoblin import mg_globals + + +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 + + 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 + + get_test_app() + + assert mg_globals.database.User.find().count() == 0 diff --git a/mediagoblin/tests/test_workbench.py b/mediagoblin/tests/test_workbench.py new file mode 100644 index 00000000..89f2ef33 --- /dev/null +++ b/mediagoblin/tests/test_workbench.py @@ -0,0 +1,96 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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 os +import tempfile + +from nose.tools import assert_raises + +from mediagoblin import workbench +from mediagoblin.tests.test_storage import get_tmp_filestorage + + +class TestWorkbench(object): + def setUp(self): + self.workbench_manager = workbench.WorkbenchManager( + os.path.join(tempfile.gettempdir(), u'mgoblin_workbench_testing')) + + def test_create_workbench(self): + workbench = self.workbench_manager.create_workbench() + assert os.path.isdir(workbench) + assert workbench.startswith(self.workbench_manager.base_workbench_dir) + + def test_destroy_workbench(self): + # kill a workbench + this_workbench = self.workbench_manager.create_workbench() + tmpfile = file(os.path.join(this_workbench, 'temp.txt'), 'w') + with tmpfile: + tmpfile.write('lollerskates') + + assert os.path.exists(os.path.join(this_workbench, 'temp.txt')) + + self.workbench_manager.destroy_workbench(this_workbench) + assert not os.path.exists(os.path.join(this_workbench, 'temp.txt')) + assert not os.path.exists(this_workbench) + + # make sure we can't kill other stuff though + dont_kill_this = tempfile.mkdtemp() + + assert_raises( + workbench.WorkbenchOutsideScope, + self.workbench_manager.destroy_workbench, + dont_kill_this) + + def test_localized_file(self): + tmpdir, this_storage = get_tmp_filestorage() + this_workbench = self.workbench_manager.create_workbench() + + # Write a brand new file + filepath = ['dir1', 'dir2', 'ourfile.txt'] + + with this_storage.get_file(filepath, 'w') as our_file: + our_file.write('Our file') + + # with a local file storage + filename = self.workbench_manager.localized_file( + this_workbench, this_storage, filepath) + assert filename == os.path.join( + tmpdir, 'dir1/dir2/ourfile.txt') + + # with a fake remote file storage + tmpdir, this_storage = get_tmp_filestorage(fake_remote=True) + + # ... write a brand new file, again ;) + with this_storage.get_file(filepath, 'w') as our_file: + our_file.write('Our file') + + filename = self.workbench_manager.localized_file( + this_workbench, this_storage, filepath) + assert filename == os.path.join( + this_workbench, 'ourfile.txt') + + # fake remote file storage, filename_if_copying set + filename = self.workbench_manager.localized_file( + this_workbench, this_storage, filepath, 'thisfile') + assert filename == os.path.join( + this_workbench, 'thisfile.txt') + + # fake remote file storage, filename_if_copying set, + # keep_extension_if_copying set to false + filename = self.workbench_manager.localized_file( + this_workbench, this_storage, filepath, 'thisfile.text', False) + assert filename == os.path.join( + this_workbench, 'thisfile.text') diff --git a/mediagoblin/tests/tools.py b/mediagoblin/tests/tools.py index 70b74b89..342b54b7 100644 --- a/mediagoblin/tests/tools.py +++ b/mediagoblin/tests/tools.py @@ -18,10 +18,11 @@ import pkg_resources import os, shutil -from paste.deploy import appconfig +from paste.deploy import appconfig, loadapp from webtest import TestApp -from mediagoblin import app +from mediagoblin import util +from mediagoblin.decorators import _make_safe from mediagoblin.db.open import setup_connection_and_db_from_config @@ -88,7 +89,21 @@ def get_test_app(dump_old_app=True): # TODO: Drop and recreate indexes # setup app and return - test_app = app.paste_app_factory( - config.global_conf, **config.local_conf) + test_app = loadapp( + 'config:' + TEST_APP_CONFIG) return TestApp(test_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. + """ + def wrapper(*args, **kwargs): + test_app = get_test_app() + util.clear_test_buckets() + return func(test_app, *args, **kwargs) + + return _make_safe(wrapper, func) |