Merge lp:~julian-edwards/launchpad/blueprint-30-changes into lp:launchpad

Proposed by Julian Edwards
Status: Merged
Approved by: Brad Crittenden
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~julian-edwards/launchpad/blueprint-30-changes
Merge into: lp:launchpad
Diff against target: None lines
To merge this branch: bzr merge lp:~julian-edwards/launchpad/blueprint-30-changes
Reviewer Review Type Date Requested Status
Brad Crittenden (community) release-critical Approve
Graham Binns (community) Approve
Review via email: mp+12218@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Julian Edwards (julian-edwards) wrote :

= Summary =
Convert some blueprint pages to 3.0

== Proposed fix ==
See https://bugs.edge.launchpad.net/blueprint/+bug/434067

== Implementation details ==
The page tests for blueprints are absolutely *shite* and use print http()
stuff. So I converted them to use the testbrowser object. Forgive me the
extra diff noise :/

I also converted the xx- tests to a standalone directory, I got totally fed up
with waiting for unrelated tests to finish before it got to my numbered ones.

Finally, the subscription page used the really old "addform" stuff which does
not play nicely with the new headings rules. I had to convert it to a
LaunchpadForm.

== Tests ==
bin/test -cvvt stories.blueprints -t subscribing.txt

== Demo and Q/A ==
ui=rs for this, but if you want to see:

https://blueprints.launchpad.dev/firefox/+spec/canvas/+deptree
https://blueprints.launchpad.dev/firefox/+spec/canvas/+requestfeedback
https://blueprints.launchpad.dev/firefox/+spec/canvas/+subscribe

= 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/templates/specification-deptree.pt
  lib/canonical/launchpad/pagetitles.py
  lib/lp/blueprints/stories/standalone/subscribing.txt
  lib/lp/blueprints/browser/specificationfeedback.py
  lib/lp/blueprints/stories/blueprints/05-reviews.txt
  lib/lp/blueprints/templates/specification-requestfeedback.pt
  lib/lp/blueprints/browser/specificationdependency.py
  lib/lp/blueprints/interfaces/specificationfeedback.py
  lib/lp/blueprints/templates/specification-subscription.pt
  lib/lp/blueprints/browser/configure.zcml
  lib/lp/blueprints/browser/specification.py

== Pyflakes notices ==
Will fix these before landing.

lib/lp/blueprints/browser/specification.py
    57: 'smartquote' imported but unused

== Pylint notices ==

lib/lp/blueprints/browser/specification.py
    57: [W0611] Unused import smartquote

Revision history for this message
Graham Binns (gmb) :
review: Approve
Revision history for this message
Brad Crittenden (bac) wrote :

Julian,

Thanks for the conversion -- I didn't realize those pages and tests were such a mess.

On the +requestfeedback page the conversion has created the form entry with the title "Feedback From?:" which looks funny. Since the colon is part of the widget rendering please remove the question mark from the title. Please fix that before landing.

I'm also bugged by the inconsistency on the +subscribe page where there is a 'Cancel' button instead of a link and I think the introductory text is pointless. I realize you inherited both of those issues. I leave it to your discretion as to whether fix now or defer. If the latter would you open a bug, please.

review: Approve (release-critical)
Revision history for this message
Julian Edwards (julian-edwards) wrote :

On Tuesday 22 September 2009 14:44:50 Brad Crittenden wrote:
> Thanks for the conversion -- I didn't realize those pages and tests were
> such a mess.

I am still suffering! :)

> On the +requestfeedback page the conversion has created the form entry with
> the title "Feedback From?:" which looks funny. Since the colon is part of
> the widget rendering please remove the question mark from the title.
> Please fix that before landing.

Ok, done.

> I'm also bugged by the inconsistency on the +subscribe page where there is
> a 'Cancel' button instead of a link and I think the introductory text is
> pointless. I realize you inherited both of those issues. I leave it to
> your discretion as to whether fix now or defer. If the latter would you
> open a bug, please.

I am a bit swamped with QA right now - it bugged me too but I don't really
have time to fix it.

https://bugs.edge.launchpad.net/launchpad/+bug/434658

