From 3298f6924a127ceca8ca38eb81cd018d68d9534a Mon Sep 17 00:00:00 2001 From: amercader Date: Thu, 9 Jun 2016 16:04:33 +0100 Subject: [PATCH] Fix ckanext tests Same as previous commits, using the app from tests.helpers._get_test_app and request contexts when necessary Conflicts: ckanext/imageview/tests/test_view.py --- ckanext/datapusher/tests/test.py | 24 +-- ckanext/datapusher/tests/test_interfaces.py | 22 +-- ckanext/datastore/tests/test_create.py | 30 +++- ckanext/datastore/tests/test_delete.py | 9 +- ckanext/datastore/tests/test_dump.py | 6 +- ckanext/datastore/tests/test_upsert.py | 62 ++++---- .../tests/test_example_iauthfunctions.py | 143 ++++++++++++------ .../tests/test_controllers.py | 6 +- .../tests/test_controllers.py | 61 +++++--- .../example_itranslation/tests/test_plugin.py | 54 ++++--- ckanext/imageview/tests/test_view.py | 8 +- .../tests/test_multilingual_plugin.py | 58 +++---- ckanext/reclineview/tests/test_view.py | 36 ++--- ckanext/resourceproxy/tests/test_proxy.py | 32 ++-- ckanext/stats/tests/test_stats_plugin.py | 2 - ckanext/textview/tests/test_view.py | 46 ++++-- 16 files changed, 364 insertions(+), 235 deletions(-) diff --git a/ckanext/datapusher/tests/test.py b/ckanext/datapusher/tests/test.py index 2d44c0b14e1..ed34bf7270c 100644 --- a/ckanext/datapusher/tests/test.py +++ b/ckanext/datapusher/tests/test.py @@ -8,15 +8,14 @@ import datetime import pylons -from pylons import config import sqlalchemy.orm as orm -import paste.fixture + +from ckan.tests import helpers import ckan.plugins as p import ckan.lib.create_test_data as ctd import ckan.model as model import ckan.tests.legacy as tests -import ckan.config.middleware as middleware import ckanext.datastore.db as db from ckanext.datastore.tests.helpers import rebuild_all_dbs, set_url_type @@ -68,9 +67,7 @@ class TestDatastoreCreate(tests.WsgiAppCase): @classmethod def setup_class(cls): - - wsgiapp = middleware.make_app(config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") p.load('datastore') @@ -81,8 +78,10 @@ def setup_class(cls): engine = db._get_engine( {'connection_url': pylons.config['ckan.datastore.write_url']}) cls.Session = orm.scoped_session(orm.sessionmaker(bind=engine)) - set_url_type( - model.Package.get('annakarenina').resources, cls.sysadmin_user) + + with cls.app.flask_app.test_request_context(): + set_url_type( + model.Package.get('annakarenina').resources, cls.sysadmin_user) # Httpretty crashes with Solr on Python 2.6, # skip the tests @@ -195,9 +194,12 @@ def test_send_datapusher_creates_task(self): 'user': self.sysadmin_user.name } - p.toolkit.get_action('datapusher_submit')(context, { - 'resource_id': resource.id - }) + # datapusher_submit will call a function further down the line that + # relies on url_for so we need a request context + with self.app.flask_app.test_request_context(): + p.toolkit.get_action('datapusher_submit')(context, { + 'resource_id': resource.id + }) context.pop('task_status', None) diff --git a/ckanext/datapusher/tests/test_interfaces.py b/ckanext/datapusher/tests/test_interfaces.py index d21bf3ab2b7..69072c5c3d5 100644 --- a/ckanext/datapusher/tests/test_interfaces.py +++ b/ckanext/datapusher/tests/test_interfaces.py @@ -9,13 +9,10 @@ from nose.tools import raises from pylons import config import sqlalchemy.orm as orm -import paste.fixture from ckan.tests import helpers, factories import ckan.plugins as p -import ckan.model as model import ckan.tests.legacy as tests -import ckan.config.middleware as middleware import ckanext.datapusher.interfaces as interfaces import ckanext.datastore.db as db @@ -42,22 +39,22 @@ def after_upload(self, context, resource_dict, package_dict): self.after_upload_calls += 1 -class TestInterace(object): +class TestInterface(object): sysadmin_user = None normal_user = None @classmethod def setup_class(cls): - wsgiapp = middleware.make_app(config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") p.load('datastore') p.load('datapusher') p.load('test_datapusher_plugin') - resource = factories.Resource(url_type='datastore') - cls.dataset = factories.Dataset(resources=[resource]) + with cls.app.flask_app.test_request_context(): + resource = factories.Resource(url_type='datastore') + cls.dataset = factories.Dataset(resources=[resource]) cls.sysadmin_user = factories.User(name='testsysadmin', sysadmin=True) cls.normal_user = factories.User(name='annafan') @@ -89,9 +86,12 @@ def test_send_datapusher_creates_task(self): 'user': self.sysadmin_user['name'] } - result = p.toolkit.get_action('datapusher_submit')(context, { - 'resource_id': resource['id'] - }) + # datapusher_submit will call a function further down the line that + # relies on url_for so we need a request context + with self.app.flask_app.test_request_context(): + result = p.toolkit.get_action('datapusher_submit')(context, { + 'resource_id': resource['id'] + }) assert not result context.pop('task_status', None) diff --git a/ckanext/datastore/tests/test_create.py b/ckanext/datastore/tests/test_create.py index a36340ec82d..bf3100bd66e 100644 --- a/ckanext/datastore/tests/test_create.py +++ b/ckanext/datastore/tests/test_create.py @@ -6,15 +6,12 @@ from nose.tools import assert_equal, raises import pylons -from pylons import config import sqlalchemy.orm as orm -import paste.fixture import ckan.plugins as p import ckan.lib.create_test_data as ctd import ckan.model as model import ckan.tests.legacy as tests -import ckan.config.middleware as middleware import ckan.tests.helpers as helpers import ckan.tests.factories as factories @@ -31,6 +28,7 @@ class TestDatastoreCreateNewTests(object): @classmethod def setup_class(cls): + cls.app = helpers._get_test_app() p.load('datastore') @classmethod @@ -38,6 +36,15 @@ def teardown_class(cls): p.unload('datastore') helpers.reset_db() + def setup(self): + + self.request_context = self.app.flask_app.test_request_context() + self.request_context.push() + + def teardown(self): + + self.request_context.pop() + def test_create_creates_index_on_primary_key(self): package = factories.Dataset() data = { @@ -240,8 +247,7 @@ class TestDatastoreCreate(tests.WsgiAppCase): @classmethod def setup_class(cls): - wsgiapp = middleware.make_app(config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") p.load('datastore') @@ -251,14 +257,24 @@ def setup_class(cls): engine = db._get_engine( {'connection_url': pylons.config['ckan.datastore.write_url']}) cls.Session = orm.scoped_session(orm.sessionmaker(bind=engine)) - set_url_type( - model.Package.get('annakarenina').resources, cls.sysadmin_user) + with cls.app.flask_app.test_request_context(): + set_url_type( + model.Package.get('annakarenina').resources, cls.sysadmin_user) @classmethod def teardown_class(cls): rebuild_all_dbs(cls.Session) p.unload('datastore') + def setup(self): + + self.request_context = self.app.flask_app.test_request_context() + self.request_context.push() + + def teardown(self): + + self.request_context.pop() + def test_create_requires_auth(self): resource = model.Package.get('annakarenina').resources[0] data = { diff --git a/ckanext/datastore/tests/test_delete.py b/ckanext/datastore/tests/test_delete.py index f0af7b861e9..0f9448c15a5 100644 --- a/ckanext/datastore/tests/test_delete.py +++ b/ckanext/datastore/tests/test_delete.py @@ -12,6 +12,7 @@ import ckan.model as model import ckan.tests.legacy as tests +import ckan.tests.helpers as helpers import ckanext.datastore.db as db from ckanext.datastore.tests.helpers import rebuild_all_dbs, set_url_type @@ -23,6 +24,8 @@ class TestDatastoreDelete(tests.WsgiAppCase): @classmethod def setup_class(cls): + + cls.app = helpers._get_test_app() if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") p.load('datastore') @@ -45,8 +48,10 @@ def setup_class(cls): engine = db._get_engine( {'connection_url': pylons.config['ckan.datastore.write_url']}) cls.Session = orm.scoped_session(orm.sessionmaker(bind=engine)) - set_url_type( - model.Package.get('annakarenina').resources, cls.sysadmin_user) + + with cls.app.flask_app.test_request_context(): + set_url_type( + model.Package.get('annakarenina').resources, cls.sysadmin_user) @classmethod def teardown_class(cls): diff --git a/ckanext/datastore/tests/test_dump.py b/ckanext/datastore/tests/test_dump.py index 15e4b447238..3add1d42997 100644 --- a/ckanext/datastore/tests/test_dump.py +++ b/ckanext/datastore/tests/test_dump.py @@ -16,6 +16,8 @@ import ckanext.datastore.db as db import ckanext.datastore.tests.helpers as helpers +import ckan.tests.helpers as test_helpers + class TestDatastoreDump(object): sysadmin_user = None @@ -23,8 +25,8 @@ class TestDatastoreDump(object): @classmethod def setup_class(cls): - wsgiapp = middleware.make_app(config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + test_helpers.reset_db() + cls.app = test_helpers._get_test_app() if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") p.load('datastore') diff --git a/ckanext/datastore/tests/test_upsert.py b/ckanext/datastore/tests/test_upsert.py index 22fedccab35..704641c2412 100644 --- a/ckanext/datastore/tests/test_upsert.py +++ b/ckanext/datastore/tests/test_upsert.py @@ -14,7 +14,6 @@ import ckan.tests.helpers as helpers import ckan.tests.factories as factories - import ckanext.datastore.db as db from ckanext.datastore.tests.helpers import rebuild_all_dbs, set_url_type @@ -85,12 +84,16 @@ class TestDatastoreUpsert(tests.WsgiAppCase): def setup_class(cls): if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") + + cls.app = helpers._get_test_app() p.load('datastore') ctd.CreateTestData.create() cls.sysadmin_user = model.User.get('testsysadmin') cls.normal_user = model.User.get('annafan') - set_url_type( - model.Package.get('annakarenina').resources, cls.sysadmin_user) + + with cls.app.flask_app.test_request_context(): + set_url_type( + model.Package.get('annakarenina').resources, cls.sysadmin_user) resource = model.Package.get('annakarenina').resources[0] cls.data = { 'resource_id': resource.id, @@ -328,7 +331,6 @@ def test_upsert_works_with_empty_list_in_json_field(self): data['records'][0]['nested']) - class TestDatastoreInsert(tests.WsgiAppCase): sysadmin_user = None normal_user = None @@ -337,33 +339,32 @@ class TestDatastoreInsert(tests.WsgiAppCase): def setup_class(cls): if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") + + cls.app = helpers._get_test_app() p.load('datastore') ctd.CreateTestData.create() cls.sysadmin_user = model.User.get('testsysadmin') cls.normal_user = model.User.get('annafan') - set_url_type( - model.Package.get('annakarenina').resources, cls.sysadmin_user) - resource = model.Package.get('annakarenina').resources[0] - cls.data = { - 'resource_id': resource.id, - 'fields': [{'id': u'b\xfck', 'type': 'text'}, - {'id': 'author', 'type': 'text'}, - {'id': 'nested', 'type': 'json'}, - {'id': 'characters', 'type': 'text[]'}, - {'id': 'published'}], - 'primary_key': u'b\xfck', - 'records': [{u'b\xfck': 'annakarenina', 'author': 'tolstoy', - 'published': '2005-03-01', 'nested': ['b', {'moo': 'moo'}]}, - {u'b\xfck': 'warandpeace', 'author': 'tolstoy', - 'nested': {'a':'b'}} - ] - } - postparams = '%s=1' % json.dumps(cls.data) - auth = {'Authorization': str(cls.sysadmin_user.apikey)} - res = cls.app.post('/api/action/datastore_create', params=postparams, - extra_environ=auth) - res_dict = json.loads(res.body) - assert res_dict['success'] is True + with cls.app.flask_app.test_request_context(): + set_url_type( + model.Package.get('annakarenina').resources, cls.sysadmin_user) + resource = model.Package.get('annakarenina').resources[0] + cls.data = { + 'resource_id': resource.id, + 'fields': [{'id': u'b\xfck', 'type': 'text'}, + {'id': 'author', 'type': 'text'}, + {'id': 'nested', 'type': 'json'}, + {'id': 'characters', 'type': 'text[]'}, + {'id': 'published'}], + 'primary_key': u'b\xfck', + 'records': [{u'b\xfck': 'annakarenina', 'author': 'tolstoy', + 'published': '2005-03-01', 'nested': ['b', {'moo': 'moo'}]}, + {u'b\xfck': 'warandpeace', 'author': 'tolstoy', + 'nested': {'a':'b'}} + ] + } + + helpers.call_action('datastore_create', **cls.data) engine = db._get_engine( {'connection_url': pylons.config['ckan.datastore.write_url']}) @@ -439,12 +440,15 @@ class TestDatastoreUpdate(tests.WsgiAppCase): def setup_class(cls): if not tests.is_datastore_supported(): raise nose.SkipTest("Datastore not supported") + + cls.app = helpers._get_test_app() p.load('datastore') ctd.CreateTestData.create() cls.sysadmin_user = model.User.get('testsysadmin') cls.normal_user = model.User.get('annafan') - set_url_type( - model.Package.get('annakarenina').resources, cls.sysadmin_user) + with cls.app.flask_app.test_request_context(): + set_url_type( + model.Package.get('annakarenina').resources, cls.sysadmin_user) resource = model.Package.get('annakarenina').resources[0] hhguide = u"hitchhiker's guide to the galaxy" cls.data = { diff --git a/ckanext/example_iauthfunctions/tests/test_example_iauthfunctions.py b/ckanext/example_iauthfunctions/tests/test_example_iauthfunctions.py index 517fdac8764..2cea8a0e370 100644 --- a/ckanext/example_iauthfunctions/tests/test_example_iauthfunctions.py +++ b/ckanext/example_iauthfunctions/tests/test_example_iauthfunctions.py @@ -3,39 +3,39 @@ '''Tests for the ckanext.example_iauthfunctions extension. ''' -import paste.fixture -import pylons.test -import pylons.config as config -import webtest - +from pylons import config import ckan.model as model import ckan.tests.legacy as tests import ckan.plugins import ckan.tests.factories as factories +import ckan.tests.helpers as helpers class TestExampleIAuthFunctionsCustomConfigSetting(object): '''Tests for the plugin_v5_custom_config_setting module. ''' - def _get_app(self, users_can_create_groups): - # Set the custom config option in pylons.config. - config['ckan.iauthfunctions.users_can_create_groups'] = ( - users_can_create_groups) + app = None - # Return a test app with the custom config. - app = ckan.config.middleware.make_app(config['global_conf'], **config) - app = webtest.TestApp(app) + @classmethod + def setup_class(cls): - ckan.plugins.load('example_iauthfunctions_v5_custom_config_setting') + if not ckan.plugins.plugin_loaded('example_iauthfunctions_v5_custom_config_setting'): + ckan.plugins.load('example_iauthfunctions_v5_custom_config_setting') - return app + # Make a copy of the Pylons config, so we can restore it in teardown. + cls._original_config = dict(config) - def teardown(self): - # Remove the custom config option from pylons.config. - del config['ckan.iauthfunctions.users_can_create_groups'] + def _get_app(self, users_can_create_groups): + + config['ckan.plugins'] = 'example_iauthfunctions_v5_custom_config_setting' + config['ckan.iauthfunctions.users_can_create_groups'] = users_can_create_groups + + return helpers._get_test_app() + + def teardown(self): # Delete any stuff that's been created in the db, so it doesn't # interfere with the next test. @@ -44,6 +44,9 @@ def teardown(self): @classmethod def teardown_class(cls): ckan.plugins.unload('example_iauthfunctions_v5_custom_config_setting') + # Restore the config to its original values + config.clear() + config.update(cls._original_config) def test_sysadmin_can_create_group_when_config_is_False(self): app = self._get_app(users_can_create_groups=False) @@ -86,39 +89,13 @@ def test_visitor_cannot_create_group_when_config_is_True(self): status=403) -class TestExampleIAuthFunctionsPluginV4(object): - '''Tests for the ckanext.example_iauthfunctions.plugin module. - - ''' - @classmethod - def setup_class(cls): - '''Nose runs this method once to setup our test class.''' - - # Make the Paste TestApp that we'll use to simulate HTTP requests to - # CKAN. - cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) - - # Test code should use CKAN's plugins.load() function to load plugins - # to be tested. - ckan.plugins.load('example_iauthfunctions_v4') +class BaseTest(object): def teardown(self): - '''Nose runs this method after each test method in our test class.''' - # Rebuild CKAN's database after each test method, so that each test # method runs with a clean slate. model.repo.rebuild_db() - @classmethod - def teardown_class(cls): - '''Nose runs this method once after all the test methods in our class - have been run. - - ''' - # We have to unload the plugin we loaded, so it doesn't affect any - # tests that run after ours. - ckan.plugins.unload('example_iauthfunctions_v4') - def _make_curators_group(self): '''This is a helper method for test methods to call when they want the 'curators' group to be created. @@ -141,6 +118,42 @@ def _make_curators_group(self): return (noncurator, curator, curators_group) + +class TestExampleIAuthFunctionsPluginV4(BaseTest): + '''Tests for the ckanext.example_iauthfunctions.plugin module. + + ''' + @classmethod + def setup_class(cls): + '''Nose runs this method once to setup our test class.''' + + # Test code should use CKAN's plugins.load() function to load plugins + # to be tested. + if not ckan.plugins.plugin_loaded('example_iauthfunctions_v4'): + ckan.plugins.load('example_iauthfunctions_v4') + + # Make a copy of the Pylons config, so we can restore it in teardown. + cls._original_config = dict(config) + config['ckan.plugins'] = 'example_iauthfunctions_v4' + + # Make the TestApp that we'll use to simulate HTTP requests to + # CKAN. + cls.app = helpers._get_test_app() + + @classmethod + def teardown_class(cls): + '''Nose runs this method once after all the test methods in our class + have been run. + + ''' + # We have to unload the plugin we loaded, so it doesn't affect any + # tests that run after ours. + ckan.plugins.unload('example_iauthfunctions_v4') + + # Restore the config to its original values + config.clear() + config.update(cls._original_config) + def test_group_create_with_no_curators_group(self): '''Test that group_create doesn't crash when there's no curators group. @@ -191,18 +204,33 @@ def test_group_create_with_curator(self): assert result['name'] == name -class TestExampleIAuthFunctionsPluginV3(TestExampleIAuthFunctionsPluginV4): +class TestExampleIAuthFunctionsPluginV3(BaseTest): '''Tests for the ckanext.example_iauthfunctions.plugin_v3 module. ''' @classmethod def setup_class(cls): - cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) - ckan.plugins.load('example_iauthfunctions_v3') + '''Nose runs this method once to setup our test class.''' + + # Test code should use CKAN's plugins.load() function to load plugins + # to be tested. + if not ckan.plugins.plugin_loaded('example_iauthfunctions_v3'): + ckan.plugins.load('example_iauthfunctions_v3') + + # Make a copy of the Pylons config, so we can restore it in teardown. + cls._original_config = dict(config) + config['ckan.plugins'] = 'example_iauthfunctions_v3' + + # Make the TestApp that we'll use to simulate HTTP requests to + # CKAN. + cls.app = helpers._get_test_app() @classmethod def teardown_class(cls): ckan.plugins.unload('example_iauthfunctions_v3') + # Restore the config to its original values + config.clear() + config.update(cls._original_config) def test_group_create_with_no_curators_group(self): '''Test that group_create returns a 404 when there's no curators group. @@ -235,18 +263,33 @@ def test_group_create_with_visitor(self): assert response['__type'] == 'Authorization Error' -class TestExampleIAuthFunctionsPluginV2(TestExampleIAuthFunctionsPluginV4): +class TestExampleIAuthFunctionsPluginV2(BaseTest): '''Tests for the ckanext.example_iauthfunctions.plugin_v2 module. ''' @classmethod def setup_class(cls): - cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) - ckan.plugins.load('example_iauthfunctions_v2') + '''Nose runs this method once to setup our test class.''' + + # Test code should use CKAN's plugins.load() function to load plugins + # to be tested. + if not ckan.plugins.plugin_loaded('example_iauthfunctions_v2'): + ckan.plugins.load('example_iauthfunctions_v2') + + # Make a copy of the Pylons config, so we can restore it in teardown. + cls._original_config = dict(config) + config['ckan.plugins'] = 'example_iauthfunctions_v2' + + # Make the TestApp that we'll use to simulate HTTP requests to + # CKAN. + cls.app = helpers._get_test_app() @classmethod def teardown_class(cls): ckan.plugins.unload('example_iauthfunctions_v2') + # Restore the config to its original values + config.clear() + config.update(cls._original_config) def test_group_create_with_curator(self): '''Test that a curator can*not* create a group. diff --git a/ckanext/example_idatasetform/tests/test_controllers.py b/ckanext/example_idatasetform/tests/test_controllers.py index 102533f96e3..86657dc83af 100644 --- a/ckanext/example_idatasetform/tests/test_controllers.py +++ b/ckanext/example_idatasetform/tests/test_controllers.py @@ -1,7 +1,7 @@ # encoding: utf-8 from nose.tools import assert_equal -from routes import url_for +from ckan.lib.helpers import url_for import ckan.plugins as plugins import ckan.tests.helpers as helpers @@ -14,8 +14,10 @@ def _get_package_edit_page(app, package_name): user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='edit', id=package_name) response = app.get( - url=url_for(controller='package', action='edit', id=package_name), + url, extra_environ=env, ) return env, response diff --git a/ckanext/example_igroupform/tests/test_controllers.py b/ckanext/example_igroupform/tests/test_controllers.py index b6f03eaf7e6..65b2370cb81 100644 --- a/ckanext/example_igroupform/tests/test_controllers.py +++ b/ckanext/example_igroupform/tests/test_controllers.py @@ -1,7 +1,7 @@ # encoding: utf-8 from nose.tools import assert_equal -from routes import url_for +from ckan.lib.helpers import url_for import ckan.plugins as plugins import ckan.tests.helpers as helpers @@ -19,8 +19,10 @@ def _get_group_new_page(app, group_type): user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} + with app.flask_app.test_request_context(): + url = url_for('%s_new' % group_type) response = app.get( - url_for('%s_new' % group_type), + url, extra_environ=env, ) return env, response @@ -43,7 +45,9 @@ def test_about(self): group = factories.Group(user=user, type=custom_group_type) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_about' % custom_group_type, + + with app.flask_app.test_request_context(): + url = url_for('%s_about' % custom_group_type, id=group_name) response = app.get(url=url, extra_environ=env) response.mustcontain(group_name) @@ -54,8 +58,10 @@ def test_bulk_process(self): group = factories.Group(user=user, type=custom_group_type) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_bulk_process' % custom_group_type, - id=group_name) + + with app.flask_app.test_request_context(): + url = url_for('%s_bulk_process' % custom_group_type, + id=group_name) try: response = app.get(url=url, extra_environ=env) except Exception as e: @@ -69,8 +75,10 @@ def test_delete(self): group = factories.Group(user=user, type=custom_group_type) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_action' % custom_group_type, action='delete', - id=group_name) + + with app.flask_app.test_request_context(): + url = url_for('%s_action' % custom_group_type, action='delete', + id=group_name) response = app.get(url=url, extra_environ=env) @@ -91,8 +99,10 @@ def test_about(self): group = factories.Organization(user=user, type=custom_group_type) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_about' % custom_group_type, - id=group_name) + + with app.flask_app.test_request_context(): + url = url_for('%s_about' % custom_group_type, + id=group_name) response = app.get(url=url, extra_environ=env) response.mustcontain(group_name) @@ -102,8 +112,10 @@ def test_bulk_process(self): group = factories.Organization(user=user, type=custom_group_type) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_bulk_process' % custom_group_type, - id=group_name) + + with app.flask_app.test_request_context(): + url = url_for('%s_bulk_process' % custom_group_type, + id=group_name) response = app.get(url=url, extra_environ=env) def test_delete(self): @@ -112,8 +124,10 @@ def test_delete(self): group = factories.Organization(user=user, type=custom_group_type) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_action' % custom_group_type, action='delete', - id=group_name) + + with app.flask_app.test_request_context(): + url = url_for('%s_action' % custom_group_type, action='delete', + id=group_name) response = app.get(url=url, extra_environ=env) @@ -137,7 +151,7 @@ def test_save(self): response = submit_and_follow(app, form, env, 'save') # check correct redirect assert_equal(response.req.url, - 'http://localhost/%s/saved' % custom_group_type) + 'http://test.ckan.net/%s/saved' % custom_group_type) # check saved ok group = model.Group.by_name(u'saved') assert_equal(group.title, u'') @@ -173,7 +187,7 @@ def test_save(self): response = submit_and_follow(app, form, env, 'save') # check correct redirect assert_equal(response.req.url, - 'http://localhost/%s/saved' % group_type) + 'http://test.ckan.net/%s/saved' % group_type) # check saved ok group = model.Group.by_name(u'saved') assert_equal(group.title, u'') @@ -195,8 +209,9 @@ def _get_group_edit_page(app, group_type, group_name=None): group = factories.Group(user=user, type=group_type) group_name = group['name'] env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_edit' % group_type, - id=group_name) + with app.flask_app.test_request_context(): + url = url_for('%s_edit' % group_type, + id=group_name) response = app.get(url=url, extra_environ=env) return env, response, group_name @@ -216,8 +231,10 @@ def test_group_doesnt_exist(self): app = self._get_test_app() user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_edit' % custom_group_type, - id='doesnt_exist') + + with app.flask_app.test_request_context(): + url = url_for('%s_edit' % custom_group_type, + id='doesnt_exist') app.get(url=url, extra_environ=env, status=404) @@ -257,8 +274,10 @@ def test_group_doesnt_exist(self): app = self._get_test_app() user = factories.User() env = {'REMOTE_USER': user['name'].encode('ascii')} - url = url_for('%s_edit' % group_type, - id='doesnt_exist') + + with app.flask_app.test_request_context(): + url = url_for('%s_edit' % group_type, + id='doesnt_exist') app.get(url=url, extra_environ=env, status=404) diff --git a/ckanext/example_itranslation/tests/test_plugin.py b/ckanext/example_itranslation/tests/test_plugin.py index cd794434aaa..e1bcd526bb3 100644 --- a/ckanext/example_itranslation/tests/test_plugin.py +++ b/ckanext/example_itranslation/tests/test_plugin.py @@ -19,48 +19,60 @@ def teardown_class(cls): def test_translated_string_in_extensions_templates(self): app = self._get_test_app() - response = app.get( - url=plugins.toolkit.url_for(controller='home', action='index', - locale='fr'), - ) + + with app.flask_app.test_request_context(): + url = plugins.toolkit.url_for(controller='home', action='index', + locale='fr') + + response = app.get(url) assert_true('This is a itranslated string' in response.body) assert_false('This is an untranslated string' in response.body) # double check the untranslated strings - response = app.get( - url=plugins.toolkit.url_for(controller='home', action='index'), - ) + + with app.flask_app.test_request_context(): + url = plugins.toolkit.url_for(controller='home', action='index') + + response = app.get(url) assert_true('This is an untranslated string' in response.body) assert_false('This is a itranslated string' in response.body) def test_translated_string_in_core_templates(self): app = self._get_test_app() - response = app.get( - url=plugins.toolkit.url_for(controller='home', action='index', - locale='fr'), - ) + + with app.flask_app.test_request_context(): + url = plugins.toolkit.url_for(controller='home', action='index', + locale='fr') + + response = app.get(url) assert_true('Overwritten string in ckan.mo' in response.body) assert_false('Connexion' in response.body) # double check the untranslated strings - response = app.get( - url=plugins.toolkit.url_for(controller='home', action='index'), - ) + + with app.flask_app.test_request_context(): + url = plugins.toolkit.url_for(controller='home', action='index') + + response = app.get(url) assert_true('Log in' in response.body) assert_false('Overwritten string in ckan.mo' in response.body) # check that we have only overwritten 'fr' - response = app.get( - url=plugins.toolkit.url_for(controller='home', action='index', - locale='de'), - ) + + with app.flask_app.test_request_context(): + url = plugins.toolkit.url_for(controller='home', action='index', + locale='de') + + response = app.get(url) assert_true('Einloggen' in response.body) assert_false('Overwritten string in ckan.mo' in response.body) def test_english_translation_replaces_default_english_string(self): app = self._get_test_app() - response = app.get( - url=plugins.toolkit.url_for(controller='home', action='index'), - ) + + with app.flask_app.test_request_context(): + url = plugins.toolkit.url_for(controller='home', action='index') + + response = app.get(url) assert_true('Replaced' in response.body) assert_false('Register' in response.body) diff --git a/ckanext/imageview/tests/test_view.py b/ckanext/imageview/tests/test_view.py index 4a742747ed7..03b0a43fa7d 100644 --- a/ckanext/imageview/tests/test_view.py +++ b/ckanext/imageview/tests/test_view.py @@ -1,6 +1,7 @@ # encoding: utf-8 -from routes import url_for + +from ckan.lib.helpers import url_for import ckan.plugins as p @@ -39,8 +40,9 @@ def test_view_shown_on_resource_page_with_image_url(self): resource_id=resource['id'], image_url='http://some.image.png') - url = url_for(controller='package', action='resource_read', - id=dataset['name'], resource_id=resource['id']) + with app.flask_app.test_request_context(): + url = url_for(controller='package', action='resource_read', + id=dataset['name'], resource_id=resource['id']) response = app.get(url) diff --git a/ckanext/multilingual/tests/test_multilingual_plugin.py b/ckanext/multilingual/tests/test_multilingual_plugin.py index 3dfc649ba62..24cd2f1ae80 100644 --- a/ckanext/multilingual/tests/test_multilingual_plugin.py +++ b/ckanext/multilingual/tests/test_multilingual_plugin.py @@ -2,13 +2,14 @@ import ckan.plugins as p import ckanext.multilingual.plugin as mulilingual_plugin -import ckan.lib.helpers + +from ckan.lib.helpers import url_for import ckan.lib.create_test_data import ckan.logic.action.update import ckan.model as model import ckan.tests.legacy import ckan.tests.legacy.html_check -import routes +from ckan.tests import helpers import paste.fixture import pylons.test @@ -18,8 +19,8 @@ class TestDatasetTermTranslation(ckan.tests.legacy.html_check.HtmlCheckMethods): 'Test the translation of datasets by the multilingual_dataset plugin.' @classmethod - def setup(cls): - cls.app = paste.fixture.TestApp(pylons.test.pylonsapp) + def setup_class(cls): + cls.app = helpers._get_test_app() if not p.plugin_loaded('multilingual_dataset'): p.load('multilingual_dataset') @@ -61,7 +62,7 @@ def setup(cls): context, data_dict) @classmethod - def teardown(cls): + def teardown_class(cls): p.unload('multilingual_dataset') p.unload('multilingual_group') p.unload('multilingual_tag') @@ -76,29 +77,30 @@ def test_user_read_translation(self): # It is testsysadmin who created the dataset, so testsysadmin whom # we'd expect to see the datasets for. - for user_name in ('testsysadmin',): - offset = routes.url_for( - controller='user', action='read', id=user_name) - for (lang_code, translations) in ( - ('de', _create_test_data.german_translations), - ('fr', _create_test_data.french_translations), - ('en', _create_test_data.english_translations), - ('pl', {})): - response = self.app.get( - offset, - status=200, - extra_environ={'CKAN_LANG': lang_code, - 'CKAN_CURRENT_URL': offset}) - terms = ('A Novel By Tolstoy') - for term in terms: - if term in translations: - assert translations[term] in response, response - elif term in _create_test_data.english_translations: - assert (_create_test_data.english_translations[term] - in response) - else: - assert term in response - assert 'this should not be rendered' not in response + with self.app.flask_app.test_request_context(): + for user_name in ('testsysadmin',): + offset = url_for( + controller='user', action='read', id=user_name) + for (lang_code, translations) in ( + ('de', _create_test_data.german_translations), + ('fr', _create_test_data.french_translations), + ('en', _create_test_data.english_translations), + ('pl', {})): + response = self.app.get( + offset, + status=200, + extra_environ={'CKAN_LANG': lang_code, + 'CKAN_CURRENT_URL': offset}) + terms = ('A Novel By Tolstoy') + for term in terms: + if term in translations: + assert translations[term] in response, response + elif term in _create_test_data.english_translations: + assert (_create_test_data.english_translations[term] + in response) + else: + assert term in response + assert 'this should not be rendered' not in response def test_org_read_translation(self): for (lang_code, translations) in ( diff --git a/ckanext/reclineview/tests/test_view.py b/ckanext/reclineview/tests/test_view.py index 897be8048f2..6a4d81a7c93 100644 --- a/ckanext/reclineview/tests/test_view.py +++ b/ckanext/reclineview/tests/test_view.py @@ -14,15 +14,14 @@ from ckan.tests import helpers, factories -class BaseTestReclineViewBase(tests.WsgiAppCase): +class BaseTestReclineViewBase(object): @classmethod def setup_class(cls): - cls.config_templates = config['ckan.legacy_templates'] - config['ckan.legacy_templates'] = 'false' - wsgiapp = middleware.make_app(config['global_conf'], **config) + + cls.app = helpers._get_test_app() + p.load(cls.view_type) - cls.app = paste.fixture.TestApp(wsgiapp) cls.p = cls.view_class() create_test_data.CreateTestData.create() @@ -32,7 +31,6 @@ def setup_class(cls): @classmethod def teardown_class(cls): - config['ckan.legacy_templates'] = cls.config_templates p.unload(cls.view_type) model.repo.rebuild_db() @@ -44,8 +42,10 @@ def test_can_view(self): assert not self.p.can_view(data_dict) def test_title_description_iframe_shown(self): - url = h.url_for(controller='package', action='resource_read', - id=self.package.name, resource_id=self.resource_id) + + with self.app.flask_app.test_request_context(): + url = h.url_for(controller='package', action='resource_read', + id=self.package.name, resource_id=self.resource_id) result = self.app.get(url) assert self.resource_view['title'] in result assert self.resource_view['description'] in result @@ -86,16 +86,12 @@ class TestReclineViewDatastoreOnly(helpers.FunctionalTestBase): @classmethod def setup_class(cls): + + cls.app = helpers._get_test_app() if not p.plugin_loaded('recline_view'): p.load('recline_view') if not p.plugin_loaded('datastore'): p.load('datastore') - app_config = config.copy() - app_config['ckan.legacy_templates'] = 'false' - app_config['ckan.plugins'] = 'recline_view datastore' - app_config['ckan.views.default_views'] = 'recline_view' - wsgiapp = middleware.make_app(config['global_conf'], **app_config) - cls.app = paste.fixture.TestApp(wsgiapp) @classmethod def teardown_class(cls): @@ -111,12 +107,16 @@ def test_create_datastore_only_view(self): 'fields': [{'id': 'a'}, {'id': 'b'}], 'records': [{'a': 1, 'b': 'xyz'}, {'a': 2, 'b': 'zzz'}] } - result = helpers.call_action('datastore_create', **data) - resource_id = result['resource_id'] + # datastore_create will call internally (or trigger something that + # calls it) so we need a Flask app context + with self.app.flask_app.test_request_context(): + result = helpers.call_action('datastore_create', **data) + + resource_id = result['resource_id'] - url = h.url_for(controller='package', action='resource_read', - id=dataset['id'], resource_id=resource_id) + url = h.url_for(controller='package', action='resource_read', + id=dataset['id'], resource_id=resource_id) result = self.app.get(url) diff --git a/ckanext/resourceproxy/tests/test_proxy.py b/ckanext/resourceproxy/tests/test_proxy.py index 28a382ef713..aca08b936cf 100644 --- a/ckanext/resourceproxy/tests/test_proxy.py +++ b/ckanext/resourceproxy/tests/test_proxy.py @@ -2,21 +2,19 @@ import sys import requests -import unittest import json import httpretty import nose +from nose.tools import assert_raises -import paste.fixture from pylons import config import ckan.model as model -import ckan.tests.legacy as tests import ckan.plugins as p import ckan.lib.create_test_data as create_test_data -import ckan.config.middleware as middleware import ckanext.resourceproxy.controller as controller import ckanext.resourceproxy.plugin as proxy +from ckan.tests import helpers JSON_STRING = json.dumps({ @@ -49,7 +47,7 @@ def set_resource_url(url): return {'resource': resource, 'package': package} -class TestProxyPrettyfied(tests.WsgiAppCase, unittest.TestCase): +class TestProxyPrettyfied(object): serving = False @@ -57,8 +55,7 @@ class TestProxyPrettyfied(tests.WsgiAppCase, unittest.TestCase): def setup_class(cls): cls._original_config = config.copy() config['ckan.plugins'] = 'resource_proxy' - wsgiapp = middleware.make_app(config['global_conf'], **config) - cls.app = paste.fixture.TestApp(wsgiapp) + cls.app = helpers._get_test_app() create_test_data.CreateTestData.create() # Httpretty crashes with Solr on Python 2.6, # skip the tests @@ -75,10 +72,17 @@ def teardown_class(cls): and not p.plugin_loaded('synchronous_search')): p.load('synchronous_search') - def setUp(self): + def setup(self): self.url = 'http://www.ckan.org/static/example.json' self.data_dict = set_resource_url(self.url) + self.request_context = self.app.flask_app.test_request_context() + self.request_context.push() + + def teardown(self): + + self.request_context.pop() + def register(self, *args, **kwargs): httpretty.HTTPretty.register_uri(httpretty.HTTPretty.GET, *args, **kwargs) @@ -113,7 +117,7 @@ def test_resource_proxy_on_404(self): result = self.app.get(proxied_url, status='*') # we expect a 409 because the resourceproxy got an error (404) # from the server - assert result.status == 409, result.status + assert result.status_int == 409, result.status_int assert '404' in result.body @httpretty.activate @@ -126,7 +130,7 @@ def test_large_file(self): proxied_url = proxy.get_proxified_resource_url(self.data_dict) result = self.app.get(proxied_url, status='*') - assert result.status == 409, result.status + assert result.status_int == 409, result.status_int assert 'too large' in result.body, result.body @httpretty.activate @@ -139,7 +143,7 @@ def test_large_file_streaming(self): proxied_url = proxy.get_proxified_resource_url(self.data_dict) result = self.app.get(proxied_url, status='*') - assert result.status == 409, result.status + assert result.status_int == 409, result.status_int assert 'too large' in result.body, result.body @httpretty.activate @@ -148,7 +152,7 @@ def test_invalid_url(self): proxied_url = proxy.get_proxified_resource_url(self.data_dict) result = self.app.get(proxied_url, status='*') - assert result.status == 409, result.status + assert result.status_int == 409, result.status_int assert 'Invalid URL' in result.body, result.body def test_non_existent_url(self): @@ -158,11 +162,11 @@ def f1(): url = self.data_dict['resource']['url'] requests.get(url) - self.assertRaises(requests.ConnectionError, f1) + assert_raises(requests.ConnectionError, f1) proxied_url = proxy.get_proxified_resource_url(self.data_dict) result = self.app.get(proxied_url, status='*') - assert result.status == 502, result.status + assert result.status_int == 502, result.status_int assert 'connection error' in result.body, result.body def test_proxied_resource_url_proxies_http_and_https_by_default(self): diff --git a/ckanext/stats/tests/test_stats_plugin.py b/ckanext/stats/tests/test_stats_plugin.py index b87af1e4625..fb3cba47aee 100644 --- a/ckanext/stats/tests/test_stats_plugin.py +++ b/ckanext/stats/tests/test_stats_plugin.py @@ -2,8 +2,6 @@ import os -from ckan.tests.legacy import url_for - from ckanext.stats.tests import StatsFixture class TestStatsPlugin(StatsFixture): diff --git a/ckanext/textview/tests/test_view.py b/ckanext/textview/tests/test_view.py index 1e6f9144cbe..ab94391f128 100644 --- a/ckanext/textview/tests/test_view.py +++ b/ckanext/textview/tests/test_view.py @@ -11,6 +11,7 @@ import ckanext.textview.plugin as plugin import ckan.lib.create_test_data as create_test_data import ckan.config.middleware as middleware +from ckan.tests import helpers def _create_test_view(view_type): @@ -29,16 +30,15 @@ def _create_test_view(view_type): return resource_view, package, resource_id -class TestTextView(tests.WsgiAppCase): +class TestTextView(object): view_type = 'text_view' @classmethod def setup_class(cls): - cls.config_templates = config['ckan.legacy_templates'] - config['ckan.legacy_templates'] = 'false' - wsgiapp = middleware.make_app(config['global_conf'], **config) - plugins.load('text_view') - cls.app = paste.fixture.TestApp(wsgiapp) + + if not plugins.plugin_loaded('text_view'): + plugins.load('text_view') + cls.p = plugin.TextView() create_test_data.CreateTestData.create() @@ -48,7 +48,6 @@ def setup_class(cls): @classmethod def teardown_class(cls): - config['ckan.legacy_templates'] = cls.config_templates plugins.unload('text_view') model.repo.rebuild_db() @@ -79,17 +78,36 @@ def test_can_view(self): assert not self.p.can_view(data_dict) def test_title_description_iframe_shown(self): - url = h.url_for(controller='package', action='resource_read', - id=self.package.name, resource_id=self.resource_id) - result = self.app.get(url) + # Make a copy of the Pylons config, so we can restore it in teardown. + original_config = dict(config) + config['ckan.plugins'] = 'text_view' + + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + url = h.url_for(controller='package', action='resource_read', + id=self.package.name, resource_id=self.resource_id) + result = app.get(url) assert self.resource_view['title'] in result assert self.resource_view['description'] in result assert 'data-module="data-viewer"' in result.body + # Restore the config to its original values + config.clear() + config.update(original_config) + def test_js_included(self): - url = h.url_for(controller='package', action='resource_view', - id=self.package.name, resource_id=self.resource_id, - view_id=self.resource_view['id']) - result = self.app.get(url) + # Make a copy of the Pylons config, so we can restore it in teardown. + original_config = dict(config) + config['ckan.plugins'] = 'text_view' + + app = helpers._get_test_app() + with app.flask_app.test_request_context(): + url = h.url_for(controller='package', action='resource_view', + id=self.package.name, resource_id=self.resource_id, + view_id=self.resource_view['id']) + result = app.get(url) assert (('text_view.js' in result.body) or ('text_view.min.js' in result.body)) + # Restore the config to its original values + config.clear() + config.update(original_config)