Merge lp:~bac/launchpad/bug-674897 into lp:launchpad

Proposed by Brad Crittenden
Status: Merged
Approved by: Graham Binns
Approved revision: no longer in the source branch.
Merged at revision: 12003
Proposed branch: lp:~bac/launchpad/bug-674897
Merge into: lp:launchpad
Diff against target: 199 lines (+59/-42)
4 files modified
lib/canonical/launchpad/pagetests/REFERENCE.txt (+33/-27)
lib/lp/registry/browser/configure.zcml (+0/-4)
lib/lp/registry/browser/nameblacklist.py (+0/-11)
lib/lp/registry/browser/tests/test_breadcrumbs.py (+26/-0)
To merge this branch: bzr merge lp:~bac/launchpad/bug-674897
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+42238@code.launchpad.net

Commit message

[r=gmb][ui=none][bug=674897] Remove intermediate breadcrumb from name blacklist edit page as it is not traversable.

Description of the change

= Summary =

The breadcrumbs for editing a NameBlackList regex have a link to a
non-traversable element.

== Proposed fix ==

Remove that part of the breadcrumb chain.

== Pre-implementation notes ==

Chat with Curtis.

== Implementation details ==

Easy fix; remove the adapter and the breadcrumb isn't created for that
portion of the traversal.

== Tests ==

bin/test -vvm lp.registry -t test_breadcrumbs

== Demo and Q/A ==

Go to https://launchpad.dev/+nameblacklist, edit an existing one and
verify the breadcrumb does not include the regex.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/browser/configure.zcml
  lib/canonical/launchpad/pagetests/REFERENCE.txt
  lib/lp/registry/browser/tests/test_breadcrumbs.py
  lib/lp/registry/browser/nameblacklist.py

