Merge lp:~wgrant/launchpad/dupe-privacy into lp:launchpad

Proposed by William Grant
Status: Merged
Merged at revision: 17728
Proposed branch: lp:~wgrant/launchpad/dupe-privacy
Merge into: lp:launchpad
Diff against target: 140 lines (+62/-20)
3 files modified
lib/lp/bugs/browser/bug.py (+9/-6)
lib/lp/bugs/browser/tests/test_bug_views.py (+52/-13)
lib/lp/bugs/templates/bug-portlet-duplicates.pt (+1/-1)
To merge this branch: bzr merge lp:~wgrant/launchpad/dupe-privacy
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+270791@code.launchpad.net

Commit message

BugTask:+index's duplicates portlet will no longer link to invisible private bugs and now uses the correct sprite for each bug.

Description of the change

BugTask:+index's duplicates portlet will no longer link to invisible private bugs and now uses the correct sprite for each bug.

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
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/bug.py'
2--- lib/lp/bugs/browser/bug.py 2015-07-08 16:05:11 +0000
3+++ lib/lp/bugs/browser/bug.py 2015-09-11 10:09:11 +0000
4@@ -572,12 +572,15 @@
5 BugTaskSearchParams(self.user, bug=any(*duplicate_bugs))))
6 dupes = []
7 for bug in duplicate_bugs:
8- dupe = {}
9- try:
10- dupe['title'] = bug.title
11- except Unauthorized:
12- dupe['title'] = 'Private Bug'
13- dupe['id'] = bug.id
14+ # Don't disclose even the ID of a private bug. The link will
15+ # just 404.
16+ if not check_permission('launchpad.View', bug):
17+ continue
18+ dupe = {
19+ 'title': bug.title,
20+ 'id': bug.id,
21+ 'bug': bug,
22+ }
23 # If the dupe has the same context as the one we're in, link
24 # to that bug task directly.
25 if bug in dupes_in_current_context:
26
27=== modified file 'lib/lp/bugs/browser/tests/test_bug_views.py'
28--- lib/lp/bugs/browser/tests/test_bug_views.py 2014-04-29 00:44:32 +0000
29+++ lib/lp/bugs/browser/tests/test_bug_views.py 2015-09-11 10:09:11 +0000
30@@ -9,6 +9,7 @@
31 datetime,
32 timedelta,
33 )
34+import re
35
36 from BeautifulSoup import BeautifulSoup
37 import pytz
38@@ -16,6 +17,7 @@
39 from soupmatchers import (
40 HTMLContains,
41 Tag,
42+ Within,
43 )
44 from storm.store import Store
45 from testtools.matchers import (
46@@ -40,6 +42,7 @@
47 from lp.services.webapp.publisher import canonical_url
48 from lp.services.webapp.servers import LaunchpadTestRequest
49 from lp.testing import (
50+ admin_logged_in,
51 BrowserTestCase,
52 login_person,
53 person_logged_in,
54@@ -62,24 +65,60 @@
55
56 layer = DatabaseFunctionalLayer
57
58- def makeDupeOfPrivateBug(self):
59- bug = self.factory.makeBug()
60+ def test_private_master_not_linked_without_permission(self):
61+ bug = self.factory.makeBug(
62+ information_type=InformationType.PRIVATESECURITY)
63 dupe = self.factory.makeBug()
64- with person_logged_in(bug.owner):
65- bug.setPrivate(private=True, who=bug.owner)
66+ with admin_logged_in():
67 dupe.markAsDuplicate(bug)
68- return dupe
69-
70- def test_private_bugs_are_not_linked_without_permission(self):
71- bug = self.makeDupeOfPrivateBug()
72- url = canonical_url(bug, rootsite="bugs")
73- browser = self.getUserBrowser(url)
74- dupe_warning = find_tag_by_id(
75- browser.contents,
76- 'warning-comment-on-duplicate')
77+ with person_logged_in(dupe.owner):
78+ getUtility(IOpenLaunchBag).add(dupe.default_bugtask)
79+ html = create_initialized_view(
80+ dupe.default_bugtask, "+index", principal=dupe.owner)()
81+ dupe_warning = find_tag_by_id(html, 'warning-comment-on-duplicate')
82 # There is no link in the dupe_warning.
83 self.assertTrue('href' not in dupe_warning)
84
85+ def test_private_dupes_not_linked_without_permission(self):
86+ bug = self.factory.makeBug()
87+ publidupe = self.factory.makeBug()
88+ visidupe = self.factory.makeBug(
89+ information_type=InformationType.PRIVATESECURITY)
90+ invisidupe = self.factory.makeBug(
91+ information_type=InformationType.PRIVATESECURITY)
92+ with admin_logged_in():
93+ publidupe.markAsDuplicate(bug)
94+ visidupe.markAsDuplicate(bug)
95+ invisidupe.markAsDuplicate(bug)
96+ visidupe.subscribe(bug.owner, visidupe.owner)
97+ with person_logged_in(bug.owner):
98+ getUtility(IOpenLaunchBag).add(bug.default_bugtask)
99+ html = create_initialized_view(
100+ bug.default_bugtask, "+index", principal=bug.owner)()
101+ # The public dupe and subscribed private dupe are listed, but
102+ # the unsubscribed one is not.
103+ dupes_portlet = Tag(
104+ "dupes portlet", "div", attrs={"id": "portlet-duplicates"})
105+ self.assertThat(
106+ html,
107+ MatchesAll(
108+ HTMLContains(
109+ Within(
110+ dupes_portlet,
111+ Tag(
112+ "public dupe", "a",
113+ text=re.compile("Bug #%d" % publidupe.id),
114+ attrs={"class": "sprite bug"})),
115+ Within(
116+ dupes_portlet,
117+ Tag(
118+ "private dupe", "a",
119+ text=re.compile("Bug #%d" % visidupe.id),
120+ attrs={"class": "sprite bug private"}))),
121+ Not(HTMLContains(Tag(
122+ "invisible dupe", "a",
123+ text=re.compile("Bug #%d" % invisidupe.id))))))
124+
125
126 class TestAlsoAffectsLinks(BrowserTestCase):
127 """ Tests the rendering of the Also Affects links on the bug index view.
128
129=== modified file 'lib/lp/bugs/templates/bug-portlet-duplicates.pt'
130--- lib/lp/bugs/templates/bug-portlet-duplicates.pt 2009-09-10 16:13:39 +0000
131+++ lib/lp/bugs/templates/bug-portlet-duplicates.pt 2015-09-11 10:09:11 +0000
132@@ -9,7 +9,7 @@
133 <li tal:repeat="dupe view/duplicates">
134 <a tal:content="string: Bug #${dupe/id}"
135 tal:attributes="href dupe/url; title dupe/title;
136- class context/image:sprite_css" />
137+ class dupe/bug/image:sprite_css" />
138 </li>
139 </ul>
140 </div>