Merge lp:~danilo/launchpad/blueprint-templates into lp:launchpad

Proposed by Данило Шеган
Status: Merged
Merged at revision: not available
Proposed branch: lp:~danilo/launchpad/blueprint-templates
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~danilo/launchpad/blueprint-templates
Reviewer Review Type Date Requested Status
Gavin Panella (community) code Approve
Review via email: mp+11840@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Данило Шеган (danilo) wrote :

= Blueprints generic-edit conversion =

Convert 12 blueprints LaunchpadForm templates to use generic-edit.pt
instead. A bunch of cancel_urls are introduced as well.

Also introduces ISpecification breadcrumb.

= Demo & QA =

specification-linksprint.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+linksprint

specification-addsubscriber.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+addsubscriber

specification-superseding.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+supersede

specificationsubscription-edit.pt
(subscribe as "name16" [<email address hidden>], then
https://blueprints.launchpad.dev/firefox/+spec/canvas/+subscription/name16)

specification-linkbranch.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+linkbranch

specification-removedep.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+removedependency

specification-dependency.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+linkdependency

specification-retargeting.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+retarget

specification-productseries.pt
https://blueprints.launchpad.dev/firefox/+spec/canvas/+setproductseries

specification-distroseries.pt
https://blueprints.launchpad.dev/ubuntu/+spec/media-integrity-check/+setdistroseries

specification-new.pt
https://blueprints.launchpad.dev/firefox/+addspec

sprint-edit.pt
https://launchpad.dev/sprints/paris/+edit

= Tests =

bin/test -vvt lp.blueprints

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/blueprints/configure.zcml
  lib/lp/blueprints/browser/configure.zcml
  lib/lp/blueprints/browser/specification.py
  lib/lp/blueprints/browser/specificationdependency.py
  lib/lp/blueprints/browser/specificationsubscription.py
  lib/lp/blueprints/browser/sprint.py
  lib/lp/blueprints/browser/tests/test_breadcrumbs.py
  lib/lp/blueprints/stories/blueprints/sprint-links.txt
  lib/lp/blueprints/stories/blueprints/xx-overview.txt

Revision history for this message
Gavin Panella (allenap) wrote :

Merging this branch into devel gives me a delta of 6174 lines, and 2393 lines into db-devel. Can you let me know what your base branch is pls? :)

review: Needs Information
Revision history for this message
Gavin Panella (allenap) wrote :

> Merging this branch into devel gives me a delta of 6174 lines...

Doh, I thought I had pulled devel very recently, but it was on a different machine. Sorry! It's all okay now.

Revision history for this message
Gavin Panella (allenap) wrote :
Download full text (27.7 KiB)

Hi Danilo,

This is really nice :)

My only comment really is that you probably ought to document the new
cancel links you've added.

Thanks, Gavin.

> === modified file 'lib/lp/blueprints/browser/configure.zcml'
> --- lib/lp/blueprints/browser/configure.zcml 2009-09-08 15:03:11 +0000
> +++ lib/lp/blueprints/browser/configure.zcml 2009-09-16 12:38:58 +0000
> @@ -68,7 +68,7 @@
> class="lp.blueprints.browser.sprint.SprintEditView"
> permission="launchpad.Edit"
> facet="overview"
> - template="../templates/sprint-edit.pt"/>
> + template="../../app/templates/generic-edit.pt"/>
> <browser:page
> name="+branding"
> for="lp.blueprints.interfaces.sprint.ISprint"
> @@ -203,7 +203,7 @@
> class="lp.blueprints.browser.specificationsubscription.SpecificationSubscriptionEditView"
> facet="specifications"
> permission="launchpad.Edit"
> - template="../templates/specificationsubscription-edit.pt"/>
> + template="../../app/templates/generic-edit.pt"/>
> <browser:defaultView
> for="lp.blueprints.interfaces.sprintattendance.ISprintAttendance"
> name="+edit"/>
> @@ -306,19 +306,19 @@
> for="lp.blueprints.interfaces.specification.ISpecification"
> class="lp.blueprints.browser.specificationsubscription.SpecificationSubscriptionAddView"
> permission="launchpad.AnyPerson"
> - template="../templates/specification-addsubscriber.pt"/>
> + template="../../app/templates/generic-edit.pt"/>
> <browser:page
> name="+retarget"
> for="lp.blueprints.interfaces.specification.ISpecification"
> class="lp.blueprints.browser.specification.SpecificationRetargetingView"
> permission="launchpad.Edit"
> - template="../templates/specification-retargeting.pt"/>
> + template="../../app/templates/generic-edit.pt"/>
> <browser:page
> name="+supersede"
> for="lp.blueprints.interfaces.specification.ISpecification"
> class="lp.blueprints.browser.specification.SpecificationSupersedingView"
> permission="launchpad.Edit"
> - template="../templates/specification-superseding.pt"/>
> + template="../../app/templates/generic-edit.pt"/>
> <browser:page
> name="+edit"
> for="lp.blueprints.interfaces.specification.ISpecification"
> @@ -342,14 +342,14 @@
> for="lp.blueprints.interfaces.specification.ISpecification"
> class="lp.blueprints.browser.specification.SpecificationGoalProposeView"
> permission="launchpad.Edit"
> - template="../templates/specification-distroseries.pt">
> + template="../../app/templates/generic-edit.pt">
> </browser:page>
> <browser:page
> name="+setproductseries"
> for="lp.blueprints.interfaces.specification.ISpecification"
> class="lp.blueprints.browser.specification.SpecificationProductSeriesGoalProposeView"
> permission="launchpad.Edit"
> - template="../te...

