You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by di...@apache.org on 2022/09/30 01:17:49 UTC

[allura] branch dw/8455-part2 updated (7805b2940 -> 8a769b86f)

This is an automated email from the ASF dual-hosted git repository.

dill0wn pushed a change to branch dw/8455-part2
in repository https://gitbox.apache.org/repos/asf/allura.git


    from 7805b2940 fixup! fixup! [#8455] remove @with_setup
     new e26ca2e2b fixup! fixup! fixup! [#8455] remove @with_setup
     new 98462a443 fixup! fixup! fixup! fixup! [#8455] remove @with_setup
     new 4c000b4aa fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup
     new 820a0159a fixup! fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup
     new 8a769b86f fixup! fixup! fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 Allura/allura/tests/model/test_monq.py         |   4 +-
 Allura/allura/tests/model/test_neighborhood.py | 107 ++++----
 Allura/allura/tests/model/test_oauth.py        |  32 ++-
 Allura/allura/tests/model/test_project.py      | 325 ++++++++++++-------------
 Allura/allura/tests/test_app.py                | 295 +++++++++++-----------
 5 files changed, 369 insertions(+), 394 deletions(-)


[allura] 01/05: fixup! fixup! fixup! [#8455] remove @with_setup

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dill0wn pushed a commit to branch dw/8455-part2
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e26ca2e2b60e5e1057e0d05fa1de2734e32bd05a
Author: Dillon Walls <di...@slashdotmedia.com>
AuthorDate: Fri Sep 30 00:30:54 2022 +0000

    fixup! fixup! fixup! [#8455] remove @with_setup
---
 Allura/allura/tests/test_app.py | 295 +++++++++++++++++++---------------------
 1 file changed, 143 insertions(+), 152 deletions(-)

diff --git a/Allura/allura/tests/test_app.py b/Allura/allura/tests/test_app.py
index 71733a2d5..8a6924ce2 100644
--- a/Allura/allura/tests/test_app.py
+++ b/Allura/allura/tests/test_app.py
@@ -20,161 +20,152 @@ import mock
 from ming.base import Object
 import pytest
 from formencode import validators as fev
+from textwrap import dedent
 
 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 alluratest.pytest_helpers import with_nose_compatibility
-
-
-def setup_method():
-    setup_unit_test()
-    c.user._id = None
-    c.project = mock.Mock()
-    c.project.name = 'Test Project'
-    c.project.shortname = 'tp'
-    c.project._id = 'testproject/'
-    c.project.url = lambda: '/testproject/'
-    app_config = mock.Mock()
-    app_config._id = None
-    app_config.project_id = 'testproject/'
-    app_config.tool_name = 'tool'
-    app_config.options = Object(mount_point='foo')
-    c.app = mock.Mock()
-    c.app.config = app_config
-    c.app.config.script_name = lambda: '/testproject/test_application/'
-    c.app.config.url = lambda: 'http://testproject/test_application/'
-    c.app.url = c.app.config.url()
-    c.app.__version__ = '0.0'
-
-def test_config_options():
-    options = [
-        app.ConfigOption('test1', str, 'MyTestValue'),
-        app.ConfigOption('test2', str, lambda:'MyTestValue')]
-    assert options[0].default == 'MyTestValue'
-    assert options[1].default == 'MyTestValue'
-
-
-def test_config_options_render_attrs():
-    opt = app.ConfigOption('test1', str, None, extra_attrs={'type': 'url'})
-    assert opt.render_attrs() == 'type="url"'
-
-
-def test_config_option_without_validator():
-    opt = app.ConfigOption('test1', str, None)
-    assert opt.validate(None) == None
-    assert opt.validate('') == ''
-    assert opt.validate('val') == 'val'
-
-
-def test_config_option_with_validator():
-    v = fev.NotEmpty()
-    opt = app.ConfigOption('test1', str, None, validator=v)
-    assert opt.validate('val') == 'val'
-    pytest.raises(fev.Invalid, opt.validate, None)
-    pytest.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)]
-    class TestApp(app.Application):
-        config_options = app.Application.config_options + opts + [
-            app.ConfigOption('not_on_install', str, None),
-        ]
-        config_on_install = ['url', 'private']
-
-    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
-        def sitemap(self):
-            children = [app.SitemapEntry('New', 'new', ui_icon=Icon('some-icon')),
-                        app.SitemapEntry('Recent', 'recent'),
-                        ]
-            return [app.SitemapEntry('My Tool', '.')[children]]
-
-    a = TestApp(c.project, c.app.config)
-    main_menu = a.main_menu()
-    assert len(main_menu) == 1
-    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/'),
-        app.SitemapEntry('b', 'b/')]
-    sm[app.SitemapEntry(lambda app:app.config.script_name(), 'c/')]
-    bound_sm = sm.bind_app(c.app)
-    assert bound_sm.url == 'http://testproject/test_application/', bound_sm.url
-    assert bound_sm.children[
-        -1].label == '/testproject/test_application/', bound_sm.children[-1].label
-    assert len(sm.children) == 3
-    sm.extend([app.SitemapEntry('a', 'a/')[
-        app.SitemapEntry('d', 'd/')]])
-    assert len(sm.children) == 3
-
-
-@with_setup(setup_method)
-@mock.patch('allura.app.Application.PostClass.query.get')
-def test_handle_artifact_unicode(qg):
-    """
-    Tests that app.handle_artifact_message can accept utf strings
-    """
-    ticket = mock.MagicMock()
-    ticket.get_discussion_thread.return_value = (mock.MagicMock(), mock.MagicMock())
-    post = mock.MagicMock()
-    qg.return_value = post
-
-    a = app.Application(c.project, c.app.config)
-
-    msg = dict(payload='foo ƒ†©¥˙¨ˆ'.encode(), message_id=1, headers={})
-    a.handle_artifact_message(ticket, msg)
-    assert post.attach.call_args[0][1].getvalue() == 'foo ƒ†©¥˙¨ˆ'.encode()
-
-    msg = dict(payload=b'foo', message_id=1, headers={})
-    a.handle_artifact_message(ticket, msg)
-    assert post.attach.call_args[0][1].getvalue() == b'foo'
-
-    msg = dict(payload="\x94my quote\x94".encode(), message_id=1, headers={})
-    a.handle_artifact_message(ticket, msg)
-    assert post.attach.call_args[0][1].getvalue() == '\x94my quote\x94'.encode()
-
-    # assert against prod example
-    msg_raw = """Message-Id: <15...@webmail.messagingengine.com>
-From: foo <fo...@bar.com>
-To: "[forge:site-support]" <15...@site-support.forge.p.re.sf.net>
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Type: multipart/alternative; boundary="_----------=_150235203132168580"
-Date: Thu, 10 Aug 2017 10:00:31 +0200
-Subject: Re: [forge:site-support] #15391 Unable to join (my own) mailing list
-This is a multi-part message in MIME format.
---_----------=_150235203132168580
-Content-Transfer-Encoding: quoted-printable
-Content-Type: text/plain; charset="utf-8"
-Hi
---_----------=_150235203132168580
-Content-Transfer-Encoding: quoted-printable
-Content-Type: text/html; charset="utf-8"
-<!DOCTYPE html>
-<html><body>Hi</body></html>
---_----------=_150235203132168580--
-    """
-    msg = mail_util.parse_message(msg_raw)
-    for p in [p for p in msg['parts'] if p['payload'] is not None]:
-        # filter here mimics logic in `route_email`
-        a.handle_artifact_message(ticket, p)
+
+
+class TestApp:
+
+    def setup_method(self):
+        setup_unit_test()
+        c.user._id = None
+        c.project = mock.Mock()
+        c.project.name = 'Test Project'
+        c.project.shortname = 'tp'
+        c.project._id = 'testproject/'
+        c.project.url = lambda: '/testproject/'
+        app_config = mock.Mock()
+        app_config._id = None
+        app_config.project_id = 'testproject/'
+        app_config.tool_name = 'tool'
+        app_config.options = Object(mount_point='foo')
+        c.app = mock.Mock()
+        c.app.config = app_config
+        c.app.config.script_name = lambda: '/testproject/test_application/'
+        c.app.config.url = lambda: 'http://testproject/test_application/'
+        c.app.url = c.app.config.url()
+        c.app.__version__ = '0.0'
+
+    def test_config_options(self):
+        options = [
+            app.ConfigOption('test1', str, 'MyTestValue'),
+            app.ConfigOption('test2', str, lambda:'MyTestValue')]
+        assert options[0].default == 'MyTestValue'
+        assert options[1].default == 'MyTestValue'
+
+    def test_config_options_render_attrs(self):
+        opt = app.ConfigOption('test1', str, None, extra_attrs={'type': 'url'})
+        assert opt.render_attrs() == 'type="url"'
+
+    def test_config_option_without_validator(self):
+        opt = app.ConfigOption('test1', str, None)
+        assert opt.validate(None) == None
+        assert opt.validate('') == ''
+        assert opt.validate('val') == 'val'
+
+    def test_config_option_with_validator(self):
+        v = fev.NotEmpty()
+        opt = app.ConfigOption('test1', str, None, validator=v)
+        assert opt.validate('val') == 'val'
+        pytest.raises(fev.Invalid, opt.validate, None)
+        pytest.raises(fev.Invalid, opt.validate, '')
+
+    def test_options_on_install_default(self):
+        a = app.Application(c.project, c.app.config)
+        assert a.options_on_install() == []
+
+    def test_options_on_install(self):
+        opts = [app.ConfigOption('url', str, None),
+                app.ConfigOption('private', bool, None)]
+        class TestApp(app.Application):
+            config_options = app.Application.config_options + opts + [
+                app.ConfigOption('not_on_install', str, None),
+            ]
+            config_on_install = ['url', 'private']
+
+        a = TestApp(c.project, c.app.config)
+        assert a.options_on_install() == opts
+
+    def test_main_menu(self):
+        class TestApp(app.Application):
+            @property
+            def sitemap(self):
+                children = [app.SitemapEntry('New', 'new', ui_icon=Icon('some-icon')),
+                            app.SitemapEntry('Recent', 'recent'),
+                            ]
+                return [app.SitemapEntry('My Tool', '.')[children]]
+
+        a = TestApp(c.project, c.app.config)
+        main_menu = a.main_menu()
+        assert len(main_menu) == 1
+        assert main_menu[0].children == []  # default main_menu implementation should drop the children from sitemap()
+
+    def test_sitemap(self):
+        sm = app.SitemapEntry('test', '')[
+            app.SitemapEntry('a', 'a/'),
+            app.SitemapEntry('b', 'b/')]
+        sm[app.SitemapEntry(lambda app:app.config.script_name(), 'c/')]
+        bound_sm = sm.bind_app(c.app)
+        assert bound_sm.url == 'http://testproject/test_application/', bound_sm.url
+        assert bound_sm.children[
+            -1].label == '/testproject/test_application/', bound_sm.children[-1].label
+        assert len(sm.children) == 3
+        sm.extend([app.SitemapEntry('a', 'a/')[
+            app.SitemapEntry('d', 'd/')]])
+        assert len(sm.children) == 3
+
+    @mock.patch('allura.app.Application.PostClass.query.get')
+    def test_handle_artifact_unicode(self, qg):
+        """
+        Tests that app.handle_artifact_message can accept utf strings
+        """
+        ticket = mock.MagicMock()
+        ticket.get_discussion_thread.return_value = (mock.MagicMock(), mock.MagicMock())
+        post = mock.MagicMock()
+        qg.return_value = post
+
+        a = app.Application(c.project, c.app.config)
+
+        msg = dict(payload='foo ƒ†©¥˙¨ˆ'.encode(), message_id=1, headers={})
+        a.handle_artifact_message(ticket, msg)
+        assert post.attach.call_args[0][1].getvalue() == 'foo ƒ†©¥˙¨ˆ'.encode()
+
+        msg = dict(payload=b'foo', message_id=1, headers={})
+        a.handle_artifact_message(ticket, msg)
+        assert post.attach.call_args[0][1].getvalue() == b'foo'
+
+        msg = dict(payload="\x94my quote\x94".encode(), message_id=1, headers={})
+        a.handle_artifact_message(ticket, msg)
+        assert post.attach.call_args[0][1].getvalue() == '\x94my quote\x94'.encode()
+
+        # assert against prod example
+        msg_raw = dedent("""\
+            Message-Id: <15...@webmail.messagingengine.com>
+            From: foo <fo...@bar.com>
+            To: "[forge:site-support]" <15...@site-support.forge.p.re.sf.net>
+            MIME-Version: 1.0
+            Content-Transfer-Encoding: 7bit
+            Content-Type: multipart/alternative; boundary="_----------=_150235203132168580"
+            Date: Thu, 10 Aug 2017 10:00:31 +0200
+            Subject: Re: [forge:site-support] #15391 Unable to join (my own) mailing list
+            This is a multi-part message in MIME format.
+            --_----------=_150235203132168580
+            Content-Transfer-Encoding: quoted-printable
+            Content-Type: text/plain; charset="utf-8"
+            Hi
+            --_----------=_150235203132168580
+            Content-Transfer-Encoding: quoted-printable
+            Content-Type: text/html; charset="utf-8"
+            <!DOCTYPE html>
+            <html><body>Hi</body></html>
+            --_----------=_150235203132168580--
+        """)
+        msg = mail_util.parse_message(msg_raw)
+        for p in [p for p in msg['parts'] if p['payload'] is not None]:
+            # filter here mimics logic in `route_email`
+            a.handle_artifact_message(ticket, p)


[allura] 02/05: fixup! fixup! fixup! fixup! [#8455] remove @with_setup

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dill0wn pushed a commit to branch dw/8455-part2
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 98462a4435f0f58717a1e42eadce2079403d9e94
Author: Dillon Walls <di...@slashdotmedia.com>
AuthorDate: Fri Sep 30 00:36:09 2022 +0000

    fixup! fixup! fixup! fixup! [#8455] remove @with_setup
---
 Allura/allura/tests/model/test_project.py | 325 +++++++++++++++---------------
 1 file changed, 157 insertions(+), 168 deletions(-)

diff --git a/Allura/allura/tests/model/test_project.py b/Allura/allura/tests/model/test_project.py
index 524754bc3..6a1d44a8a 100644
--- a/Allura/allura/tests/model/test_project.py
+++ b/Allura/allura/tests/model/test_project.py
@@ -31,172 +31,161 @@ from allura.lib.exceptions import ToolError, Invalid
 from mock import MagicMock, patch
 
 
-def setup_method():
-    setup_basic_test()
-    setup_with_tools()
-
-
-@td.with_wiki
-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()
-    old_proj = c.project
-    h.set_context('test/sub1', neighborhood='Projects')
-    assert type(c.project.sidebar_menu()) == list
-    assert type(c.project.sitemap()) == list
-    assert c.project.sitemap()[1].label == 'Admin'
-    assert old_proj in list(c.project.parent_iter())
-    h.set_context('test', 'wiki', neighborhood='Projects')
-    adobe_nbhd = M.Neighborhood.query.get(name='Adobe')
-    p = M.Project.query.get(
-        shortname='adobe-1', neighborhood_id=adobe_nbhd._id)
-    # assert 'http' in p.url() # We moved adobe into /adobe/, not
-    # http://adobe....
-    assert p.script_name in p.url()
-    assert c.project.shortname == 'test'
-    assert '<p>' in c.project.description_html
-    c.project.uninstall_app('hello-test-mount-point')
-    ThreadLocalORMSession.flush_all()
-
-    c.project.install_app('Wiki', 'hello-test-mount-point')
-    c.project.support_page = 'hello-test-mount-point'
-    assert c.project.app_config('wiki').tool_name == 'wiki'
-    ThreadLocalORMSession.flush_all()
-    with td.raises(ToolError):
-        # already installed
+class TestProjectModel:
+
+    def setup_method(self):
+        setup_basic_test()
+        self.setup_with_tools()
+
+    @td.with_wiki
+    def setup_with_tools(self):
+        setup_global_objects()
+
+    def test_project(self):
+        assert type(c.project.sidebar_menu()) == list
+        assert c.project.script_name in c.project.url()
+        old_proj = c.project
+        h.set_context('test/sub1', neighborhood='Projects')
+        assert type(c.project.sidebar_menu()) == list
+        assert type(c.project.sitemap()) == list
+        assert c.project.sitemap()[1].label == 'Admin'
+        assert old_proj in list(c.project.parent_iter())
+        h.set_context('test', 'wiki', neighborhood='Projects')
+        adobe_nbhd = M.Neighborhood.query.get(name='Adobe')
+        p = M.Project.query.get(
+            shortname='adobe-1', neighborhood_id=adobe_nbhd._id)
+        # assert 'http' in p.url() # We moved adobe into /adobe/, not
+        # http://adobe....
+        assert p.script_name in p.url()
+        assert c.project.shortname == 'test'
+        assert '<p>' in c.project.description_html
+        c.project.uninstall_app('hello-test-mount-point')
+        ThreadLocalORMSession.flush_all()
+
         c.project.install_app('Wiki', 'hello-test-mount-point')
-    ThreadLocalORMSession.flush_all()
-    c.project.uninstall_app('hello-test-mount-point')
-    ThreadLocalORMSession.flush_all()
-    with td.raises(ToolError):
-        # mount point reserved
-        c.project.install_app('Wiki', 'feed')
-    with td.raises(ToolError):
-        # mount point too long
-        c.project.install_app('Wiki', 'a' * 64)
-    with td.raises(ToolError):
-        # mount point must begin with letter
-        c.project.install_app('Wiki', '1')
-    # single letter mount points are allowed
-    c.project.install_app('Wiki', 'a')
-    # Make sure the project support page is reset if the tool it was pointing
-    # to is uninstalled.
-    assert c.project.support_page == ''
-    app_config = c.project.app_config('hello')
-    app_inst = c.project.app_instance(app_config)
-    app_inst = c.project.app_instance('hello')
-    app_inst = c.project.app_instance('hello2123')
-    c.project.breadcrumbs()
-    c.app.config.breadcrumbs()
-
-
-@with_setup(setup_method)
-def test_install_app_validates_options():
-    from forgetracker.tracker_main import ForgeTrackerApp
-    name = 'TicketMonitoringEmail'
-    opt = [o for o in ForgeTrackerApp.config_options if o.name == name][0]
-    opt.validator = fev.Email(not_empty=True)
-    with patch.object(ForgeTrackerApp, 'config_on_install', new=[opt.name]):
-        for v in [None, '', 'bad@email']:
-            with td.raises(ToolError):
-                c.project.install_app('Tickets', 'test-tickets', **{name: v})
-            assert c.project.app_instance('test-tickets') == None
-        c.project.install_app('Tickets', 'test-tickets', **{name: 'e@e.com'})
-        app = c.project.app_instance('test-tickets')
-        assert app.config.options[name] == 'e@e.com'
-
-
-def test_project_index():
-    project, idx = c.project, c.project.index()
-    assert 'id' in idx
-    assert idx['id'] == project.index_id()
-    assert 'title' in idx
-    assert 'type_s' in idx
-    assert 'deleted_b' in idx
-    assert 'private_b' in idx
-    assert 'neighborhood_id_s' in idx
-    assert 'short_description_t' in idx
-    assert 'url_s' in idx
-
-
-def test_subproject():
-    project = M.Project.query.get(shortname='test')
-    with td.raises(ToolError):
-        with patch('allura.lib.plugin.ProjectRegistrationProvider') as Provider:
-            Provider.get().shortname_validator.to_python.side_effect = Invalid(
-                'name', 'value', {})
-            # name doesn't validate
-            sp = project.new_subproject('test-proj-nose')
-    sp = project.new_subproject('test-proj-nose')
-    spp = sp.new_subproject('spp')
-    ThreadLocalORMSession.flush_all()
-    sp.delete()
-    ThreadLocalORMSession.flush_all()
-
-
-@td.with_wiki
-def test_anchored_tools():
-    c.project.neighborhood.anchored_tools = 'wiki:Wiki, tickets:Ticket'
-    c.project.install_app = MagicMock()
-    assert c.project.sitemap()[0].label == 'Wiki'
-    assert c.project.install_app.call_args[0][0] == 'tickets'
-    assert c.project.ordered_mounts()[0]['ac'].tool_name == 'wiki'
-
-
-def test_set_ordinal_to_admin_tool():
-    with h.push_config(c,
-                       user=M.User.by_username('test-admin'),
-                       project=M.Project.query.get(shortname='test')):
-        sm = c.project.sitemap()
-        assert sm[-1].tool_name == 'admin'
-
-
-@with_setup(setup_method)
-def test_users_and_roles():
-    p = M.Project.query.get(shortname='test')
-    sub = p.direct_subprojects[0]
-    u = M.User.by_username('test-admin')
-    assert p.users_with_role('Admin') == [u]
-    assert p.users_with_role('Admin') == sub.users_with_role('Admin')
-    assert p.users_with_role('Admin') == p.admins()
-
-    user = p.admins()[0]
-    user.disabled = True
-    ThreadLocalORMSession.flush_all()
-    assert p.users_with_role('Admin') == []
-    assert p.users_with_role('Admin') == p.admins()
-
-
-@with_setup(setup_method)
-def test_project_disabled_users():
-    p = M.Project.query.get(shortname='test')
-    users = p.users()
-    assert users[0].username == 'test-admin'
-    user = M.User.by_username('test-admin')
-    user.disabled = True
-    ThreadLocalORMSession.flush_all()
-    users = p.users()
-    assert users == []
-
-def test_screenshot_unicode_serialization():
-    p = M.Project.query.get(shortname='test')
-    screenshot_unicode = M.ProjectFile(project_id=p._id, category='screenshot', caption="ConSelección", filename='ConSelección.jpg')
-    screenshot_ascii = M.ProjectFile(project_id=p._id, category='screenshot', caption='test-screenshot', filename='test_file.jpg')
-    ThreadLocalORMSession.flush_all()
-
-    serialized = p.__json__()
-    screenshots = sorted(serialized['screenshots'], key=lambda k: k['caption'])
-
-    assert len(screenshots) == 2
-    assert screenshots[0]['url'] == 'http://localhost/p/test/screenshot/ConSelecci%C3%B3n.jpg'
-    assert screenshots[0]['caption'] == "ConSelección"
-    assert screenshots[0]['thumbnail_url'] == 'http://localhost/p/test/screenshot/ConSelecci%C3%B3n.jpg/thumb'
-
-    assert screenshots[1]['url'] == 'http://localhost/p/test/screenshot/test_file.jpg'
-    assert screenshots[1]['caption'] == 'test-screenshot'
-    assert screenshots[1]['thumbnail_url'] == 'http://localhost/p/test/screenshot/test_file.jpg/thumb'
+        c.project.support_page = 'hello-test-mount-point'
+        assert c.project.app_config('wiki').tool_name == 'wiki'
+        ThreadLocalORMSession.flush_all()
+        with td.raises(ToolError):
+            # already installed
+            c.project.install_app('Wiki', 'hello-test-mount-point')
+        ThreadLocalORMSession.flush_all()
+        c.project.uninstall_app('hello-test-mount-point')
+        ThreadLocalORMSession.flush_all()
+        with td.raises(ToolError):
+            # mount point reserved
+            c.project.install_app('Wiki', 'feed')
+        with td.raises(ToolError):
+            # mount point too long
+            c.project.install_app('Wiki', 'a' * 64)
+        with td.raises(ToolError):
+            # mount point must begin with letter
+            c.project.install_app('Wiki', '1')
+        # single letter mount points are allowed
+        c.project.install_app('Wiki', 'a')
+        # Make sure the project support page is reset if the tool it was pointing
+        # to is uninstalled.
+        assert c.project.support_page == ''
+        app_config = c.project.app_config('hello')
+        app_inst = c.project.app_instance(app_config)
+        app_inst = c.project.app_instance('hello')
+        app_inst = c.project.app_instance('hello2123')
+        c.project.breadcrumbs()
+        c.app.config.breadcrumbs()
+
+    def test_install_app_validates_options(self):
+        from forgetracker.tracker_main import ForgeTrackerApp
+        name = 'TicketMonitoringEmail'
+        opt = [o for o in ForgeTrackerApp.config_options if o.name == name][0]
+        opt.validator = fev.Email(not_empty=True)
+        with patch.object(ForgeTrackerApp, 'config_on_install', new=[opt.name]):
+            for v in [None, '', 'bad@email']:
+                with td.raises(ToolError):
+                    c.project.install_app('Tickets', 'test-tickets', **{name: v})
+                assert c.project.app_instance('test-tickets') == None
+            c.project.install_app('Tickets', 'test-tickets', **{name: 'e@e.com'})
+            app = c.project.app_instance('test-tickets')
+            assert app.config.options[name] == 'e@e.com'
+
+    def test_project_index(self):
+        project, idx = c.project, c.project.index()
+        assert 'id' in idx
+        assert idx['id'] == project.index_id()
+        assert 'title' in idx
+        assert 'type_s' in idx
+        assert 'deleted_b' in idx
+        assert 'private_b' in idx
+        assert 'neighborhood_id_s' in idx
+        assert 'short_description_t' in idx
+        assert 'url_s' in idx
+
+    def test_subproject(self):
+        project = M.Project.query.get(shortname='test')
+        with td.raises(ToolError):
+            with patch('allura.lib.plugin.ProjectRegistrationProvider') as Provider:
+                Provider.get().shortname_validator.to_python.side_effect = Invalid(
+                    'name', 'value', {})
+                # name doesn't validate
+                sp = project.new_subproject('test-proj-nose')
+        sp = project.new_subproject('test-proj-nose')
+        spp = sp.new_subproject('spp')
+        ThreadLocalORMSession.flush_all()
+        sp.delete()
+        ThreadLocalORMSession.flush_all()
+
+    @td.with_wiki
+    def test_anchored_tools(self):
+        c.project.neighborhood.anchored_tools = 'wiki:Wiki, tickets:Ticket'
+        c.project.install_app = MagicMock()
+        assert c.project.sitemap()[0].label == 'Wiki'
+        assert c.project.install_app.call_args[0][0] == 'tickets'
+        assert c.project.ordered_mounts()[0]['ac'].tool_name == 'wiki'
+
+    def test_set_ordinal_to_admin_tool(self):
+        with h.push_config(c,
+                        user=M.User.by_username('test-admin'),
+                        project=M.Project.query.get(shortname='test')):
+            sm = c.project.sitemap()
+            assert sm[-1].tool_name == 'admin'
+
+    def test_users_and_roles(self):
+        p = M.Project.query.get(shortname='test')
+        sub = p.direct_subprojects[0]
+        u = M.User.by_username('test-admin')
+        assert p.users_with_role('Admin') == [u]
+        assert p.users_with_role('Admin') == sub.users_with_role('Admin')
+        assert p.users_with_role('Admin') == p.admins()
+
+        user = p.admins()[0]
+        user.disabled = True
+        ThreadLocalORMSession.flush_all()
+        assert p.users_with_role('Admin') == []
+        assert p.users_with_role('Admin') == p.admins()
+
+    def test_project_disabled_users(self):
+        p = M.Project.query.get(shortname='test')
+        users = p.users()
+        assert users[0].username == 'test-admin'
+        user = M.User.by_username('test-admin')
+        user.disabled = True
+        ThreadLocalORMSession.flush_all()
+        users = p.users()
+        assert users == []
+
+    def test_screenshot_unicode_serialization(self):
+        p = M.Project.query.get(shortname='test')
+        screenshot_unicode = M.ProjectFile(project_id=p._id, category='screenshot', caption="ConSelección", filename='ConSelección.jpg')
+        screenshot_ascii = M.ProjectFile(project_id=p._id, category='screenshot', caption='test-screenshot', filename='test_file.jpg')
+        ThreadLocalORMSession.flush_all()
+
+        serialized = p.__json__()
+        screenshots = sorted(serialized['screenshots'], key=lambda k: k['caption'])
+
+        assert len(screenshots) == 2
+        assert screenshots[0]['url'] == 'http://localhost/p/test/screenshot/ConSelecci%C3%B3n.jpg'
+        assert screenshots[0]['caption'] == "ConSelección"
+        assert screenshots[0]['thumbnail_url'] == 'http://localhost/p/test/screenshot/ConSelecci%C3%B3n.jpg/thumb'
+
+        assert screenshots[1]['url'] == 'http://localhost/p/test/screenshot/test_file.jpg'
+        assert screenshots[1]['caption'] == 'test-screenshot'
+        assert screenshots[1]['thumbnail_url'] == 'http://localhost/p/test/screenshot/test_file.jpg/thumb'


[allura] 03/05: fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dill0wn pushed a commit to branch dw/8455-part2
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 4c000b4aaa04cae833c513f037511a99be9d9e0d
Author: Dillon Walls <di...@slashdotmedia.com>
AuthorDate: Fri Sep 30 00:47:39 2022 +0000

    fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup
---
 Allura/allura/tests/model/test_oauth.py | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/Allura/allura/tests/model/test_oauth.py b/Allura/allura/tests/model/test_oauth.py
index 67d12b094..edb396abc 100644
--- a/Allura/allura/tests/model/test_oauth.py
+++ b/Allura/allura/tests/model/test_oauth.py
@@ -16,28 +16,26 @@
 #       under the License.
 
 
-from alluratest.tools import with_setup, assert_equal, assert_not_equal
-
 from ming.odm import ThreadLocalORMSession
 
 from allura import model as M
 from alluratest.controller import setup_basic_test, setup_global_objects
 
 
-def setup_method():
-    setup_basic_test()
-    ThreadLocalORMSession.close_all()
-    setup_global_objects()
+class TestOAuthModel:
 
+    def setup_method(self):
+        setup_basic_test()
+        ThreadLocalORMSession.close_all()
+        setup_global_objects()
 
-@with_setup(setup_method)
-def test_upsert():
-    admin = M.User.by_username('test-admin')
-    user = M.User.by_username('test-user')
-    name = 'test-token'
-    token1 = M.OAuthConsumerToken.upsert(name, admin)
-    token2 = M.OAuthConsumerToken.upsert(name, admin)
-    token3 = M.OAuthConsumerToken.upsert(name, user)
-    assert M.OAuthConsumerToken.query.find().count() == 2
-    assert token1._id == token2._id
-    assert token1._id != token3._id
+    def test_upsert(self):
+        admin = M.User.by_username('test-admin')
+        user = M.User.by_username('test-user')
+        name = 'test-token'
+        token1 = M.OAuthConsumerToken.upsert(name, admin)
+        token2 = M.OAuthConsumerToken.upsert(name, admin)
+        token3 = M.OAuthConsumerToken.upsert(name, user)
+        assert M.OAuthConsumerToken.query.find().count() == 2
+        assert token1._id == token2._id
+        assert token1._id != token3._id


[allura] 04/05: fixup! fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dill0wn pushed a commit to branch dw/8455-part2
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 820a0159a2d0918ae509e24738282e624a3246d7
Author: Dillon Walls <di...@slashdotmedia.com>
AuthorDate: Fri Sep 30 01:16:12 2022 +0000

    fixup! fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup
---
 Allura/allura/tests/model/test_neighborhood.py | 107 ++++++++++++-------------
 1 file changed, 53 insertions(+), 54 deletions(-)

diff --git a/Allura/allura/tests/model/test_neighborhood.py b/Allura/allura/tests/model/test_neighborhood.py
index 26a773331..247370888 100644
--- a/Allura/allura/tests/model/test_neighborhood.py
+++ b/Allura/allura/tests/model/test_neighborhood.py
@@ -25,65 +25,64 @@ from allura.tests import decorators as td
 from alluratest.controller import setup_basic_test, setup_global_objects
 
 
-def setup_method():
-    setup_basic_test()
-    setup_with_tools()
+class TestNeighboorhoodModel:
 
+    def setup_method(self):
+        setup_basic_test()
+        self.setup_with_tools()
 
-@td.with_wiki
-def setup_with_tools():
-    setup_global_objects()
+    @td.with_wiki
+    def setup_with_tools(self):
+        setup_global_objects()
 
+    def test_neighborhood(self):
+        neighborhood = M.Neighborhood.query.get(name='Projects')
+        # Check css output depends of neighborhood level
+        test_css = ".text{color:#000;}"
+        neighborhood.css = test_css
+        neighborhood.features['css'] = 'none'
+        assert neighborhood.get_custom_css() == ""
+        neighborhood.features['css'] = 'picker'
+        assert neighborhood.get_custom_css() == test_css
+        neighborhood.features['css'] = 'custom'
+        assert neighborhood.get_custom_css() == test_css
+        # Check max projects
+        neighborhood.features['max_projects'] = None
+        assert neighborhood.get_max_projects() is None
+        neighborhood.features['max_projects'] = 500
+        assert neighborhood.get_max_projects() == 500
 
-@with_setup(setup_method)
-def test_neighborhood():
-    neighborhood = M.Neighborhood.query.get(name='Projects')
-    # Check css output depends of neighborhood level
-    test_css = ".text{color:#000;}"
-    neighborhood.css = test_css
-    neighborhood.features['css'] = 'none'
-    assert neighborhood.get_custom_css() == ""
-    neighborhood.features['css'] = 'picker'
-    assert neighborhood.get_custom_css() == test_css
-    neighborhood.features['css'] = 'custom'
-    assert neighborhood.get_custom_css() == test_css
-    # Check max projects
-    neighborhood.features['max_projects'] = None
-    assert neighborhood.get_max_projects() is None
-    neighborhood.features['max_projects'] = 500
-    assert neighborhood.get_max_projects() == 500
+        # Check picker css styles
+        test_css_dict = {'barontop': '#444',
+                        'titlebarbackground': '#555',
+                        'projecttitlefont': 'arial,sans-serif',
+                        'projecttitlecolor': '#333',
+                        'titlebarcolor': '#666'}
+        css_text = neighborhood.compile_css_for_picker(test_css_dict)
+        assert '#333' in css_text
+        assert '#444' in css_text
+        assert '#555' in css_text
+        assert '#666' in css_text
+        assert 'arial,sans-serif' in css_text
+        neighborhood.css = css_text
+        styles_list = neighborhood.get_css_for_picker()
+        for style in styles_list:
+            assert test_css_dict[style['name']] == style['value']
 
-    # Check picker css styles
-    test_css_dict = {'barontop': '#444',
-                     'titlebarbackground': '#555',
-                     'projecttitlefont': 'arial,sans-serif',
-                     'projecttitlecolor': '#333',
-                     'titlebarcolor': '#666'}
-    css_text = neighborhood.compile_css_for_picker(test_css_dict)
-    assert '#333' in css_text
-    assert '#444' in css_text
-    assert '#555' in css_text
-    assert '#666' in css_text
-    assert 'arial,sans-serif' in css_text
-    neighborhood.css = css_text
-    styles_list = neighborhood.get_css_for_picker()
-    for style in styles_list:
-        assert test_css_dict[style['name']] == style['value']
+        # Check neighborhood custom css showing
+        neighborhood.features['css'] = 'none'
+        assert not neighborhood.allow_custom_css
+        neighborhood.features['css'] = 'picker'
+        assert neighborhood.allow_custom_css
+        neighborhood.features['css'] = 'custom'
+        assert neighborhood.allow_custom_css
 
-    # Check neighborhood custom css showing
-    neighborhood.features['css'] = 'none'
-    assert not neighborhood.allow_custom_css
-    neighborhood.features['css'] = 'picker'
-    assert neighborhood.allow_custom_css
-    neighborhood.features['css'] = 'custom'
-    assert neighborhood.allow_custom_css
+        neighborhood.anchored_tools = 'wiki:Wiki, tickets:Tickets'
+        assert neighborhood.get_anchored_tools()['wiki'] == 'Wiki'
+        assert neighborhood.get_anchored_tools()['tickets'] == 'Tickets'
 
-    neighborhood.anchored_tools = 'wiki:Wiki, tickets:Tickets'
-    assert neighborhood.get_anchored_tools()['wiki'] == 'Wiki'
-    assert neighborhood.get_anchored_tools()['tickets'] == 'Tickets'
+        neighborhood.prohibited_tools = 'wiki, tickets'
+        assert neighborhood.get_prohibited_tools() == ['wiki', 'tickets']
 
-    neighborhood.prohibited_tools = 'wiki, tickets'
-    assert neighborhood.get_prohibited_tools() == ['wiki', 'tickets']
-
-    # Check properties
-    assert neighborhood.shortname == "p"
+        # Check properties
+        assert neighborhood.shortname == "p"


[allura] 05/05: fixup! fixup! fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup

Posted by di...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dill0wn pushed a commit to branch dw/8455-part2
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 8a769b86f95d5638d6790632f28842c16a0b0f6f
Author: Dillon Walls <di...@slashdotmedia.com>
AuthorDate: Fri Sep 30 01:17:33 2022 +0000

    fixup! fixup! fixup! fixup! fixup! fixup! fixup! [#8455] remove @with_setup
---
 Allura/allura/tests/model/test_monq.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/Allura/allura/tests/model/test_monq.py b/Allura/allura/tests/model/test_monq.py
index 9dc682149..9b2d51754 100644
--- a/Allura/allura/tests/model/test_monq.py
+++ b/Allura/allura/tests/model/test_monq.py
@@ -16,7 +16,6 @@
 #       under the License.
 
 import pprint
-from alluratest.tools import with_setup
 
 from ming.orm import ThreadLocalORMSession
 
@@ -24,14 +23,13 @@ from alluratest.controller import setup_basic_test, setup_global_objects
 from allura import model as M
 
 
-def setup_method():
+def setup_module():
     setup_basic_test()
     ThreadLocalORMSession.close_all()
     setup_global_objects()
     M.MonQTask.query.remove({})
 
 
-@with_setup(setup_method)
 def test_basic_task():
     task = M.MonQTask.post(pprint.pformat, ([5, 6],))
     ThreadLocalORMSession.flush_all()