diff --git a/ckan/tests/__init__.py b/ckan/tests/__init__.py
index 074522b7781..82d72bbd93e 100644
--- a/ckan/tests/__init__.py
+++ b/ckan/tests/__init__.py
@@ -312,11 +312,11 @@ def list(cls):
return [model.Package.get(pkg_index.package_id).name for pkg_index in model.Session.query(model.PackageSearch)]
def setup_test_search_index():
- from ckan import plugins
+ #from ckan import plugins
if not is_search_supported():
raise SkipTest("Search not supported")
search.clear()
- plugins.load('synchronous_search')
+ #plugins.load('synchronous_search')
def is_search_supported():
is_supported_db = not model.engine_is_sqlite()
diff --git a/ckan/tests/ckantestplugin/ckantestplugin.egg-info/entry_points.txt b/ckan/tests/ckantestplugin/ckantestplugin.egg-info/entry_points.txt
index cc2189702fb..8a3326fccb2 100644
--- a/ckan/tests/ckantestplugin/ckantestplugin.egg-info/entry_points.txt
+++ b/ckan/tests/ckantestplugin/ckantestplugin.egg-info/entry_points.txt
@@ -1,9 +1,13 @@
[ckan.plugins]
routes_plugin = ckantestplugin:RoutesPlugin
-authorizer_plugin = ckantestplugin:AuthorizerPlugin
+auth_plugin = ckantestplugin:AuthPlugin
mapper_plugin2 = ckantestplugin:MapperPlugin2
-mapper_plugin = ckantestplugin:MapperPlugin
-test_observer_plugin = ckantestplugin:PluginObserverPlugin
action_plugin = ckantestplugin:ActionPlugin
-auth_plugin = ckantestplugin:AuthPlugin
+test_observer_plugin = ckantestplugin:PluginObserverPlugin
+test_resource_preview = ckantestplugin:MockResourcePreviewExtension
+test_package_controller_plugin = ckantestplugin:MockPackageControllerPlugin
+test_json_resource_preview = ckantestplugin:JsonMockResourcePreviewExtension
+authorizer_plugin = ckantestplugin:AuthorizerPlugin
+mapper_plugin = ckantestplugin:MapperPlugin
+test_group_plugin = ckantestplugin:MockGroupControllerPlugin
diff --git a/ckan/tests/ckantestplugin/ckantestplugin/__init__.py b/ckan/tests/ckantestplugin/ckantestplugin/__init__.py
index 848c9648b0c..79fbef42a1b 100644
--- a/ckan/tests/ckantestplugin/ckantestplugin/__init__.py
+++ b/ckan/tests/ckantestplugin/ckantestplugin/__init__.py
@@ -1,12 +1,13 @@
-from ckan.plugins import SingletonPlugin, implements
-from ckan.plugins import IMapper, IRoutes, IPluginObserver, IActions, IAuthFunctions
-from ckan.tests.mock_plugin import MockSingletonPlugin
+from collections import defaultdict
+import ckan.plugins as p
+import ckan.tests.mock_plugin as mock_plugin
-class MapperPlugin(SingletonPlugin):
- implements(IMapper, inherit=True)
- def __init__(self):
+class MapperPlugin(p.SingletonPlugin):
+ p.implements(p.IMapper, inherit=True)
+
+ def __init__(self, *args, **kw):
self.added = []
self.deleted = []
@@ -17,12 +18,12 @@ def before_delete(self, mapper, conn, instance):
self.deleted.append(instance)
class MapperPlugin2(MapperPlugin):
- implements(IMapper)
+ p.implements(p.IMapper)
-class RoutesPlugin(SingletonPlugin):
- implements(IRoutes, inherit=True)
+class RoutesPlugin(p.SingletonPlugin):
+ p.implements(p.IRoutes, inherit=True)
- def __init__(self):
+ def __init__(self, *args, **kw):
self.calls_made = []
def before_map(self, map):
@@ -34,18 +35,149 @@ def after_map(self, map):
return map
-class PluginObserverPlugin(MockSingletonPlugin):
- implements(IPluginObserver)
+class PluginObserverPlugin(mock_plugin.MockSingletonPlugin):
+ p.implements(p.IPluginObserver)
-class ActionPlugin(SingletonPlugin):
- implements(IActions)
+class ActionPlugin(p.SingletonPlugin):
+ p.implements(p.IActions)
def get_actions(self):
return {'status_show': lambda context, data_dict: {}}
-class AuthPlugin(SingletonPlugin):
- implements(IAuthFunctions)
+class AuthPlugin(p.SingletonPlugin):
+ p.implements(p.IAuthFunctions)
def get_auth_functions(self):
return {'package_list': lambda context, data_dict: {}}
+class MockGroupControllerPlugin(p.SingletonPlugin):
+ p.implements(p.IGroupController)
+
+ def __init__(self, *args, **kw):
+ self.calls = defaultdict(int)
+
+ def read(self, entity):
+ self.calls['read'] += 1
+
+ def create(self, entity):
+ self.calls['create'] += 1
+
+ def edit(self, entity):
+ self.calls['edit'] += 1
+
+ def authz_add_role(self, object_role):
+ self.calls['authz_add_role'] += 1
+
+ def authz_remove_role(self, object_role):
+ self.calls['authz_remove_role'] += 1
+
+ def delete(self, entity):
+ self.calls['delete'] += 1
+
+ def before_view(self, data_dict):
+ self.calls['before_view'] += 1
+ return data_dict
+
+
+class MockPackageControllerPlugin(p.SingletonPlugin):
+ p.implements(p.IPackageController)
+
+ def __init__(self, *args, **kw):
+ self.calls = defaultdict(int)
+
+ def read(self, entity):
+ self.calls['read'] += 1
+
+ def create(self, entity):
+ self.calls['create'] += 1
+
+ def edit(self, entity):
+ self.calls['edit'] += 1
+
+ def authz_add_role(self, object_role):
+ self.calls['authz_add_role'] += 1
+
+ def authz_remove_role(self, object_role):
+ self.calls['authz_remove_role'] += 1
+
+ def delete(self, entity):
+ self.calls['delete'] += 1
+
+ def before_search(self, search_params):
+ self.calls['before_search'] += 1
+ return search_params
+
+ def after_search(self, search_results, search_params):
+ self.calls['after_search'] += 1
+ return search_results
+
+ def before_index(self, data_dict):
+ self.calls['before_index'] += 1
+ return data_dict
+
+ def before_view(self, data_dict):
+ self.calls['before_view'] += 1
+ return data_dict
+
+ def after_create(self, context, data_dict):
+ self.calls['after_create'] += 1
+ self.id_in_dict = 'id' in data_dict
+
+ return data_dict
+
+ def after_update(self, context, data_dict):
+ self.calls['after_update'] += 1
+ return data_dict
+
+ def after_delete(self, context, data_dict):
+ self.calls['after_delete'] += 1
+ return data_dict
+
+ def after_show(self, context, data_dict):
+ self.calls['after_show'] += 1
+ return data_dict
+
+ def update_facet_titles(self, facet_titles):
+ return facet_titles
+
+
+
+class MockResourcePreviewExtension(mock_plugin.MockSingletonPlugin):
+ p.implements(p.IResourcePreview)
+
+ def __init__(self, *args, **kw):
+ self.calls = defaultdict(int)
+
+ def can_preview(self, data_dict):
+ assert(isinstance(data_dict['resource'], dict))
+ assert(isinstance(data_dict['package'], dict))
+ assert('on_same_domain' in data_dict['resource'])
+
+ self.calls['can_preview'] += 1
+ return data_dict['resource']['format'].lower() == 'mock'
+
+ def setup_template_variables(self, context, data_dict):
+ self.calls['setup_template_variables'] += 1
+
+ def preview_template(self, context, data_dict):
+ assert(isinstance(data_dict['resource'], dict))
+ assert(isinstance(data_dict['package'], dict))
+
+ self.calls['preview_templates'] += 1
+ return 'tests/mock_resource_preview_template.html'
+
+
+class JsonMockResourcePreviewExtension(MockResourcePreviewExtension):
+ def can_preview(self, data_dict):
+ super(JsonMockResourcePreviewExtension, self).can_preview(data_dict)
+ return data_dict['resource']['format'].lower() == 'json'
+
+ def preview_template(self, context, data_dict):
+ super(JsonMockResourcePreviewExtension, self).preview_template(context, data_dict)
+ self.calls['preview_templates'] += 1
+ return 'tests/mock_json_resource_preview_template.html'
+
+
+# importing this file loads all these extensions by default
+# so clean up the extensions
+p.plugins_update()
diff --git a/ckan/tests/ckantestplugin/setup.py b/ckan/tests/ckantestplugin/setup.py
index c06a99891e3..8219fda18a8 100644
--- a/ckan/tests/ckantestplugin/setup.py
+++ b/ckan/tests/ckantestplugin/setup.py
@@ -1,6 +1,5 @@
# After editing this file run python setup.py egg_info in this directory
from setuptools import setup, find_packages
-import sys, os
version = '0.0'
@@ -30,6 +29,11 @@
'test_observer_plugin=ckantestplugin:PluginObserverPlugin',
'action_plugin=ckantestplugin:ActionPlugin',
'auth_plugin=ckantestplugin:AuthPlugin',
+ 'test_group_plugin=ckantestplugin:MockGroupControllerPlugin',
+ 'test_package_controller_plugin=ckantestplugin:MockPackageControllerPlugin',
+ 'test_resource_preview=ckantestplugin:MockResourcePreviewExtension',
+ 'test_json_resource_preview=ckantestplugin:JsonMockResourcePreviewExtension',
+
]
}
)
diff --git a/ckan/tests/functional/api/model/test_package.py b/ckan/tests/functional/api/model/test_package.py
index 82b3d125938..a5af988089f 100644
--- a/ckan/tests/functional/api/model/test_package.py
+++ b/ckan/tests/functional/api/model/test_package.py
@@ -3,7 +3,6 @@
from nose.tools import assert_equal, assert_raises
from ckan.lib.create_test_data import CreateTestData
-from ckan import plugins
import ckan.lib.search as search
from ckan.lib.search.common import SolrSettings
@@ -268,7 +267,6 @@ def test_register_post_indexerror(self):
bad_solr_url = 'http://127.0.0.1/badsolrurl'
original_settings = SolrSettings.get()[0]
try:
- plugins.load('synchronous_search')
SolrSettings.init(bad_solr_url)
assert not self.get_package_by_name(self.package_fixture_data['name'])
@@ -659,14 +657,12 @@ def test_entity_update_indexerror(self):
bad_solr_url = 'http://127.0.0.1/badsolrurl'
original_settings = SolrSettings.get()[0]
try:
- plugins.load('synchronous_search')
SolrSettings.init(bad_solr_url)
assert_raises(
search.SearchIndexError, self.assert_package_update_ok, 'name', 'post'
)
finally:
- plugins.unload('synchronous_search')
SolrSettings.init(original_settings)
def test_package_update_delete_resource(self):
diff --git a/ckan/tests/functional/api/test_util.py b/ckan/tests/functional/api/test_util.py
index 8949760be32..746ee2f41a8 100644
--- a/ckan/tests/functional/api/test_util.py
+++ b/ckan/tests/functional/api/test_util.py
@@ -163,5 +163,5 @@ def test_status(self):
assert_equal(res['locale_default'], 'en')
assert_equal(type(res['extensions']), list)
- expected_extensions = set(('stats', 'test_tag_vocab_plugin'))
+ expected_extensions = set(('stats',))
assert_equal(set(res['extensions']), expected_extensions)
diff --git a/ckan/tests/functional/test_group.py b/ckan/tests/functional/test_group.py
index 432d288eb69..fb02d886e75 100644
--- a/ckan/tests/functional/test_group.py
+++ b/ckan/tests/functional/test_group.py
@@ -17,35 +17,7 @@
from base import FunctionalTestCase
from ckan.tests import search_related, is_search_supported
-
-class MockGroupControllerPlugin(SingletonPlugin):
- implements(IGroupController)
-
- def __init__(self):
- from collections import defaultdict
- self.calls = defaultdict(int)
-
- def read(self, entity):
- self.calls['read'] += 1
-
- def create(self, entity):
- self.calls['create'] += 1
-
- def edit(self, entity):
- self.calls['edit'] += 1
-
- def authz_add_role(self, object_role):
- self.calls['authz_add_role'] += 1
-
- def authz_remove_role(self, object_role):
- self.calls['authz_remove_role'] += 1
-
- def delete(self, entity):
- self.calls['delete'] += 1
-
- def before_view(self, data_dict):
- self.calls['before_view'] += 1
- return data_dict
+import ckan.tests.test_plugins as test_plugins
class TestGroup(FunctionalTestCase):
@@ -55,6 +27,7 @@ def setup_class(self):
search.clear()
model.Session.remove()
CreateTestData.create()
+ test_plugins.install_ckantestplugin()
@classmethod
def teardown_class(self):
@@ -215,14 +188,14 @@ def test_read_non_existent(self):
res = self.app.get(offset, status=404)
def test_read_plugin_hook(self):
- plugin = MockGroupControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_group_plugin')
name = u'david'
offset = url_for(controller='group', action='read', id=name)
res = self.app.get(offset, status=200,
extra_environ={'REMOTE_USER': 'testsysadmin'})
- assert plugin.calls['read'] == 1, plugin.calls
- plugins.unload(plugin)
+ p = plugins.get_plugin('test_group_plugin')
+ assert p.calls['read'] == 1, p.calls
+ plugins.unload('test_group_plugin')
def test_read_and_authorized_to_edit(self):
name = u'david'
@@ -288,6 +261,7 @@ def setup_class(self):
model.repo.new_revision()
model.Session.add(model.Package(name=self.packagename))
model.repo.commit_and_remove()
+ test_plugins.install_ckantestplugin()
@classmethod
@@ -388,8 +362,7 @@ def test_4_new_duplicate_package(self):
assert_equal(pkg_names, [self.packagename])
def test_edit_plugin_hook(self):
- plugin = MockGroupControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_group_plugin')
offset = url_for(controller='group', action='edit', id=self.groupname)
res = self.app.get(offset, status=200,
extra_environ={'REMOTE_USER': 'testsysadmin'})
@@ -398,8 +371,9 @@ def test_edit_plugin_hook(self):
form['title'] = "huhuhu"
res = form.submit('save', status=302,
extra_environ={'REMOTE_USER': 'testsysadmin'})
- assert plugin.calls['edit'] == 1, plugin.calls
- plugins.unload(plugin)
+ p = plugins.get_plugin('test_group_plugin')
+ assert p.calls['edit'] == 1, p.calls
+ plugins.unload('test_group_plugin')
def test_edit_image_url(self):
group = model.Group.by_name(self.groupname)
@@ -596,8 +570,7 @@ def test_3_new_duplicate_group(self):
assert 'class="field_error"' in res, res
def test_new_plugin_hook(self):
- plugin = MockGroupControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_group_plugin')
offset = url_for(controller='group', action='new')
res = self.app.get(offset, status=200,
extra_environ={'REMOTE_USER': 'testsysadmin'})
@@ -606,8 +579,9 @@ def test_new_plugin_hook(self):
form['title'] = "huhuhu"
res = form.submit('save', status=302,
extra_environ={'REMOTE_USER': 'testsysadmin'})
- assert plugin.calls['create'] == 1, plugin.calls
- plugins.unload(plugin)
+ p = plugins.get_plugin('test_group_plugin')
+ assert p.calls['create'] == 1, p.calls
+ plugins.unload('test_group_plugin')
def test_new_bad_param(self):
offset = url_for(controller='group', action='new',
diff --git a/ckan/tests/functional/test_package.py b/ckan/tests/functional/test_package.py
index 56a1f3edf27..2326ac236e9 100644
--- a/ckan/tests/functional/test_package.py
+++ b/ckan/tests/functional/test_package.py
@@ -1,12 +1,8 @@
-import cgi
import datetime
-from paste.fixture import AppError
-from pylons import config
-from pylons import c
+from pylons import config, c
from genshi.core import escape as genshi_escape
from difflib import unified_diff
-from nose.plugins.skip import SkipTest
from nose.tools import assert_equal
from ckan.tests import *
@@ -15,77 +11,11 @@
from base import FunctionalTestCase
import ckan.model as model
from ckan.lib.create_test_data import CreateTestData
-import ckan.lib.helpers as h
-import ckan.lib.search as search
from ckan.logic.action import get, update
-from ckan.controllers.package import PackageController
-from ckan.plugins import SingletonPlugin, implements, IPackageController
from ckan import plugins
-from ckan.rating import set_rating
from ckan.lib.search.common import SolrSettings
-class MockPackageControllerPlugin(SingletonPlugin):
- implements(IPackageController)
-
- def __init__(self):
- from collections import defaultdict
- self.calls = defaultdict(int)
-
- def read(self, entity):
- self.calls['read'] += 1
-
- def create(self, entity):
- self.calls['create'] += 1
-
- def edit(self, entity):
- self.calls['edit'] += 1
-
- def authz_add_role(self, object_role):
- self.calls['authz_add_role'] += 1
-
- def authz_remove_role(self, object_role):
- self.calls['authz_remove_role'] += 1
-
- def delete(self, entity):
- self.calls['delete'] += 1
-
- def before_search(self, search_params):
- self.calls['before_search'] += 1
- return search_params
-
- def after_search(self, search_results, search_params):
- self.calls['after_search'] += 1
- return search_results
-
- def before_index(self, data_dict):
- self.calls['before_index'] += 1
- return data_dict
-
- def before_view(self, data_dict):
- self.calls['before_view'] += 1
- return data_dict
-
- def after_create(self, context, data_dict):
- self.calls['after_create'] += 1
- self.id_in_dict = 'id' in data_dict
-
- return data_dict
-
- def after_update(self, context, data_dict):
- self.calls['after_update'] += 1
- return data_dict
-
- def after_delete(self, context, data_dict):
- self.calls['after_delete'] += 1
- return data_dict
-
- def after_show(self, context, data_dict):
- self.calls['after_show'] += 1
- return data_dict
-
- def update_facet_titles(self, facet_titles):
- return facet_titles
existing_extra_html = ('', '')
@@ -386,15 +316,15 @@ def test_history(self):
assert name in res
def test_read_plugin_hook(self):
- plugin = MockPackageControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_package_controller_plugin')
+ plugin = plugins.get_plugin('test_package_controller_plugin')
name = u'annakarenina'
offset = url_for(controller='package', action='read', id=name)
res = self.app.get(offset)
assert plugin.calls['read'] == 1, plugin.calls
assert plugin.calls['after_show'] == 1, plugin.calls
- plugins.unload(plugin)
+ plugins.unload('test_package_controller_plugin')
def test_resource_list(self):
# TODO restore this test. It doesn't make much sense with the
@@ -934,8 +864,8 @@ def test_edit_bad_name(self):
def test_edit_plugin_hook(self):
# just the absolute basics
try:
- plugin = MockPackageControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_package_controller_plugin')
+ plugin = plugins.get_plugin('test_package_controller_plugin')
res = self.app.get(self.offset, extra_environ=self.extra_environ_admin)
new_name = u'new-name'
new_title = u'New Title'
@@ -946,15 +876,15 @@ def test_edit_plugin_hook(self):
res = fv.submit('save', extra_environ=self.extra_environ_admin)
# get redirected ...
assert plugin.calls['edit'] == 1, plugin.calls
- plugins.unload(plugin)
+ plugins.unload('test_package_controller_plugin')
finally:
self._reset_data()
def test_after_update_plugin_hook(self):
# just the absolute basics
try:
- plugin = MockPackageControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_package_controller_plugin')
+ plugin = plugins.get_plugin('test_package_controller_plugin')
res = self.app.get(self.offset, extra_environ=self.extra_environ_admin)
new_name = u'new-name'
new_title = u'New Title'
@@ -966,7 +896,7 @@ def test_after_update_plugin_hook(self):
# get redirected ...
assert plugin.calls['after_update'] == 1, plugin.calls
assert plugin.calls['after_create'] == 0, plugin.calls
- plugins.unload(plugin)
+ plugins.unload('test_package_controller_plugin')
finally:
self._reset_data()
@@ -1023,16 +953,13 @@ def test_edit_indexerror(self):
bad_solr_url = 'http://127.0.0.1/badsolrurl'
solr_url = SolrSettings.get()[0]
try:
- plugins.load('synchronous_search')
SolrSettings.init(bad_solr_url)
fv = self.res.forms['dataset-edit']
- prefix = ''
fv['log_message'] = u'Test log message'
res = fv.submit('save', status=500, extra_environ=self.extra_environ_admin)
assert 'Unable to update search index' in res, res
finally:
- plugins.unload('synchronous_search')
SolrSettings.init(solr_url)
def test_edit_pkg_with_relationships(self):
@@ -1085,8 +1012,8 @@ def teardown_class(self):
model.repo.rebuild_db()
def test_delete(self):
- plugin = MockPackageControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_package_controller_plugin')
+ plugin = plugins.get_plugin('test_package_controller_plugin')
offset = url_for(controller='package', action='delete',
id='warandpeace')
@@ -1099,8 +1026,7 @@ def test_delete(self):
assert plugin.calls['delete'] == 1
assert plugin.calls['after_delete'] == 1
-
- plugins.unload(plugin)
+ plugins.unload('test_package_controller_plugin')
class TestNew(TestPackageForm):
@@ -1296,8 +1222,8 @@ def test_new_existing_name(self):
self._assert_form_errors(res)
def test_new_plugin_hook(self):
- plugin = MockPackageControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_package_controller_plugin')
+ plugin = plugins.get_plugin('test_package_controller_plugin')
offset = url_for(controller='package', action='new')
res = self.app.get(offset, extra_environ=self.extra_environ_tester)
new_name = u'plugged'
@@ -1308,11 +1234,11 @@ def test_new_plugin_hook(self):
# get redirected ...
assert plugin.calls['edit'] == 0, plugin.calls
assert plugin.calls['create'] == 1, plugin.calls
- plugins.unload(plugin)
+ plugins.unload('test_package_controller_plugin')
def test_after_create_plugin_hook(self):
- plugin = MockPackageControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_package_controller_plugin')
+ plugin = plugins.get_plugin('test_package_controller_plugin')
offset = url_for(controller='package', action='new')
res = self.app.get(offset, extra_environ=self.extra_environ_tester)
new_name = u'plugged2'
@@ -1325,14 +1251,12 @@ def test_after_create_plugin_hook(self):
assert plugin.calls['after_create'] == 1, plugin.calls
assert plugin.id_in_dict
-
- plugins.unload(plugin)
+ plugins.unload('test_package_controller_plugin')
def test_new_indexerror(self):
bad_solr_url = 'http://127.0.0.1/badsolrurl'
solr_url = SolrSettings.get()[0]
try:
- plugins.load('synchronous_search')
SolrSettings.init(bad_solr_url)
new_package_name = u'new-package-missing-solr'
@@ -1348,7 +1272,6 @@ def test_new_indexerror(self):
res = fv.submit('save', status=500, extra_environ=self.extra_environ_tester)
assert 'Unable to add package to search index' in res, res
finally:
- plugins.unload('synchronous_search')
SolrSettings.init(solr_url)
def test_change_locale(self):
@@ -1374,14 +1297,14 @@ def teardown_class(self):
model.repo.rebuild_db()
def test_search_plugin_hooks(self):
- plugin = MockPackageControllerPlugin()
- plugins.load(plugin)
+ plugins.load('test_package_controller_plugin')
+ plugin = plugins.get_plugin('test_package_controller_plugin')
offset = url_for(controller='package', action='search')
res = self.app.get(offset)
# get redirected ...
assert plugin.calls['before_search'] == 1, plugin.calls
assert plugin.calls['after_search'] == 1, plugin.calls
- plugins.unload(plugin)
+ plugins.unload('test_package_controller_plugin')
class TestNewPreview(TestPackageBase):
pkgname = u'testpkg'
diff --git a/ckan/tests/functional/test_preview_interface.py b/ckan/tests/functional/test_preview_interface.py
index 13f649a5337..d294e083b9d 100644
--- a/ckan/tests/functional/test_preview_interface.py
+++ b/ckan/tests/functional/test_preview_interface.py
@@ -6,54 +6,14 @@
import ckan.lib.create_test_data as create_test_data
import ckan.tests.functional.base as base
import ckan.plugins as plugins
-import ckan.tests.mock_plugin as mock
import ckan.lib.dictization.model_dictize as model_dictize
-class MockResourcePreviewExtension(mock.MockSingletonPlugin):
- plugins.implements(plugins.IResourcePreview)
-
- def __init__(self):
- from collections import defaultdict
- self.calls = defaultdict(int)
-
- def can_preview(self, data_dict):
- assert(isinstance(data_dict['resource'], dict))
- assert(isinstance(data_dict['package'], dict))
- assert('on_same_domain' in data_dict['resource'])
-
- self.calls['can_preview'] += 1
- return data_dict['resource']['format'].lower() == 'mock'
-
- def setup_template_variables(self, context, data_dict):
- self.calls['setup_template_variables'] += 1
-
- def preview_template(self, context, data_dict):
- assert(isinstance(data_dict['resource'], dict))
- assert(isinstance(data_dict['package'], dict))
-
- self.calls['preview_templates'] += 1
- return 'tests/mock_resource_preview_template.html'
-
-
-class JsonMockResourcePreviewExtension(MockResourcePreviewExtension):
- def can_preview(self, data_dict):
- super(JsonMockResourcePreviewExtension, self).can_preview(data_dict)
- return data_dict['resource']['format'].lower() == 'json'
-
- def preview_template(self, context, data_dict):
- super(JsonMockResourcePreviewExtension, self).preview_template(context, data_dict)
- self.calls['preview_templates'] += 1
- return 'tests/mock_json_resource_preview_template.html'
-
-
class TestPluggablePreviews(base.FunctionalTestCase):
@classmethod
def setup_class(cls):
- cls.plugin = MockResourcePreviewExtension()
- plugins.load(cls.plugin)
- json_plugin = JsonMockResourcePreviewExtension()
- plugins.load(json_plugin)
+ plugins.load('test_resource_preview', 'test_json_resource_preview')
+ cls.plugin = plugins.get_plugin('test_resource_preview')
create_test_data.CreateTestData.create()
@@ -71,7 +31,7 @@ def setup_class(cls):
@classmethod
def teardown_class(cls):
model.repo.rebuild_db()
- plugins.unload(cls.plugin)
+ plugins.unload('test_resource_preview', 'test_json_resource_preview')
def test_hook(self):
testpackage = self.package
diff --git a/ckan/tests/functional/test_tag_vocab.py b/ckan/tests/functional/test_tag_vocab.py
index a7ad0fa9135..04ca960a7bf 100644
--- a/ckan/tests/functional/test_tag_vocab.py
+++ b/ckan/tests/functional/test_tag_vocab.py
@@ -4,8 +4,7 @@
from ckan.lib.create_test_data import CreateTestData
import ckan.lib.helpers as h
from ckan.tests import WsgiAppCase
-# ensure that test_tag_vocab_plugin is added as a plugin in the testing .ini file
-from ckanext.test_tag_vocab_plugin import MockVocabTagsPlugin
+import ckan.plugins as plugins
TEST_VOCAB_NAME = 'test-vocab'
@@ -72,7 +71,7 @@ def value__get(self):
class TestWUI(WsgiAppCase):
@classmethod
def setup_class(cls):
- MockVocabTagsPlugin().set_active(True)
+ plugins.load('test_tag_vocab_plugin')
CreateTestData.create(package_type='mock_vocab_tags_plugin')
cls.sysadmin_user = model.User.get('testsysadmin')
cls.dset = model.Package.get('warandpeace')
@@ -105,7 +104,7 @@ def setup_class(cls):
@classmethod
def teardown_class(cls):
- MockVocabTagsPlugin().set_active(False)
+ plugins.unload('test_tag_vocab_plugin')
paste.fixture.Field.classes['select'] = cls.old_select
model.repo.rebuild_db()
@@ -141,7 +140,7 @@ def test_01_dataset_view(self):
self._add_vocab_tag_to_dataset(self.dset.id, vocab_id, self.tag1_name)
response = self.app.get(h.url_for(controller='package', action='read',
id=self.dset.id))
- assert self.tag1_name in response.body
+ assert self.tag1_name in response.body, self.tag1_name
self._remove_vocab_tags(self.dset.id, vocab_id, self.tag1_name)
def test_02_dataset_edit_add_vocab_tag(self):
diff --git a/ckan/tests/mock_plugin.py b/ckan/tests/mock_plugin.py
index edfbfbd941e..a8f074bb823 100644
--- a/ckan/tests/mock_plugin.py
+++ b/ckan/tests/mock_plugin.py
@@ -4,7 +4,7 @@ class _MockPlugin(object):
"""
MockPlugin tracks method calls via __getattr__ for rapid mocking of
plugins.
-
+
Use MockPlugin.calls or MockPlugin..calls to access
call information
"""
@@ -19,8 +19,8 @@ def __init__(self, boundto, name):
def __call__(self, *args, **kwargs):
self.boundto.calls.append((self.name, args, kwargs))
self.calls.append((args, kwargs))
-
- def __init__(self):
+
+ def __init__(self, *arg, **kw):
self.calls = []
self.__mockmethods__ = {}
@@ -35,6 +35,7 @@ def reset_calls(self):
"""
for mockmethod in self.MockMethod.registry.values():
mockmethod.calls = []
+ self.__mockmethods__ = {}
self.calls = []
class MockPlugin(_MockPlugin, Plugin):
diff --git a/ckan/tests/test_plugins.py b/ckan/tests/test_plugins.py
index 816a84d218a..98c12f91283 100644
--- a/ckan/tests/test_plugins.py
+++ b/ckan/tests/test_plugins.py
@@ -5,21 +5,19 @@
from nose.tools import raises
from unittest import TestCase
-from paste.deploy import loadapp
from pyutilib.component.core import PluginGlobals
from pylons import config
from pkg_resources import working_set, Distribution, PathMetadata
import ckan.logic as logic
import ckan.new_authz as new_authz
-from ckan import plugins
-from ckan.config.middleware import make_app
-from ckan.tests import conf_dir
-from ckan.tests.mock_plugin import MockSingletonPlugin
+import ckan.plugins as plugins
from ckan.plugins.core import find_system_plugins
from ckan.plugins import Interface, implements
from ckan.lib.create_test_data import CreateTestData
+import ckantestplugin
+
def install_ckantestplugin():
# Create the ckantestplugin setuptools distribution
@@ -31,6 +29,14 @@ def install_ckantestplugin():
ckantestplugin_dist = Distribution(
base_dir, project_name=dist_name, metadata=metadata)
working_set.add(ckantestplugin_dist)
+ # We have messed up the pluginns so lets clean up
+ plugins.plugins_update()
+
+def _make_calls(*args):
+ out = []
+ for arg in args:
+ out.append(((arg,), {}))
+ return out
class IFoo(Interface):
@@ -65,139 +71,122 @@ def test_provided_by(self):
assert IFoo.provided_by(FooBarImpl())
assert not IFoo.provided_by(BarImpl())
-class TestIPluginObserverPlugin(TestCase):
+class TestIPluginObserverPlugin(object):
- class PluginObserverPlugin(MockSingletonPlugin):
- from ckan.plugins import IPluginObserver
- implements(IPluginObserver)
- class OtherPlugin(MockSingletonPlugin):
- implements(IFoo)
+ @classmethod
+ def setup(cls):
+ cls.observer = plugins.load('test_observer_plugin')
- def setUp(self):
- plugins.unload_all()
- plugins.load(self.PluginObserverPlugin)
- self.PluginObserverPlugin().reset_calls()
+ @classmethod
+ def teardown(cls):
+ plugins.unload('test_observer_plugin')
def test_notified_on_load(self):
- observer = self.PluginObserverPlugin()
- plugins.load(self.OtherPlugin)
- assert observer.before_load.calls == [((self.OtherPlugin,), {})]
- assert observer.after_load.calls == [((self.OtherPlugin(),), {})]
- assert observer.before_unload.calls == []
- assert observer.after_unload.calls == []
-
- def test_notified_on_unload(self):
-
- plugins.load(self.OtherPlugin)
- observer = self.PluginObserverPlugin()
+ observer = self.observer
observer.reset_calls()
+ with plugins.use_plugin('action_plugin') as action:
+ assert observer.before_load.calls == _make_calls(action), observer.before_load.calls
+ assert observer.after_load.calls == _make_calls(action), observer.after_load.calls
+ assert observer.before_unload.calls == []
+ assert observer.after_unload.calls == []
- plugins.unload(self.OtherPlugin)
+ def test_notified_on_unload(self):
+ with plugins.use_plugin('action_plugin') as action:
+ observer = self.observer
+ observer.reset_calls()
assert observer.before_load.calls == []
assert observer.after_load.calls == []
- assert observer.before_unload.calls == [((self.OtherPlugin(),), {})], observer.before_unload.calls
- assert observer.after_unload.calls == [((self.OtherPlugin(),), {})]
+ assert observer.before_unload.calls == _make_calls(action)
+ assert observer.after_unload.calls == _make_calls(action)
+
+class TestPlugins(object):
-class TestPlugins(TestCase):
- def setUp(self):
- self._saved_plugins_config = config.get('ckan.plugins', '')
- config['ckan.plugins'] = ''
- plugins.reset()
+ @classmethod
+ def setup(cls):
install_ckantestplugin()
- def tearDown(self):
- # Ideally this would remove the ckantestplugin_dist from the working
- # set, but I can't find a way to do that in setuptools.
- plugins.unload_all()
- config['ckan.plugins'] = self._saved_plugins_config
- plugins.load_all(config)
def test_plugins_load(self):
+ config_plugins = config['ckan.plugins']
config['ckan.plugins'] = 'mapper_plugin routes_plugin'
plugins.load_all(config)
- # Imported after call to plugins.load_all to ensure that we test the
- # plugin loader starting from a blank slate.
- from ckantestplugin import MapperPlugin, MapperPlugin2, RoutesPlugin
- import ckan.lib.search as search
-
- system_plugins = set(plugin() for plugin in find_system_plugins())
- assert PluginGlobals.env().services == set([MapperPlugin(), RoutesPlugin(), search.SynchronousSearchPlugin()]) | system_plugins
+ # synchronous_search automatically gets loaded
+ current_plugins = set([plugins.get_plugin(p) for p in ['mapper_plugin', 'routes_plugin', 'synchronous_search'] + find_system_plugins()])
+ assert PluginGlobals.env().services == current_plugins
+ # cleanup
+ config['ckan.plugins'] = config_plugins
+ plugins.load_all(config)
def test_only_configured_plugins_loaded(self):
- config['ckan.plugins'] = 'mapper_plugin'
- plugins.load_all(config)
-
- from ckantestplugin import MapperPlugin, MapperPlugin2, RoutesPlugin
from ckan.model.extension import PluginMapperExtension
from ckan.config.routing import routing_plugins
-
-
- # MapperPlugin should be loaded as it is listed in config['ckan.plugins']
- assert MapperPlugin() in iter(PluginMapperExtension.observers)
-
- # MapperPlugin2 and RoutesPlugin should NOT be loaded
- assert MapperPlugin2() not in iter(PluginMapperExtension.observers)
- assert RoutesPlugin() not in routing_plugins
+ with plugins.use_plugin('mapper_plugin'):
+ # MapperPlugin should be loaded as it is listed in
+ assert ckantestplugin.MapperPlugin() in iter(PluginMapperExtension.observers)
+ # MapperPlugin2 and RoutesPlugin should NOT be loaded
+ assert ckantestplugin.MapperPlugin2() not in iter(PluginMapperExtension.observers)
+ assert ckantestplugin.RoutesPlugin() not in routing_plugins
def test_plugin_loading_order(self):
"""
Check that plugins are loaded in the order specified in the config
"""
- from ckantestplugin import MapperPlugin, MapperPlugin2, PluginObserverPlugin
-
- observerplugin = PluginObserverPlugin()
-
+ config_plugins = config['ckan.plugins']
config['ckan.plugins'] = 'test_observer_plugin mapper_plugin mapper_plugin2'
- expected_order = MapperPlugin, MapperPlugin2
-
plugins.load_all(config)
- print observerplugin.before_load.calls
- assert observerplugin.before_load.calls[:-1] == [((p,), {}) for p in expected_order]
- assert observerplugin.after_load.calls[:-1] == [((p.__instance__,), {}) for p in (observerplugin,) + expected_order]
+
+ observerplugin = plugins.get_plugin('test_observer_plugin')
+
+ expected_order = _make_calls(plugins.get_plugin('mapper_plugin'),
+ plugins.get_plugin('mapper_plugin2'))
+ assert observerplugin.before_load.calls[:-2] == expected_order
+ expected_order = _make_calls(plugins.get_plugin('test_observer_plugin'),
+ plugins.get_plugin('mapper_plugin'),
+ plugins.get_plugin('mapper_plugin2'))
+ assert observerplugin.after_load.calls[:-2] == expected_order
config['ckan.plugins'] = 'test_observer_plugin mapper_plugin2 mapper_plugin'
- expected_order = MapperPlugin2, MapperPlugin
- observerplugin.reset_calls()
+ plugins.load_all(config)
+ expected_order = _make_calls(plugins.get_plugin('mapper_plugin2'),
+ plugins.get_plugin('mapper_plugin'))
+ assert observerplugin.before_load.calls[:-2] == expected_order
+ expected_order = _make_calls(plugins.get_plugin('test_observer_plugin'),
+ plugins.get_plugin('mapper_plugin2'),
+ plugins.get_plugin('mapper_plugin'))
+ assert observerplugin.after_load.calls[:-2] == expected_order
+ # cleanup
+ config['ckan.plugins'] = config_plugins
plugins.load_all(config)
- assert observerplugin.before_load.calls[:-1] == [((p,), {}) for p in expected_order]
- assert observerplugin.after_load.calls[:-1] == [((p.__instance__,), {}) for p in (observerplugin,) + expected_order]
def test_mapper_plugin_fired(self):
- config['ckan.plugins'] = 'mapper_plugin'
- plugins.load_all(config)
- CreateTestData.create_arbitrary([{'name':u'testpkg'}])
- mapper_plugin = PluginGlobals.env_registry['pca'].plugin_registry['MapperPlugin'].__instance__
- assert len(mapper_plugin.added) == 2 # resource group table added automatically
- assert mapper_plugin.added[0].name == 'testpkg'
+ with plugins.use_plugin('mapper_plugin') as mapper_plugin:
+ CreateTestData.create_arbitrary([{'name':u'testpkg'}])
+ assert len(mapper_plugin.added) == 2 # resource group table added automatically
+ assert mapper_plugin.added[0].name == 'testpkg'
def test_routes_plugin_fired(self):
- config['ckan.plugins'] = 'routes_plugin'
- app = make_app(config['global_conf'], **config)
- routes_plugin = PluginGlobals.env_registry['pca'].plugin_registry['RoutesPlugin'].__instance__
- assert routes_plugin.calls_made == ['before_map', 'after_map'], \
- routes_plugin.calls_made
+ with plugins.use_plugin('routes_plugin'):
+ routes_plugin = PluginGlobals.env_registry['pca'].plugin_registry['RoutesPlugin'].__instance__
+ assert routes_plugin.calls_made == ['before_map', 'after_map'], \
+ routes_plugin.calls_made
+
def test_action_plugin_override(self):
- plugins.load_all(config)
status_show_original = logic.get_action('status_show')(None, {})
- plugins.load('action_plugin')
- assert logic.get_action('status_show')(None, {}) != status_show_original
- plugins.unload('action_plugin')
+ with plugins.use_plugin('action_plugin'):
+ assert logic.get_action('status_show')(None, {}) != status_show_original
assert logic.get_action('status_show')(None, {}) == status_show_original
def test_auth_plugin_override(self):
- plugins.load_all(config)
package_list_original = new_authz.is_authorized('package_list', {})
- plugins.load('auth_plugin')
- assert new_authz.is_authorized('package_list', {}) != package_list_original
- plugins.unload('auth_plugin')
+ with plugins.use_plugin('auth_plugin'):
+ assert new_authz.is_authorized('package_list', {}) != package_list_original
assert new_authz.is_authorized('package_list', {}) == package_list_original
-
diff --git a/test-core.ini b/test-core.ini
index d4372d234c2..7c99531ef46 100644
--- a/test-core.ini
+++ b/test-core.ini
@@ -54,7 +54,7 @@ search_backend = sql
# Change API key HTTP header to something non-standard.
apikey_header_name = X-Non-Standard-CKAN-API-Key
-ckan.plugins = stats test_tag_vocab_plugin
+ckan.plugins = stats
# use so we can check that html is *not* escaped
ckan.template_head_end =