Merge lp:~stevenk/launchpad/link-bug-tags-correctly into lp:launchpad

Proposed by Steve Kowalik on 2012-01-19
Status: Merged
Approved by: Ian Booth on 2012-01-19
Approved revision: no longer in the source branch.
Merged at revision: 14704
Proposed branch: lp:~stevenk/launchpad/link-bug-tags-correctly
Merge into: lp:launchpad
Diff against target: 113 lines (+36/-14)
3 files modified
lib/lp/bugs/browser/bugtask.py (+15/-5)
lib/lp/bugs/browser/tests/test_bugtask.py (+17/-5)
lib/lp/bugs/templates/bugtask-index.pt (+4/-4)
To merge this branch: bzr merge lp:~stevenk/launchpad/link-bug-tags-correctly
Reviewer Review Type Date Requested Status
Ian Booth (community) 2012-01-19 Approve on 2012-01-19
Review via email: mp+89187@code.launchpad.net

Commit Message

[r=wallyworld][bug=911189] Make certain bug tag links are properly encoded.

Description of the Change

Fiddle with BugTaskView.{,un}official_tags so they return a dict of tag: url, and then use the url in the TAL. Also add a test to make sure that unofficial_tags returns what we expect, and that the TAL is using the data in the right way.

Fixed up two imports which were in a very odd place.

To post a comment you must log in.
Ian Booth (wallyworld) wrote :

Looks good. I assume there are no other places where those view properties are used that need porting.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/browser/bugtask.py'
2--- lib/lp/bugs/browser/bugtask.py 2012-01-17 14:14:49 +0000
3+++ lib/lp/bugs/browser/bugtask.py 2012-01-20 00:17:28 +0000
4@@ -1,4 +1,4 @@
5-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
6+# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
7 # GNU Affero General Public License version 3 (see the file LICENSE).
8
9 """IBugTask-related browser views."""
10@@ -1038,15 +1038,25 @@
11 def official_tags(self):
12 """The list of official tags for this bug."""
13 target_official_tags = set(self.context.bug.official_tags)
14- return [tag for tag in self.context.bug.tags
15- if tag in target_official_tags]
16+ links = []
17+ for tag in self.context.bug.tags:
18+ if tag in target_official_tags:
19+ links.append((tag, '%s?field.tag=%s' % (
20+ canonical_url(self.context.target, view_name='+bugs',
21+ force_local_path=True), urllib.quote(tag))))
22+ return links
23
24 @property
25 def unofficial_tags(self):
26 """The list of unofficial tags for this bug."""
27 target_official_tags = set(self.context.bug.official_tags)
28- return [tag for tag in self.context.bug.tags
29- if tag not in target_official_tags]
30+ links = []
31+ for tag in self.context.bug.tags:
32+ if tag not in target_official_tags:
33+ links.append((tag, '%s?field.tag=%s' % (
34+ canonical_url(self.context.target, view_name='+bugs',
35+ force_local_path=True), urllib.quote(tag))))
36+ return links
37
38 @property
39 def available_official_tags_js(self):
40
41=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
42--- lib/lp/bugs/browser/tests/test_bugtask.py 2012-01-18 12:04:16 +0000
43+++ lib/lp/bugs/browser/tests/test_bugtask.py 2012-01-20 00:17:28 +0000
44@@ -1,9 +1,5 @@
45-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
46+# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
47 # GNU Affero General Public License version 3 (see the file LICENSE).
48-from BeautifulSoup import BeautifulSoup
49-
50-from lp.registry.interfaces.person import PersonVisibility
51-
52
53 __metaclass__ = type
54
55@@ -16,6 +12,7 @@
56 import simplejson
57 import urllib
58
59+from BeautifulSoup import BeautifulSoup
60 from lazr.lifecycle.event import ObjectModifiedEvent
61 from lazr.restful.interfaces import IJSONRequestCache
62 from lazr.lifecycle.snapshot import Snapshot
63@@ -35,6 +32,7 @@
64 from zope.interface import providedBy
65 from zope.security.proxy import removeSecurityProxy
66
67+from lp.registry.interfaces.person import PersonVisibility
68 from lp.services.config import config
69 from lp.services.database.constants import UTC_NOW
70 from lp.testing import (
71@@ -254,6 +252,20 @@
72 self.assertEqual(1, len(view.errors))
73 self.assertEqual(product, bug.default_bugtask.target)
74
75+ def test_bugtag_urls_are_encoded(self):
76+ # The link to bug tags are encoded to protect against special chars.
77+ product = self.factory.makeProduct(name='foobar')
78+ bug = self.factory.makeBug(product=product, tags=['depends-on+987'])
79+ getUtility(ILaunchBag).add(bug.default_bugtask)
80+ view = create_initialized_view(bug.default_bugtask, name=u'+index')
81+ expected = [(u'depends-on+987',
82+ u'/foobar/+bugs?field.tag=depends-on%2B987')]
83+ self.assertEqual(expected, view.unofficial_tags)
84+ browser = self.getUserBrowser(canonical_url(bug), bug.owner)
85+ self.assertIn(
86+ 'href="/foobar/+bugs?field.tag=depends-on%2B987"',
87+ browser.contents)
88+
89
90 class TestBugTasksAndNominationsView(TestCaseWithFactory):
91
92
93=== modified file 'lib/lp/bugs/templates/bugtask-index.pt'
94--- lib/lp/bugs/templates/bugtask-index.pt 2011-12-08 20:31:53 +0000
95+++ lib/lp/bugs/templates/bugtask-index.pt 2012-01-20 00:17:28 +0000
96@@ -146,13 +146,13 @@
97 Tags:
98 <span id="tag-list">
99 <a tal:repeat="tag view/official_tags"
100- tal:content="tag"
101+ tal:content="python: tag[0]"
102 class="official-tag"
103- tal:attributes="href string:${context/target/fmt:url}/+bugs?field.tag=${tag}">tag</a>
104+ tal:attributes="href python: tag[1]">tag</a>
105 <a tal:repeat="tag view/unofficial_tags"
106- tal:content="tag"
107+ tal:content="python: tag[0]"
108 class="unofficial-tag"
109- tal:attributes="href string:${context/target/fmt:url}/+bugs?field.tag=${tag}">tag</a>
110+ tal:attributes="href python: tag[1]">tag</a>
111 </span>
112 <form id="tags-form" style="display: inline">
113 <input type="text" id="tag-input" class="hidden" style="width: 35em;" />