You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2020/08/27 20:35:40 UTC
[allura] 15/16: [#8375] tracker fixes
This is an automated email from the ASF dual-hosted git repository.
brondsem pushed a commit to branch db/8375
in repository https://gitbox.apache.org/repos/asf/allura.git
commit 727d750b938bcffd63d8a677a4325673af9d17a9
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Wed Aug 26 16:48:56 2020 -0400
[#8375] tracker fixes
---
Allura/allura/tests/decorators.py | 11 +++++++++++
ForgeTracker/forgetracker/import_support.py | 4 ++--
ForgeTracker/forgetracker/model/ticket.py | 15 +++++++++------
ForgeTracker/forgetracker/tests/functional/test_root.py | 16 +++++++++-------
.../forgetracker/tests/unit/test_ticket_model.py | 16 ++++++++--------
ForgeTracker/forgetracker/tracker_main.py | 4 ++--
6 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/Allura/allura/tests/decorators.py b/Allura/allura/tests/decorators.py
index 6a72710..28f6bb6 100644
--- a/Allura/allura/tests/decorators.py
+++ b/Allura/allura/tests/decorators.py
@@ -21,7 +21,9 @@ import sys
import re
from functools import wraps
import contextlib
+from six.moves.urllib.parse import parse_qs
+from nose.tools import assert_equal
from ming.orm.ormsession import ThreadLocalORMSession
from tg import tmpl_context as c
from mock import patch
@@ -220,3 +222,12 @@ def assert_logmsg_and_no_warnings_or_errors(logs, msg):
if r.levelno > logging.INFO:
raise AssertionError('unexpected log {} {}'.format(r.levelname, r.getMessage()))
assert found_msg, 'Did not find {} in logs: {}'.format(msg, '\n'.join([r.getMessage() for r in logs.records]))
+
+
+def assert_equivalent_urls(url1, url2):
+ base1, _, qs1 = url1.partition('?')
+ base2, _, qs2 = url2.partition('?')
+ assert_equal(
+ (base1, parse_qs(qs1)),
+ (base2, parse_qs(qs2)),
+ )
diff --git a/ForgeTracker/forgetracker/import_support.py b/ForgeTracker/forgetracker/import_support.py
index 3a482c6..d643134 100644
--- a/ForgeTracker/forgetracker/import_support.py
+++ b/ForgeTracker/forgetracker/import_support.py
@@ -73,11 +73,11 @@ class ResettableStream(object):
def read(self, size=-1):
self._read_header()
- data = ''
+ data = b''
if self.buf_pos < self.stream_pos:
data = self.buf.read(size)
self.buf_pos += len(data)
- if len(data) == size:
+ if len(data) == size or size == -1:
return data
size -= len(data)
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 36b252f..0efbdca 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -390,8 +390,7 @@ class Globals(MappedClass):
for ticket in tickets:
message = ''
if labels:
- values['labels'] = self.append_new_labels(
- ticket.labels, labels.split(','))
+ values['labels'] = self.append_new_labels(ticket.labels, labels.split(','))
for k, v in sorted(six.iteritems(values)):
if k == 'deleted':
if v:
@@ -533,9 +532,13 @@ class Globals(MappedClass):
return filtered
def append_new_labels(self, old_labels, new_labels):
- old_labels = set(old_labels)
- new_labels = set(l.strip() for l in new_labels)
- return list(old_labels | new_labels)
+ # append without duplicating any. preserve order
+ labels = old_labels[:] # make copy to ensure no edits to possible underlying model field
+ for l in new_labels:
+ l = l.strip()
+ if l not in old_labels:
+ labels.append(l)
+ return labels
class TicketHistory(Snapshot):
@@ -850,7 +853,7 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
role_developer = ProjectRole.by_name('Developer')
role_creator = ProjectRole.by_user(self.reported_by, upsert=True) if self.reported_by else None
def _allow_all(role, perms):
- return [ACE.allow(role._id, perm) for perm in perms]
+ return [ACE.allow(role._id, perm) for perm in sorted(perms)] # sorted just for consistency (for tests)
# maintain existing access for developers and the ticket creator,
# but revoke all access for everyone else
acl = _allow_all(role_developer, security.all_allowed(self, role_developer))
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index eb341cc..bb6ff6f 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -45,6 +45,7 @@ from tg import tmpl_context as c
from tg import app_globals as g
from tg import config
+from allura.tests.decorators import assert_equivalent_urls
from allura.tests.test_globals import squish_spaces
from alluratest.controller import TestController, setup_basic_test
from allura import model as M
@@ -1623,7 +1624,7 @@ class TestFunctionalController(TrackerTestController):
edit_link = response.html.find('a', {'title': 'Bulk Edit'})
expected_link = "/p/test/bugs/edit/?q=%21status%3Awont-fix+%26%26+%21status%3Aclosed"\
"&sort=snippet_s+asc&limit=25&filter=&page=0"
- assert_equal(expected_link, edit_link['href'])
+ assert_equivalent_urls(expected_link, edit_link['href'])
response = self.app.get(edit_link['href'])
ticket_rows = response.html.find('tbody', {'class': 'ticket-list'})
assert_in('test first ticket', ticket_rows.text)
@@ -1646,7 +1647,7 @@ class TestFunctionalController(TrackerTestController):
assert_in('test third ticket', ticket_rows.text)
edit_link = response.html.find('a', {'title': 'Bulk Edit'})
expected_link = "/p/test/bugs/edit/?q=_milestone%3A1.0&sort=ticket_num_i+asc&limit=25&filter=&page=0"
- assert_equal(expected_link, edit_link['href'])
+ assert_equivalent_urls(expected_link, edit_link['href'])
response = self.app.get(edit_link['href'])
ticket_rows = response.html.find('tbody', {'class': 'ticket-list'})
assert_in('test first ticket', ticket_rows.text)
@@ -1667,7 +1668,7 @@ class TestFunctionalController(TrackerTestController):
assert_false('test third ticket' in ticket_rows.text)
edit_link = response.html.find('a', {'title': 'Bulk Edit'})
expected_link = "/p/test/bugs/edit/?q=status%3Aopen&limit=25&filter=%7B%7D&page=0"
- assert_equal(expected_link, edit_link['href'])
+ assert_equivalent_urls(expected_link, edit_link['href'])
response = self.app.get(edit_link['href'])
ticket_rows = response.html.find('tbody', {'class': 'ticket-list'})
assert_in('test first ticket', ticket_rows.text)
@@ -1983,19 +1984,19 @@ class TestFunctionalController(TrackerTestController):
# invalid vote
r = self.app.post('/bugs/1/vote', dict(vote='invalid'))
expected_resp = json.dumps(dict(status='error', votes_up=0, votes_down=0, votes_percent=0))
- assert r.response.content == expected_resp
+ assert_equal(r.response.text, expected_resp)
# vote up
r = self.app.post('/bugs/1/vote', dict(vote='u'))
expected_resp = json.dumps(dict(status='ok', votes_up=1, votes_down=0, votes_percent=100))
- assert r.response.content == expected_resp
+ assert_equal(r.response.text, expected_resp)
# vote down by another user
r = self.app.post('/bugs/1/vote', dict(vote='d'),
extra_environ=dict(username=str('test-user-0')))
expected_resp = json.dumps(dict(status='ok', votes_up=1, votes_down=1, votes_percent=50))
- assert r.response.content == expected_resp
+ assert_equal(r.response.text, expected_resp)
# make sure that on the page we see the same result
r = self.app.get('/bugs/1/')
@@ -2949,7 +2950,8 @@ class TestHelpTextOptions(TrackerTestController):
assert len(r.html.findAll(attrs=dict(id='new-ticket-help-msg'))) == 0
-class test_show_default_fields(TrackerTestController):
+class TestShowDefaultFields(TrackerTestController):
+
def test_show_default_fields(self):
r = self.app.get('/admin/bugs/fields')
assert '<td>Ticket Number</td> <td><input type="checkbox" name="ticket_num" checked ></td>' in r
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
index 149cc8a..f1ca974 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
@@ -139,17 +139,17 @@ class TestTicketModel(TrackerTestWithModel):
t.private = True
assert_equal(t.acl, [
- ACE.allow(role_developer, 'save_searches'),
- ACE.allow(role_developer, 'read'),
ACE.allow(role_developer, 'create'),
- ACE.allow(role_developer, 'update'),
- ACE.allow(role_developer, 'unmoderated_post'),
- ACE.allow(role_developer, 'post'),
- ACE.allow(role_developer, 'moderate'),
ACE.allow(role_developer, 'delete'),
- ACE.allow(role_creator, 'read'),
- ACE.allow(role_creator, 'post'),
+ ACE.allow(role_developer, 'moderate'),
+ ACE.allow(role_developer, 'post'),
+ ACE.allow(role_developer, 'read'),
+ ACE.allow(role_developer, 'save_searches'),
+ ACE.allow(role_developer, 'unmoderated_post'),
+ ACE.allow(role_developer, 'update'),
ACE.allow(role_creator, 'create'),
+ ACE.allow(role_creator, 'post'),
+ ACE.allow(role_creator, 'read'),
ACE.allow(role_creator, 'unmoderated_post'),
DENY_ALL])
assert has_access(t, 'read', user=admin)()
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 7588ecc..d3228e6 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -864,7 +864,7 @@ class RootController(BaseController, FeedController):
else:
feed = FG.Rss201rev2Feed(**d)
for t in result['tickets']:
- url = h.absurl(t.url().encode('utf-8'))
+ url = h.absurl(t.url())
feed_kwargs = dict(title=t.summary,
link=url,
pubdate=t.mod_date,
@@ -1920,7 +1920,7 @@ class MilestoneController(BaseController):
else:
raise exc.HTTPNotFound()
for m in fld.milestones:
- if m.name == unquote(milestone).decode('utf-8'):
+ if m.name == six.ensure_text(unquote(milestone)):
break
else:
raise exc.HTTPNotFound()