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/23 18:43:30 UTC
[allura] 05/10: [#8455] allura pytest - fix misc test failures that popped up during pytest conversion
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 df4c736ddbaf86f9cd4da6e1846f97b92c1d654d
Author: Dillon Walls <di...@slashdotmedia.com>
AuthorDate: Mon Sep 12 20:00:41 2022 +0000
[#8455] allura pytest - fix misc test failures that popped up during pytest conversion
---
Allura/allura/lib/macro.py | 15 +--
Allura/allura/model/project.py | 20 +++-
Allura/allura/tests/exclude_from_rewrite_hook.py | 31 ++++++
.../allura/tests/functional/test_neighborhood.py | 8 +-
.../allura/tests/functional/test_user_profile.py | 70 +++++++------
Allura/allura/tests/model/test_auth.py | 2 +-
Allura/allura/tests/test_globals.py | 115 ++++++++++++---------
Allura/allura/tests/test_plugin.py | 34 +++---
Allura/allura/tests/test_tasks.py | 38 +++----
Allura/allura/tests/test_webhooks.py | 101 +++++++++---------
10 files changed, 249 insertions(+), 185 deletions(-)
diff --git a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
index b1af50297..0e293037e 100644
--- a/Allura/allura/lib/macro.py
+++ b/Allura/allura/lib/macro.py
@@ -177,14 +177,15 @@ def project_blog_posts(max_number=5, sort='timestamp', summary=False, mount_poin
'state': 'published',
})
posts = posts.sort(sort, pymongo.DESCENDING).limit(int(max_number)).all()
- output = ((dict(
- href=post.url(),
- title=post.title,
- author=post.author().display_name,
- ago=h.ago(post.timestamp),
- description=summary and ' ' or g.markdown.cached_convert(post, 'text')))
+ output = [
+ dict(href=post.url(),
+ title=post.title,
+ author=post.author().display_name,
+ ago=h.ago(post.timestamp),
+ description=summary and ' ' or g.markdown.cached_convert(post, 'text'))
for post in posts if security.has_access(post, 'read', project=post.app.project)() and
- security.has_access(post.app.project, 'read', project=post.app.project)())
+ security.has_access(post.app.project, 'read', project=post.app.project)()
+ ]
posts = BlogPosts(posts=output)
g.resource_manager.register(posts)
response = posts.display(posts=output)
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index c0a010f5e..66b265e80 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -1102,12 +1102,30 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
ThreadLocalORMSession.flush_all()
def add_user(self, user, role_names):
- 'Convenience method to add member with the given role(s).'
+ '''Convenience method to add member with the given role(s).'''
pr = ProjectRole.by_user(user, project=self, upsert=True)
for role_name in role_names:
r = ProjectRole.by_name(role_name, self)
pr.roles.append(r._id)
+ def remove_user(self, user, role_names=None):
+ '''Convenience method to add member with the given role(s).'''
+ pr = ProjectRole.by_user(user, project=self)
+ if not pr:
+ return
+
+ if not role_names or not isinstance(role_names, Iterable):
+ ProjectRole.query.remove({'_id': pr._id})
+ return
+
+ for role_name in role_names:
+ r = ProjectRole.by_name(role_name, self)
+ if r._id in pr.roles:
+ pr.roles.remove(r._id)
+
+ if not pr.roles:
+ pr.remove()
+
@property
def twitter_handle(self):
return self.social_account('Twitter').accounturl
diff --git a/Allura/allura/tests/exclude_from_rewrite_hook.py b/Allura/allura/tests/exclude_from_rewrite_hook.py
new file mode 100644
index 000000000..509841776
--- /dev/null
+++ b/Allura/allura/tests/exclude_from_rewrite_hook.py
@@ -0,0 +1,31 @@
+import sys
+
+from allura.app import Application
+from allura.lib.decorators import task
+from allura.lib.exceptions import CompoundError
+
+
+class ThemeProviderTestApp(Application):
+ """
+ If this test class is added directly to a test module, pkg_resources internals
+ will throw this error:
+ NotImplementedError: Can't perform this operation for unregistered loader type
+ This is because pytest adds a hook to override the default assert behavior and this
+ conflicts/messes-with pkg_resources. Theoretically on python > py37, importlib.resources
+ can do the same things as pkg_resources and faster, but those solutions don't currently
+ work on py37.
+ """
+ icons = {
+ 24: 'images/testapp_24.png',
+ }
+
+
+@task
+def raise_compound_exception():
+ errs = []
+ for x in range(10):
+ try:
+ assert False, 'assert %d' % x
+ except Exception:
+ errs.append(sys.exc_info())
+ raise CompoundError(*errs)
\ No newline at end of file
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index a1d1e7d57..ac7ee3c9d 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -43,12 +43,12 @@ from allura.tests.pytest_helpers import with_nose_compatibility
@with_nose_compatibility
class TestNeighborhood(TestController):
- def setUp(self):
- super().setUp()
+ def setup_method(self, method):
+ super().setup_method(method)
self._cleanup_audit_log()
- def tearDown(self):
- super().tearDown()
+ def teardown_method(self, method):
+ super().teardown_method(method)
self._cleanup_audit_log()
def _cleanup_audit_log(self):
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index 4a54ffa69..e4df160e1 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -26,6 +26,46 @@ from allura.tests import TestController
from allura.tests.pytest_helpers import with_nose_compatibility
+class TestUserProfileSections(TestController):
+
+ def teardown_method(self, method):
+ super().teardown_method(method)
+ project = Project.query.get(shortname='u/test-user')
+ app = project.app_instance('profile')
+ if hasattr(type(app), '_sections'):
+ delattr(type(app), '_sections')
+
+ @td.with_user_project('test-user')
+ def test_profile_sections(self):
+ project = Project.query.get(shortname='u/test-user')
+ app = project.app_instance('profile')
+
+ def ep(n):
+ m = mock.Mock()
+ m.name = n
+ m.load()().display.return_value = 'Section %s' % n
+ return m
+ eps = list(map(ep, ['a', 'b', 'c', 'd']))
+ order = {'user_profile_sections.order': 'b, d,c , f '}
+ if hasattr(type(app), '_sections'):
+ delattr(type(app), '_sections')
+ with mock.patch('allura.lib.helpers.iter_entry_points') as iep:
+ with mock.patch.dict(tg.config, order):
+ iep.return_value = eps
+ sections = app.profile_sections
+ assert sections == [
+ eps[1].load(),
+ eps[3].load(),
+ eps[2].load(),
+ eps[0].load()]
+ r = self.app.get('/u/test-user/profile')
+ assert 'Section a' in r.text
+ assert 'Section b' in r.text
+ assert 'Section c' in r.text
+ assert 'Section d' in r.text
+ assert 'Section f' not in r.text
+
+
@with_nose_compatibility
class TestUserProfile(TestController):
@@ -230,36 +270,6 @@ class TestUserProfile(TestController):
r = self.app.get('/u/test-user/profile/send_message', status=200)
assert 'you currently have user messages disabled' in r
- @td.with_user_project('test-user')
- def test_profile_sections(self):
- project = Project.query.get(shortname='u/test-user')
- app = project.app_instance('profile')
-
- def ep(n):
- m = mock.Mock()
- m.name = n
- m.load()().display.return_value = 'Section %s' % n
- return m
- eps = list(map(ep, ['a', 'b', 'c', 'd']))
- order = {'user_profile_sections.order': 'b, d,c , f '}
- if hasattr(type(app), '_sections'):
- delattr(type(app), '_sections')
- with mock.patch('allura.lib.helpers.iter_entry_points') as iep:
- with mock.patch.dict(tg.config, order):
- iep.return_value = eps
- sections = app.profile_sections
- assert sections == [
- eps[1].load(),
- eps[3].load(),
- eps[2].load(),
- eps[0].load()]
- r = self.app.get('/u/test-user/profile')
- assert 'Section a' in r.text
- assert 'Section b' in r.text
- assert 'Section c' in r.text
- assert 'Section d' in r.text
- assert 'Section f' not in r.text
-
def test_no_index_tag_in_empty_profile(self):
r = self.app.get('/u/test-user/profile/')
assert 'content="noindex, follow"' in r.text
diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py
index 2d6aa75f7..7f48c49bc 100644
--- a/Allura/allura/tests/model/test_auth.py
+++ b/Allura/allura/tests/model/test_auth.py
@@ -352,8 +352,8 @@ def test_check_sent_user_message_times():
assert not user1.can_send_user_message()
-@td.with_user_project('test-admin')
@with_setup(setup_method)
+@td.with_user_project('test-admin')
def test_user_track_active():
# without this session flushing inside track_active raises Exception
setup_functional_test()
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 4d4b3b592..389c7a228 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -18,6 +18,7 @@
import re
import os
+from textwrap import dedent
import allura
import unittest
import hashlib
@@ -48,11 +49,6 @@ from forgewiki import model as WM
from forgeblog import model as BM
-def setup_module(module):
- setup_basic_test()
- setup_unit_test()
-
-
def squish_spaces(text):
# \s is whitespace
# \xa0 is in unicode form
@@ -84,8 +80,28 @@ def get_projects_property_in_the_same_order(names, prop):
@with_nose_compatibility
class Test():
+ @classmethod
+ def setup_class(cls):
+ setup_basic_test()
+ setup_global_objects()
+
def setup_method(self, method):
setup_global_objects()
+ p_nbhd = M.Neighborhood.query.get(name='Projects')
+ p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
+ self.acl_bak = p_test.acl.copy()
+
+ def teardown_method(self, method):
+ user = M.User.by_username('test-admin')
+ user.display_name = 'Test Admin'
+
+ p_nbhd = M.Neighborhood.query.get(name='Projects')
+ p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
+ p_test.remove_user(M.User.by_username('test-user'))
+ p_test.remove_user(M.User.by_username('test-user-0'))
+ p_test.acl = self.acl_bak
+
+ ThreadLocalORMSession.flush_all()
@td.with_wiki
def test_app_globals(self):
@@ -358,17 +374,19 @@ class Test():
def test_markdown_toc(self):
with h.push_context('test', neighborhood='Projects'):
- r = g.markdown_wiki.convert("""[TOC]
+ r = g.markdown_wiki.convert(dedent("""\
+ [TOC]
- # Header 1
+ # 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
+ ## Header 2"""))
+ assert dedent('''\
+ <ul>
+ <li><a href="#header-1">Header 1</a><ul>
+ <li><a href="#header-2">Header 2</a></li>
+ </ul>
+ </li>
+ </ul>''') in r
@td.with_wiki
def test_wiki_artifact_links(self):
@@ -442,38 +460,35 @@ class Test():
'<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.markdown.convert("<class 'foo'>") == \
+ '''<div class="markdown_content"><p><class 'foo'=""></class></p></div>'''
+
+ assert g.markdown.convert(dedent('''\
+ # Header
+
+ Some text in a regular paragraph
+
+ :::python
+ for i in range(10):
+ print i
+ ''')) == dedent('''\
+ <div class="markdown_content"><h1 id="header">Header</h1>
+ <p>Some text in a regular paragraph</p>
+ <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>
+ <span class="nb">print</span> <span class="n">i</span>
+ </code></pre></div>
+ </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>')
+ assert g.markdown.convert(dedent('''\
+ ~~~~
+ def foo(): pass
+ ~~~~''')) == dedent('''\
+ <div class="markdown_content"><div class="codehilite"><pre><span></span><code>def foo(): pass
+ </code></pre></div>
+ </div>''')
def test_markdown_list_without_break(self):
# this is not a valid way to make a list in original Markdown or python-markdown
@@ -482,37 +497,37 @@ class Test():
# TODO: try https://github.com/adamb70/mdx-breakless-lists
# or https://gitlab.com/ayblaq/prependnewline
assert (
- g.markdown.convert('''\
+ g.markdown.convert(dedent('''\
Regular text
* first item
- * second 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('''\
+ g.markdown.convert(dedent('''\
Regular text
- first item
- - second item''') ==
+ - second item''')) ==
'<div class="markdown_content"><p>Regular text<br/>\n'
'- first item<br/>\n'
'- second item</p></div>')
assert (
- g.markdown.convert('''\
+ g.markdown.convert(dedent('''\
Regular text
+ first item
- + second item''') ==
+ + second item''')) ==
'<div class="markdown_content"><p>Regular text<br/>\n'
'+ first item<br/>\n'
'+ second item</p></div>')
assert (
- g.markdown.convert('''\
+ g.markdown.convert(dedent('''\
Regular text
1. first item
- 2. second item''') ==
+ 2. second item''')) ==
'<div class="markdown_content"><p>Regular text<br/>\n'
'1. first item<br/>\n'
'2. second item</p></div>')
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index 22a7ed8bf..f11eae8d7 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -35,7 +35,6 @@ from alluratest.tools import (
from mock import Mock, MagicMock, patch
from allura import model as M
-from allura.app import Application
from allura.lib import plugin
from allura.lib import phone
from allura.lib import helpers as h
@@ -44,15 +43,19 @@ from allura.lib.plugin import ProjectRegistrationProvider
from allura.lib.plugin import ThemeProvider
from allura.lib.exceptions import ProjectConflict, ProjectShortnameInvalid
from allura.tests.decorators import audits
+from allura.tests.exclude_from_rewrite_hook import ThemeProviderTestApp
from alluratest.controller import setup_basic_test, setup_global_objects
from allura.tests.pytest_helpers import with_nose_compatibility
+def setup_module(module):
+ setup_basic_test()
+
+
@with_nose_compatibility
class TestProjectRegistrationProvider:
def setup_method(self, method):
- setup_basic_test()
self.provider = ProjectRegistrationProvider()
@patch('allura.lib.security.has_access')
@@ -170,7 +173,6 @@ class TestProjectRegistrationProviderPhoneVerification:
self.user = UserMock()
self.nbhd = MagicMock()
-
def test_phone_verified_disabled(self):
with h.push_config(tg.config, **{'project.verify_phone': 'false'}):
assert self.p.phone_verified(self.user, self.nbhd)
@@ -280,36 +282,30 @@ class TestProjectRegistrationProviderPhoneVerification:
assert result == g.phone_service.verify.return_value
assert 5 == g.phone_service.verify.call_count
+
@with_nose_compatibility
class TestThemeProvider:
@patch('allura.app.g')
@patch('allura.lib.plugin.g')
def test_app_icon_str(self, plugin_g, app_g):
- class TestApp(Application):
- icons = {
- 24: 'images/testapp_24.png',
- }
- plugin_g.entry_points = {'tool': {'testapp': TestApp}}
- assert (ThemeProvider().app_icon_url('testapp', 24) ==
- app_g.theme_href.return_value)
+ plugin_g.entry_points = {'tool': {'testapp': ThemeProviderTestApp}}
+ app_icon = ThemeProvider().app_icon_url('testapp', 24)
+ other = app_g.theme_href.return_value
+ assert app_icon == other
+
app_g.theme_href.assert_called_with('images/testapp_24.png')
@patch('allura.lib.plugin.g')
def test_app_icon_str_invalid(self, g):
g.entry_points = {'tool': {'testapp': Mock()}}
- assert (ThemeProvider().app_icon_url('invalid', 24) ==
- None)
+ assert ThemeProvider().app_icon_url('invalid', 24) == None
@patch('allura.app.g')
def test_app_icon_app(self, g):
- class TestApp(Application):
- icons = {
- 24: 'images/testapp_24.png',
- }
- app = TestApp(None, None)
- assert (ThemeProvider().app_icon_url(app, 24) ==
- g.theme_href.return_value)
+ app = ThemeProviderTestApp(None, None)
+ assert ThemeProvider().app_icon_url(app, 24) == \
+ g.theme_href.return_value
g.theme_href.assert_called_with('images/testapp_24.png')
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 735b3294b..429effd80 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -18,6 +18,7 @@
import operator
import shutil
import sys
+from textwrap import dedent
import unittest
import six
@@ -52,6 +53,7 @@ from allura.tasks import export_tasks
from allura.tasks import admin_tasks
from allura.tests import decorators as td
from allura.tests.pytest_helpers import with_nose_compatibility
+from allura.tests.exclude_from_rewrite_hook import raise_compound_exception
from allura.lib.decorators import event_handler, task
@@ -148,7 +150,7 @@ class TestEventTasks(unittest.TestCase):
assert M.MonQTask.query.get(task_name='allura.tasks.event_tasks.event', args=['my_event4'])
def test_compound_error(self):
- t = raise_exc.post()
+ t = raise_compound_exception.post()
with LogCapture(level=logging.ERROR) as l, \
mock.patch.dict(tg.config, {'monq.raise_errors': False}): # match normal non-test behavior
t()
@@ -158,7 +160,7 @@ class TestEventTasks(unittest.TestCase):
assert "AssertionError('assert 0'" in msg
assert "AssertionError('assert 5'" in msg
assert ' on job <MonQTask ' in msg
- assert ' (error) P:10 allura.tests.test_tasks.raise_exc ' in msg
+ assert ' (error) P:10 allura.tests.exclude_from_rewrite_hook.raise_compound_exception ' in msg
for x in range(10):
assert ('assert %d' % x) in t.result
@@ -510,16 +512,17 @@ class TestMailTasks(unittest.TestCase):
@td.with_tool('test', 'Tickets', 'bugs')
def test_receive_autoresponse(self):
- message = '''Date: Wed, 30 Oct 2013 01:38:40 -0700
-From: <te...@domain.net>
-To: <1...@bugs.test.p.in.localhost>
-Message-ID: <super-unique-id>
-Subject: Not here Re: Message notification
-Precedence: bulk
-X-Autoreply: yes
-Auto-Submitted: auto-replied
-
-I'm not here'''
+ message = dedent('''\
+ Date: Wed, 30 Oct 2013 01:38:40 -0700
+ From: <te...@domain.net>
+ To: <1...@bugs.test.p.in.localhost>
+ Message-ID: <super-unique-id>
+ Subject: Not here Re: Message notification
+ Precedence: bulk
+ X-Autoreply: yes
+ Auto-Submitted: auto-replied
+
+ I'm not here''')
import forgetracker
c.user = M.User.by_username('test-admin')
with mock.patch.object(forgetracker.tracker_main.ForgeTrackerApp, 'handle_message') as hm:
@@ -597,17 +600,6 @@ def _my_event(event_type, testcase, *args, **kwargs):
testcase.called_with.append((args, kwargs))
-@task
-def raise_exc():
- errs = []
- for x in range(10):
- try:
- assert False, 'assert %d' % x
- except Exception:
- errs.append(sys.exc_info())
- raise CompoundError(*errs)
-
-
class _TestArtifact(M.Artifact):
_shorthand_id = FieldProperty(str)
text = FieldProperty(str)
diff --git a/Allura/allura/tests/test_webhooks.py b/Allura/allura/tests/test_webhooks.py
index 5b9d5b1f2..8237847d6 100644
--- a/Allura/allura/tests/test_webhooks.py
+++ b/Allura/allura/tests/test_webhooks.py
@@ -132,6 +132,7 @@ class TestValidators(TestWebhookBase):
@with_nose_compatibility
class TestWebhookController(TestController):
+
def setup_method(self, method):
super().setup_method(method)
self.patches = self.monkey_patch()
@@ -182,6 +183,56 @@ class TestWebhookController(TestController):
else:
assert False, 'Validation error not found'
+ def test_AAAA_WORKAROUND__edit(self):
+ """
+ This must run first in this test class for unknown reasons ever since
+ https://github.com/TurboGears/tg2/commit/02fb49b14e70fdd8ac16973488fb3637e5e59114
+
+ If any test runs the self.app.post from create_webhook before this one, then this test will fail on:
+ with td.audits(msg):
+ r = form.submit()
+ because WebhookValidator's `value` will be "create" instead of an objectid str
+
+ Maybe something to do with WebhookControllerMeta setup of `validate` decorators?
+ """
+ data1 = {'url': 'http://httpbin.org/post',
+ 'secret': 'secret'}
+ data2 = {'url': 'http://example.com/hook',
+ 'secret': 'secret2'}
+ self.create_webhook(data1).follow()
+ self.create_webhook(data2).follow()
+ assert M.Webhook.query.find().count() == 2
+ wh1 = M.Webhook.query.get(hook_url=data1['url'])
+ r = self.app.get(self.url + '/repo-push/%s' % wh1._id)
+ form = r.forms[0]
+ assert form['url'].value == data1['url']
+ assert form['secret'].value == data1['secret']
+ assert form['webhook'].value == str(wh1._id)
+ form['url'] = 'http://host.org/hook'
+ form['secret'] = 'new secret'
+ msg = 'edit webhook repo-push\n{} => {}\n{}'.format(
+ data1['url'], form['url'].value, 'secret changed')
+ with td.audits(msg):
+ r = form.submit()
+ wf = json.loads(self.webflash(r))
+ assert wf['status'] == 'ok'
+ assert wf['message'] == 'Edited successfully'
+ assert M.Webhook.query.find().count() == 2
+ wh1 = M.Webhook.query.get(_id=wh1._id)
+ assert wh1.hook_url == 'http://host.org/hook'
+ assert wh1.app_config_id == self.git.config._id
+ assert wh1.secret == 'new secret'
+ assert wh1.type == 'repo-push'
+
+ # Duplicates
+ r = self.app.get(self.url + '/repo-push/%s' % wh1._id)
+ form = r.forms[0]
+ form['url'] = data2['url']
+ r = form.submit()
+ self.find_error(r, '_the_form',
+ '"repo-push" webhook already exists for Git http://example.com/hook',
+ form_type='edit')
+
def test_access(self):
self.app.get(self.url + '/repo-push/')
self.app.get(self.url + '/repo-push/',
@@ -256,56 +307,6 @@ class TestWebhookController(TestController):
self.find_error(r, 'url',
'You must provide a full domain name (like qwer.com)')
- def test_AAAA_WORKAROUND__edit(self):
- """
- This must run first in this test class for unknown reasons ever since
- https://github.com/TurboGears/tg2/commit/02fb49b14e70fdd8ac16973488fb3637e5e59114
-
- If any test runs the self.app.post from create_webhook before this one, then this test will fail on:
- with td.audits(msg):
- r = form.submit()
- because WebhookValidator's `value` will be "create" instead of an objectid str
-
- Maybe something to do with WebhookControllerMeta setup of `validate` decorators?
- """
- data1 = {'url': 'http://httpbin.org/post',
- 'secret': 'secret'}
- data2 = {'url': 'http://example.com/hook',
- 'secret': 'secret2'}
- self.create_webhook(data1).follow()
- self.create_webhook(data2).follow()
- assert M.Webhook.query.find().count() == 2
- wh1 = M.Webhook.query.get(hook_url=data1['url'])
- r = self.app.get(self.url + '/repo-push/%s' % wh1._id)
- form = r.forms[0]
- assert form['url'].value == data1['url']
- assert form['secret'].value == data1['secret']
- assert form['webhook'].value == str(wh1._id)
- form['url'] = 'http://host.org/hook'
- form['secret'] = 'new secret'
- msg = 'edit webhook repo-push\n{} => {}\n{}'.format(
- data1['url'], form['url'].value, 'secret changed')
- with td.audits(msg):
- r = form.submit()
- wf = json.loads(self.webflash(r))
- assert wf['status'] == 'ok'
- assert wf['message'] == 'Edited successfully'
- assert M.Webhook.query.find().count() == 2
- wh1 = M.Webhook.query.get(_id=wh1._id)
- assert wh1.hook_url == 'http://host.org/hook'
- assert wh1.app_config_id == self.git.config._id
- assert wh1.secret == 'new secret'
- assert wh1.type == 'repo-push'
-
- # Duplicates
- r = self.app.get(self.url + '/repo-push/%s' % wh1._id)
- form = r.forms[0]
- form['url'] = data2['url']
- r = form.submit()
- self.find_error(r, '_the_form',
- '"repo-push" webhook already exists for Git http://example.com/hook',
- form_type='edit')
-
def test_edit_validation(self):
invalid = M.Webhook(
type='invalid type',