To post a comment you must log in.
Revision history for this message
Graham Binns (gmb) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/pagetests/REFERENCE.txt'
2--- lib/canonical/launchpad/pagetests/REFERENCE.txt 2008-09-23 13:02:41 +0000
3+++ lib/canonical/launchpad/pagetests/REFERENCE.txt 2010-11-30 15:31:40 +0000
4@@ -1,4 +1,5 @@
5-= Kiko's wonderfully incomplete testbrowser reference manual for dummies =
6+Kiko's wonderfully incomplete testbrowser reference manual for dummies
7+======================================================================
8
9 Opening pages:
10
11@@ -31,7 +32,8 @@
12 True
13
14
15-== Debugging ==
16+Debugging
17+---------
18
19 If you need to debug a pagetest, you can use the convenient 'stop()' method
20 exported into pagetest globals. This is essentially the same as importing pdb
21@@ -49,7 +51,8 @@
22 appserver will be unhappy.
23
24
25-== Parsing content ==
26+Parsing content
27+---------------
28
29 Parsing specific sections of pages:
30
31@@ -73,7 +76,7 @@
32 >>> print extract_text(html_string, extract_image_text=True)
33 Here's some text with an image.
34
35- >>> html_string = "<img src="/@@/bar" alt="Alt text works too." />"
36+ >>> html_string = """<img src="/@@/bar" alt="Alt text works too." />"""
37 >>> print extract_text(html_string, extract_image_text=True)
38 Alt text works too.
39
40@@ -110,21 +113,22 @@
41
42 Using BeautifulSoup in all its glory:
43
44- >>> from BeautifulSoup import BeautifulSoup, SoupStrainer
45- >>> anon_browser.open("http://launchpad.dev/~name16")
46- >>> strainer = SoupStrainer(['link'], {'type': ['application/rdf+xml']})
47- >>> soup = BeautifulSoup(anon_browser.contents, parseOnlyThese=strainer)
48- >>> print soup.renderContents()
49- <link rel="meta" type="application/rdf+xml" title="FOAF" href="+rdf" />
50-
51- >>> strainer = SoupStrainer({'class': ['error']})
52- >>> soup = BeautifulSoup(anon_browser.contents, parseOnlyThese=strainer)
53- >>> for tag in soup:
54- ... print extract_text(tag)
55- Quantities must be greater than or equal 0.
56-
57-
58-== Links ==
59+ >>> from BeautifulSoup import BeautifulSoup, SoupStrainer
60+ >>> anon_browser.open("http://launchpad.dev/~name16")
61+ >>> strainer = SoupStrainer(['link'], {'type': ['application/rdf+xml']})
62+ >>> soup = BeautifulSoup(anon_browser.contents, parseOnlyThese=strainer)
63+ >>> print soup.renderContents()
64+ <link rel="meta" type="application/rdf+xml" title="FOAF" href="+rdf" />
65+
66+ >>> strainer = SoupStrainer({'class': ['error']})
67+ >>> soup = BeautifulSoup(anon_browser.contents, parseOnlyThese=strainer)
68+ >>> for tag in soup:
69+ ... print extract_text(tag)
70+ Quantities must be greater than or equal 0.
71+
72+
73+Links
74+-----
75
76 Manipulating links:
77
78@@ -163,7 +167,8 @@
79 u'http://launchpad.dev/foo'
80
81
82-== Form Controls ==
83+Form Controls
84+-------------
85
86 Basics:
87
88@@ -202,7 +207,8 @@
89 'http://where-you-went-after-posting/'
90
91
92-== Committing transactions ==
93+Committing transactions
94+-----------------------
95
96 The transaction module is already imported into your pagetest's globals, so
97 just do:
98@@ -213,24 +219,24 @@
99 You do not need to be logged in to do this.
100
101
102-== Gotchas ==
103+Gotchas
104+-------
105
106 If you get:
107
108- AttributeError: 'zope.thread.local' object has no attribute 'interaction'
109+ AttributeError: 'thread._local' object has no attribute 'interaction'
110
111 This means you are trying to getUtility() and aren't logged in.
112 Use something like this:
113
114-If you get:
115-
116 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
117 >>> login(ANONYMOUS)
118
119+If you get:
120+
121 AssertionError: newInteraction called while another interaction is
122 active.
123
124 This means you forgot to log out:
125
126- >>> logout()
127-
128+ >>> logout()
129
130=== modified file 'lib/lp/registry/browser/configure.zcml'
131--- lib/lp/registry/browser/configure.zcml 2010-11-22 23:08:45 +0000
132+++ lib/lp/registry/browser/configure.zcml 2010-11-30 15:31:40 +0000
133@@ -1607,10 +1607,6 @@
134 <adapter
135 factory="lp.registry.browser.nameblacklist.NameBlacklistSetBreadcrumb"
136 />
137- <adapter
138- factory="lp.registry.browser.nameblacklist.NameBlacklistBreadcrumb"
139- />
140-
141 <browser:page
142 name="+addseries"
143 for="lp.registry.interfaces.product.IProduct"
144
145=== modified file 'lib/lp/registry/browser/nameblacklist.py'
146--- lib/lp/registry/browser/nameblacklist.py 2010-11-23 23:22:27 +0000
147+++ lib/lp/registry/browser/nameblacklist.py 2010-11-30 15:31:40 +0000
148@@ -162,14 +162,3 @@
149 implements(IBreadcrumb)
150
151 text = "Name Blacklist"
152-
153-
154-@adapter(INameBlacklist)
155-class NameBlacklistBreadcrumb(Breadcrumb):
156- """Return a breadcrumb for an `INameBlackList`."""
157-
158- implements(IBreadcrumb)
159-
160- @property
161- def text(self):
162- return self.context.regexp
163
164=== modified file 'lib/lp/registry/browser/tests/test_breadcrumbs.py'
165--- lib/lp/registry/browser/tests/test_breadcrumbs.py 2010-08-20 20:31:18 +0000
166+++ lib/lp/registry/browser/tests/test_breadcrumbs.py 2010-11-30 15:31:40 +0000
167@@ -125,6 +125,32 @@
168 last_crumb = crumbs[-1]
169 self.assertEqual(self.poll.title, last_crumb.text)
170
171+from lp.registry.interfaces.nameblacklist import INameBlacklistSet
172+
173+
174+class TestNameblacklistBreadcrumb(BaseBreadcrumbTestCase):
175+ """Test breadcrumbs for +nameblacklist."""
176+
177+ def setUp(self):
178+ super(TestNameblacklistBreadcrumb, self).setUp()
179+ self.name_blacklist_set = getUtility(INameBlacklistSet)
180+ self.registry_expert = self.factory.makeRegistryExpert()
181+ login_person(self.registry_expert)
182+
183+ def test_nameblacklist(self):
184+ expected = [('Name Blacklist', 'http://launchpad.dev/+nameblacklist')]
185+ self.assertBreadcrumbs(expected, self.name_blacklist_set)
186+
187+ def test_nameblacklist_edit(self):
188+ blacklist = self.name_blacklist_set.getByRegExp(u'blacklist')
189+ expected = [
190+ ('Name Blacklist',
191+ 'http://launchpad.dev/+nameblacklist'),
192+ ('Edit a blacklist expression',
193+ 'http://launchpad.dev/+nameblacklist/1/+edit'),
194+ ]
195+ self.assertBreadcrumbs(expected, blacklist, view_name='+edit')
196+
197
198 def test_suite():
199 return unittest.TestLoader().loadTestsFromName(__name__)