review: Approve (code)
Revision history for this message
Данило Шеган (danilo) wrote :

Hi Gavin,

Thanks for the review.

У сре, 16. 09 2009. у 12:58 +0000, Gavin Panella пише:
> This is really nice :)

I play dirty: choose the easiest possible conversions in blueprints and
do a big number of them. Nobody can say I didn't help out later :)

> My only comment really is that you probably ought to document the new
> cancel links you've added.

Yeah, I ought to. I'll do that later and then land this.

Cheers,
Danilo

Revision history for this message
Данило Шеган (danilo) wrote :

У сре, 16. 09 2009. у 13:33 +0000, Данило Шеган пише:

> > My only comment really is that you probably ought to document the new
> > cancel links you've added.
>
> Yeah, I ought to. I'll do that later and then land this.

Here it is. Off to pqm now.

1=== modified file 'lib/lp/blueprints/stories/blueprints/01-creation.txt'
2--- lib/lp/blueprints/stories/blueprints/01-creation.txt 2009-09-09 23:16:08 +0000
3+++ lib/lp/blueprints/stories/blueprints/01-creation.txt 2009-09-16 17:32:16 +0000
4@@ -195,6 +195,11 @@
5
6 >>> user_browser.open('http://blueprints.launchpad.dev/specs/+new')
7
8+Canceling creation, brings one back to the blueprints home page.
9+
10+ >>> user_browser.getLink('Cancel').url
11+ 'http://blueprints.launchpad.dev/'
12+
13 When a blueprint is registered from the Blueprints home page, Launchpad
14 requires the user to specify a target for the new blueprint. This target
15 must be an existing distribution or product in Launchpad.
16@@ -278,6 +283,11 @@
17 >>> control('URL').value = 'http://wiki.ubuntu.com/NetworkMagic2'
18 >>> control('Summary').value = summary
19
20+Canceling creation, brings one back to the blueprints Hoary home.
21+
22+ >>> user_browser.getLink('Cancel').url
23+ 'http://blueprints.launchpad.dev/ubuntu/hoary'
24+
25 By default, blueprints are not proposed as series goals:
26
27 >>> control('series goal').control.value
28@@ -357,6 +367,11 @@
29 >>> control('URL').value = 'http://wiki.firefox.com/SvgSupport1'
30 >>> control('Summary').value = summary
31
32+Canceling creation, brings one back to the blueprints Firefox home.
33+
34+ >>> user_browser.getLink('Cancel').url
35+ 'http://blueprints.launchpad.dev/firefox'
36+
37 Pressing the "Register Blueprint" button creates a blueprint targeted to the
38 Mozilla Firefox product, then redirects the user to the new blueprint's page:
39
40
41=== modified file 'lib/lp/blueprints/stories/blueprints/06-dependencies.txt'
42--- lib/lp/blueprints/stories/blueprints/06-dependencies.txt 2009-05-11 18:19:21 +0000
43+++ lib/lp/blueprints/stories/blueprints/06-dependencies.txt 2009-09-16 17:29:25 +0000
44@@ -28,6 +28,11 @@
45 >>> owner_browser.url
46 'http://blueprints.launchpad.dev/firefox/+spec/canvas/+linkdependency'
47
48+One can decide not to add a dependency after all.
49+
50+ >>> owner_browser.getLink('Cancel').url
51+ 'http://blueprints.launchpad.dev/firefox/+spec/canvas'
52+
53 This +linkdependency page and the link to it are only accessible by
54 users with launchpad.Edit permission for the blueprint.
55
56@@ -70,6 +75,11 @@
57 >>> owner_browser.url
58 'http://blueprints.launchpad.dev/firefox/+spec/canvas/+removedependency'
59
60+One can decide not to remove a dependency after all.
61+
62+ >>> owner_browser.getLink('Cancel').url
63+ 'http://blueprints.launchpad.dev/firefox/+spec/canvas'
64+
65 Now, we make sure we can load the page. It should show two potential
66 dependencies we could remove. The extension manager one, and "e4x".
67
68
69=== modified file 'lib/lp/blueprints/stories/blueprints/08-productseries.txt'
70--- lib/lp/blueprints/stories/blueprints/08-productseries.txt 2009-05-11 18:19:21 +0000
71+++ lib/lp/blueprints/stories/blueprints/08-productseries.txt 2009-09-16 17:27:07 +0000
72@@ -16,6 +16,8 @@
73 >>> back_link = browser.getLink('Support Native SVG Objects')
74 >>> back_link.url
75 'http://blueprints.launchpad.dev/firefox/+spec/svg-support'
76+ >>> browser.getLink('Cancel').url
77+ 'http://blueprints.launchpad.dev/firefox/+spec/svg-support'
78
79 We can see two potential series candidates, the "trunk" and the "1.0" series.
80
81
82=== modified file 'lib/lp/blueprints/stories/blueprints/10-distrorelease.txt'
83--- lib/lp/blueprints/stories/blueprints/10-distrorelease.txt 2009-05-11 18:19:21 +0000
84+++ lib/lp/blueprints/stories/blueprints/10-distrorelease.txt 2009-09-16 17:27:45 +0000
85@@ -45,7 +45,9 @@
86 >>> back_link = browser.getLink('Test Specification')
87 >>> back_link.url
88 'http://blueprints.launchpad.dev/ubuntu/+spec/testspec'
89-
90+ >>> browser.getLink('Cancel').url
91+ 'http://blueprints.launchpad.dev/ubuntu/+spec/testspec'
92+
93 We are able to target a specification to a distroseries. We expect to be
94 redirected back to the spec page when we are done.
95
96
97=== modified file 'lib/lp/blueprints/stories/blueprints/13-superseding.txt'
98--- lib/lp/blueprints/stories/blueprints/13-superseding.txt 2009-05-11 18:19:21 +0000
99+++ lib/lp/blueprints/stories/blueprints/13-superseding.txt 2009-09-16 17:28:04 +0000
100@@ -34,6 +34,8 @@
101 >>> back_link = browser.getLink('Extension Manager System Upgrades')
102 >>> back_link.url
103 'http://blueprints.launchpad.dev/firefox/+spec/extension-manager-upgrades'
104+ >>> browser.getLink('Cancel').url
105+ 'http://blueprints.launchpad.dev/firefox/+spec/extension-manager-upgrades'
106
107 Next, we will POST to that form, setting the spec which supersedes this one:
108
109
110=== modified file 'lib/lp/blueprints/stories/blueprints/xx-retargeting.txt'
111--- lib/lp/blueprints/stories/blueprints/xx-retargeting.txt 2009-05-11 18:19:21 +0000
112+++ lib/lp/blueprints/stories/blueprints/xx-retargeting.txt 2009-09-16 17:31:11 +0000
113@@ -17,6 +17,8 @@
114 >>> back_link = admin_browser.getLink('Support Native SVG Objects')
115 >>> back_link.url
116 'http://blueprints.launchpad.dev/firefox/+spec/svg-support'
117+ >>> admin_browser.getLink('Cancel').url
118+ 'http://blueprints.launchpad.dev/firefox/+spec/svg-support'
119
120 We can move the blueprint to Evolution.
121
122
123=== modified file 'lib/lp/blueprints/stories/sprints/10-sprint-editing.txt'
124--- lib/lp/blueprints/stories/sprints/10-sprint-editing.txt 2009-05-11 18:19:21 +0000
125+++ lib/lp/blueprints/stories/sprints/10-sprint-editing.txt 2009-09-16 17:31:53 +0000
126@@ -24,6 +24,8 @@
127 >>> browser.getLink('Change details').click()
128 >>> browser.url
129 'http://launchpad.dev/sprints/ubz/+edit'
130+ >>> browser.getLink('Cancel').url
131+ 'http://launchpad.dev/sprints/ubz'
132
133 The sprint start and end times are expressed to the nearest minute, and
134 not the second:

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/blueprints/browser/configure.zcml'
2--- lib/lp/blueprints/browser/configure.zcml 2009-09-08 15:03:11 +0000
3+++ lib/lp/blueprints/browser/configure.zcml 2009-09-16 03:37:47 +0000
4@@ -68,7 +68,7 @@
5 class="lp.blueprints.browser.sprint.SprintEditView"
6 permission="launchpad.Edit"
7 facet="overview"
8- template="../templates/sprint-edit.pt"/>
9+ template="../../app/templates/generic-edit.pt"/>
10 <browser:page
11 name="+branding"
12 for="lp.blueprints.interfaces.sprint.ISprint"
13@@ -203,7 +203,7 @@
14 class="lp.blueprints.browser.specificationsubscription.SpecificationSubscriptionEditView"
15 facet="specifications"
16 permission="launchpad.Edit"
17- template="../templates/specificationsubscription-edit.pt"/>
18+ template="../../app/templates/generic-edit.pt"/>
19 <browser:defaultView
20 for="lp.blueprints.interfaces.sprintattendance.ISprintAttendance"
21 name="+edit"/>
22@@ -306,19 +306,19 @@
23 for="lp.blueprints.interfaces.specification.ISpecification"
24 class="lp.blueprints.browser.specificationsubscription.SpecificationSubscriptionAddView"
25 permission="launchpad.AnyPerson"
26- template="../templates/specification-addsubscriber.pt"/>
27+ template="../../app/templates/generic-edit.pt"/>
28 <browser:page
29 name="+retarget"
30 for="lp.blueprints.interfaces.specification.ISpecification"
31 class="lp.blueprints.browser.specification.SpecificationRetargetingView"
32 permission="launchpad.Edit"
33- template="../templates/specification-retargeting.pt"/>
34+ template="../../app/templates/generic-edit.pt"/>
35 <browser:page
36 name="+supersede"
37 for="lp.blueprints.interfaces.specification.ISpecification"
38 class="lp.blueprints.browser.specification.SpecificationSupersedingView"
39 permission="launchpad.Edit"
40- template="../templates/specification-superseding.pt"/>
41+ template="../../app/templates/generic-edit.pt"/>
42 <browser:page
43 name="+edit"
44 for="lp.blueprints.interfaces.specification.ISpecification"
45@@ -342,14 +342,14 @@
46 for="lp.blueprints.interfaces.specification.ISpecification"
47 class="lp.blueprints.browser.specification.SpecificationGoalProposeView"
48 permission="launchpad.Edit"
49- template="../templates/specification-distroseries.pt">
50+ template="../../app/templates/generic-edit.pt">
51 </browser:page>
52 <browser:page
53 name="+setproductseries"
54 for="lp.blueprints.interfaces.specification.ISpecification"
55 class="lp.blueprints.browser.specification.SpecificationProductSeriesGoalProposeView"
56 permission="launchpad.Edit"
57- template="../templates/specification-productseries.pt">
58+ template="../../app/templates/generic-edit.pt">
59 </browser:page>
60 <browser:page
61 name="+decide"
62@@ -411,20 +411,20 @@
63 for="lp.blueprints.interfaces.specification.ISpecification"
64 class="lp.blueprints.browser.specificationdependency.SpecificationDependencyAddView"
65 permission="launchpad.Edit"
66- template="../templates/specification-dependency.pt"/>
67+ template="../../app/templates/generic-edit.pt"/>
68 <browser:page
69 name="+removedependency"
70 for="lp.blueprints.interfaces.specification.ISpecification"
71 class="lp.blueprints.browser.specificationdependency.SpecificationDependencyRemoveView"
72 permission="launchpad.Edit"
73- template="../templates/specification-removedep.pt">
74+ template="../../app/templates/generic-edit.pt">
75 </browser:page>
76 <browser:page
77 name="+linksprint"
78 for="lp.blueprints.interfaces.specification.ISpecification"
79 class="lp.blueprints.browser.specification.SpecificationSprintAddView"
80 permission="launchpad.AnyPerson"
81- template="../templates/specification-linksprint.pt"/>
82+ template="../../app/templates/generic-edit.pt"/>
83 <browser:page
84 for="lp.blueprints.interfaces.specification.ISpecification"
85 name="deptree.png"
86@@ -447,7 +447,7 @@
87 for="lp.blueprints.interfaces.specification.ISpecification"
88 name="+linkbranch"
89 class="lp.blueprints.browser.specification.SpecificationLinkBranchView"
90- template="../templates/specification-linkbranch.pt"
91+ template="../../app/templates/generic-edit.pt"
92 permission="launchpad.AnyPerson"/>
93 <browser:url
94 for="lp.blueprints.interfaces.specification.ISpecificationSet"
95@@ -492,7 +492,7 @@
96 name="+new"
97 for="lp.blueprints.interfaces.specification.ISpecificationSet"
98 permission="launchpad.AnyPerson"
99- template="../templates/specification-new.pt"
100+ template="../../app/templates/generic-edit.pt"
101 class="lp.blueprints.browser.specification.NewSpecificationFromRootView"/>
102 </facet>
103 <facet
104
105=== modified file 'lib/lp/blueprints/browser/specification.py'
106--- lib/lp/blueprints/browser/specification.py 2009-09-08 15:03:11 +0000
107+++ lib/lp/blueprints/browser/specification.py 2009-09-16 03:37:47 +0000
108@@ -111,6 +111,10 @@
109 # Set the default value for the next URL.
110 self._next_url = canonical_url(spec)
111
112+ @property
113+ def cancel_url(self):
114+ return canonical_url(self.context)
115+
116 def transform(self, data):
117 """Transforms the given form data.
118
119@@ -568,6 +572,10 @@
120 self.context, data['distroseries'], self.user)
121 self.next_url = canonical_url(self.context)
122
123+ @property
124+ def cancel_url(self):
125+ return canonical_url(self.context)
126+
127
128 class SpecificationProductSeriesGoalProposeView(SpecificationGoalProposeView):
129 label = 'Target to a product series'
130@@ -580,6 +588,10 @@
131 self.context, data['productseries'], self.user)
132 self.next_url = canonical_url(self.context)
133
134+ @property
135+ def cancel_url(self):
136+ return canonical_url(self.context)
137+
138
139 def propose_goal_with_automatic_approval(specification, series, user):
140 """Proposes the given specification as a goal for the given series. If
141@@ -664,6 +676,10 @@
142 def next_url(self):
143 return self._nextURL
144
145+ @property
146+ def cancel_url(self):
147+ return canonical_url(self.context)
148+
149
150 class SupersededByWidget(DropdownWidget):
151 """Custom select widget for specification superseding.
152@@ -733,6 +749,10 @@
153 'Specification is now considered "%s".' % newstate.title)
154 self.next_url = canonical_url(self.context)
155
156+ @property
157+ def cancel_url(self):
158+ return canonical_url(self.context)
159+
160
161 class SpecGraph:
162 """A directed linked graph of nodes representing spec dependencies."""
163@@ -923,6 +943,10 @@
164 self.context.linkSprint(data["sprint"], self.user)
165 self.next_url = canonical_url(self.context)
166
167+ @property
168+ def cancel_url(self):
169+ return canonical_url(self.context)
170+
171
172 class SpecGraphNode:
173 """Node in the spec dependency graph.
174@@ -1160,14 +1184,14 @@
175 self.context.linkBranch(branch=data['branch'],
176 registrant=self.user)
177
178- @action(_('Cancel'), name='cancel', validator='validate_cancel')
179- def cancel_action(self, action, data):
180- """Do nothing and go back to the blueprint page."""
181-
182 @property
183 def next_url(self):
184 return canonical_url(self.context)
185
186+ @property
187+ def cancel_url(self):
188+ return canonical_url(self.context)
189+
190
191 class SpecificationSetView(AppFrontPageSearchView, HasSpecificationsView):
192 """View for the Blueprints index page."""
193
194=== modified file 'lib/lp/blueprints/browser/specificationdependency.py'
195--- lib/lp/blueprints/browser/specificationdependency.py 2009-07-27 18:06:21 +0000
196+++ lib/lp/blueprints/browser/specificationdependency.py 2009-09-16 03:37:47 +0000
197@@ -62,6 +62,10 @@
198 def next_url(self):
199 return canonical_url(self.context)
200
201+ @property
202+ def cancel_url(self):
203+ return canonical_url(self.context)
204+
205
206 class SpecificationDependencyRemoveView(LaunchpadFormView):
207 schema = ISpecificationDependencyRemoval
208@@ -73,3 +77,7 @@
209 def continue_action(self, action, data):
210 self.context.removeDependency(data['dependency'])
211 self.next_url = canonical_url(self.context)
212+
213+ @property
214+ def cancel_url(self):
215+ return canonical_url(self.context)
216
217=== modified file 'lib/lp/blueprints/browser/specificationsubscription.py'
218--- lib/lp/blueprints/browser/specificationsubscription.py 2009-06-25 00:00:26 +0000
219+++ lib/lp/blueprints/browser/specificationsubscription.py 2009-09-16 03:37:47 +0000
220@@ -44,3 +44,7 @@
221 def change_action(self, action, data):
222 self.updateContextFromData(data)
223 self.next_url = canonical_url(self.context.specification)
224+
225+ @property
226+ def cancel_url(self):
227+ return canonical_url(self.context.specification)
228
229=== modified file 'lib/lp/blueprints/browser/sprint.py'
230--- lib/lp/blueprints/browser/sprint.py 2009-09-03 15:04:13 +0000
231+++ lib/lp/blueprints/browser/sprint.py 2009-09-16 03:37:47 +0000
232@@ -321,6 +321,10 @@
233 def next_url(self):
234 return canonical_url(self.context)
235
236+ @property
237+ def cancel_url(self):
238+ return canonical_url(self.context)
239+
240
241 class SprintTopicSetView(HasSpecificationsView, LaunchpadView):
242 """Custom view class to process the results of this unusual page.
243
244=== modified file 'lib/lp/blueprints/browser/tests/test_breadcrumbs.py'
245--- lib/lp/blueprints/browser/tests/test_breadcrumbs.py 2009-08-24 20:28:33 +0000
246+++ lib/lp/blueprints/browser/tests/test_breadcrumbs.py 2009-09-16 03:37:47 +0000
247@@ -41,6 +41,28 @@
248 'Blueprints involving %s' % self.person.displayname)
249
250
251+class TestSpecificationBreadcrumb(BaseBreadcrumbTestCase):
252+ """Test breadcrumbs for an `ISpecification`."""
253+
254+ def setUp(self):
255+ super(TestSpecificationBreadcrumb, self).setUp()
256+ self.product = self.factory.makeProduct(
257+ name='crumb-tester', displayname="Crumb Tester")
258+ self.specification = self.factory.makeSpecification(
259+ title="Crumby Specification", product=self.product)
260+ self.specification_url = canonical_url(
261+ self.specification, rootsite='blueprints')
262+
263+ def test_specification(self):
264+ crumbs = self._getBreadcrumbs(
265+ self.specification_url,
266+ [self.root, self.product, self.specification])
267+ last_crumb = crumbs[-1]
268+ self.assertEquals(last_crumb.url, self.specification_url)
269+ self.assertEquals(
270+ last_crumb.text, self.specification.title)
271+
272+
273 def test_suite():
274 return unittest.TestLoader().loadTestsFromName(__name__)
275
276
277=== modified file 'lib/lp/blueprints/configure.zcml'
278--- lib/lp/blueprints/configure.zcml 2009-09-03 15:04:13 +0000
279+++ lib/lp/blueprints/configure.zcml 2009-09-16 03:37:47 +0000
280@@ -35,6 +35,11 @@
281 for="lp.blueprints.interfaces.sprint.ISprintSet"
282 factory="lp.blueprints.browser.sprint.SprintSetBreadcrumb"
283 permission="zope.Public"/>
284+ <adapter
285+ provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"
286+ for="lp.blueprints.interfaces.specification.ISpecification"
287+ factory="canonical.launchpad.webapp.breadcrumb.TitleBreadcrumb"
288+ permission="zope.Public"/>
289
290 <!-- This is a view used to export data needed by the sprint scheduler.
291 As there are no API stability guarantees, the view name starts
292
293=== modified file 'lib/lp/blueprints/stories/blueprints/sprint-links.txt'
294--- lib/lp/blueprints/stories/blueprints/sprint-links.txt 2009-05-11 18:19:21 +0000
295+++ lib/lp/blueprints/stories/blueprints/sprint-links.txt 2009-09-16 03:37:47 +0000
296@@ -22,7 +22,7 @@
297
298 >>> browser.getLink('Propose for sprint').click()
299 >>> browser.title
300- 'Put blueprint on sprint agenda'
301+ '+linksprint : Support <canvas> Objects : Blueprints for Mozilla Firefox : Mozilla Firefox'
302
303 The page contains a link back to the blueprint, in case we change our
304 mind.
305
306=== modified file 'lib/lp/blueprints/stories/blueprints/xx-overview.txt'
307--- lib/lp/blueprints/stories/blueprints/xx-overview.txt 2009-09-09 23:16:08 +0000
308+++ lib/lp/blueprints/stories/blueprints/xx-overview.txt 2009-09-16 03:37:47 +0000
309@@ -52,9 +52,11 @@
310 >>> browser.getLink('Propose as goal').click()
311 >>> main = find_main_content(browser.contents)
312 >>> print extract_text(main).encode('ascii', 'backslashreplace')
313+ Target to a product series
314+ Mozilla Firefox
315+ ...
316 Support Native SVG Objects
317- Select the release series of Mozilla Firefox
318- for which this feature should be implemented...
319+ ...
320
321 >>> series = browser.getControl('Series Goal')
322 >>> series.displayValue = ['firefox 1.0']
323@@ -149,9 +151,11 @@
324 >>> browser.getLink('Propose as goal').click()
325 >>> main = find_main_content(browser.contents)
326 >>> print extract_text(main).encode('ascii', 'backslashreplace')
327+ Target to a distribution series
328+ Ubuntu
329+ ...
330 CD Media Integrity Check
331- Select the release of Ubuntu for which this blueprint should be
332- a feature goal...
333+ ...
334 >>> series = browser.getControl('Series Goal')
335 >>> series.displayValue = ['ubuntu grumpy']
336 >>> browser.getControl('Continue').click()
337
338=== removed file 'lib/lp/blueprints/templates/specification-addsubscriber.pt'
339--- lib/lp/blueprints/templates/specification-addsubscriber.pt 2009-07-17 17:59:07 +0000
340+++ lib/lp/blueprints/templates/specification-addsubscriber.pt 1970-01-01 00:00:00 +0000
341@@ -1,25 +0,0 @@
342-<html
343- xmlns="http://www.w3.org/1999/xhtml"
344- xmlns:tal="http://xml.zope.org/namespaces/tal"
345- xmlns:metal="http://xml.zope.org/namespaces/metal"
346- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
347- xml:lang="en"
348- lang="en"
349- dir="ltr"
350- metal:use-macro="context/@@main_template/master"
351- i18n:domain="launchpad"
352->
353- <body>
354-
355-<div metal:fill-slot="main">
356-
357- <div tal:content="structure context/fmt:link" />
358-
359- <div metal:use-macro="context/@@launchpad_form/form">
360-
361- </div>
362-
363-</div>
364-
365-</body>
366-</html>
367
368=== removed file 'lib/lp/blueprints/templates/specification-dependency.pt'
369--- lib/lp/blueprints/templates/specification-dependency.pt 2009-07-17 17:59:07 +0000
370+++ lib/lp/blueprints/templates/specification-dependency.pt 1970-01-01 00:00:00 +0000
371@@ -1,30 +0,0 @@
372-<html
373- xmlns="http://www.w3.org/1999/xhtml"
374- xmlns:tal="http://xml.zope.org/namespaces/tal"
375- xmlns:metal="http://xml.zope.org/namespaces/metal"
376- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
377- xml:lang="en"
378- lang="en"
379- dir="ltr"
380- metal:use-macro="context/@@main_template/master"
381- i18n:domain="launchpad"
382->
383-
384- <body>
385-
386- <metal:leftportlets fill-slot="portlets_one">
387- <div tal:replace="structure context/@@+portlet-dependencies" />
388- </metal:leftportlets>
389-
390- <div metal:fill-slot="main">
391-
392- <div tal:content="structure context/fmt:link" />
393- <div metal:use-macro="context/@@launchpad_form/form">
394-
395- </div>
396-
397- </div>
398-
399- </body>
400-
401-</html>
402
403=== removed file 'lib/lp/blueprints/templates/specification-distroseries.pt'
404--- lib/lp/blueprints/templates/specification-distroseries.pt 2009-07-17 17:59:07 +0000
405+++ lib/lp/blueprints/templates/specification-distroseries.pt 1970-01-01 00:00:00 +0000
406@@ -1,38 +0,0 @@
407-<tal:root
408- xmlns:tal="http://xml.zope.org/namespaces/tal"
409- xmlns:metal="http://xml.zope.org/namespaces/metal"
410- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
411- omit-tag="">
412-
413-<html
414- xmlns="http://www.w3.org/1999/xhtml"
415- xmlns:tal="http://xml.zope.org/namespaces/tal"
416- xmlns:metal="http://xml.zope.org/namespaces/metal"
417- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
418- xml:lang="en"
419- lang="en"
420- dir="ltr"
421- metal:use-macro="context/@@main_template/master"
422- i18n:domain="launchpad"
423->
424-
425-<body>
426-
427- <div metal:fill-slot="main">
428-
429- <div tal:content="structure context/fmt:link" />
430-
431- <div metal:use-macro="context/@@launchpad_form/form">
432-
433- <p metal:fill-slot="extra_info">
434- Select the release of
435- <span tal:replace="context/distribution/displayname">Ubuntu</span>
436- for which this blueprint should be a feature goal.
437- </p>
438-
439- </div>
440-
441-</div>
442-</body>
443-</html>
444-</tal:root>
445
446=== removed file 'lib/lp/blueprints/templates/specification-linkbranch.pt'
447--- lib/lp/blueprints/templates/specification-linkbranch.pt 2009-07-17 17:59:07 +0000
448+++ lib/lp/blueprints/templates/specification-linkbranch.pt 1970-01-01 00:00:00 +0000
449@@ -1,28 +0,0 @@
450-<html
451- xmlns="http://www.w3.org/1999/xhtml"
452- xmlns:tal="http://xml.zope.org/namespaces/tal"
453- xmlns:metal="http://xml.zope.org/namespaces/metal"
454- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
455- xml:lang="en"
456- lang="en"
457- dir="ltr"
458- metal:use-macro="context/@@main_template/master"
459- i18n:domain="launchpad"
460->
461- <body>
462-
463- <div metal:fill-slot="main">
464-
465- <div tal:content="structure context/fmt:link" />
466- <div metal:use-macro="context/@@launchpad_form/form" />
467-
468- </div>
469-
470- <div metal:fill-slot="help">
471- <p>If you have a branch related to a blueprint (implementing
472- the feature, or fixing the problem the blueprint outlines),
473- you can create a link between them. The summary field can be used
474- to leave a note about the relationship.</p>
475- </div>
476-</body>
477-</html>
478
479=== removed file 'lib/lp/blueprints/templates/specification-linksprint.pt'
480--- lib/lp/blueprints/templates/specification-linksprint.pt 2009-07-17 17:59:07 +0000
481+++ lib/lp/blueprints/templates/specification-linksprint.pt 1970-01-01 00:00:00 +0000
482@@ -1,24 +0,0 @@
483-<html
484- xmlns="http://www.w3.org/1999/xhtml"
485- xmlns:tal="http://xml.zope.org/namespaces/tal"
486- xmlns:metal="http://xml.zope.org/namespaces/metal"
487- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
488- xml:lang="en"
489- lang="en"
490- dir="ltr"
491- metal:use-macro="context/@@main_template/master"
492- i18n:domain="launchpad"
493->
494-
495-<body>
496-
497-<div metal:fill-slot="main">
498-
499- <div tal:content="structure context/fmt:link" />
500-
501- <div metal:use-macro="context/@@launchpad_form/form" />
502-
503-</div>
504-
505-</body>
506-</html>
507
508=== removed file 'lib/lp/blueprints/templates/specification-new.pt'
509--- lib/lp/blueprints/templates/specification-new.pt 2009-07-17 17:59:07 +0000
510+++ lib/lp/blueprints/templates/specification-new.pt 1970-01-01 00:00:00 +0000
511@@ -1,29 +0,0 @@
512-<html
513- xmlns="http://www.w3.org/1999/xhtml"
514- xmlns:tal="http://xml.zope.org/namespaces/tal"
515- xmlns:metal="http://xml.zope.org/namespaces/metal"
516- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
517- xml:lang="en"
518- lang="en"
519- dir="ltr"
520- metal:use-macro="view/macro:page/applicationhome"
521- i18n:domain="specifications">
522-
523-<body>
524-
525-<h1 metal:fill-slot="heading">Blueprint tracking</h1>
526-
527-<metal:leftportlets fill-slot="portlets_one">
528-</metal:leftportlets>
529-
530-<metal:rightportlets fill-slot="portlets_two">
531-</metal:rightportlets>
532-
533-<div metal:fill-slot="main">
534-
535- <div metal:use-macro="context/@@launchpad_form/form" />
536-
537-</div>
538-
539-</body>
540-</html>
541
542=== removed file 'lib/lp/blueprints/templates/specification-productseries.pt'
543--- lib/lp/blueprints/templates/specification-productseries.pt 2009-07-17 17:59:07 +0000
544+++ lib/lp/blueprints/templates/specification-productseries.pt 1970-01-01 00:00:00 +0000
545@@ -1,33 +0,0 @@
546-<tal:root
547- xmlns:tal="http://xml.zope.org/namespaces/tal"
548- xmlns:metal="http://xml.zope.org/namespaces/metal"
549- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
550- omit-tag="">
551-
552-<html
553- xmlns="http://www.w3.org/1999/xhtml"
554- xml:lang="en"
555- lang="en"
556- metal:use-macro="context/@@main_template/master"
557- i18n:domain="launchpad">
558-
559-<body>
560-
561- <div metal:fill-slot="main">
562-
563- <div tal:content="structure context/fmt:link" />
564-
565- <div metal:use-macro="context/@@launchpad_form/form">
566-
567- <p metal:fill-slot="extra_info">
568- Select the release series of
569- <span tal:replace="context/product/displayname">Firefox</span>
570- for which this feature should be implemented.
571- </p>
572-
573- </div>
574-
575-</div>
576-</body>
577-</html>
578-</tal:root>
579
580=== removed file 'lib/lp/blueprints/templates/specification-removedep.pt'
581--- lib/lp/blueprints/templates/specification-removedep.pt 2009-07-17 17:59:07 +0000
582+++ lib/lp/blueprints/templates/specification-removedep.pt 1970-01-01 00:00:00 +0000
583@@ -1,38 +0,0 @@
584-<html
585- xmlns="http://www.w3.org/1999/xhtml"
586- xmlns:tal="http://xml.zope.org/namespaces/tal"
587- xmlns:metal="http://xml.zope.org/namespaces/metal"
588- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
589- xml:lang="en"
590- lang="en"
591- dir="ltr"
592- metal:use-macro="context/@@main_template/master"
593- i18n:domain="launchpad"
594->
595-
596-<body>
597-
598-<metal:portlets fill-slot="portlets">
599- <div tal:replace="structure context/@@+portlet-dependencies" />
600-</metal:portlets>
601-
602-<div metal:fill-slot="main">
603-
604- <div>
605- <img alt="" src="/@@/blueprint" />
606- <a tal:attributes="href context/fmt:url" tal:content="context/title" />
607- </div>
608-
609- <div metal:use-macro="context/@@launchpad_form/form">
610-
611- <p metal:fill-slot="extra_info">
612- This will <em>remove</em> the dependency on the selected blueprint.
613- </p>
614-
615- </div>
616-
617-</div>
618-
619-</body>
620-</html>
621-
622
623=== removed file 'lib/lp/blueprints/templates/specification-retargeting.pt'
624--- lib/lp/blueprints/templates/specification-retargeting.pt 2009-07-17 17:59:07 +0000
625+++ lib/lp/blueprints/templates/specification-retargeting.pt 1970-01-01 00:00:00 +0000
626@@ -1,36 +0,0 @@
627-<html
628- xmlns="http://www.w3.org/1999/xhtml"
629- xmlns:tal="http://xml.zope.org/namespaces/tal"
630- xmlns:metal="http://xml.zope.org/namespaces/metal"
631- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
632- xml:lang="en"
633- lang="en"
634- dir="ltr"
635- metal:use-macro="context/@@main_template/master"
636- i18n:domain="launchpad"
637->
638-
639-<body>
640-
641-<div metal:fill-slot="main">
642-
643- <div tal:content="structure context/fmt:link" />
644-
645- <div metal:use-macro="context/@@launchpad_form/form">
646-
647- <h1 tal:condition="view/label"
648- tal:content="view/label"
649- metal:fill-slot="heading">Heading from ZCML label="xxx"</h1>
650-
651- <div metal:fill-slot="extra_info" class="documentDescription">
652- You can target the blueprint to a different project. Be careful, when
653- you retarget the blueprint you will lose any goal or milestone
654- information for it.
655- </div>
656-
657- </div>
658-
659-</div>
660-
661-</body>
662-</html>
663
664=== removed file 'lib/lp/blueprints/templates/specificationsubscription-edit.pt'
665--- lib/lp/blueprints/templates/specificationsubscription-edit.pt 2009-07-17 17:59:07 +0000
666+++ lib/lp/blueprints/templates/specificationsubscription-edit.pt 1970-01-01 00:00:00 +0000
667@@ -1,31 +0,0 @@
668-<html
669- xmlns="http://www.w3.org/1999/xhtml"
670- xmlns:tal="http://xml.zope.org/namespaces/tal"
671- xmlns:metal="http://xml.zope.org/namespaces/metal"
672- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
673- xml:lang="en"
674- lang="en"
675- dir="ltr"
676- metal:use-macro="context/@@main_template/master"
677- i18n:domain="launchpad"
678->
679-
680-<body>
681-
682-<metal:portlets fill-slot="portlets">
683- <div tal:replace="structure context/person/@@+portlet-details" />
684-</metal:portlets>
685-
686-<div metal:fill-slot="main">
687-
688- <div>
689- <img alt="" src="/@@/blueprint" />
690- <a tal:attributes="href context/specification/fmt:url"
691- tal:content="context/specification/title" />
692- </div>
693-
694- <div metal:use-macro="context/@@launchpad_form/form" />
695-
696-</div>
697-</body>
698-</html>
699
700=== removed file 'lib/lp/blueprints/templates/sprint-edit.pt'
701--- lib/lp/blueprints/templates/sprint-edit.pt 2009-07-17 17:59:07 +0000
702+++ lib/lp/blueprints/templates/sprint-edit.pt 1970-01-01 00:00:00 +0000
703@@ -1,35 +0,0 @@
704-<html
705- xmlns="http://www.w3.org/1999/xhtml"
706- xmlns:tal="http://xml.zope.org/namespaces/tal"
707- xmlns:metal="http://xml.zope.org/namespaces/metal"
708- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
709- xml:lang="en"
710- lang="en"
711- dir="ltr"
712- metal:use-macro="context/@@main_template/master"
713- i18n:domain="launchpad"
714->
715-
716-<body>
717-
718-<metal:leftportlets fill-slot="portlets_one">
719- <div tal:replace="structure context/@@+portlet-attendees" />
720-</metal:leftportlets>
721-
722-<metal:rightportlets fill-slot="portlets_two">
723- <div tal:replace="structure context/@@+portlet-details" />
724-</metal:rightportlets>
725-
726-<div metal:fill-slot="main">
727-
728- <div metal:use-macro="context/@@launchpad_form/form" />
729-
730-</div>
731-
732-<div metal:fill-slot="help">
733-<p>Note that the start and end dates for the sprint are treated as
734-local time for the sprint.</p>
735-</div>
736-
737-</body>
738-</html>
739