Thanks Brad.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/canonical/launchpad/pagetitles.py'
2--- lib/canonical/launchpad/pagetitles.py 2009-09-20 19:40:47 +0000
3+++ lib/canonical/launchpad/pagetitles.py 2009-09-22 11:42:13 +0000
4@@ -810,8 +810,6 @@
5
6 specification_dependency = 'Create a blueprint dependency'
7
8-specification_deptree = 'Complete dependency tree'
9-
10 specification_distroseries = ('Target blueprint to a distribution release')
11
12 specification_productseries = 'Target blueprint to a series'
13@@ -820,14 +818,10 @@
14
15 specification_givefeedback = 'Clear feedback requests'
16
17-specification_requestfeedback = 'Request feedback on this blueprint'
18-
19 specification_edit = 'Edit blueprint details'
20
21 specification_linksprint = 'Put blueprint on sprint agenda'
22
23-specification_subscription = 'Subscribe to blueprint'
24-
25 specification_queue = 'Queue blueprint for review'
26
27 specification_linkbranch = 'Link branch to blueprint'
28
29=== modified file 'lib/lp/blueprints/browser/configure.zcml'
30--- lib/lp/blueprints/browser/configure.zcml 2009-09-17 21:20:14 +0000
31+++ lib/lp/blueprints/browser/configure.zcml 2009-09-22 11:35:39 +0000
32@@ -248,9 +248,6 @@
33 for="lp.blueprints.interfaces.specification.ISpecification"
34 permission="zope.Public">
35 <browser:page
36- name="+deptree"
37- template="../templates/specification-deptree.pt"/>
38- <browser:page
39 name="+listing-column"
40 template="../templates/specification-listing-column.pt"/>
41 <browser:page
42@@ -272,6 +269,12 @@
43 name="+portlet-feedbackqueue"
44 template="../templates/specification-portlet-feedbackqueue.pt"/>
45 </browser:pages>
46+ <browser:page
47+ for="lp.blueprints.interfaces.specification.ISpecification"
48+ class="lp.blueprints.browser.specificationdependency.SpecificationDependencyTreeView"
49+ permission="zope.Public"
50+ name="+deptree"
51+ template="../templates/specification-deptree.pt"/>
52 <browser:pages
53 for="lp.blueprints.interfaces.specification.ISpecification"
54 permission="zope.Public"
55@@ -292,7 +295,7 @@
56 <browser:page
57 for="lp.blueprints.interfaces.specification.ISpecification"
58 name="+subscribe"
59- class="lp.blueprints.browser.specification.SpecificationView"
60+ class="lp.blueprints.browser.specification.SpecificationSubscriptionView"
61 permission="launchpad.AnyPerson"
62 template="../templates/specification-subscription.pt"/>
63 <browser:page
64@@ -376,24 +379,13 @@
65 class="lp.blueprints.browser.specification.SpecificationEditMilestoneView"
66 permission="launchpad.Edit"
67 template="../templates/specification-edit.pt"/>
68- <browser:addform
69+ <browser:page
70 name="+requestfeedback"
71 for="lp.blueprints.interfaces.specification.ISpecification"
72- schema="lp.blueprints.interfaces.specificationfeedback.ISpecificationFeedback"
73 class="lp.blueprints.browser.specificationfeedback.SpecificationFeedbackAddView"
74- label="Request feedback on specification"
75- fields="reviewer requester queuemsg"
76- keyword_arguments="reviewer requester queuemsg"
77 permission="launchpad.AnyPerson"
78 template="../templates/specification-requestfeedback.pt">
79- <browser:widget
80- field="requester"
81- class="canonical.widgets.HiddenUserWidget"/>
82- <browser:widget
83- field="queuemsg"
84- class="zope.app.form.browser.TextAreaWidget"
85- height="5"/>
86- </browser:addform>
87+ </browser:page>
88 <browser:page
89 name="+linkbug"
90 for="lp.blueprints.interfaces.specification.ISpecification"
91
92=== modified file 'lib/lp/blueprints/browser/specification.py'
93--- lib/lp/blueprints/browser/specification.py 2009-09-19 08:58:42 +0000
94+++ lib/lp/blueprints/browser/specification.py 2009-09-21 18:07:54 +0000
95@@ -29,6 +29,7 @@
96 'SpecificationProductSeriesGoalProposeView',
97 'SpecificationRetargetingView',
98 'SpecificationSprintAddView',
99+ 'SpecificationSubscriptionView',
100 'SpecificationSupersedingView',
101 'SpecificationTreePNGView',
102 'SpecificationTreeImageTag',
103@@ -503,6 +504,15 @@
104 self.notices.append(msg)
105
106
107+class SpecificationSubscriptionView(SpecificationView):
108+
109+ @property
110+ def label(self):
111+ if self.subscription is not None:
112+ return "Modify subscription"
113+ return "Subscribe to blueprint"
114+
115+
116 class SpecificationEditView(LaunchpadEditFormView):
117
118 schema = ISpecification
119
120=== modified file 'lib/lp/blueprints/browser/specificationdependency.py'
121--- lib/lp/blueprints/browser/specificationdependency.py 2009-09-16 03:37:47 +0000
122+++ lib/lp/blueprints/browser/specificationdependency.py 2009-09-22 11:42:13 +0000
123@@ -8,11 +8,12 @@
124 __all__ = [
125 'SpecificationDependencyAddView',
126 'SpecificationDependencyRemoveView',
127+ 'SpecificationDependencyTreeView',
128 ]
129
130 from canonical.launchpad import _
131 from canonical.launchpad.webapp import (
132- action, canonical_url, LaunchpadFormView)
133+ action, canonical_url, LaunchpadFormView, LaunchpadView)
134 from lp.blueprints.interfaces.specificationdependency import (
135 ISpecificationDependency, ISpecificationDependencyRemoval)
136
137@@ -81,3 +82,11 @@
138 @property
139 def cancel_url(self):
140 return canonical_url(self.context)
141+
142+
143+class SpecificationDependencyTreeView(LaunchpadView):
144+ label = "Blueprint dependency tree"
145+
146+ @property
147+ def page_title(self):
148+ return self.label
149
150=== modified file 'lib/lp/blueprints/browser/specificationfeedback.py'
151--- lib/lp/blueprints/browser/specificationfeedback.py 2009-07-17 00:26:05 +0000
152+++ lib/lp/blueprints/browser/specificationfeedback.py 2009-09-22 10:48:09 +0000
153@@ -5,15 +5,17 @@
154
155 __metaclass__ = type
156
157-from zope.app.form.interfaces import WidgetsError
158-from zope.app.form.browser.add import AddView
159+from zope.app.form.browser import TextAreaWidget
160
161 from zope.component import getUtility
162
163 from canonical.launchpad import _
164 from canonical.launchpad.webapp.interfaces import ILaunchBag
165 from lp.registry.interfaces.person import IPersonSet
166-from canonical.launchpad.webapp import canonical_url
167+from canonical.launchpad.webapp import action, canonical_url, custom_widget
168+from canonical.launchpad.webapp.launchpadform import LaunchpadFormView
169+from lp.blueprints.interfaces.specificationfeedback import (
170+ ISpecificationFeedback)
171
172
173 __all__ = [
174@@ -22,39 +24,49 @@
175 ]
176
177
178-class SpecificationFeedbackAddView(AddView):
179-
180- def __init__(self, context, request):
181- AddView.__init__(self, context, request)
182- self.top_of_page_errors = []
183-
184- def valid_feedback_request(self, spec, reviewer, requester):
185- for request in spec.getFeedbackRequests(reviewer):
186+class SpecificationFeedbackAddView(LaunchpadFormView):
187+
188+ schema = ISpecificationFeedback
189+
190+ field_names = [
191+ 'reviewer', 'queuemsg',
192+ ]
193+
194+ custom_widget('queuemsg', TextAreaWidget, height=5)
195+
196+ @property
197+ def label(self):
198+ return "Request feedback on specification"
199+
200+ @property
201+ def page_title(self):
202+ return self.label
203+
204+ def validate(self, data):
205+ reviewer = data.get('reviewer')
206+ requester = self.user
207+ for request in self.context.getFeedbackRequests(reviewer):
208 if request.requester == requester:
209- return False
210- return True
211-
212- def create(self, reviewer, requester, queuemsg=None):
213+ self.addError("You've already requested feedback from %s"
214+ % reviewer.displayname)
215 if reviewer == requester:
216- self.top_of_page_errors.append(_(
217- "You can't request feedback from yourself"))
218- elif not self.valid_feedback_request(
219- self.context, reviewer, requester):
220- self.top_of_page_errors.append(_(
221- "You've already requested feedback from %s"
222- % reviewer.displayname))
223- if self.top_of_page_errors:
224- raise WidgetsError(self.top_of_page_errors)
225+ self.addError("You can't request feedback from yourself")
226+
227+ @action(_("Add"), name="create")
228+ def create_action(self, action, data):
229+ reviewer = data.get('reviewer')
230+ requester = self.user
231+ queuemsg = data.get('queuemsg')
232 return self.context.queue(reviewer, requester, queuemsg)
233
234- def add(self, content):
235- """Skipping 'adding' this content to a container, because
236- this is a placeless system."""
237- return content
238-
239- def nextURL(self):
240+ @property
241+ def next_url(self):
242 return canonical_url(self.context)
243
244+ @property
245+ def cancel_url(self):
246+ return self.next_url
247+
248
249 class SpecificationFeedbackClearingView:
250
251
252=== modified file 'lib/lp/blueprints/interfaces/specificationfeedback.py'
253--- lib/lp/blueprints/interfaces/specificationfeedback.py 2009-06-25 00:00:26 +0000
254+++ lib/lp/blueprints/interfaces/specificationfeedback.py 2009-09-22 10:48:09 +0000
255@@ -25,7 +25,7 @@
256
257 reviewer = PublicPersonChoice(
258 title=_('Feedback From?'), required=True,
259- vocabulary='ValidPersonOrTeam', readonly=True,
260+ vocabulary='ValidPersonOrTeam', readonly=False,
261 description=_("Select the person who you would like to give you "
262 "some feedback on this specification."))
263 requester = PublicPersonChoice(
264
265=== modified file 'lib/lp/blueprints/stories/blueprints/05-reviews.txt'
266--- lib/lp/blueprints/stories/blueprints/05-reviews.txt 2009-08-13 19:03:36 +0000
267+++ lib/lp/blueprints/stories/blueprints/05-reviews.txt 2009-09-22 10:48:09 +0000
268@@ -14,229 +14,140 @@
269 >>> browser.url
270 'http://blueprints.launchpad.dev/firefox/+spec/canvas/+requestfeedback'
271
272-This page contains a link back to the blueprint page, in case you change
273-your mind.
274+This page contains a cancellation link back to the blueprint page, in case you
275+change your mind.
276
277- >>> back_link = browser.getLink('Support <canvas> Objects')
278- >>> back_link.url
279- 'http://blueprints.launchpad.dev/firefox/+spec/canvas'
280+ >>> print browser.getLink('Cancel').url
281+ http://blueprints.launchpad.dev/firefox/+spec/canvas
282
283 Now we try to POST to the form behind it. We expect to be redirected to the
284 spec home page.
285
286- >>> print http(r"""
287- ... POST /firefox/+spec/canvas/+requestfeedback HTTP/1.1
288- ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
289- ... Content-Type: multipart/form-data; boundary=---------------------------9851763078341624562133848003
290- ...
291- ... -----------------------------9851763078341624562133848003
292- ... Content-Disposition: form-data; name="field.reviewer"
293- ...
294- ... mark
295- ... -----------------------------9851763078341624562133848003
296- ... Content-Disposition: form-data; name="field.queuemsg"
297- ...
298- ... specification, review thyself
299- ... -----------------------------9851763078341624562133848003
300- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
301- ...
302- ... Add
303- ... -----------------------------9851763078341624562133848003--
304- ... """)
305- HTTP/1.1 303 See Other
306- ...
307- Location: http://.../firefox/+spec/canvas
308- ...
309+ >>> browser.getControl(name="field.reviewer").value = "mark"
310+ >>> browser.getControl(
311+ ... name="field.queuemsg").value = "specification, review thyself"
312+ >>> browser.getControl("Add").click()
313+ >>> print browser.url
314+ http://blueprints.launchpad.dev/firefox/+spec/canvas
315
316 If we try to request feedback to the same person to the same specification,
317 we'll get a nice error message
318
319- >>> print http(r"""
320- ... POST /firefox/+spec/canvas/+requestfeedback HTTP/1.1
321- ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
322- ... Content-Type: multipart/form-data; boundary=---------------------------9851763078341624562133848003
323- ...
324- ... -----------------------------9851763078341624562133848003
325- ... Content-Disposition: form-data; name="field.reviewer"
326- ...
327- ... mark
328- ... -----------------------------9851763078341624562133848003
329- ... Content-Disposition: form-data; name="field.queuemsg"
330- ...
331- ... specification, review thyself
332- ... -----------------------------9851763078341624562133848003
333- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
334- ...
335- ... Add
336- ... -----------------------------9851763078341624562133848003--
337- ... """)
338- HTTP/1.1 200 Ok
339- ...
340- <p class="error message">An error occurred.</p>
341- <BLANKLINE>
342- <BLANKLINE>
343- ...You've already requested feedback from Mark Shuttleworth
344- ...
345-
346-I can't request feedback from myself
347-
348- >>> print http(r"""
349- ... POST /firefox/+spec/canvas/+requestfeedback HTTP/1.1
350- ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
351- ... Content-Type: multipart/form-data; boundary=---------------------------9851763078341624562133848003
352- ...
353- ... -----------------------------9851763078341624562133848003
354- ... Content-Disposition: form-data; name="field.reviewer"
355- ...
356- ... name12
357- ... -----------------------------9851763078341624562133848003
358- ... Content-Disposition: form-data; name="field.queuemsg"
359- ...
360- ... test spec request
361- ... -----------------------------9851763078341624562133848003
362- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
363- ...
364- ... Add
365- ... -----------------------------9851763078341624562133848003--
366- ... """)
367- HTTP/1.1 200 Ok
368- ...
369- <p class="error message">An error occurred.</p>
370- <BLANKLINE>
371- <BLANKLINE>
372- You can't request feedback from yourself
373- ...
374-
375-Now We should see that review request message on the spec page.
376-
377- >>> print http(r"""
378- ... GET /firefox/+spec/canvas HTTP/1.1
379- ... """)
380- HTTP/1.1 200 Ok
381- ...Feedback requests...
382- ...Mark Shuttleworth...
383- ...specification, review thyself...
384-
385+ >>> browser.open(
386+ ... 'http://blueprints.launchpad.dev/firefox/+spec/canvas/'
387+ ... '+requestfeedback')
388+ >>> browser.getControl(name="field.reviewer").value = "mark"
389+ >>> browser.getControl(
390+ ... name="field.queuemsg").value = "specification, review thyself"
391+ >>> browser.getControl("Add").click()
392+ >>> print browser.url
393+ http://blueprints.launchpad.dev/firefox/+spec/canvas/+requestfeedback
394+
395+ >>> for error in get_feedback_messages(browser.contents):
396+ ... print error
397+ There is 1 error.
398+ You've already requested feedback from Mark Shuttleworth
399+
400+I can't request feedback from myself.
401+
402+ >>> browser.getControl(name="field.reviewer").value = "name12"
403+ >>> browser.getControl(
404+ ... name="field.queuemsg").value = "test spec request"
405+ >>> browser.getControl("Add").click()
406+ >>> print browser.url
407+ http://blueprints.launchpad.dev/firefox/+spec/canvas/+requestfeedback
408+ >>> for error in get_feedback_messages(browser.contents):
409+ ... print error
410+ There is 1 error.
411+ You can't request feedback from yourself
412+
413+We will see that review request message on the spec page.
414+
415+ >>> browser.open('http://blueprints.launchpad.dev/firefox/+spec/canvas')
416+ >>> print extract_text(
417+ ... find_portlet(browser.contents, 'Feedback requests'))
418+ Feedback requests
419+ Sample Person requested feedback from Mark Shuttleworth:
420+ specification, review thyself
421+ ...
422
423 We will do another 2 feedback requests for mark with different logged in
424 users, first with Carlos.
425
426- >>> print http(r"""
427- ... POST /firefox/+spec/canvas/+requestfeedback HTTP/1.1
428- ... Authorization: Basic Y2FybG9zQGNhbm9uaWNhbC5jb206dGVzdA==
429- ... Content-Type: multipart/form-data; boundary=---------------------------9563630295607919491334846818
430- ...
431- ... -----------------------------9563630295607919491334846818
432- ... Content-Disposition: form-data; name="field.reviewer"
433- ...
434- ... mark
435- ... -----------------------------9563630295607919491334846818
436- ... Content-Disposition: form-data; name="field.queuemsg"
437- ...
438- ... do we really want to maintain compatibility with windows?
439- ... -----------------------------9563630295607919491334846818
440- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
441- ...
442- ... Add
443- ... -----------------------------9563630295607919491334846818--
444- ... """)
445- HTTP/1.1 303 See Other
446- ...
447- Location: http://.../firefox/+spec/canvas
448- ...
449+ >>> carlos_browser = setupBrowser(auth='Basic carlos@canonical.com:test')
450+ >>> carlos_browser.open(
451+ ... 'http://blueprints.launchpad.dev/firefox/+spec/canvas/'
452+ ... '+requestfeedback')
453+ >>> carlos_browser.getControl(name="field.reviewer").value = "mark"
454+ >>> carlos_browser.getControl(
455+ ... name="field.queuemsg").value = "do we really want to maintain "
456+ ... "compatibility with windows?"
457+ >>> carlos_browser.getControl("Add").click()
458
459 And then with Foo Bar
460
461- >>> print http(r"""
462- ... POST /firefox/+spec/canvas/+requestfeedback HTTP/1.1
463- ... Authorization: Basic Zm9vLmJhckBjYW5vbmljYWwuY29tOnRlc3Q=
464- ... Content-Length: 458
465- ... Content-Type: multipart/form-data; boundary=---------------------------3460313531928717451553877484
466- ...
467- ... -----------------------------3460313531928717451553877484
468- ... Content-Disposition: form-data; name="field.reviewer"
469- ...
470- ... mark
471- ... -----------------------------3460313531928717451553877484
472- ... Content-Disposition: form-data; name="field.queuemsg"
473- ...
474- ... please check my grammer and speling
475- ... -----------------------------3460313531928717451553877484
476- ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
477- ...
478- ... Add
479- ... -----------------------------3460313531928717451553877484--
480- ... """)
481- HTTP/1.1 303 See Other
482- ...
483- Location: http://.../firefox/+spec/canvas
484- ...
485+ >>> admin_browser.open(
486+ ... 'http://blueprints.launchpad.dev/firefox/+spec/canvas/'
487+ ... '+requestfeedback')
488+ >>> admin_browser.getControl(name="field.reviewer").value = "mark"
489+ >>> admin_browser.getControl(
490+ ... name="field.queuemsg").value = "please check my grammer and "
491+ ... "speling"
492+ >>> admin_browser.getControl("Add").click()
493
494-Now, let's go and clear a review request. Sabdfl has been asked to review spec
495+Now, let's go and clear a review request. Mark has been asked to review spec
496 "canvas". Let's view the page, and tell it that we have completed the review.
497 First, on the spec home page we see an alert reminding us that we have been
498 asked to review this page in particular.
499
500- >>> print http(r"""
501- ... GET /firefox/+spec/canvas HTTP/1.1
502- ... Authorization: Basic mark@example.com:test
503- ... """)
504- HTTP/1.1 200 Ok
505- ...You have 3 feedback request(s)...
506+ >>> mark_browser = setupBrowser(auth='Basic mark@example.com:test')
507+ >>> mark_browser.open(
508+ ... 'http://blueprints.launchpad.dev/firefox/+spec/canvas/')
509+ >>> print extract_text(find_main_content(mark_browser.contents))
510+ Registered by
511+ ...
512+ You have 3 feedback request(s)...
513
514 We also see our name in the "feedback requests" portlet.
515
516- >>> print http(r"""
517- ... GET /firefox/+spec/canvas HTTP/1.1
518- ... """)
519- HTTP/1.1 200 Ok
520- ...Feedback requests...
521- ...Mark Shuttleworth...
522+ >>> print extract_text(
523+ ... find_portlet(mark_browser.contents, 'Feedback requests'))
524+ Feedback requests
525+ ...
526+ Mark Shuttleworth:
527+ ...
528
529 And we see the "Give Feedback" menu item.
530
531- >>> print http(r"""
532- ... GET /firefox/+spec/canvas HTTP/1.1
533- ... Authorization: Basic mark@example.com:test
534- ... """)
535- HTTP/1.1 200 Ok
536- ...Give feedback...
537+ >>> give_feedback = mark_browser.getLink("Give feedback")
538
539 Let's load the "+givefeedback" page, to tell the system that our work is
540 complete. Note that the form posts back to the main spec home page.
541
542- >>> print http(r"""
543- ... GET /firefox/+spec/canvas/+givefeedback HTTP/1.1
544- ... Authorization: Basic mark@example.com:test
545- ... """)
546- HTTP/1.1 200 Ok
547- ...
548+ >>> give_feedback.click()
549+ >>> print mark_browser.url
550+ http://blueprints.launchpad.dev/firefox/+spec/canvas/+givefeedback
551
552 Now we POST this page back to itself. First, we clear a single item.
553
554- >>> print http(r"""
555- ... POST /firefox/+spec/canvas/+givefeedback HTTP/1.1
556- ... Authorization: Basic mark@example.com:test
557- ... Content-Length: 43
558- ... Content-Type: application/x-www-form-urlencoded
559- ...
560- ... feedbackrequest=carlos&FORM_SUBMIT=Continue""")
561- HTTP/1.1 200 Ok
562- ...Cleared requests from: Carlos Perelló Marín...
563+ >>> mark_browser.getControl("Carlos Perelló Marín").selected = True
564+ >>> mark_browser.getControl("Continue").click()
565+ >>> print mark_browser.url
566+ http://blueprints.launchpad.dev/firefox/+spec/canvas/+givefeedback
567
568+ >>> print extract_text(find_main_content(mark_browser.contents))
569+ Give feedback on this blueprint
570+ ...
571+ Cleared requests from: Carlos Perelló Marín
572+ ...
573
574 And now, the remaining two. This time we expect to be redirected.
575
576- >>> print http(r"""
577- ... POST /firefox/+spec/canvas/+givefeedback HTTP/1.1
578- ... Authorization: Basic mark@example.com:test
579- ... Content-Length: 66
580- ... Content-Type: application/x-www-form-urlencoded
581- ...
582- ... feedbackrequest=name12&feedbackrequest=name16&FORM_SUBMIT=Continue""")
583- HTTP/1.1 303 See Other
584- ...
585- Location: http://.../firefox/+spec/canvas
586- ...
587+ >>> mark_browser.getControl("Sample Person").selected = True
588+ >>> mark_browser.getControl("Foo Bar").selected = True
589+ >>> mark_browser.getControl("Continue").click()
590+
591+ >>> print mark_browser.url
592+ http://blueprints.launchpad.dev/firefox/+spec/canvas
593
594
595
596=== added directory 'lib/lp/blueprints/stories/standalone'
597=== renamed file 'lib/lp/blueprints/stories/blueprints/sprint-links.txt' => 'lib/lp/blueprints/stories/standalone/sprint-links.txt'
598=== renamed file 'lib/lp/blueprints/stories/blueprints/subscribing.txt' => 'lib/lp/blueprints/stories/standalone/subscribing.txt'
599--- lib/lp/blueprints/stories/blueprints/subscribing.txt 2009-05-12 21:52:56 +0000
600+++ lib/lp/blueprints/stories/standalone/subscribing.txt 2009-09-22 10:48:09 +0000
601@@ -25,6 +25,9 @@
602
603 >>> browser.addHeader('Authorization', 'Basic carlos@canonical.com:test')
604 >>> browser.open("http://blueprints.launchpad.dev/firefox/+spec/e4x/+subscribe")
605+ >>> print browser.title
606+ Subscribe to blueprint : Support E4X in EcmaScript :
607+ Blueprints for Mozilla Firefox : Mozilla Firefox
608
609 The page links back to the blueprint page, in case we change our minds.
610
611@@ -32,6 +35,7 @@
612 >>> back_link.url
613 'http://blueprints.launchpad.dev/firefox/+spec/e4x'
614
615+
616 There should be a control to set whether or not participation in discussions
617 of this feature is essential. We will say we want to be essential to this
618 feature planning:
619@@ -60,6 +64,10 @@
620 link to modify the subscription. It should currently be checked.
621
622 >>> submod_link.click()
623+ >>> print browser.title
624+ Modify subscription : Support E4X in EcmaScript :
625+ Blueprints for Mozilla Firefox : Mozilla Firefox
626+
627 >>> essential = browser.getControl('essential')
628 >>> essential.selected
629 True
630
631=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-batching.txt' => 'lib/lp/blueprints/stories/standalone/xx-batching.txt'
632=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-branch-links.txt' => 'lib/lp/blueprints/stories/standalone/xx-branch-links.txt'
633=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-index.txt' => 'lib/lp/blueprints/stories/standalone/xx-index.txt'
634=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-informational-blueprints.txt' => 'lib/lp/blueprints/stories/standalone/xx-informational-blueprints.txt'
635=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-overview.txt' => 'lib/lp/blueprints/stories/standalone/xx-overview.txt'
636=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-personviews.txt' => 'lib/lp/blueprints/stories/standalone/xx-personviews.txt'
637=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-retargeting.txt' => 'lib/lp/blueprints/stories/standalone/xx-retargeting.txt'
638=== renamed file 'lib/lp/blueprints/stories/blueprints/xx-views.txt' => 'lib/lp/blueprints/stories/standalone/xx-views.txt'
639=== modified file 'lib/lp/blueprints/templates/specification-deptree.pt'
640--- lib/lp/blueprints/templates/specification-deptree.pt 2009-07-17 17:59:07 +0000
641+++ lib/lp/blueprints/templates/specification-deptree.pt 2009-09-22 11:35:39 +0000
642@@ -3,57 +3,49 @@
643 xmlns:tal="http://xml.zope.org/namespaces/tal"
644 xmlns:metal="http://xml.zope.org/namespaces/metal"
645 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
646- xml:lang="en"
647- lang="en"
648- dir="ltr"
649- metal:use-macro="context/@@main_template/master"
650+ metal:use-macro="view/macro:page/main_side"
651 i18n:domain="launchpad"
652 >
653
654 <body>
655
656-<metal:leftportlets fill-slot="portlets_one">
657+<div metal:fill-slot="side">
658 <div tal:replace="structure context/@@+portlet-blocked" />
659-</metal:leftportlets>
660-
661-<metal:rightportlets fill-slot="portlets_two">
662 <div tal:replace="structure context/@@+portlet-dependencies" />
663-</metal:rightportlets>
664+</div>
665
666 <div metal:fill-slot="main">
667
668- <div>
669- <img alt="" src="/@@/blueprint" />
670- <a tal:attributes="href context/fmt:url" tal:content="context/title" />
671- </div>
672-
673- <h1>Blueprint dependency tree</h1>
674-
675+ <div class="top-portlet">
676 <p>
677 This is the sequence in which blueprints related to this one must be
678 implemented.
679 </p>
680+ </div>
681
682+ <div class="portlet">
683 <h2>Blueprints that must be implemented first</h2>
684-
685 <div tal:repeat="spec context/all_deps"
686 tal:replace="structure spec/@@+listing-detailed" />
687 <p tal:condition="not: context/dependencies">
688 <i>None - this blueprint does not depend on any others.</i>
689 </p>
690+ </div>
691
692+ <div class="portlet">
693 <h2>This blueprint</h2>
694-
695 <div tal:replace="structure context/@@+listing-detailed" />
696+ </div>
697
698+ <div class="portlet">
699 <h2>Blueprints that can then be implemented</h2>
700-
701 <div tal:repeat="spec context/all_blocked"
702 tal:replace="structure spec/@@+listing-detailed" />
703 <p tal:condition="not: context/blocked_specs">
704 No blueprints depend on this one.
705 </p>
706-
707+ </div>
708+
709 </div>
710 </body>
711 </html>
712
713=== modified file 'lib/lp/blueprints/templates/specification-requestfeedback.pt'
714--- lib/lp/blueprints/templates/specification-requestfeedback.pt 2009-07-17 17:59:07 +0000
715+++ lib/lp/blueprints/templates/specification-requestfeedback.pt 2009-09-22 10:48:09 +0000
716@@ -3,24 +3,20 @@
717 xmlns:tal="http://xml.zope.org/namespaces/tal"
718 xmlns:metal="http://xml.zope.org/namespaces/metal"
719 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
720- xml:lang="en"
721- lang="en"
722- dir="ltr"
723- metal:use-macro="context/@@main_template/master"
724+ metal:use-macro="view/macro:page/main_side"
725 i18n:domain="launchpad"
726 >
727
728 <body>
729
730-<metal:leftportlets fill-slot="portlets_one">
731- <div tal:replace="structure context/@@+portlet-feedbackqueue" />
732-</metal:leftportlets>
733+<div metal:fill-slot="side">
734+ <div class="portlet"
735+ tal:content="structure context/@@+portlet-feedbackqueue" />
736+</div>
737
738 <div metal:fill-slot="main">
739
740- <div tal:content="structure context/fmt:link" />
741-
742- <div metal:use-macro="context/@@launchpad_addform/addform">
743+ <div metal:use-macro="context/@@launchpad_form/form">
744
745 <p metal:fill-slot="extra_info" class="documentDescription">
746 You can request feedback from a specific person,
747@@ -28,12 +24,6 @@
748 consider.
749 </p>
750
751- <tal:errors
752- metal:fill-slot="extra_top"
753- repeat="top_of_page_error view/top_of_page_errors"
754- replace="structure top_of_page_error"
755- />
756-
757 </div>
758
759 </div>
760
761=== modified file 'lib/lp/blueprints/templates/specification-subscription.pt'
762--- lib/lp/blueprints/templates/specification-subscription.pt 2009-07-17 17:59:07 +0000
763+++ lib/lp/blueprints/templates/specification-subscription.pt 2009-09-21 18:07:54 +0000
764@@ -3,49 +3,40 @@
765 xmlns:tal="http://xml.zope.org/namespaces/tal"
766 xmlns:metal="http://xml.zope.org/namespaces/metal"
767 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
768- xml:lang="en"
769- lang="en"
770- dir="ltr"
771- metal:use-macro="context/@@main_template/master"
772+ metal:use-macro="view/macro:page/main_side"
773 i18n:domain="launchpad"
774 >
775
776 <body>
777
778- <metal:portlets fill-slot="portlets">
779- <div tal:replace="structure context/@@+portlet-subscribers" />
780- </metal:portlets>
781+<div metal:fill-slot="side">
782+ <div tal:replace="structure context/@@+portlet-subscribers" />
783+</div>
784
785 <div metal:fill-slot="main">
786
787- <div tal:content="structure context/fmt:link" />
788-
789- <tal:subscribed condition="view/subscription">
790-
791- <h1>Modify subscription</h1>
792+ <div class="top-portlet" tal:condition="view/subscription">
793
794 <p>
795 Choose &#8220;Unsubscribe&#8221; to remove your subscription to this
796 blueprint, or &#8220;Cancel&#8221; to return to the blueprint page.
797 </p>
798
799- </tal:subscribed>
800-
801- <tal:not_subscribed condition="not: view/subscription">
802-
803- <h1>Subscribe to blueprint</h1>
804+ </div>
805+
806+ <div class="top-portlet" tal:condition="not: view/subscription">
807
808 <p>
809 Choose &#8220;Subscribe&#8221; to subscribe to this blueprint,
810 or &#8220;Cancel&#8221; to return to the blueprint page.
811 </p>
812-
813- </tal:not_subscribed>
814+
815+ </div>
816
817 <form action="." method="POST">
818
819 <div class="field">
820-
821+
822 <tal:subscribed condition="view/subscription">
823 <input type="checkbox" id="essential" name="essential"
824 value="yes" checked="yes"
825@@ -69,9 +60,9 @@
826 this feature when you are attending sprints or meetings with this
827 feature on the agenda.
828 </p>
829-
830+
831 </div>
832-
833+
834 <div class="actions">
835 <input tal:condition="not: view/subscription"
836 type="submit"