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