This is an automated email from the ASF dual-hosted git repository. dill0wn pushed a commit to branch dw/8455 in repository https://gitbox.apache.org/repos/asf/allura.git
commit ba1a294cb2d0edf0da6831c4c56c193d94846ecd Author: Kenton Taylor <[email protected]> AuthorDate: Tue Aug 23 20:19:46 2022 +0000 all trivial failures resolved for ./Allura, only legit failures remain --- Allura/allura/tests/functional/test_admin.py | 2 +- Allura/allura/tests/functional/test_discuss.py | 2 +- Allura/allura/tests/functional/test_feeds.py | 4 +- Allura/allura/tests/functional/test_nav.py | 2 +- .../tests/functional/test_personal_dashboard.py | 2 +- Allura/allura/tests/functional/test_rest.py | 2 +- Allura/allura/tests/functional/test_root.py | 4 +- Allura/allura/tests/functional/test_site_admin.py | 4 +- .../allura/tests/functional/test_user_profile.py | 3 - Allura/allura/tests/model/test_artifact.py | 5 +- Allura/allura/tests/model/test_auth.py | 2 +- Allura/allura/tests/model/test_discussion.py | 4 +- Allura/allura/tests/model/test_filesystem.py | 2 +- Allura/allura/tests/model/test_monq.py | 2 +- Allura/allura/tests/model/test_neighborhood.py | 2 +- Allura/allura/tests/model/test_notification.py | 12 +- Allura/allura/tests/model/test_oauth.py | 2 +- Allura/allura/tests/model/test_project.py | 3 +- Allura/allura/tests/model/test_repo.py | 8 +- Allura/allura/tests/model/test_timeline.py | 2 +- .../tests/scripts/test_create_sitemap_files.py | 2 +- .../allura/tests/scripts/test_delete_projects.py | 2 +- Allura/allura/tests/scripts/test_misc_scripts.py | 2 +- Allura/allura/tests/scripts/test_reindexes.py | 4 +- .../tests/templates/jinja_master/test_lib.py | 2 +- Allura/allura/tests/test_app.py | 12 +- Allura/allura/tests/test_commands.py | 19 +- Allura/allura/tests/test_decorators.py | 4 + Allura/allura/tests/test_diff.py | 2 +- Allura/allura/tests/test_globals.py | 1452 ++++++++++---------- Allura/allura/tests/test_helpers.py | 19 +- Allura/allura/tests/test_mail_util.py | 6 +- Allura/allura/tests/test_middlewares.py | 2 +- Allura/allura/tests/test_multifactor.py | 8 +- Allura/allura/tests/test_plugin.py | 11 +- Allura/allura/tests/test_scripttask.py | 2 +- Allura/allura/tests/test_tasks.py | 16 +- Allura/allura/tests/test_utils.py | 8 +- Allura/allura/tests/test_validators.py | 37 +- Allura/allura/tests/test_webhooks.py | 10 +- Allura/allura/tests/unit/__init__.py | 6 +- .../test_discussion_moderation_controller.py | 4 +- Allura/allura/tests/unit/phone/test_nexmo.py | 2 +- Allura/allura/tests/unit/spam/test_spam_filter.py | 2 +- .../allura/tests/unit/spam/test_stopforumspam.py | 2 +- Allura/allura/tests/unit/test_app.py | 6 +- Allura/allura/tests/unit/test_discuss.py | 2 - Allura/allura/tests/unit/test_helpers/test_ago.py | 2 +- .../tests/unit/test_helpers/test_set_context.py | 8 +- .../allura/tests/unit/test_ldap_auth_provider.py | 2 +- Allura/allura/tests/unit/test_mixins.py | 2 +- Allura/allura/tests/unit/test_post_model.py | 2 +- Allura/allura/tests/unit/test_repo.py | 2 +- Allura/allura/tests/unit/test_session.py | 6 +- Allura/allura/tests/unit/test_solr.py | 8 +- .../forgetracker/tests/functional/test_root.py | 4 +- 56 files changed, 879 insertions(+), 870 deletions(-) diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py index 8c1caab3a..b5f39a393 100644 --- a/Allura/allura/tests/functional/test_admin.py +++ b/Allura/allura/tests/functional/test_admin.py @@ -964,7 +964,7 @@ class TestProjectAdmin(TestController): @with_nose_compatibility class TestExport(TestController): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.setup_with_tools() diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py index 5164142d3..a2442074a 100644 --- a/Allura/allura/tests/functional/test_discuss.py +++ b/Allura/allura/tests/functional/test_discuss.py @@ -402,7 +402,7 @@ class TestDiscuss(TestDiscussBase): @with_nose_compatibility class TestAttachment(TestDiscussBase): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.thread_link = self._thread_link() thread = self.app.get(self.thread_link) diff --git a/Allura/allura/tests/functional/test_feeds.py b/Allura/allura/tests/functional/test_feeds.py index de32fa04c..4baf5f9d0 100644 --- a/Allura/allura/tests/functional/test_feeds.py +++ b/Allura/allura/tests/functional/test_feeds.py @@ -26,8 +26,8 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestFeeds(TestController): - def setup_class(self, method): - TestController.setUp(self) + def setup_method(self, method): + TestController.setup_method(self, method) self._setUp() @td.with_wiki diff --git a/Allura/allura/tests/functional/test_nav.py b/Allura/allura/tests/functional/test_nav.py index f865d8f32..840a97969 100644 --- a/Allura/allura/tests/functional/test_nav.py +++ b/Allura/allura/tests/functional/test_nav.py @@ -33,7 +33,7 @@ class TestNavigation(TestController): - Test of logo. """ - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.logo_pattern = ('div', {'class': 'nav-logo'}) self.global_nav_pattern = ('nav', {'class': 'nav-left'}) diff --git a/Allura/allura/tests/functional/test_personal_dashboard.py b/Allura/allura/tests/functional/test_personal_dashboard.py index ea3244123..428afb029 100644 --- a/Allura/allura/tests/functional/test_personal_dashboard.py +++ b/Allura/allura/tests/functional/test_personal_dashboard.py @@ -89,7 +89,7 @@ class TestTicketsSection(TrackerTestController): @with_nose_compatibility class TestMergeRequestsSection(TestController): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) setup_unit_test() self.setup_with_tools() diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py index a24ff59e4..0be71b396 100644 --- a/Allura/allura/tests/functional/test_rest.py +++ b/Allura/allura/tests/functional/test_rest.py @@ -420,7 +420,7 @@ class TestRestHome(TestRestApiBase): @with_nose_compatibility class TestRestNbhdAddProject(TestRestApiBase): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) # create some troves we'll need M.TroveCategory(fullname="Root", trove_cat_id=1, trove_parent_id=0) diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py index 47105f8d9..95a1ea15b 100644 --- a/Allura/allura/tests/functional/test_root.py +++ b/Allura/allura/tests/functional/test_root.py @@ -47,7 +47,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestRootController(TestController): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) n_adobe = M.Neighborhood.query.get(name='Adobe') assert n_adobe @@ -192,7 +192,7 @@ class TestRootController(TestController): @with_nose_compatibility class TestRootWithSSLPattern(TestController): - def setup_class(self, method): + def setup_method(self, method): with td.patch_middleware_config({'force_ssl.pattern': '^/auth'}): super().setup_method(method) diff --git a/Allura/allura/tests/functional/test_site_admin.py b/Allura/allura/tests/functional/test_site_admin.py index fce6abe29..7ca541362 100644 --- a/Allura/allura/tests/functional/test_site_admin.py +++ b/Allura/allura/tests/functional/test_site_admin.py @@ -361,7 +361,7 @@ class TestProjectsSearch(TestController): 'id': 'allura/model/project/Project#53ccf6e8100d2b0741746e9f', }]) - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) # Create project that matches TEST_HIT id _id = ObjectId('53ccf6e8100d2b0741746e9f') @@ -419,7 +419,7 @@ class TestUsersSearch(TestController): 'user_registration_date_dt': '2014-09-09T13:17:38Z', 'username_s': 'darth'}]) - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) # Create user that matches TEST_HIT id _id = ObjectId('540efdf2100d2b1483155d39') diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py index 9ec08f518..4a54ffa69 100644 --- a/Allura/allura/tests/functional/test_user_profile.py +++ b/Allura/allura/tests/functional/test_user_profile.py @@ -269,9 +269,6 @@ class TestUserProfile(TestController): assert 'content="noindex, follow"' not in r.text - - - @with_nose_compatibility class TestUserProfileHasAccessAPI(TestRestApiBase): diff --git a/Allura/allura/tests/model/test_artifact.py b/Allura/allura/tests/model/test_artifact.py index 43ac4828d..8f0100e82 100644 --- a/Allura/allura/tests/model/test_artifact.py +++ b/Allura/allura/tests/model/test_artifact.py @@ -54,7 +54,10 @@ class Checkmessage(M.Message): Mapper.compile_all() -def setup_method(self, method): +# def setup_method_wrapper(fn): +# fn(None) + +def setup_method(): setup_basic_test() setup_unit_test() setup_with_tools() diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py index 870fcfa21..2d6aa75f7 100644 --- a/Allura/allura/tests/model/test_auth.py +++ b/Allura/allura/tests/model/test_auth.py @@ -45,7 +45,7 @@ from alluratest.controller import setup_basic_test, setup_global_objects, setup_ from allura.tests.pytest_helpers import with_nose_compatibility -def setup_method(self, method): +def setup_method(): setup_basic_test() ThreadLocalORMSession.close_all() setup_global_objects() diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py index 86f3467e0..1bfc445b9 100644 --- a/Allura/allura/tests/model/test_discussion.py +++ b/Allura/allura/tests/model/test_discussion.py @@ -38,9 +38,9 @@ from allura.tests import TestController from alluratest.controller import setup_global_objects -def setup_method(self, method): +def setup_method(): controller = TestController() - controller.setup_method(method) + controller.setup_method(None) controller.app.get('/wiki/Home/') setup_global_objects() ThreadLocalORMSession.close_all() diff --git a/Allura/allura/tests/model/test_filesystem.py b/Allura/allura/tests/model/test_filesystem.py index 29a32b5d8..df0e5b7d5 100644 --- a/Allura/allura/tests/model/test_filesystem.py +++ b/Allura/allura/tests/model/test_filesystem.py @@ -41,7 +41,7 @@ Mapper.compile_all() @with_nose_compatibility class TestFile(TestCase): - def setup_class(self, method): + def setup_method(self, method): config = { 'ming.main.uri': 'mim://host/allura', 'ming.project.uri': 'mim://host/project-data', diff --git a/Allura/allura/tests/model/test_monq.py b/Allura/allura/tests/model/test_monq.py index f2fd7ad29..9dc682149 100644 --- a/Allura/allura/tests/model/test_monq.py +++ b/Allura/allura/tests/model/test_monq.py @@ -24,7 +24,7 @@ from alluratest.controller import setup_basic_test, setup_global_objects from allura import model as M -def setup_method(self, method): +def setup_method(): setup_basic_test() ThreadLocalORMSession.close_all() setup_global_objects() diff --git a/Allura/allura/tests/model/test_neighborhood.py b/Allura/allura/tests/model/test_neighborhood.py index 28b85dca1..26a773331 100644 --- a/Allura/allura/tests/model/test_neighborhood.py +++ b/Allura/allura/tests/model/test_neighborhood.py @@ -25,7 +25,7 @@ from allura.tests import decorators as td from alluratest.controller import setup_basic_test, setup_global_objects -def setup_method(self, method): +def setup_method(): setup_basic_test() setup_with_tools() diff --git a/Allura/allura/tests/model/test_notification.py b/Allura/allura/tests/model/test_notification.py index 5df6a54df..7e0b8ed3d 100644 --- a/Allura/allura/tests/model/test_notification.py +++ b/Allura/allura/tests/model/test_notification.py @@ -37,7 +37,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestNotification(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() self.setup_with_tools() @@ -169,7 +169,7 @@ class TestNotification(unittest.TestCase): @with_nose_compatibility class TestPostNotifications(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() self.setup_with_tools() @@ -308,7 +308,7 @@ class TestPostNotifications(unittest.TestCase): @with_nose_compatibility class TestSubscriptionTypes(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() self.setup_with_tools() @@ -346,10 +346,10 @@ class TestSubscriptionTypes(unittest.TestCase): def test_message(self): self._test_message() - self.setup_method(method) + self.setup_method(None) self._test_message() - self.setup_method(method) + self.setup_method(None) M.notification.MAILBOX_QUIESCENT = timedelta(minutes=1) # will raise "assert msg is not None" since the new message is not 1 # min old: @@ -481,7 +481,7 @@ class TestSubscriptionTypes(unittest.TestCase): @with_nose_compatibility class TestSiteNotification(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): self.note = M.SiteNotification( active=True, impressions=0, diff --git a/Allura/allura/tests/model/test_oauth.py b/Allura/allura/tests/model/test_oauth.py index 2a8b82ad6..67d12b094 100644 --- a/Allura/allura/tests/model/test_oauth.py +++ b/Allura/allura/tests/model/test_oauth.py @@ -24,7 +24,7 @@ from allura import model as M from alluratest.controller import setup_basic_test, setup_global_objects -def setup_method(self, method): +def setup_method(): setup_basic_test() ThreadLocalORMSession.close_all() setup_global_objects() diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py index 339168f15..524754bc3 100644 --- a/Allura/allura/tests/model/test_project.py +++ b/Allura/allura/tests/model/test_project.py @@ -31,7 +31,7 @@ from allura.lib.exceptions import ToolError, Invalid from mock import MagicMock, patch -def setup_method(self, method): +def setup_method(): setup_basic_test() setup_with_tools() @@ -41,6 +41,7 @@ def setup_with_tools(): setup_global_objects() +@with_setup(setup_method) def test_project(): assert type(c.project.sidebar_menu()) == list assert c.project.script_name in c.project.url() diff --git a/Allura/allura/tests/model/test_repo.py b/Allura/allura/tests/model/test_repo.py index 60d5487c7..873b411c8 100644 --- a/Allura/allura/tests/model/test_repo.py +++ b/Allura/allura/tests/model/test_repo.py @@ -74,7 +74,7 @@ class RepoImplTestBase: class RepoTestBase(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() @mock.patch('allura.model.repository.Repository.url') @@ -132,7 +132,7 @@ class RepoTestBase(unittest.TestCase): @with_nose_compatibility class TestLastCommit(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() self.repo = mock.Mock( @@ -405,7 +405,7 @@ class TestLastCommit(unittest.TestCase): @with_nose_compatibility class TestModelCache(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): self.cache = M.repository.ModelCache() def test_normalize_query(self): @@ -685,7 +685,7 @@ class TestModelCache(unittest.TestCase): @with_nose_compatibility class TestMergeRequest: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() self.mr = M.MergeRequest( diff --git a/Allura/allura/tests/model/test_timeline.py b/Allura/allura/tests/model/test_timeline.py index f1e32434b..3d8bc26e7 100644 --- a/Allura/allura/tests/model/test_timeline.py +++ b/Allura/allura/tests/model/test_timeline.py @@ -27,7 +27,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility class TestActivityObject_Functional: # NOTE not for unit tests, this class sets up all the junk - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() diff --git a/Allura/allura/tests/scripts/test_create_sitemap_files.py b/Allura/allura/tests/scripts/test_create_sitemap_files.py index 6df1d6f3a..c5835109f 100644 --- a/Allura/allura/tests/scripts/test_create_sitemap_files.py +++ b/Allura/allura/tests/scripts/test_create_sitemap_files.py @@ -33,7 +33,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestCreateSitemapFiles: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() def run_script(self, options): diff --git a/Allura/allura/tests/scripts/test_delete_projects.py b/Allura/allura/tests/scripts/test_delete_projects.py index 29a983f8c..57c219f54 100644 --- a/Allura/allura/tests/scripts/test_delete_projects.py +++ b/Allura/allura/tests/scripts/test_delete_projects.py @@ -31,7 +31,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestDeleteProjects(TestController): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) n = M.Neighborhood.query.get(name='Projects') admin = M.User.by_username('test-admin') diff --git a/Allura/allura/tests/scripts/test_misc_scripts.py b/Allura/allura/tests/scripts/test_misc_scripts.py index c36a064b6..8ebbba848 100644 --- a/Allura/allura/tests/scripts/test_misc_scripts.py +++ b/Allura/allura/tests/scripts/test_misc_scripts.py @@ -28,7 +28,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestClearOldNotifications: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() def run_script(self, options): diff --git a/Allura/allura/tests/scripts/test_reindexes.py b/Allura/allura/tests/scripts/test_reindexes.py index eaa4eb7bc..53a51f04a 100644 --- a/Allura/allura/tests/scripts/test_reindexes.py +++ b/Allura/allura/tests/scripts/test_reindexes.py @@ -28,7 +28,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestReindexProjects: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() def run_script(self, options): @@ -53,7 +53,7 @@ class TestReindexProjects: @with_nose_compatibility class TestReindexUsers: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() def run_script(self, options): diff --git a/Allura/allura/tests/templates/jinja_master/test_lib.py b/Allura/allura/tests/templates/jinja_master/test_lib.py index 87cc5fe87..f3eea9edd 100644 --- a/Allura/allura/tests/templates/jinja_master/test_lib.py +++ b/Allura/allura/tests/templates/jinja_master/test_lib.py @@ -30,7 +30,7 @@ def strip_space(s): class TemplateTest: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() self.jinja2_env = AlluraJinjaRenderer.create(config, g)['jinja'].jinja2_env diff --git a/Allura/allura/tests/test_app.py b/Allura/allura/tests/test_app.py index eeeb9ecea..b93170a8e 100644 --- a/Allura/allura/tests/test_app.py +++ b/Allura/allura/tests/test_app.py @@ -18,17 +18,18 @@ from tg import tmpl_context as c import mock from ming.base import Object -from alluratest.tools import assert_equal, assert_raises +from alluratest.tools import assert_raises from formencode import validators as fev from alluratest.controller import setup_unit_test +from alluratest.tools import with_setup from allura import app from allura.lib.app_globals import Icon from allura.lib import mail_util from allura.tests.pytest_helpers import with_nose_compatibility -def setup_method(self, method): +def setup_method(): setup_unit_test() c.user._id = None c.project = mock.Mock() @@ -48,7 +49,6 @@ def setup_method(self, method): c.app.url = c.app.config.url() c.app.__version__ = '0.0' - def test_config_options(): options = [ app.ConfigOption('test1', str, 'MyTestValue'), @@ -77,11 +77,13 @@ def test_config_option_with_validator(): assert_raises(fev.Invalid, opt.validate, '') +@with_setup(setup_method) def test_options_on_install_default(): a = app.Application(c.project, c.app.config) assert a.options_on_install() == [] +@with_setup(setup_method) def test_options_on_install(): opts = [app.ConfigOption('url', str, None), app.ConfigOption('private', bool, None)] @@ -94,7 +96,7 @@ def test_options_on_install(): a = TestApp(c.project, c.app.config) assert a.options_on_install() == opts - +@with_setup(setup_method) def test_main_menu(): class TestApp(app.Application): @property @@ -110,6 +112,7 @@ def test_main_menu(): assert main_menu[0].children == [] # default main_menu implementation should drop the children from sitemap() +@with_setup(setup_method) def test_sitemap(): sm = app.SitemapEntry('test', '')[ app.SitemapEntry('a', 'a/'), @@ -125,6 +128,7 @@ def test_sitemap(): assert len(sm.children) == 3 +@with_setup(setup_method) @mock.patch('allura.app.Application.PostClass.query.get') def test_handle_artifact_unicode(qg): """ diff --git a/Allura/allura/tests/test_commands.py b/Allura/allura/tests/test_commands.py index 03b3fb954..84bac7a10 100644 --- a/Allura/allura/tests/test_commands.py +++ b/Allura/allura/tests/test_commands.py @@ -19,7 +19,7 @@ import datetime import six -from alluratest.tools import assert_raises, assert_in +from alluratest.tools import assert_raises, assert_in, with_setup from testfixtures import OutputCapture from datadiff.tools import assert_equal @@ -30,7 +30,7 @@ from mock import Mock, call, patch import pymongo import pkg_resources -from alluratest.controller import setup_basic_test, setup_global_objects +from alluratest.controller import setup_basic_test, setup_global_objects, setup_unit_test from allura.command import base, script, set_neighborhood_features, \ create_neighborhood, show_models, taskd_cleanup, taskd from allura import model as M @@ -47,12 +47,13 @@ class EmptyClass: pass -def setup_class(self, method): +def setup_method(): """Method called by nose before running each test""" setup_basic_test() setup_global_objects() + setup_unit_test() - +@with_setup(setup_method) def test_script(): cmd = script.ScriptCommand('script') cmd.run( @@ -61,6 +62,7 @@ def test_script(): [test_config, pkg_resources.resource_filename('allura', 'tests/tscript_error.py')]) +@with_setup(setup_method) def test_set_neighborhood_max_projects(): neighborhood = M.Neighborhood.query.find().first() n_id = neighborhood._id @@ -84,6 +86,7 @@ def test_set_neighborhood_max_projects(): [test_config, str(n_id), 'max_projects', '2.8']) +@with_setup(setup_method) def test_set_neighborhood_private(): neighborhood = M.Neighborhood.query.find().first() n_id = neighborhood._id @@ -109,6 +112,7 @@ def test_set_neighborhood_private(): [test_config, str(n_id), 'private_projects', '2.8']) +@with_setup(setup_method) def test_set_neighborhood_google_analytics(): neighborhood = M.Neighborhood.query.find().first() n_id = neighborhood._id @@ -134,6 +138,7 @@ def test_set_neighborhood_google_analytics(): [test_config, str(n_id), 'google_analytics', '2.8']) +@with_setup(setup_method) def test_set_neighborhood_css(): neighborhood = M.Neighborhood.query.find().first() n_id = neighborhood._id @@ -168,6 +173,7 @@ def test_set_neighborhood_css(): [test_config, str(n_id), 'css', 'True']) +@with_setup(setup_method) def test_update_neighborhood(): cmd = create_neighborhood.UpdateNeighborhoodCommand('update-neighborhood') cmd.run([test_config, 'Projects', 'True']) @@ -341,7 +347,7 @@ class TestTaskCommand: @with_nose_compatibility class TestTaskdCleanupCommand: - def setup_class(self, method): + def setup_method(self, method): self.cmd_class = taskd_cleanup.TaskdCleanupCommand self.old_check_taskd_status = self.cmd_class._check_taskd_status self.cmd_class._check_taskd_status = lambda x, p: 'OK' @@ -503,6 +509,9 @@ class TestReindexAsTask: @with_nose_compatibility class TestReindexCommand: + def setup_method(self, method): + setup_method() + @patch('allura.command.show_models.g') def test_skip_solr_delete(self, g): cmd = show_models.ReindexCommand('reindex') diff --git a/Allura/allura/tests/test_decorators.py b/Allura/allura/tests/test_decorators.py index 5bdf5cf70..033e5c41a 100644 --- a/Allura/allura/tests/test_decorators.py +++ b/Allura/allura/tests/test_decorators.py @@ -23,11 +23,15 @@ import gc from alluratest.tools import assert_equal, assert_not_equal from allura.tests.pytest_helpers import with_nose_compatibility from allura.lib.decorators import task, memoize +from alluratest.controller import setup_basic_test, setup_global_objects @with_nose_compatibility class TestTask(TestCase): + def setup_method(self, method): + setup_basic_test() + def test_no_params(self): @task def func(): diff --git a/Allura/allura/tests/test_diff.py b/Allura/allura/tests/test_diff.py index 505b95c33..d128386b0 100644 --- a/Allura/allura/tests/test_diff.py +++ b/Allura/allura/tests/test_diff.py @@ -24,7 +24,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestHtmlSideBySideDiff(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): self.diff = HtmlSideBySideDiff() def test_render_change(self): diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py index b1f67003b..f75f2d268 100644 --- a/Allura/allura/tests/test_globals.py +++ b/Allura/allura/tests/test_globals.py @@ -25,7 +25,6 @@ import six from mock import patch, Mock from bson import ObjectId -from alluratest.tools import with_setup, assert_equal, assert_in, assert_not_in from tg import tmpl_context as c, app_globals as g import tg from oembed import OEmbedError @@ -54,756 +53,6 @@ def squish_spaces(text): # \xa0 is in unicode form return re.sub(r'[\s\xa0]+', ' ', text) - -def setup_method(self, method): - """Method called by nose once before running the package. Some functions need it run again to reset data""" - setup_basic_test() - setup_unit_test() - setup_with_tools() - - -def teadown_method(): - setup_method(None) - - [email protected]_wiki -def setup_with_tools(): - setup_global_objects() - - [email protected]_wiki -def test_app_globals(): - with h.push_context('test', 'wiki', neighborhood='Projects'): - assert g.app_static( - 'css/wiki.css') == '/nf/_static_/wiki/css/wiki.css', g.app_static('css/wiki.css') - - -@with_setup(setup_method) -def test_macro_projects(): - file_name = 'neo-icon-set-454545-256x350.png' - file_path = os.path.join( - allura.__path__[0], 'nf', 'allura', 'images', file_name) - - p_nbhd = M.Neighborhood.query.get(name='Projects') - p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) - c.project = p_test - icon_file = open(file_path, 'rb') - M.ProjectFile.save_image( - file_name, icon_file, content_type='image/png', - square=True, thumbnail_size=(48, 48), - thumbnail_meta=dict(project_id=c.project._id, category='icon')) - icon_file.close() - p_test2 = M.Project.query.get( - shortname='test2', neighborhood_id=p_nbhd._id) - c.project = p_test2 - icon_file = open(file_path, 'rb') - M.ProjectFile.save_image( - file_name, icon_file, content_type='image/png', - square=True, thumbnail_size=(48, 48), - thumbnail_meta=dict(project_id=c.project._id, category='icon')) - icon_file.close() - p_sub1 = M.Project.query.get( - shortname='test/sub1', neighborhood_id=p_nbhd._id) - c.project = p_sub1 - icon_file = open(file_path, 'rb') - M.ProjectFile.save_image( - file_name, icon_file, content_type='image/png', - square=True, thumbnail_size=(48, 48), - thumbnail_meta=dict(project_id=c.project._id, category='icon')) - icon_file.close() - p_test.labels = ['test', 'root'] - p_sub1.labels = ['test', 'sub1'] - # Make one project private - p_test.private = False - p_sub1.private = False - p_test2.private = True - - ThreadLocalORMSession.flush_all() - - with h.push_config(c, - project=p_nbhd.neighborhood_project, - user=M.User.by_username('test-admin')): - r = g.markdown_wiki.convert('[[projects]]') - assert 'alt="Test Project Logo"' in r, r - assert 'alt="A Subproject Logo"' in r, r - r = g.markdown_wiki.convert('[[projects labels=root]]') - assert 'alt="Test Project Logo"' in r, r - assert 'alt="A Subproject Logo"' not in r, r - r = g.markdown_wiki.convert('[[projects labels=sub1]]') - assert 'alt="Test Project Logo"' not in r, r - assert 'alt="A Subproject Logo"' in r, r - r = g.markdown_wiki.convert('[[projects labels=test]]') - assert 'alt="Test Project Logo"' in r, r - assert 'alt="A Subproject Logo"' in r, r - r = g.markdown_wiki.convert('[[projects labels=test,root]]') - assert 'alt="Test Project Logo"' in r, r - assert 'alt="A Subproject Logo"' not in r, r - r = g.markdown_wiki.convert('[[projects labels=test,sub1]]') - assert 'alt="Test Project Logo"' not in r, r - assert 'alt="A Subproject Logo"' in r, r - r = g.markdown_wiki.convert('[[projects labels=root|sub1]]') - assert 'alt="Test Project Logo"' in r, r - assert 'alt="A Subproject Logo"' in r, r - r = g.markdown_wiki.convert('[[projects labels=test,root|root,sub1]]') - assert 'alt="Test Project Logo"' in r, r - assert 'alt="A Subproject Logo"' not in r, r - r = g.markdown_wiki.convert('[[projects labels=test,root|test,sub1]]') - assert 'alt="Test Project Logo"' in r, r - assert 'alt="A Subproject Logo"' in r, r - r = g.markdown_wiki.convert('[[projects show_total=True sort=random]]') - assert '<p class="macro_projects_total">3 Projects' in r, r - r = g.markdown_wiki.convert( - '[[projects show_total=True private=True sort=random]]') - assert '<p class="macro_projects_total">1 Projects' in r, r - assert 'alt="Test 2 Logo"' in r, r - assert 'alt="Test Project Logo"' not in r, r - assert 'alt="A Subproject Logo"' not in r, r - - r = g.markdown_wiki.convert('[[projects show_proj_icon=True]]') - assert 'alt="Test Project Logo"' in r - r = g.markdown_wiki.convert('[[projects show_proj_icon=False]]') - assert 'alt="Test Project Logo"' not in r - - -def test_macro_neighborhood_feeds(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) - with h.push_context('--init--', 'wiki', neighborhood='Projects'): - r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') - assert 'Home modified by' in r, r - r = re.sub(r'<small>.*? ago</small>', '', r) # remove "less than 1 second ago" etc - orig_len = len(r) - # Make project private & verify we don't see its new feed items - anon = M.User.anonymous() - p_test.acl.insert(0, M.ACE.deny( - M.ProjectRole.anonymous(p_test)._id, 'read')) - ThreadLocalORMSession.flush_all() - pg = WM.Page.query.get(title='Home', app_config_id=c.app.config._id) - pg.text = 'Change' - with h.push_config(c, user=M.User.by_username('test-admin')): - pg.commit() - r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') - r = re.sub(r'<small>.*? ago</small>', '', r) # remove "less than 1 second ago" etc - new_len = len(r) - assert new_len == orig_len - p = BM.BlogPost(title='test me', - neighborhood_id=p_test.neighborhood_id) - p.text = 'test content' - p.state = 'published' - p.make_slug() - with h.push_config(c, user=M.User.by_username('test-admin')): - p.commit() - ThreadLocalORMSession.flush_all() - with h.push_config(c, user=anon): - r = g.markdown_wiki.convert('[[neighborhood_blog_posts]]') - assert 'test content' in r - - -@with_setup(setup_method) -def test_macro_members(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) - p_test.add_user(M.User.by_username('test-user'), ['Developer']) - p_test.add_user(M.User.by_username('test-user-0'), ['Member']) - ThreadLocalORMSession.flush_all() - r = g.markdown_wiki.convert('[[members limit=2]]').replace('\t', '').replace('\n', '') - assert (r == - '<div class="markdown_content"><h6>Project Members:</h6>' - '<ul class="md-users-list">' - '<li><a href="/u/test-admin/">Test Admin</a> (admin)</li>' - '<li><a href="/u/test-user/">Test User</a></li>' - '<li class="md-users-list-more"><a href="/p/test/_members">All Members</a></li>' - '</ul>' - '</div>') - - -@with_setup(setup_method) -def test_macro_members_escaping(): - user = M.User.by_username('test-admin') - user.display_name = 'Test Admin <script>' - r = g.markdown_wiki.convert('[[members]]') - assert (r.replace('\n', '').replace('\t', '') == - '<div class="markdown_content"><h6>Project Members:</h6>' - '<ul class="md-users-list">' - '<li><a href="/u/test-admin/">Test Admin <script></a> (admin)</li>' - '</ul></div>') - - -@with_setup(setup_method) -def test_macro_project_admins(): - user = M.User.by_username('test-admin') - user.display_name = 'Test Ådmin <script>' - with h.push_context('test', neighborhood='Projects'): - r = g.markdown_wiki.convert('[[project_admins]]') - assert (r.replace('\n', '') == - '<div class="markdown_content"><h6>Project Admins:</h6>' - '<ul class="md-users-list">' - ' <li><a href="/u/test-admin/">Test \xc5dmin <script></a></li>' - '</ul></div>') - - -@with_setup(setup_method) -def test_macro_project_admins_one_br(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) - p_test.add_user(M.User.by_username('test-user'), ['Admin']) - ThreadLocalORMSession.flush_all() - with h.push_config(c, project=p_test): - r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]') - - assert '</a><br/><br/><a href=' not in r, r - assert '</a></li><li><a href=' in r, r - - [email protected]_wiki -def test_macro_include_no_extra_br(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) - wiki = p_test.app_instance('wiki') - with h.push_context(p_test._id, app_config_id=wiki.config._id): - p = WM.Page.upsert(title='Include_1') - p.text = 'included page 1' - p.commit() - p = WM.Page.upsert(title='Include_2') - p.text = 'included page 2' - p.commit() - p = WM.Page.upsert(title='Include_3') - p.text = 'included page 3' - p.commit() - ThreadLocalORMSession.flush_all() - md = '[[include ref=Include_1]]\n[[include ref=Include_2]]\n[[include ref=Include_3]]' - html = g.markdown_wiki.convert(md) - - expected_html = '''<div class="markdown_content"><p></p><div> -<div class="markdown_content"><p>included page 1</p></div> -</div> -<div> -<div class="markdown_content"><p>included page 2</p></div> -</div> -<div> -<div class="markdown_content"><p>included page 3</p></div> -</div> -<p></p></div>''' - assert squish_spaces(html) == squish_spaces(expected_html) - - -@with_setup(setup_method, teadown_method) [email protected]_wiki [email protected]_tool('test', 'Wiki', 'wiki2') -def test_macro_include_permissions(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) - wiki = p_test.app_instance('wiki') - wiki2 = p_test.app_instance('wiki2') - with h.push_context(p_test._id, app_config_id=wiki.config._id): - p = WM.Page.upsert(title='CanRead') - p.text = 'Can see this!' - p.commit() - ThreadLocalORMSession.flush_all() - - with h.push_context(p_test._id, app_config_id=wiki2.config._id): - role = M.ProjectRole.by_name('*anonymous')._id - read_perm = M.ACE.allow(role, 'read') - acl = c.app.config.acl - if read_perm in acl: - acl.remove(read_perm) - p = WM.Page.upsert(title='CanNotRead') - p.text = 'Can not see this!' - p.commit() - ThreadLocalORMSession.flush_all() - - with h.push_context(p_test._id, app_config_id=wiki.config._id): - c.user = M.User.anonymous() - md = '[[include ref=CanRead]]\n[[include ref=wiki2:CanNotRead]]' - html = g.markdown_wiki.convert(md) - assert 'Can see this!' in html - assert 'Can not see this!' not in html - assert "[[include: you don't have a read permission for wiki2:CanNotRead]]" in html - - -@patch('oembed.OEmbedEndpoint.fetch') -def test_macro_embed(oembed_fetch): - oembed_fetch.return_value = { - "html": '<iframe width="480" height="270" src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" ' - 'frameborder="0" allowfullscreen></iframe>)', - "title": "Nature's 3D Printer: MIND BLOWING Cocoon in Rainforest - Smarter Every Day 94", - } - r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=kOLpSPEA72U]]') - assert ('<p><iframe height="270" ' - 'src="https://www.youtube-nocookie.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe></p>' in - r.replace('\n', '')) - - -def test_macro_embed_video_gone(): - # this does a real fetch - r = g.markdown_wiki.convert('[[embed url=https://www.youtube.com/watch?v=OWsFqPZ3v-0]]') - r = str(r) # convert away from Markup, to get better assertion diff output - # either of these could happen depending on the mood of youtube's oembed API: - assert r in [ - '<div class="markdown_content"><p>Video not available</p></div>', - '<div class="markdown_content"><p>Could not embed: https://www.youtube.com/watch?v=OWsFqPZ3v-0</p></div>', - ] - - -@patch('oembed.OEmbedEndpoint.fetch') -def test_macro_embed_video_error(oembed_fetch): - oembed_fetch.side_effect = OEmbedError('Invalid mime-type in response...') - r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=6YbBmqUnoQM]]') - assert (r == '<div class="markdown_content"><p>Could not embed: ' - 'http://www.youtube.com/watch?v=6YbBmqUnoQM</p></div>') - - -def test_macro_embed_notsupported(): - r = g.markdown_wiki.convert('[[embed url=http://vimeo.com/46163090]]') - assert ( - r == '<div class="markdown_content"><p>[[embed url=http://vimeo.com/46163090]]</p></div>') - - -def test_markdown_toc(): - with h.push_context('test', neighborhood='Projects'): - r = g.markdown_wiki.convert("""[TOC] - -# Header 1 - -## Header 2""") - assert '''<ul> -<li><a href="#header-1">Header 1</a><ul> -<li><a href="#header-2">Header 2</a></li> -</ul> -</li> -</ul>''' in r, r - - [email protected]_wiki -def test_wiki_artifact_links(): - text = g.markdown.convert('See [18:13:49]') - assert 'See <span>[18:13:49]</span>' in text, text - with h.push_context('test', 'wiki', neighborhood='Projects'): - text = g.markdown.convert('Read [here](Home) about our project') - assert '<a class="" href="/p/test/wiki/Home/">here</a>' in text, text - text = g.markdown.convert('[Go home](test:wiki:Home)') - assert '<a class="" href="/p/test/wiki/Home/">Go home</a>' in text, text - text = g.markdown.convert('See [test:wiki:Home]') - assert '<a class="alink" href="/p/test/wiki/Home/">[test:wiki:Home]</a>' in text, text - - -def test_markdown_links(): - with patch.dict(tg.config, {'nofollow_exempt_domains': 'foobar.net'}): - text = g.markdown.convert('Read [here](http://foobar.net/) about our project') - assert 'class="" href="http://foobar.net/">here</a> about' in text - - text = g.markdown.convert('Read [here](http://foobar.net/) about our project') - assert 'class="" href="http://foobar.net/" rel="nofollow">here</a> about' in text - - text = g.markdown.convert('Read [here](/p/foobar/blah) about our project') - assert 'class="" href="/p/foobar/blah">here</a> about' in text - - text = g.markdown.convert('Read [here](/p/foobar/blah/) about our project') - assert 'class="" href="/p/foobar/blah/">here</a> about' in text - - text = g.markdown.convert('Read <http://foobar.net/> about our project') - assert 'href="http://foobar.net/" rel="nofollow">http://foobar.net/</a> about' in text - - -def test_markdown_and_html(): - with h.push_context('test', neighborhood='Projects'): - r = g.markdown_wiki.convert('<div style="float:left">blah</div>') - assert '<div style="float: left;">blah</div>' in r, r - - -def test_markdown_within_html(): - with h.push_context('test', neighborhood='Projects'): - r = g.markdown_wiki.convert('<div style="float:left" markdown>**blah**</div>') - assert ('<div style="float: left;"><p><strong>blah</strong></p></div>' in - r.replace('\n', '')) - - -def test_markdown_with_html_comments(): - text = g.markdown.convert('test <!-- comment -->') - assert '<div class="markdown_content"><p>test </p></div>' == text, text - - -def test_markdown_big_text(): - '''If text is too big g.markdown.convert should return plain text''' - text = 'a' * 40001 - assert g.markdown.convert(text) == '<pre>%s</pre>' % text - assert g.markdown_wiki.convert(text) == '<pre>%s</pre>' % text - - [email protected]_wiki -def test_markdown_basics(): - with h.push_context('test', 'wiki', neighborhood='Projects'): - text = g.markdown.convert('# Foo!\n[Home]') - assert (text == - '<div class="markdown_content"><h1 id="foo">Foo!</h1>\n' - '<p><a class="alink" href="/p/test/wiki/Home/">[Home]</a></p></div>') - text = g.markdown.convert('# Foo!\n[Rooted]') - assert (text == - '<div class="markdown_content"><h1 id="foo">Foo!</h1>\n' - '<p><span>[Rooted]</span></p></div>') - - assert ( - g.markdown.convert('Multi\nLine') == - '<div class="markdown_content"><p>Multi<br/>\n' - 'Line</p></div>') - assert ( - g.markdown.convert('Multi\n\nLine') == - '<div class="markdown_content"><p>Multi</p>\n' - '<p>Line</p></div>') - - # should not raise an exception: - assert ( - g.markdown.convert("<class 'foo'>") == - '''<div class="markdown_content"><p><class 'foo'=""></class></p></div>''') - - assert ( - g.markdown.convert('''# Header - -Some text in a regular paragraph - - :::python - for i in range(10): - print i -''') == - # no <br - '<div class="markdown_content"><h1 id="header">Header</h1>\n' - '<p>Some text in a regular paragraph</p>\n' - '<div class="codehilite"><pre><span></span><code><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>\n' - ' <span class="nb">print</span> <span class="n">i</span>\n' - '</code></pre></div>\n' - '</div>') - assert ( - g.forge_markdown(email=True).convert('[Home]') == - # uses localhost: - '<div class="markdown_content"><p><a class="alink" href="http://localhost/p/test/wiki/Home/">[Home]</a></p></div>') - assert ( - g.markdown.convert(''' -~~~~ -def foo(): pass -~~~~''') == - '<div class="markdown_content"><div class="codehilite"><pre><span></span><code>def foo(): pass\n' - '</code></pre></div>\n' - '</div>') - - -def test_markdown_list_without_break(): - # this is not a valid way to make a list in original Markdown or python-markdown - # https://github.com/Python-Markdown/markdown/issues/874 - # it is valid in the CommonMark spec https://spec.commonmark.org/0.30/#lists - # TODO: try https://github.com/adamb70/mdx-breakless-lists - # or https://gitlab.com/ayblaq/prependnewline - assert ( - g.markdown.convert('''\ -Regular text -* first item -* second item''') == - '<div class="markdown_content"><p>Regular text\n' # no <br> - '* first item\n' # no <br> - '* second item</p></div>') - - assert ( - g.markdown.convert('''\ -Regular text -- first item -- second item''') == - '<div class="markdown_content"><p>Regular text<br/>\n' - '- first item<br/>\n' - '- second item</p></div>') - - assert ( - g.markdown.convert('''\ -Regular text -+ first item -+ second item''') == - '<div class="markdown_content"><p>Regular text<br/>\n' - '+ first item<br/>\n' - '+ second item</p></div>') - - assert ( - g.markdown.convert('''\ -Regular text -1. first item -2. second item''') == - '<div class="markdown_content"><p>Regular text<br/>\n' - '1. first item<br/>\n' - '2. second item</p></div>') - - -def test_markdown_autolink(): - tgt = 'http://everything2.com/?node=nate+oostendorp' - s = g.markdown.convert('This is %s' % tgt) - assert ( - s == f'<div class="markdown_content"><p>This is <a href="{tgt}" rel="nofollow">{tgt}</a></p></div>') - assert '<a href=' in g.markdown.convert('This is http://domain.net') - # beginning of doc - assert '<a href=' in g.markdown.convert('http://domain.net abc') - # beginning of a line - assert ('<br/>\n<a href="http://' in - g.markdown.convert('foobar\nhttp://domain.net abc')) - # no conversion of these urls: - assert ('a blahttp://sdf.com z' in - g.markdown.convert('a blahttp://sdf.com z')) - assert ('literal <code>http://domain.net</code> literal' in - g.markdown.convert('literal `http://domain.net` literal')) - assert ('<pre><span></span><code>preformatted http://domain.net\n</code></pre>' in - g.markdown.convert(' :::text\n' - ' preformatted http://domain.net')) - - -def test_markdown_autolink_with_escape(): - # \_ is unnecessary but valid markdown escaping and should be considered as a regular underscore - # (it occurs during html2text conversion during project migrations) - r = g.markdown.convert(r'a http://www.phpmyadmin.net/home\_page/security/\#target b') - assert 'href="http://www.phpmyadmin.net/home_page/security/#target"' in r, r - - -def test_markdown_invalid_script(): - r = g.markdown.convert('<script>alert(document.cookies)</script>') - assert '<div class="markdown_content"><script>alert(document.cookies)</script>\n</div>' == r - - -def test_markdown_invalid_onerror(): - r = g.markdown.convert('<img src=x onerror=alert(document.cookie)>') - assert 'onerror' not in r - - -def test_markdown_invalid_tagslash(): - r = g.markdown.convert('<div/onload><img src=x onerror=alert(document.cookie)>') - assert 'onerror' not in r - - -def test_markdown_invalid_script_in_link(): - r = g.markdown.convert('[xss](http://"><a onmouseover=prompt(document.domain)>xss</a>)') - assert ('<div class="markdown_content"><p><a class="" ' - '''href='http://"><a%20onmouseover=prompt(document.domain)>xss</a>' ''' - 'rel="nofollow">xss</a></p></div>' == r) - - -def test_markdown_invalid_script_in_link2(): - r = g.markdown.convert('[xss](http://"><img src=x onerror=alert(document.cookie)>)') - assert ('<div class="markdown_content"><p><a class="" ' - '''href='http://"><img%20src=x%20onerror=alert(document.cookie)>' ''' - 'rel="nofollow">xss</a></p></div>' == r) - - -def test_markdown_extremely_slow(): - r = g.markdown.convert('''bonjour, voila ce que j'obtient en voulant ajouter un utilisateur a un groupe de sécurite, que ce soit sur un groupe pre-existant, ou sur un groupe crée. -message d'erreur: - -ERROR: Could not complete the Add UserLogin To SecurityGroup [file:/C:/neogia/ofbizNeogia/applications/securityext/script/org/ofbiz/securityext/securitygroup/SecurityGroupServices.xml#addUserLoginToSecurityGroup] process [problem creating the newEntity value: Exception while inserting the following entity: [GenericEntity:UserLoginSecurityGroup][createdStamp,2006-01-23 17:42:39.312(java.sql.Timestamp)][createdTxStamp,2006-01-23 17:42:38.875(java.sql.Timestamp)][fromDate,2006-01-23 17:42:3 [...] - -à priori les données du formulaire ne sont pas traitées : VALUES (?, ?, ?, ?, ?, ?, ?, ?) ce qui entraine l'echec du traitement SQL. - - -Si une idée vous vient à l'esprit, merci de me tenir au courant. - -cordialement, julien.''') - assert True # finished! - - [email protected]_tool('test', 'Wiki', 'wiki-len') -def test_markdown_link_length_limits(): - with h.push_context('test', 'wiki-len', neighborhood='Projects'): - # these are always ok, no matter the NOBRACKET length - WM.Page.upsert(title='12345678901').commit() - text = g.markdown.convert('See [12345678901]') - assert 'href="/p/test/wiki-len/12345678901/">[12345678901]</a>' in text, text - WM.Page.upsert(title='this is 26 characters long').commit() - text = g.markdown.convert('See [this is 26 characters long]') - assert 'href="/p/test/wiki-len/this%20is%2026%20characters%20long/">[this is 26 characters long]</a>' in text, text - - # NOBRACKET regex length impacts standard markdown links - text = g.markdown.convert('See [short](http://a.de)') - assert 'href="http://a.de" rel="nofollow">short</a>' in text, text - text = g.markdown.convert('See [this is 26 characters long](http://a.de)') - assert 'href="http://a.de" rel="nofollow">this is 26 characters long</a>' in text, text # {0,12} fails {0,13} ok - - # NOBRACKET regex length impacts our custom artifact links - text = g.markdown.convert('See [short](Home)') - assert 'href="/p/test/wiki-len/Home/">short</a>' in text, text - text = g.markdown.convert('See [123456789](Home)') - assert 'href="/p/test/wiki-len/Home/">123456789</a>' in text, text - text = g.markdown.convert('See [12345678901](Home)') - assert 'href="/p/test/wiki-len/Home/">12345678901</a>' in text, text # {0,5} fails, {0,6} ok - text = g.markdown.convert('See [this is 16 chars](Home)') - assert 'href="/p/test/wiki-len/Home/">this is 16 chars</a>' in text, text # {0,7} fails {0,8} ok - text = g.markdown.convert('See [this is 26 characters long](Home)') - assert 'href="/p/test/wiki-len/Home/">this is 26 characters long</a>' in text, text # {0,12} fails {0,13} ok - - # limit, currently - charSuperLong = '1234567890'*21 - text = g.markdown.convert(f'See [{charSuperLong}](Home)') - assert f'<span>[{charSuperLong}]</span>(Home)' in text, text # current limitation, not a link - # assert f'href="/p/test/wiki-len/Home/">{charSuperLong}</a>' in text, text # ideal output - - [email protected]_wiki -def test_macro_include(): - r = g.markdown.convert('[[include ref=Home id=foo]]') - assert '<div id="foo">' in r, r - assert 'href="../foo"' in g.markdown.convert('[My foo](foo)') - assert 'href="..' not in g.markdown.convert('[My foo](./foo)') - - -def test_macro_nbhd_feeds(): - with h.push_context('--init--', 'wiki', neighborhood='Projects'): - r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') - assert 'Home modified by ' in r, r - assert '<div class="markdown_content">' not in r - - -def test_sort_alpha(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - - with h.push_context(p_nbhd.neighborhood_project._id): - r = g.markdown_wiki.convert('[[projects sort=alpha]]') - project_list = get_project_names(r) - assert project_list == sorted(project_list) - - -def test_sort_registered(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - - with h.push_context(p_nbhd.neighborhood_project._id): - r = g.markdown_wiki.convert('[[projects sort=last_registered]]') - project_names = get_project_names(r) - ids = get_projects_property_in_the_same_order(project_names, '_id') - assert ids == sorted(ids, reverse=True) - - -def test_sort_updated(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - - with h.push_context(p_nbhd.neighborhood_project._id): - r = g.markdown_wiki.convert('[[projects sort=last_updated]]') - project_names = get_project_names(r) - updated_at = get_projects_property_in_the_same_order( - project_names, 'last_updated') - assert updated_at == sorted(updated_at, reverse=True) - - -@with_setup(setup_functional_test) -def test_filtering(): - # set up for test - from random import choice - setup_trove_categories() - random_trove = choice(M.TroveCategory.query.find().all()) - test_project = M.Project.query.get(shortname='test') - test_project_troves = getattr(test_project, 'trove_' + random_trove.type) - test_project_troves.append(random_trove._id) - ThreadLocalORMSession.flush_all() - - p_nbhd = M.Neighborhood.query.get(name='Projects') - with h.push_config(c, - project=p_nbhd.neighborhood_project, - user=M.User.by_username('test-admin')): - r = g.markdown_wiki.convert( - '[[projects category="%s"]]' % random_trove.fullpath) - project_names = get_project_names(r) - assert [test_project.name] == project_names - - -def test_projects_macro(): - two_column_style = 'width: 330px;' - - p_nbhd = M.Neighborhood.query.get(name='Projects') - with h.push_config(c, - project=p_nbhd.neighborhood_project, - user=M.User.anonymous()): - # test columns - r = g.markdown_wiki.convert('[[projects display_mode=list columns=2]]') - assert two_column_style in r - r = g.markdown_wiki.convert('[[projects display_mode=list columns=3]]') - assert two_column_style not in r - - [email protected]_user_project('test-admin') [email protected]_user_project('test-user-1') -def test_myprojects_macro(): - h.set_context('u/%s' % (c.user.username), 'wiki', neighborhood='Users') - r = g.markdown_wiki.convert('[[my_projects]]') - for p in c.user.my_projects(): - if p.deleted or p.is_nbhd_project: - continue - proj_title = f'<h2><a href="{p.url()}">{p.name}</a></h2>' - assert proj_title in r - - h.set_context('u/test-user-1', 'wiki', neighborhood='Users') - user = M.User.query.get(username='test-user-1') - r = g.markdown_wiki.convert('[[my_projects]]') - for p in user.my_projects(): - if p.deleted or p.is_nbhd_project: - continue - proj_title = f'<h2><a href="{p.url()}">{p.name}</a></h2>' - assert proj_title in r - - [email protected]_wiki -def test_hideawards_macro(): - p_nbhd = M.Neighborhood.query.get(name='Projects') - - app_config_id = ObjectId() - award = M.Award(app_config_id=app_config_id) - award.short = 'Award short' - award.full = 'Award full' - award.created_by_neighborhood_id = p_nbhd._id - - project = M.Project.query.get( - neighborhood_id=p_nbhd._id, shortname='test') - - M.AwardGrant( - award=award, - award_url='http://award.org', - comment='Winner!', - granted_by_neighborhood=p_nbhd, - granted_to_project=project) - - ThreadLocalORMSession.flush_all() - - with h.push_context(p_nbhd.neighborhood_project._id): - r = g.markdown_wiki.convert('[[projects]]') - assert ('<div class="feature"> <a href="http://award.org" rel="nofollow" title="Winner!">' - 'Award short</a> </div>' in - squish_spaces(r)) - - r = g.markdown_wiki.convert('[[projects show_awards_banner=False]]') - assert 'Award short' not in r - - [email protected]_tool('test', 'Blog', 'blog') -def test_project_blog_posts_macro(): - from forgeblog import model as BM - with h.push_context('test', 'blog', neighborhood='Projects'): - BM.BlogPost.new( - title='Test title', - text='test post', - state='published', - ) - BM.BlogPost.new( - title='Test title2', - text='test post2', - state='published', - ) - - r = g.markdown_wiki.convert('[[project_blog_posts]]') - assert 'Test title</a></h3>' in r - assert 'Test title2</a></h3>' in r - assert '<div class="markdown_content"><p>test post</p></div>' in r - assert '<div class="markdown_content"><p>test post2</p></div>' in r - assert 'by <em>Test Admin</em>' in r - - -def test_project_screenshots_macro(): - with h.push_context('test', neighborhood='Projects'): - M.ProjectFile(project_id=c.project._id, category='screenshot', caption='caption', filename='test_file.jpg') - ThreadLocalORMSession.flush_all() - - r = g.markdown_wiki.convert('[[project_screenshots]]') - - assert 'href="/p/test/screenshot/test_file.jpg"' in r - assert 'src="/p/test/screenshot/test_file.jpg/thumb"' in r - - def get_project_names(r): """ Extracts a list of project names from a wiki page HTML. @@ -826,10 +75,705 @@ def get_projects_property_in_the_same_order(names, prop): return [projects_dict[name] for name in names] + +@with_nose_compatibility +class Test(): + + def setup_method(self, method): + setup_basic_test() + setup_unit_test() + setup_global_objects() + + @td.with_wiki + def test_app_globals(self): + with h.push_context('test', 'wiki', neighborhood='Projects'): + assert g.app_static( + 'css/wiki.css') == '/nf/_static_/wiki/css/wiki.css', g.app_static('css/wiki.css') + + def test_macro_projects(self): + file_name = 'neo-icon-set-454545-256x350.png' + file_path = os.path.join( + allura.__path__[0], 'nf', 'allura', 'images', file_name) + + p_nbhd = M.Neighborhood.query.get(name='Projects') + p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) + c.project = p_test + icon_file = open(file_path, 'rb') + M.ProjectFile.save_image( + file_name, icon_file, content_type='image/png', + square=True, thumbnail_size=(48, 48), + thumbnail_meta=dict(project_id=c.project._id, category='icon')) + icon_file.close() + p_test2 = M.Project.query.get( + shortname='test2', neighborhood_id=p_nbhd._id) + c.project = p_test2 + icon_file = open(file_path, 'rb') + M.ProjectFile.save_image( + file_name, icon_file, content_type='image/png', + square=True, thumbnail_size=(48, 48), + thumbnail_meta=dict(project_id=c.project._id, category='icon')) + icon_file.close() + p_sub1 = M.Project.query.get( + shortname='test/sub1', neighborhood_id=p_nbhd._id) + c.project = p_sub1 + icon_file = open(file_path, 'rb') + M.ProjectFile.save_image( + file_name, icon_file, content_type='image/png', + square=True, thumbnail_size=(48, 48), + thumbnail_meta=dict(project_id=c.project._id, category='icon')) + icon_file.close() + p_test.labels = ['test', 'root'] + p_sub1.labels = ['test', 'sub1'] + # Make one project private + p_test.private = False + p_sub1.private = False + p_test2.private = True + + ThreadLocalORMSession.flush_all() + + with h.push_config(c, + project=p_nbhd.neighborhood_project, + user=M.User.by_username('test-admin')): + r = g.markdown_wiki.convert('[[projects]]') + assert 'alt="Test Project Logo"' in r, r + assert 'alt="A Subproject Logo"' in r, r + r = g.markdown_wiki.convert('[[projects labels=root]]') + assert 'alt="Test Project Logo"' in r, r + assert 'alt="A Subproject Logo"' not in r, r + r = g.markdown_wiki.convert('[[projects labels=sub1]]') + assert 'alt="Test Project Logo"' not in r, r + assert 'alt="A Subproject Logo"' in r, r + r = g.markdown_wiki.convert('[[projects labels=test]]') + assert 'alt="Test Project Logo"' in r, r + assert 'alt="A Subproject Logo"' in r, r + r = g.markdown_wiki.convert('[[projects labels=test,root]]') + assert 'alt="Test Project Logo"' in r, r + assert 'alt="A Subproject Logo"' not in r, r + r = g.markdown_wiki.convert('[[projects labels=test,sub1]]') + assert 'alt="Test Project Logo"' not in r, r + assert 'alt="A Subproject Logo"' in r, r + r = g.markdown_wiki.convert('[[projects labels=root|sub1]]') + assert 'alt="Test Project Logo"' in r, r + assert 'alt="A Subproject Logo"' in r, r + r = g.markdown_wiki.convert('[[projects labels=test,root|root,sub1]]') + assert 'alt="Test Project Logo"' in r, r + assert 'alt="A Subproject Logo"' not in r, r + r = g.markdown_wiki.convert('[[projects labels=test,root|test,sub1]]') + assert 'alt="Test Project Logo"' in r, r + assert 'alt="A Subproject Logo"' in r, r + r = g.markdown_wiki.convert('[[projects show_total=True sort=random]]') + assert '<p class="macro_projects_total">3 Projects' in r, r + r = g.markdown_wiki.convert( + '[[projects show_total=True private=True sort=random]]') + assert '<p class="macro_projects_total">1 Projects' in r, r + assert 'alt="Test 2 Logo"' in r, r + assert 'alt="Test Project Logo"' not in r, r + assert 'alt="A Subproject Logo"' not in r, r + + r = g.markdown_wiki.convert('[[projects show_proj_icon=True]]') + assert 'alt="Test Project Logo"' in r + r = g.markdown_wiki.convert('[[projects show_proj_icon=False]]') + assert 'alt="Test Project Logo"' not in r + + def test_macro_neighborhood_feeds(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) + with h.push_context('--init--', 'wiki', neighborhood='Projects'): + r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') + assert 'Home modified by' in r, r + r = re.sub(r'<small>.*? ago</small>', '', r) # remove "less than 1 second ago" etc + orig_len = len(r) + # Make project private & verify we don't see its new feed items + anon = M.User.anonymous() + p_test.acl.insert(0, M.ACE.deny( + M.ProjectRole.anonymous(p_test)._id, 'read')) + ThreadLocalORMSession.flush_all() + pg = WM.Page.query.get(title='Home', app_config_id=c.app.config._id) + pg.text = 'Change' + with h.push_config(c, user=M.User.by_username('test-admin')): + pg.commit() + r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') + r = re.sub(r'<small>.*? ago</small>', '', r) # remove "less than 1 second ago" etc + new_len = len(r) + assert new_len == orig_len + p = BM.BlogPost(title='test me', + neighborhood_id=p_test.neighborhood_id) + p.text = 'test content' + p.state = 'published' + p.make_slug() + with h.push_config(c, user=M.User.by_username('test-admin')): + p.commit() + ThreadLocalORMSession.flush_all() + with h.push_config(c, user=anon): + r = g.markdown_wiki.convert('[[neighborhood_blog_posts]]') + assert 'test content' in r + + def test_macro_members(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) + p_test.add_user(M.User.by_username('test-user'), ['Developer']) + p_test.add_user(M.User.by_username('test-user-0'), ['Member']) + ThreadLocalORMSession.flush_all() + r = g.markdown_wiki.convert('[[members limit=2]]').replace('\t', '').replace('\n', '') + assert (r == + '<div class="markdown_content"><h6>Project Members:</h6>' + '<ul class="md-users-list">' + '<li><a href="/u/test-admin/">Test Admin</a> (admin)</li>' + '<li><a href="/u/test-user/">Test User</a></li>' + '<li class="md-users-list-more"><a href="/p/test/_members">All Members</a></li>' + '</ul>' + '</div>') + + def test_macro_members_escaping(self): + user = M.User.by_username('test-admin') + user.display_name = 'Test Admin <script>' + r = g.markdown_wiki.convert('[[members]]') + assert (r.replace('\n', '').replace('\t', '') == + '<div class="markdown_content"><h6>Project Members:</h6>' + '<ul class="md-users-list">' + '<li><a href="/u/test-admin/">Test Admin <script></a> (admin)</li>' + '</ul></div>') + + def test_macro_project_admins(self): + user = M.User.by_username('test-admin') + user.display_name = 'Test Ådmin <script>' + with h.push_context('test', neighborhood='Projects'): + r = g.markdown_wiki.convert('[[project_admins]]') + assert (r.replace('\n', '') == + '<div class="markdown_content"><h6>Project Admins:</h6>' + '<ul class="md-users-list">' + ' <li><a href="/u/test-admin/">Test \xc5dmin <script></a></li>' + '</ul></div>') + + def test_macro_project_admins_one_br(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) + p_test.add_user(M.User.by_username('test-user'), ['Admin']) + ThreadLocalORMSession.flush_all() + with h.push_config(c, project=p_test): + r = g.markdown_wiki.convert('[[project_admins]]\n[[download_button]]') + + assert '</a><br/><br/><a href=' not in r, r + assert '</a></li><li><a href=' in r, r + + @td.with_wiki + def test_macro_include_no_extra_br(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) + wiki = p_test.app_instance('wiki') + with h.push_context(p_test._id, app_config_id=wiki.config._id): + p = WM.Page.upsert(title='Include_1') + p.text = 'included page 1' + p.commit() + p = WM.Page.upsert(title='Include_2') + p.text = 'included page 2' + p.commit() + p = WM.Page.upsert(title='Include_3') + p.text = 'included page 3' + p.commit() + ThreadLocalORMSession.flush_all() + md = '[[include ref=Include_1]]\n[[include ref=Include_2]]\n[[include ref=Include_3]]' + html = g.markdown_wiki.convert(md) + + expected_html = '''<div class="markdown_content"><p></p><div> + <div class="markdown_content"><p>included page 1</p></div> + </div> + <div> + <div class="markdown_content"><p>included page 2</p></div> + </div> + <div> + <div class="markdown_content"><p>included page 3</p></div> + </div> + <p></p></div>''' + assert squish_spaces(html) == squish_spaces(expected_html) + + @td.with_wiki + @td.with_tool('test', 'Wiki', 'wiki2') + def test_macro_include_permissions(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id) + wiki = p_test.app_instance('wiki') + wiki2 = p_test.app_instance('wiki2') + with h.push_context(p_test._id, app_config_id=wiki.config._id): + p = WM.Page.upsert(title='CanRead') + p.text = 'Can see this!' + p.commit() + ThreadLocalORMSession.flush_all() + + with h.push_context(p_test._id, app_config_id=wiki2.config._id): + role = M.ProjectRole.by_name('*anonymous')._id + read_perm = M.ACE.allow(role, 'read') + acl = c.app.config.acl + if read_perm in acl: + acl.remove(read_perm) + p = WM.Page.upsert(title='CanNotRead') + p.text = 'Can not see this!' + p.commit() + ThreadLocalORMSession.flush_all() + + with h.push_context(p_test._id, app_config_id=wiki.config._id): + c.user = M.User.anonymous() + md = '[[include ref=CanRead]]\n[[include ref=wiki2:CanNotRead]]' + html = g.markdown_wiki.convert(md) + assert 'Can see this!' in html + assert 'Can not see this!' not in html + assert "[[include: you don't have a read permission for wiki2:CanNotRead]]" in html + + @patch('oembed.OEmbedEndpoint.fetch') + def test_macro_embed(self, oembed_fetch): + oembed_fetch.return_value = { + "html": '<iframe width="480" height="270" src="http://www.youtube.com/embed/kOLpSPEA72U?feature=oembed" ' + 'frameborder="0" allowfullscreen></iframe>)', + "title": "Nature's 3D Printer: MIND BLOWING Cocoon in Rainforest - Smarter Every Day 94", + } + r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=kOLpSPEA72U]]') + assert ('<p><iframe height="270" ' + 'src="https://www.youtube-nocookie.com/embed/kOLpSPEA72U?feature=oembed" width="480"></iframe></p>' in + r.replace('\n', '')) + + def test_macro_embed_video_gone(self): + # this does a real fetch + r = g.markdown_wiki.convert('[[embed url=https://www.youtube.com/watch?v=OWsFqPZ3v-0]]') + r = str(r) # convert away from Markup, to get better assertion diff output + # either of these could happen depending on the mood of youtube's oembed API: + assert r in [ + '<div class="markdown_content"><p>Video not available</p></div>', + '<div class="markdown_content"><p>Could not embed: https://www.youtube.com/watch?v=OWsFqPZ3v-0</p></div>', + ] + + @patch('oembed.OEmbedEndpoint.fetch') + def test_macro_embed_video_error(self, oembed_fetch): + oembed_fetch.side_effect = OEmbedError('Invalid mime-type in response...') + r = g.markdown_wiki.convert('[[embed url=http://www.youtube.com/watch?v=6YbBmqUnoQM]]') + assert (r == '<div class="markdown_content"><p>Could not embed: ' + 'http://www.youtube.com/watch?v=6YbBmqUnoQM</p></div>') + + def test_macro_embed_notsupported(self): + r = g.markdown_wiki.convert('[[embed url=http://vimeo.com/46163090]]') + assert ( + r == '<div class="markdown_content"><p>[[embed url=http://vimeo.com/46163090]]</p></div>') + + def test_markdown_toc(self): + with h.push_context('test', neighborhood='Projects'): + r = g.markdown_wiki.convert("""[TOC] + + # Header 1 + + ## Header 2""") + assert '''<ul> + <li><a href="#header-1">Header 1</a><ul> + <li><a href="#header-2">Header 2</a></li> + </ul> + </li> + </ul>''' in r, r + + @td.with_wiki + def test_wiki_artifact_links(self): + text = g.markdown.convert('See [18:13:49]') + assert 'See <span>[18:13:49]</span>' in text, text + with h.push_context('test', 'wiki', neighborhood='Projects'): + text = g.markdown.convert('Read [here](Home) about our project') + assert '<a class="" href="/p/test/wiki/Home/">here</a>' in text, text + text = g.markdown.convert('[Go home](test:wiki:Home)') + assert '<a class="" href="/p/test/wiki/Home/">Go home</a>' in text, text + text = g.markdown.convert('See [test:wiki:Home]') + assert '<a class="alink" href="/p/test/wiki/Home/">[test:wiki:Home]</a>' in text, text + + def test_markdown_links(self): + with patch.dict(tg.config, {'nofollow_exempt_domains': 'foobar.net'}): + text = g.markdown.convert('Read [here](http://foobar.net/) about our project') + assert 'class="" href="http://foobar.net/">here</a> about' in text + + text = g.markdown.convert('Read [here](http://foobar.net/) about our project') + assert 'class="" href="http://foobar.net/" rel="nofollow">here</a> about' in text + + text = g.markdown.convert('Read [here](/p/foobar/blah) about our project') + assert 'class="" href="/p/foobar/blah">here</a> about' in text + + text = g.markdown.convert('Read [here](/p/foobar/blah/) about our project') + assert 'class="" href="/p/foobar/blah/">here</a> about' in text + + text = g.markdown.convert('Read <http://foobar.net/> about our project') + assert 'href="http://foobar.net/" rel="nofollow">http://foobar.net/</a> about' in text + + def test_markdown_and_html(self): + with h.push_context('test', neighborhood='Projects'): + r = g.markdown_wiki.convert('<div style="float:left">blah</div>') + assert '<div style="float: left;">blah</div>' in r, r + + def test_markdown_within_html(self): + with h.push_context('test', neighborhood='Projects'): + r = g.markdown_wiki.convert('<div style="float:left" markdown>**blah**</div>') + assert ('<div style="float: left;"><p><strong>blah</strong></p></div>' in + r.replace('\n', '')) + + def test_markdown_with_html_comments(self): + text = g.markdown.convert('test <!-- comment -->') + assert '<div class="markdown_content"><p>test </p></div>' == text, text + + def test_markdown_big_text(self): + '''If text is too big g.markdown.convert should return plain text''' + text = 'a' * 40001 + assert g.markdown.convert(text) == '<pre>%s</pre>' % text + assert g.markdown_wiki.convert(text) == '<pre>%s</pre>' % text + + @td.with_wiki + def test_markdown_basics(self): + with h.push_context('test', 'wiki', neighborhood='Projects'): + text = g.markdown.convert('# Foo!\n[Home]') + assert (text == + '<div class="markdown_content"><h1 id="foo">Foo!</h1>\n' + '<p><a class="alink" href="/p/test/wiki/Home/">[Home]</a></p></div>') + text = g.markdown.convert('# Foo!\n[Rooted]') + assert (text == + '<div class="markdown_content"><h1 id="foo">Foo!</h1>\n' + '<p><span>[Rooted]</span></p></div>') + + assert ( + g.markdown.convert('Multi\nLine') == + '<div class="markdown_content"><p>Multi<br/>\n' + 'Line</p></div>') + assert ( + g.markdown.convert('Multi\n\nLine') == + '<div class="markdown_content"><p>Multi</p>\n' + '<p>Line</p></div>') + + # should not raise an exception: + assert ( + g.markdown.convert("<class 'foo'>") == + '''<div class="markdown_content"><p><class 'foo'=""></class></p></div>''') + + assert ( + g.markdown.convert('''# Header + + Some text in a regular paragraph + + :::python + for i in range(10): + print i + ''') == + # no <br + '<div class="markdown_content"><h1 id="header">Header</h1>\n' + '<p>Some text in a regular paragraph</p>\n' + '<div class="codehilite"><pre><span></span><code><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>\n' + ' <span class="nb">print</span> <span class="n">i</span>\n' + '</code></pre></div>\n' + '</div>') + assert ( + g.forge_markdown(email=True).convert('[Home]') == + # uses localhost: + '<div class="markdown_content"><p><a class="alink" href="http://localhost/p/test/wiki/Home/">[Home]</a></p></div>') + assert ( + g.markdown.convert(''' + ~~~~ + def foo(): pass + ~~~~''') == + '<div class="markdown_content"><div class="codehilite"><pre><span></span><code>def foo(): pass\n' + '</code></pre></div>\n' + '</div>') + + def test_markdown_list_without_break(self): + # this is not a valid way to make a list in original Markdown or python-markdown + # https://github.com/Python-Markdown/markdown/issues/874 + # it is valid in the CommonMark spec https://spec.commonmark.org/0.30/#lists + # TODO: try https://github.com/adamb70/mdx-breakless-lists + # or https://gitlab.com/ayblaq/prependnewline + assert ( + g.markdown.convert('''\ + Regular text + * first item + * second item''') == + '<div class="markdown_content"><p>Regular text\n' # no <br> + '* first item\n' # no <br> + '* second item</p></div>') + + assert ( + g.markdown.convert('''\ + Regular text + - first item + - second item''') == + '<div class="markdown_content"><p>Regular text<br/>\n' + '- first item<br/>\n' + '- second item</p></div>') + + assert ( + g.markdown.convert('''\ + Regular text + + first item + + second item''') == + '<div class="markdown_content"><p>Regular text<br/>\n' + '+ first item<br/>\n' + '+ second item</p></div>') + + assert ( + g.markdown.convert('''\ + Regular text + 1. first item + 2. second item''') == + '<div class="markdown_content"><p>Regular text<br/>\n' + '1. first item<br/>\n' + '2. second item</p></div>') + + + def test_markdown_autolink(self): + tgt = 'http://everything2.com/?node=nate+oostendorp' + s = g.markdown.convert('This is %s' % tgt) + assert ( + s == f'<div class="markdown_content"><p>This is <a href="{tgt}" rel="nofollow">{tgt}</a></p></div>') + assert '<a href=' in g.markdown.convert('This is http://domain.net') + # beginning of doc + assert '<a href=' in g.markdown.convert('http://domain.net abc') + # beginning of a line + assert ('<br/>\n<a href="http://' in + g.markdown.convert('foobar\nhttp://domain.net abc')) + # no conversion of these urls: + assert ('a blahttp://sdf.com z' in + g.markdown.convert('a blahttp://sdf.com z')) + assert ('literal <code>http://domain.net</code> literal' in + g.markdown.convert('literal `http://domain.net` literal')) + assert ('<pre><span></span><code>preformatted http://domain.net\n</code></pre>' in + g.markdown.convert(' :::text\n' + ' preformatted http://domain.net')) + + def test_markdown_autolink_with_escape(self): + # \_ is unnecessary but valid markdown escaping and should be considered as a regular underscore + # (it occurs during html2text conversion during project migrations) + r = g.markdown.convert(r'a http://www.phpmyadmin.net/home\_page/security/\#target b') + assert 'href="http://www.phpmyadmin.net/home_page/security/#target"' in r, r + + def test_markdown_invalid_script(self): + r = g.markdown.convert('<script>alert(document.cookies)</script>') + assert '<div class="markdown_content"><script>alert(document.cookies)</script>\n</div>' == r + + def test_markdown_invalid_onerror(self): + r = g.markdown.convert('<img src=x onerror=alert(document.cookie)>') + assert 'onerror' not in r + + def test_markdown_invalid_tagslash(self): + r = g.markdown.convert('<div/onload><img src=x onerror=alert(document.cookie)>') + assert 'onerror' not in r + + def test_markdown_invalid_script_in_link(self): + r = g.markdown.convert('[xss](http://"><a onmouseover=prompt(document.domain)>xss</a>)') + assert ('<div class="markdown_content"><p><a class="" ' + '''href='http://"><a%20onmouseover=prompt(document.domain)>xss</a>' ''' + 'rel="nofollow">xss</a></p></div>' == r) + + def test_markdown_invalid_script_in_link2(self): + r = g.markdown.convert('[xss](http://"><img src=x onerror=alert(document.cookie)>)') + assert ('<div class="markdown_content"><p><a class="" ' + '''href='http://"><img%20src=x%20onerror=alert(document.cookie)>' ''' + 'rel="nofollow">xss</a></p></div>' == r) + + def test_markdown_extremely_slow(self): + r = g.markdown.convert('''bonjour, voila ce que j'obtient en voulant ajouter un utilisateur a un groupe de sécurite, que ce soit sur un groupe pre-existant, ou sur un groupe crée. + message d'erreur: + + ERROR: Could not complete the Add UserLogin To SecurityGroup [file:/C:/neogia/ofbizNeogia/applications/securityext/script/org/ofbiz/securityext/securitygroup/SecurityGroupServices.xml#addUserLoginToSecurityGroup] process [problem creating the newEntity value: Exception while inserting the following entity: [GenericEntity:UserLoginSecurityGroup][createdStamp,2006-01-23 17:42:39.312(java.sql.Timestamp)][createdTxStamp,2006-01-23 17:42:38.875(java.sql.Timestamp)][fromDate,2006-01-23 17: [...] + + à priori les données du formulaire ne sont pas traitées : VALUES (?, ?, ?, ?, ?, ?, ?, ?) ce qui entraine l'echec du traitement SQL. + + + Si une idée vous vient à l'esprit, merci de me tenir au courant. + + cordialement, julien.''') + assert True # finished! + + @td.with_tool('test', 'Wiki', 'wiki-len') + def test_markdown_link_length_limits(self): + with h.push_context('test', 'wiki-len', neighborhood='Projects'): + # these are always ok, no matter the NOBRACKET length + WM.Page.upsert(title='12345678901').commit() + text = g.markdown.convert('See [12345678901]') + assert 'href="/p/test/wiki-len/12345678901/">[12345678901]</a>' in text, text + WM.Page.upsert(title='this is 26 characters long').commit() + text = g.markdown.convert('See [this is 26 characters long]') + assert 'href="/p/test/wiki-len/this%20is%2026%20characters%20long/">[this is 26 characters long]</a>' in text, text + + # NOBRACKET regex length impacts standard markdown links + text = g.markdown.convert('See [short](http://a.de)') + assert 'href="http://a.de" rel="nofollow">short</a>' in text, text + text = g.markdown.convert('See [this is 26 characters long](http://a.de)') + assert 'href="http://a.de" rel="nofollow">this is 26 characters long</a>' in text, text # {0,12} fails {0,13} ok + + # NOBRACKET regex length impacts our custom artifact links + text = g.markdown.convert('See [short](Home)') + assert 'href="/p/test/wiki-len/Home/">short</a>' in text, text + text = g.markdown.convert('See [123456789](Home)') + assert 'href="/p/test/wiki-len/Home/">123456789</a>' in text, text + text = g.markdown.convert('See [12345678901](Home)') + assert 'href="/p/test/wiki-len/Home/">12345678901</a>' in text, text # {0,5} fails, {0,6} ok + text = g.markdown.convert('See [this is 16 chars](Home)') + assert 'href="/p/test/wiki-len/Home/">this is 16 chars</a>' in text, text # {0,7} fails {0,8} ok + text = g.markdown.convert('See [this is 26 characters long](Home)') + assert 'href="/p/test/wiki-len/Home/">this is 26 characters long</a>' in text, text # {0,12} fails {0,13} ok + + # limit, currently + charSuperLong = '1234567890'*21 + text = g.markdown.convert(f'See [{charSuperLong}](Home)') + assert f'<span>[{charSuperLong}]</span>(Home)' in text, text # current limitation, not a link + # assert f'href="/p/test/wiki-len/Home/">{charSuperLong}</a>' in text, text # ideal output + + @td.with_wiki + def test_macro_include(self): + r = g.markdown.convert('[[include ref=Home id=foo]]') + assert '<div id="foo">' in r, r + assert 'href="../foo"' in g.markdown.convert('[My foo](foo)') + assert 'href="..' not in g.markdown.convert('[My foo](./foo)') + + def test_macro_nbhd_feeds(self): + with h.push_context('--init--', 'wiki', neighborhood='Projects'): + r = g.markdown_wiki.convert('[[neighborhood_feeds tool_name=wiki]]') + assert 'Home modified by ' in r, r + assert '<div class="markdown_content">' not in r + + def test_sort_alpha(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + + with h.push_context(p_nbhd.neighborhood_project._id): + r = g.markdown_wiki.convert('[[projects sort=alpha]]') + project_list = get_project_names(r) + assert project_list == sorted(project_list) + + def test_sort_registered(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + + with h.push_context(p_nbhd.neighborhood_project._id): + r = g.markdown_wiki.convert('[[projects sort=last_registered]]') + project_names = get_project_names(r) + ids = get_projects_property_in_the_same_order(project_names, '_id') + assert ids == sorted(ids, reverse=True) + + def test_sort_updated(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + + with h.push_context(p_nbhd.neighborhood_project._id): + r = g.markdown_wiki.convert('[[projects sort=last_updated]]') + project_names = get_project_names(r) + updated_at = get_projects_property_in_the_same_order( + project_names, 'last_updated') + assert updated_at == sorted(updated_at, reverse=True) + + def test_filtering(self): + # set up for test + from random import choice + setup_trove_categories() + random_trove = choice(M.TroveCategory.query.find().all()) + test_project = M.Project.query.get(shortname='test') + test_project_troves = getattr(test_project, 'trove_' + random_trove.type) + test_project_troves.append(random_trove._id) + ThreadLocalORMSession.flush_all() + + p_nbhd = M.Neighborhood.query.get(name='Projects') + with h.push_config(c, + project=p_nbhd.neighborhood_project, + user=M.User.by_username('test-admin')): + r = g.markdown_wiki.convert( + '[[projects category="%s"]]' % random_trove.fullpath) + project_names = get_project_names(r) + assert [test_project.name] == project_names + + def test_projects_macro(self): + two_column_style = 'width: 330px;' + + p_nbhd = M.Neighborhood.query.get(name='Projects') + with h.push_config(c, + project=p_nbhd.neighborhood_project, + user=M.User.anonymous()): + # test columns + r = g.markdown_wiki.convert('[[projects display_mode=list columns=2]]') + assert two_column_style in r + r = g.markdown_wiki.convert('[[projects display_mode=list columns=3]]') + assert two_column_style not in r + + @td.with_user_project('test-admin') + @td.with_user_project('test-user-1') + def test_myprojects_macro(self): + h.set_context('u/%s' % (c.user.username), 'wiki', neighborhood='Users') + r = g.markdown_wiki.convert('[[my_projects]]') + for p in c.user.my_projects(): + if p.deleted or p.is_nbhd_project: + continue + proj_title = f'<h2><a href="{p.url()}">{p.name}</a></h2>' + assert proj_title in r + + h.set_context('u/test-user-1', 'wiki', neighborhood='Users') + user = M.User.query.get(username='test-user-1') + r = g.markdown_wiki.convert('[[my_projects]]') + for p in user.my_projects(): + if p.deleted or p.is_nbhd_project: + continue + proj_title = f'<h2><a href="{p.url()}">{p.name}</a></h2>' + assert proj_title in r + + @td.with_wiki + def test_hideawards_macro(self): + p_nbhd = M.Neighborhood.query.get(name='Projects') + + app_config_id = ObjectId() + award = M.Award(app_config_id=app_config_id) + award.short = 'Award short' + award.full = 'Award full' + award.created_by_neighborhood_id = p_nbhd._id + + project = M.Project.query.get( + neighborhood_id=p_nbhd._id, shortname='test') + + M.AwardGrant( + award=award, + award_url='http://award.org', + comment='Winner!', + granted_by_neighborhood=p_nbhd, + granted_to_project=project) + + ThreadLocalORMSession.flush_all() + + with h.push_context(p_nbhd.neighborhood_project._id): + r = g.markdown_wiki.convert('[[projects]]') + assert ('<div class="feature"> <a href="http://award.org" rel="nofollow" title="Winner!">' + 'Award short</a> </div>' in + squish_spaces(r)) + + r = g.markdown_wiki.convert('[[projects show_awards_banner=False]]') + assert 'Award short' not in r + + @td.with_tool('test', 'Blog', 'blog') + def test_project_blog_posts_macro(self): + from forgeblog import model as BM + with h.push_context('test', 'blog', neighborhood='Projects'): + BM.BlogPost.new( + title='Test title', + text='test post', + state='published', + ) + BM.BlogPost.new( + title='Test title2', + text='test post2', + state='published', + ) + + r = g.markdown_wiki.convert('[[project_blog_posts]]') + assert 'Test title</a></h3>' in r + assert 'Test title2</a></h3>' in r + assert '<div class="markdown_content"><p>test post</p></div>' in r + assert '<div class="markdown_content"><p>test post2</p></div>' in r + assert 'by <em>Test Admin</em>' in r + + + def test_project_screenshots_macro(self): + with h.push_context('test', neighborhood='Projects'): + M.ProjectFile(project_id=c.project._id, category='screenshot', caption='caption', filename='test_file.jpg') + ThreadLocalORMSession.flush_all() + + r = g.markdown_wiki.convert('[[project_screenshots]]') + + assert 'href="/p/test/screenshot/test_file.jpg"' in r + assert 'src="/p/test/screenshot/test_file.jpg/thumb"' in r + @with_nose_compatibility class TestCachedMarkdown(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): self.md = ForgeMarkdown() self.post = M.Post() self.post.text = '**bold**' @@ -1025,7 +969,7 @@ class TestUserMentions(unittest.TestCase): @with_nose_compatibility class TestHandlePaging(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): prefs = {} c.user = Mock() @@ -1086,7 +1030,7 @@ class TestHandlePaging(unittest.TestCase): @with_nose_compatibility class TestIconRender: - def setup_class(self, method): + def setup_method(self, method): self.i = g.icons['edit'] def test_default(self): diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py index ea0c50a2b..dbd359e33 100644 --- a/Allura/allura/tests/test_helpers.py +++ b/Allura/allura/tests/test_helpers.py @@ -23,7 +23,7 @@ import time import PIL from mock import Mock, patch from tg import tmpl_context as c -from alluratest.tools import assert_equals, assert_raises, module_not_available +from alluratest.tools import assert_equals, assert_raises, module_not_available, with_setup from datadiff import tools as dd from webob import Request from webob.exc import HTTPUnauthorized @@ -42,7 +42,7 @@ from alluratest.controller import setup_basic_test import six -def setup_class(self, method): +def setup_method(): """Method called by nose before running each test""" setup_basic_test() @@ -50,7 +50,7 @@ def setup_class(self, method): @with_nose_compatibility class TestMakeSafePathPortion(TestCase): - def setup_class(self, method): + def setup_method(self, method): self.f = h.make_safe_path_portion def test_no_ascii_chars(self): @@ -118,7 +118,7 @@ def test_really_unicode(): assert isinstance(s, Markup) assert s == '<b>test</b>' - +@with_setup(setup_method) def test_find_project(): proj, rest = h.find_project('/p/test/foo') assert proj.shortname == 'test' @@ -127,12 +127,14 @@ def test_find_project(): assert proj is None +@with_setup(setup_method) def test_make_roles(): h.set_context('test', 'wiki', neighborhood='Projects') pr = M.ProjectRole.anonymous() assert next(h.make_roles([pr._id])) == pr +@with_setup(setup_method) @td.with_wiki def test_make_app_admin_only(): h.set_context('test', 'wiki', neighborhood='Projects') @@ -165,6 +167,7 @@ def test_make_app_admin_only(): assert c.app.is_visible_to(admin) +@with_setup(setup_method) @td.with_wiki def test_context_setters(): h.set_context('test', 'wiki', neighborhood='Projects') @@ -259,6 +262,7 @@ def test_render_any_markup_empty(): assert h.render_any_markup('foo', '') == '<p><em>Empty File</em></p>' +@with_setup(setup_method) def test_render_any_markup_plain(): assert ( h.render_any_markup( @@ -266,6 +270,7 @@ def test_render_any_markup_plain(): '<pre><b>blah</b>\n<script>alert(1)</script>\nfoo</pre>') +@with_setup(setup_method) def test_render_any_markup_formatting(): assert (str(h.render_any_markup('README.md', '### foo\n' ' <script>alert(1)</script> bar')) == @@ -275,6 +280,7 @@ def test_render_any_markup_formatting(): '</script></span> bar\n</code></pre></div>\n</div>') +@with_setup(setup_method) def test_render_any_markdown_encoding(): # send encoded content in, make sure it converts it to actual unicode object which Markdown lib needs assert (h.render_any_markup('README.md', 'Müller'.encode()) == @@ -306,6 +312,7 @@ def test_log_if_changed(): assert AuditLogMock.logs[0] == 'updated value' +@with_setup(setup_method) def test_get_tool_packages(): assert h.get_tool_packages('tickets') == ['forgetracker'] assert h.get_tool_packages('Tickets') == ['forgetracker'] @@ -321,6 +328,7 @@ def test_get_first(): assert h.get_first({'title': ['Value']}, 'title') == 'Value' +@with_setup(setup_method) @patch('allura.lib.search.c') def test_inject_user(context): user = Mock(username='user01') @@ -515,6 +523,7 @@ class TestUrlOpen(TestCase): self.assertEqual(urlopen.call_count, 1) +@with_setup(setup_method) def test_absurl(): assert h.absurl('/p/test/foobar') == 'http://localhost/p/test/foobar' @@ -525,6 +534,7 @@ def test_daterange(): [datetime(2013, 1, 1), datetime(2013, 1, 2), datetime(2013, 1, 3)]) +@with_setup(setup_method) @patch.object(h, 'request', new=Request.blank('/p/test/foobar', base_url='https://www.mysite.com/p/test/foobar')) def test_login_overlay(): @@ -591,6 +601,7 @@ class TestIterEntryPoints(TestCase): list, h.iter_entry_points('allura')) +@with_setup(setup_method) def test_get_user_status(): user = M.User.by_username('test-admin') assert h.get_user_status(user) == 'enabled' diff --git a/Allura/allura/tests/test_mail_util.py b/Allura/allura/tests/test_mail_util.py index 4a3970c82..f1ad21d09 100644 --- a/Allura/allura/tests/test_mail_util.py +++ b/Allura/allura/tests/test_mail_util.py @@ -49,7 +49,7 @@ config = ConfigProxy( @with_nose_compatibility class TestReactor(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() ThreadLocalORMSession.flush_all() @@ -236,7 +236,7 @@ class TestHeader: @with_nose_compatibility class TestIsAutoreply: - def setup_class(self, method): + def setup_method(self, method): self.msg = {'headers': {}} def test_empty(self): @@ -333,7 +333,7 @@ def test_parse_message_id(): @with_nose_compatibility class TestMailServer: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() @mock.patch('allura.command.base.log', autospec=True) diff --git a/Allura/allura/tests/test_middlewares.py b/Allura/allura/tests/test_middlewares.py index fa15b7fa3..1f8e78a79 100644 --- a/Allura/allura/tests/test_middlewares.py +++ b/Allura/allura/tests/test_middlewares.py @@ -25,7 +25,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestCORSMiddleware: - def setup_class(self, method): + def setup_method(self, method): self.app = MagicMock() self.allowed_methods = ['GET', 'POST', 'DELETE'] self.allowed_headers = ['Authorization', 'Accept'] diff --git a/Allura/allura/tests/test_multifactor.py b/Allura/allura/tests/test_multifactor.py index de6208c3b..e007b0adf 100644 --- a/Allura/allura/tests/test_multifactor.py +++ b/Allura/allura/tests/test_multifactor.py @@ -181,7 +181,7 @@ class TestMongodbTotpService(TestAnyTotpServiceImplementation): __test__ = True Service = MongodbTotpService - def setup_class(self, method): + def setup_method(self, method): config = { 'ming.main.uri': 'mim://host/allura_test', } @@ -191,7 +191,7 @@ class TestMongodbTotpService(TestAnyTotpServiceImplementation): @with_nose_compatibility class TestGoogleAuthenticatorPamFilesystemMixin: - def setup_class(self, method): + def setup_method(self, method): self.totp_basedir = tempfile.mkdtemp(prefix='totp-test', dir=os.getenv('TMPDIR', '/tmp')) config['auth.multifactor.totp.filesystem.basedir'] = self.totp_basedir @@ -312,7 +312,7 @@ class TestMongodbRecoveryCodeService(TestAnyRecoveryCodeServiceImplementation): Service = MongodbRecoveryCodeService - def setup_class(self, method): + def setup_method(self, method): config = { 'ming.main.uri': 'mim://host/allura_test', } @@ -327,7 +327,7 @@ class TestGoogleAuthenticatorPamFilesystemRecoveryCodeService(TestAnyRecoveryCod Service = GoogleAuthenticatorPamFilesystemRecoveryCodeService - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) # make a regular .google-authenticator file first, so recovery keys have somewhere to go diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py index c0498de69..22a7ed8bf 100644 --- a/Allura/allura/tests/test_plugin.py +++ b/Allura/allura/tests/test_plugin.py @@ -51,7 +51,8 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestProjectRegistrationProvider: - def setup_class(self, method): + def setup_method(self, method): + setup_basic_test() self.provider = ProjectRegistrationProvider() @patch('allura.lib.security.has_access') @@ -89,7 +90,7 @@ class TestProjectRegistrationProvider: @with_nose_compatibility class TestProjectRegistrationProviderParseProjectFromUrl: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() ThreadLocalORMSession.close_all() setup_global_objects() @@ -164,7 +165,7 @@ class UserMock: @with_nose_compatibility class TestProjectRegistrationProviderPhoneVerification: - def setup_class(self, method): + def setup_method(self, method): self.p = ProjectRegistrationProvider() self.user = UserMock() self.nbhd = MagicMock() @@ -637,7 +638,7 @@ class TestThemeProvider_notifications: @with_nose_compatibility class TestLocalAuthenticationProvider: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() ThreadLocalORMSession.close_all() setup_global_objects() @@ -752,7 +753,7 @@ class TestLocalAuthenticationProvider: @with_nose_compatibility class TestAuthenticationProvider: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() self.provider = plugin.AuthenticationProvider(Request.blank('/')) self.pwd_updated = dt.datetime.utcnow() - dt.timedelta(days=100) diff --git a/Allura/allura/tests/test_scripttask.py b/Allura/allura/tests/test_scripttask.py index d66bf2684..f8576bbf8 100644 --- a/Allura/allura/tests/test_scripttask.py +++ b/Allura/allura/tests/test_scripttask.py @@ -25,7 +25,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestScriptTask(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): class TestScriptTask(ScriptTask): _parser = mock.Mock() diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py index 0547b1954..735b3294b 100644 --- a/Allura/allura/tests/test_tasks.py +++ b/Allura/allura/tests/test_tasks.py @@ -58,6 +58,10 @@ from allura.lib.decorators import event_handler, task @with_nose_compatibility class TestRepoTasks(unittest.TestCase): + def setup_method(self, method): + setup_basic_test() + setup_global_objects() + @mock.patch('allura.tasks.repo_tasks.c.app') @mock.patch('allura.tasks.repo_tasks.g.post_event') def test_clone_posts_event_on_failure(self, post_event, app): @@ -103,7 +107,7 @@ def _task_that_creates_event(event_name,): @with_nose_compatibility class TestEventTasks(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() self.called_with = [] @@ -162,7 +166,7 @@ class TestEventTasks(unittest.TestCase): @with_nose_compatibility class TestIndexTasks(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() @@ -248,7 +252,7 @@ class TestIndexTasks(unittest.TestCase): @with_nose_compatibility class TestMailTasks(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() @@ -543,7 +547,7 @@ I'm not here''' @with_nose_compatibility class TestUserNotificationTasks(TestController): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.setup_with_tools() @@ -576,7 +580,7 @@ class TestUserNotificationTasks(TestController): @with_nose_compatibility class TestNotificationTasks(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() @@ -623,7 +627,7 @@ class _TestArtifact(M.Artifact): @with_nose_compatibility class TestExportTasks(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() setup_global_objects() project = M.Project.query.get(shortname='test') diff --git a/Allura/allura/tests/test_utils.py b/Allura/allura/tests/test_utils.py index ac408a586..6e7fca1cc 100644 --- a/Allura/allura/tests/test_utils.py +++ b/Allura/allura/tests/test_utils.py @@ -51,7 +51,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestConfigProxy(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): self.cp = utils.ConfigProxy(mybaz="baz") def test_getattr(self): @@ -72,7 +72,7 @@ class TestConfigProxy(unittest.TestCase): @with_nose_compatibility class TestChunkedIterator(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_unit_test() config = { 'ming.main.uri': 'mim://host/allura_test', @@ -115,7 +115,7 @@ class TestChunkedList(unittest.TestCase): @with_nose_compatibility class TestAntispam(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_unit_test() self.a = utils.AntiSpam() @@ -256,7 +256,7 @@ class TestIsTextFile(unittest.TestCase): @with_nose_compatibility class TestCodeStats(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): setup_unit_test() def test_generate_code_stats(self): diff --git a/Allura/allura/tests/test_validators.py b/Allura/allura/tests/test_validators.py index cc9f2fba0..2e0f5af65 100644 --- a/Allura/allura/tests/test_validators.py +++ b/Allura/allura/tests/test_validators.py @@ -27,7 +27,7 @@ from allura.websetup.bootstrap import create_user from allura.tests.pytest_helpers import with_nose_compatibility -def setup_method(self, method): +def _setup_method(): setup_basic_test() @@ -40,6 +40,9 @@ def dummy_task(*args, **kw): class TestJsonConverter(unittest.TestCase): val = v.JsonConverter + def setup_method(self, method): + _setup_method() + def test_valid(self): self.assertEqual({}, self.val.to_python('{}')) @@ -52,6 +55,10 @@ class TestJsonConverter(unittest.TestCase): @with_nose_compatibility class TestJsonFile(unittest.TestCase): + + def setup_method(self, method): + _setup_method() + val = v.JsonFile class FieldStorage: @@ -71,6 +78,9 @@ class TestJsonFile(unittest.TestCase): class TestUserMapFile(unittest.TestCase): val = v.UserMapJsonFile() + def setup_method(self, method): + _setup_method() + class FieldStorage: def __init__(self, content): @@ -94,6 +104,9 @@ class TestUserMapFile(unittest.TestCase): class TestUserValidator(unittest.TestCase): val = v.UserValidator + def setup_method(self, method): + _setup_method() + def test_valid(self): self.assertEqual(M.User.by_username('root'), self.val.to_python('root')) @@ -108,6 +121,9 @@ class TestUserValidator(unittest.TestCase): class TestAnonymousValidator(unittest.TestCase): val = v.AnonymousValidator + def setup_method(self, method): + _setup_method() + @patch('allura.lib.validators.c') def test_valid(self, c): c.user = M.User.by_username('root') @@ -124,6 +140,9 @@ class TestAnonymousValidator(unittest.TestCase): @with_nose_compatibility class TestMountPointValidator(unittest.TestCase): + def setup_method(self, method): + _setup_method() + @patch('allura.lib.validators.c') def test_valid(self, c): App = Mock() @@ -186,6 +205,9 @@ class TestMountPointValidator(unittest.TestCase): class TestTaskValidator(unittest.TestCase): val = v.TaskValidator + def setup_method(self, method): + _setup_method() + def test_valid(self): self.assertEqual( dummy_task, self.val.to_python('allura.tests.test_validators.dummy_task')) @@ -208,15 +230,18 @@ class TestTaskValidator(unittest.TestCase): def test_not_a_task(self): with self.assertRaises(fe.Invalid) as cm: - self.val.to_python('allura.tests.test_validators.setUp') + self.val.to_python('allura.tests.test_validators._setup_method') self.assertEqual(str(cm.exception), - '"allura.tests.test_validators.setUp" is not a task.') + '"allura.tests.test_validators._setup_method" is not a task.') @with_nose_compatibility class TestPathValidator(unittest.TestCase): val = v.PathValidator(strip=True, if_missing={}, if_empty={}) + def setup_method(self, method): + _setup_method() + def test_valid_project(self): project = M.Project.query.get(shortname='test') d = self.val.to_python('/p/test') @@ -266,6 +291,9 @@ class TestPathValidator(unittest.TestCase): class TestUrlValidator(unittest.TestCase): val = v.URL + def setup_method(self, method): + _setup_method() + def test_valid(self): self.assertEqual('http://192.168.0.1', self.val.to_python('192.168.0.1')) self.assertEqual('http://url', self.val.to_python('url')) @@ -285,6 +313,9 @@ class TestUrlValidator(unittest.TestCase): class TestNonHttpUrlValidator(unittest.TestCase): val = v.NonHttpUrl + def setup_method(self, method): + _setup_method() + def test_valid(self): self.assertEqual('svn://192.168.0.1', self.val.to_python('svn://192.168.0.1')) self.assertEqual('ssh+git://url', self.val.to_python('ssh+git://url')) diff --git a/Allura/allura/tests/test_webhooks.py b/Allura/allura/tests/test_webhooks.py index df7512d59..5b9d5b1f2 100644 --- a/Allura/allura/tests/test_webhooks.py +++ b/Allura/allura/tests/test_webhooks.py @@ -62,7 +62,7 @@ with_git2 = td.with_tool(test_project_with_repo, 'git', 'src2', 'Git2') @with_nose_compatibility class TestWebhookBase: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() self.patches = self.monkey_patch() for p in self.patches: @@ -132,7 +132,7 @@ class TestValidators(TestWebhookBase): @with_nose_compatibility class TestWebhookController(TestController): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.patches = self.monkey_patch() for p in self.patches: @@ -424,8 +424,8 @@ class TestWebhookController(TestController): @with_nose_compatibility class TestSendWebhookHelper(TestWebhookBase): - def setUp(self, *args, **kw): - super().setUp(*args, **kw) + def setup_method(self, method): + super().setup_method(method) self.payload = {'some': ['data', 23]} self.h = SendWebhookHelper(self.wh, self.payload) @@ -678,7 +678,7 @@ class TestModels(TestWebhookBase): @with_nose_compatibility class TestWebhookRestController(TestRestApiBase): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.patches = self.monkey_patch() for p in self.patches: diff --git a/Allura/allura/tests/unit/__init__.py b/Allura/allura/tests/unit/__init__.py index 43b8c8256..4097ac952 100644 --- a/Allura/allura/tests/unit/__init__.py +++ b/Allura/allura/tests/unit/__init__.py @@ -19,14 +19,14 @@ from alluratest.controller import setup_basic_test from allura.websetup.bootstrap import clear_all_database_tables -def setup_class(self, method): +def setup_module(module): setup_basic_test() class MockPatchTestCase: patches = [] - def setup_class(self, method): + def setup_method(self, method): self._patch_instances = [patch_fn(self) for patch_fn in self.patches] for patch_instance in self._patch_instances: patch_instance.__enter__() @@ -38,6 +38,6 @@ class MockPatchTestCase: class WithDatabase(MockPatchTestCase): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) clear_all_database_tables() diff --git a/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py b/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py index 10a0e113d..72abd8ed4 100644 --- a/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py +++ b/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py @@ -35,7 +35,7 @@ class TestWhenModerating(WithDatabase): patches.fake_request_patch, patches.disable_notifications_patch] - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) post = create_post('mypost') discussion_controller = Mock( @@ -89,7 +89,7 @@ class TestIndexWithNoPosts(WithDatabase): class TestIndexWithAPostInTheDiscussion(WithDatabase): patches = [patches.fake_app_patch] - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.post = create_post('mypost') discussion = self.post.discussion diff --git a/Allura/allura/tests/unit/phone/test_nexmo.py b/Allura/allura/tests/unit/phone/test_nexmo.py index 776b4af01..2bcff5cfa 100644 --- a/Allura/allura/tests/unit/phone/test_nexmo.py +++ b/Allura/allura/tests/unit/phone/test_nexmo.py @@ -27,7 +27,7 @@ from allura.lib.phone.nexmo import NexmoPhoneService @with_nose_compatibility class TestPhoneService: - def setup_class(self, method): + def setup_method(self, method): config = {'phone.api_key': 'test-api-key', 'phone.api_secret': 'test-api-secret', 'site_name': 'Very loooooooooong site name'} diff --git a/Allura/allura/tests/unit/spam/test_spam_filter.py b/Allura/allura/tests/unit/spam/test_spam_filter.py index fa71ccecd..99f6ce1a9 100644 --- a/Allura/allura/tests/unit/spam/test_spam_filter.py +++ b/Allura/allura/tests/unit/spam/test_spam_filter.py @@ -79,7 +79,7 @@ class TestSpamFilter(unittest.TestCase): @with_nose_compatibility class TestSpamFilterFunctional: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() def test_record_result(self): diff --git a/Allura/allura/tests/unit/spam/test_stopforumspam.py b/Allura/allura/tests/unit/spam/test_stopforumspam.py index fbc6f9e40..2037ddde8 100644 --- a/Allura/allura/tests/unit/spam/test_stopforumspam.py +++ b/Allura/allura/tests/unit/spam/test_stopforumspam.py @@ -28,7 +28,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestStopForumSpam: - def setup_class(self, method): + def setup_method(self, method): self.content = 'spåm text' self.artifact = mock.Mock() diff --git a/Allura/allura/tests/unit/test_app.py b/Allura/allura/tests/unit/test_app.py index f60b95432..2a374f415 100644 --- a/Allura/allura/tests/unit/test_app.py +++ b/Allura/allura/tests/unit/test_app.py @@ -17,8 +17,6 @@ from unittest import TestCase -from alluratest.tools import assert_equal - from allura.app import Application from allura import model from allura.tests.unit import WithDatabase @@ -73,7 +71,7 @@ class TestInstall(WithDatabase): class TestDefaultDiscussion(WithDatabase): patches = [fake_app_patch] - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) install_app() self.discussion = model.Discussion.query.get( @@ -94,7 +92,7 @@ class TestDefaultDiscussion(WithDatabase): class TestAppDefaults(WithDatabase): patches = [fake_app_patch] - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.app = install_app() diff --git a/Allura/allura/tests/unit/test_discuss.py b/Allura/allura/tests/unit/test_discuss.py index 393d08921..9cb225e40 100644 --- a/Allura/allura/tests/unit/test_discuss.py +++ b/Allura/allura/tests/unit/test_discuss.py @@ -15,8 +15,6 @@ # specific language governing permissions and limitations # under the License. -from alluratest.tools import assert_false, assert_true - from allura import model as M from allura.tests.unit import WithDatabase from allura.tests.unit.patches import fake_app_patch diff --git a/Allura/allura/tests/unit/test_helpers/test_ago.py b/Allura/allura/tests/unit/test_helpers/test_ago.py index 0c538e752..7fef39014 100644 --- a/Allura/allura/tests/unit/test_helpers/test_ago.py +++ b/Allura/allura/tests/unit/test_helpers/test_ago.py @@ -27,7 +27,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestAgo: - def setup_class(self, method): + def setup_method(self, method): self.start_time = datetime(2010, 1, 1, 0, 0, 0) def test_that_exact_times_are_phrased_in_seconds(self): diff --git a/Allura/allura/tests/unit/test_helpers/test_set_context.py b/Allura/allura/tests/unit/test_helpers/test_set_context.py index 102e48ab8..3468ceed0 100644 --- a/Allura/allura/tests/unit/test_helpers/test_set_context.py +++ b/Allura/allura/tests/unit/test_helpers/test_set_context.py @@ -32,7 +32,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestWhenProjectIsFoundAndAppIsNot(WithDatabase): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.myproject = create_project('myproject') set_context('myproject', neighborhood=self.myproject.neighborhood) @@ -47,7 +47,7 @@ class TestWhenProjectIsFoundAndAppIsNot(WithDatabase): @with_nose_compatibility class TestWhenProjectIsFoundInNeighborhood(WithDatabase): - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.myproject = create_project('myproject') set_context('myproject', neighborhood=self.myproject.neighborhood) @@ -63,7 +63,7 @@ class TestWhenProjectIsFoundInNeighborhood(WithDatabase): class TestWhenAppIsFoundByID(WithDatabase): patches = [patches.project_app_loading_patch] - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.myproject = create_project('myproject') self.app_config = create_app_config(self.myproject, 'my_mounted_app') @@ -81,7 +81,7 @@ class TestWhenAppIsFoundByID(WithDatabase): class TestWhenAppIsFoundByMountPoint(WithDatabase): patches = [patches.project_app_loading_patch] - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.myproject = create_project('myproject') self.app_config = create_app_config(self.myproject, 'my_mounted_app') diff --git a/Allura/allura/tests/unit/test_ldap_auth_provider.py b/Allura/allura/tests/unit/test_ldap_auth_provider.py index 57c0ea6cb..d94430188 100644 --- a/Allura/allura/tests/unit/test_ldap_auth_provider.py +++ b/Allura/allura/tests/unit/test_ldap_auth_provider.py @@ -38,7 +38,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestLdapAuthenticationProvider: - def setup_class(self, method): + def setup_method(self, method): setup_basic_test() self.provider = plugin.LdapAuthenticationProvider(Request.blank('/')) diff --git a/Allura/allura/tests/unit/test_mixins.py b/Allura/allura/tests/unit/test_mixins.py index 670a8c929..f4e50aafe 100644 --- a/Allura/allura/tests/unit/test_mixins.py +++ b/Allura/allura/tests/unit/test_mixins.py @@ -23,7 +23,7 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestVotableArtifact: - def setup_class(self, method): + def setup_method(self, method): self.user1 = Mock() self.user1.username = 'test-user' self.user2 = Mock() diff --git a/Allura/allura/tests/unit/test_post_model.py b/Allura/allura/tests/unit/test_post_model.py index a6d62fff8..e1f7504ed 100644 --- a/Allura/allura/tests/unit/test_post_model.py +++ b/Allura/allura/tests/unit/test_post_model.py @@ -30,7 +30,7 @@ class TestPostModel(WithDatabase): patches = [patches.fake_app_patch, patches.disable_notifications_patch] - def setup_class(self, method): + def setup_method(self, method): super().setup_method(method) self.post = create_post('mypost') diff --git a/Allura/allura/tests/unit/test_repo.py b/Allura/allura/tests/unit/test_repo.py index 12bc058c0..df862d547 100644 --- a/Allura/allura/tests/unit/test_repo.py +++ b/Allura/allura/tests/unit/test_repo.py @@ -314,7 +314,7 @@ class TestPrefixPathsUnion(unittest.TestCase): @with_nose_compatibility class TestGroupCommits: - def setup_class(self, method): + def setup_method(self, method): self.repo = Mock() self.repo.symbolics_for_commit.return_value = ([], []) diff --git a/Allura/allura/tests/unit/test_session.py b/Allura/allura/tests/unit/test_session.py index fbf6e7f0e..cb7f02f7d 100644 --- a/Allura/allura/tests/unit/test_session.py +++ b/Allura/allura/tests/unit/test_session.py @@ -88,7 +88,7 @@ class TestSessionExtension(TestCase): @with_nose_compatibility class TestIndexerSessionExtension(TestSessionExtension): - def setup_class(self, method): + def setup_method(self, method): session = mock.Mock() self.ExtensionClass = IndexerSessionExtension self.extension = self.ExtensionClass(session) @@ -127,7 +127,7 @@ class TestIndexerSessionExtension(TestSessionExtension): @with_nose_compatibility class TestArtifactSessionExtension(TestSessionExtension): - def setup_class(self, method): + def setup_method(self, method): session = mock.Mock(disable_index=False) self.ExtensionClass = ArtifactSessionExtension self.extension = self.ExtensionClass(session) @@ -157,7 +157,7 @@ class TestArtifactSessionExtension(TestSessionExtension): @with_nose_compatibility class TestBatchIndexer(TestCase): - def setup_class(self, method): + def setup_method(self, method): session = mock.Mock() self.extcls = BatchIndexer self.ext = self.extcls(session) diff --git a/Allura/allura/tests/unit/test_solr.py b/Allura/allura/tests/unit/test_solr.py index 7bb5a188a..cc73cdb6f 100644 --- a/Allura/allura/tests/unit/test_solr.py +++ b/Allura/allura/tests/unit/test_solr.py @@ -32,6 +32,10 @@ from allura.tests.pytest_helpers import with_nose_compatibility @with_nose_compatibility class TestSolr(unittest.TestCase): + def setup_method(self, method): + # need to create the "test" project so @td.with_wiki works + setup_basic_test() + @mock.patch('allura.lib.solr.pysolr') def test_init(self, pysolr): servers = ['server1', 'server2'] @@ -122,7 +126,7 @@ class TestSolr(unittest.TestCase): @with_nose_compatibility class TestSearchIndexable(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): self.obj = SearchIndexable() def test_solarize_empty_index(self): @@ -147,7 +151,7 @@ class TestSearchIndexable(unittest.TestCase): @with_nose_compatibility class TestSearch_app(unittest.TestCase): - def setup_class(self, method): + def setup_method(self, method): # need to create the "test" project so @td.with_wiki works setup_basic_test() diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py index 8faf398de..1630d7d06 100644 --- a/ForgeTracker/forgetracker/tests/functional/test_root.py +++ b/ForgeTracker/forgetracker/tests/functional/test_root.py @@ -66,8 +66,8 @@ def find(d, pred): class TrackerTestController(TestController): - def setUp(self): - super().setUp() + def setup_method(self, method): + super().setup_method(method) self.setup_with_tools() @td.with_tracker
