Merge lp:~sinzui/launchpad/edit-question-bug-210312 into lp:launchpad

Proposed by Curtis Hovey
Status: Merged
Approved by: Aaron Bentley
Approved revision: not available
Merged at revision: not available
Proposed branch: lp:~sinzui/launchpad/edit-question-bug-210312
Merge into: lp:launchpad
Diff against target: 333 lines (+86/-60)
7 files modified
lib/lp/answers/browser/question.py (+11/-12)
lib/lp/answers/browser/tests/views.txt (+31/-12)
lib/lp/answers/interfaces/faq.py (+2/-2)
lib/lp/answers/interfaces/question.py (+1/-1)
lib/lp/answers/stories/question-subscriptions.txt (+24/-24)
lib/lp/answers/stories/this-is-a-faq.txt (+6/-2)
lib/lp/answers/templates/question-subscription.pt (+11/-7)
To merge this branch: bzr merge lp:~sinzui/launchpad/edit-question-bug-210312
Reviewer Review Type Date Requested Status
Aaron Bentley (community) Approve
Review via email: mp+15695@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (4.6 KiB)

This is my branch to fix some simple issues with Launchpad Answers.

    lp:~sinzui/launchpad/edit-question-bug-210312
    Diff size: 334
    Launchpad bug: https://bugs.launchpad.net/bugs/210312
                   https://bugs.launchpad.net/bugs/275475
                   https://bugs.launchpad.net/bugs/386158
    Test command: ./bin/test -vv \
        -t answers.*views.txt
        -t question-subscriptions
        -t this-is-a-faq
    Pre-implementation: no one
    Target release: 3.1.12

= Fix some simple issues with Launchpad Answers =

Bug 210312 [cannot edit the language of the question]
    The question +edit page only shows the user's preferred languages. It
    must show all languages so that the user can fix the language.

Bug 275475 [launchpad displays the hint for subscribing when i click on
    unsubscribe]
    The paragraph talks about subscribing, but the action is unsubscribing.

Bug 386158 [confusingly redundant fields in create faq page]
    There are two textareas, each of which seems to want the answer to the faq.

== Rules ==

Bug 210312 [cannot edit the language of the question]
    * Remove the QuestionSupportLanguageMixin and use the interface's
      language

Bug 275475 [launchpad displays the hint for subscribing when i click on
    unsubscribe]
    * Add a condition to the template to select the right paragraph to show.

Bug 386158 [confusingly redundant fields in create faq page]
    * Revise the field labels and hints to distinguish between the FAQ and
      the question the user is answering.

== QA ==

Bug 210312 [cannot edit the language of the question]
    * Edit a question on edge.
    * Verify the language choice contains every language registered in
      Launchpad.

Bug 275475 [launchpad displays the hint for subscribing when i click on
    unsubscribe]
    * Choose the subscribe link on a a question.
    * Verify the link to your subscriptions page actually goes to your
      subscription page.
    * Choose the Subscribe button
    * Choose the Unsubscribe link
    * Verify that the paragraph talks about the consequence of unsubscribing.

Bug 386158 [confusingly redundant fields in create faq page]
    * Choose create a new FAQ link from any question.
    * Verify the FAQ field speak of "this FAQ".
    * Verify the last field labeled "Additional comment for question #..."

== Lint ==

Linting changed files:
  lib/lp/answers/browser/question.py
  lib/lp/answers/browser/tests/views.txt
  lib/lp/answers/interfaces/faq.py
  lib/lp/answers/interfaces/question.py
  lib/lp/answers/stories/question-subscriptions.txt
  lib/lp/answers/stories/this-is-a-faq.txt
  lib/lp/answers/templates/question-subscription.pt

== Test ==

    * lib/lp/answers/browser/tests/views.txt
      * Modernised part of the test--they predated LaunchpadFormView
      * Added label and page_title tests to verify that sane fragments
        for subscribe/unsubscribe were created for the automated rules.
      * Verified that the QuestionEdit form uses the LanguageVocabulary.
    * lib/lp/answers/stories/question-subscriptions.txt
      * Removed some cruft from the story.
      * Revised the story to verify the links in the subscr...

Read more...

Revision history for this message
Aaron Bentley (abentley) wrote :

Looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/answers/browser/question.py'
2--- lib/lp/answers/browser/question.py 2009-11-11 22:17:17 +0000
3+++ lib/lp/answers/browser/question.py 2009-12-05 17:20:55 +0000
4@@ -46,6 +46,7 @@
5
6 from lazr.lifecycle.event import ObjectModifiedEvent
7 from lazr.lifecycle.snapshot import Snapshot
8+from lazr.restful.interface import copy_field
9
10 from canonical.cachedproperty import cachedproperty
11 from canonical.launchpad import _
12@@ -321,7 +322,7 @@
13
14 @property
15 def page_title(self):
16- return 'Subscription to question #%s' % self.context.id
17+ return 'Subscription'
18
19 @property
20 def label(self):
21@@ -452,8 +453,7 @@
22 "The language in which this question is written. "
23 "The languages marked with a star (*) are the "
24 "languages spoken by at least one answer contact in "
25- "the community."
26- )),
27+ "the community.")),
28 render_context=self.render_context)
29
30 def shouldWarnAboutUnsupportedLanguage(self):
31@@ -659,11 +659,12 @@
32 cancel_url = next_url
33
34
35-class QuestionEditView(QuestionSupportLanguageMixin, LaunchpadEditFormView):
36+class QuestionEditView(LaunchpadEditFormView):
37 """View for editing a Question."""
38 schema = IQuestion
39 label = 'Edit question'
40- field_names = ["title", "description", "target", "assignee", "whiteboard"]
41+ field_names = [
42+ "language", "title", "description", "target", "assignee", "whiteboard"]
43
44 custom_widget('title', TextWidget, displayWidth=40)
45 custom_widget('whiteboard', TextAreaWidget, height=5)
46@@ -685,10 +686,6 @@
47 self.form_fields = self.form_fields.omit("distribution",
48 "sourcepackagename", "product")
49
50- # Add the language field with a vocabulary specialized for display
51- # purpose.
52- self.form_fields = self.createLanguageField() + self.form_fields
53-
54 editable_fields = []
55 for field in self.form_fields:
56 if zope.security.canWrite(self.context, field.__name__):
57@@ -764,7 +761,6 @@
58 return '%s suggests this article as an answer to your question:' % (
59 self.user.displayname)
60
61-
62 def getFAQMessageReference(self, faq):
63 """Return the reference for the FAQ to use in the linking message."""
64 return smartquote('FAQ #%s: "%s".' % (faq.id, faq.title))
65@@ -991,7 +987,7 @@
66 def original_bug(self):
67 """Return the bug that the question was created from or None."""
68 for buglink in self.context.bug_links:
69- if (check_permission('launchpad.View', buglink.bug)
70+ if (check_permission('launchpad.View', buglink.bug)
71 and buglink.bug.owner == self.context.owner
72 and buglink.bug.datecreated == self.context.datecreated):
73 return buglink.bug
74@@ -1140,7 +1136,10 @@
75 Adds a message field to the form.
76 """
77 super(QuestionCreateFAQView, self).setUpFields()
78- self.form_fields += form.Fields(IQuestionLinkFAQForm['message'])
79+ self.form_fields += form.Fields(
80+ copy_field(IQuestionLinkFAQForm['message']))
81+ self.form_fields['message'].field.title = _(
82+ 'Additional comment for question #%s' % self.context.id)
83 self.form_fields['message'].custom_widget = (
84 self.custom_widgets['message'])
85
86
87=== modified file 'lib/lp/answers/browser/tests/views.txt'
88--- lib/lp/answers/browser/tests/views.txt 2009-09-28 09:11:17 +0000
89+++ lib/lp/answers/browser/tests/views.txt 2009-12-05 17:20:55 +0000
90@@ -38,34 +38,46 @@
91 This view is used to subscribe and unsubscribe from a question.
92 Subscription is done when the user click on the 'Subscribe' button.
93
94- >>> request = LaunchpadTestRequest(form={'subscribe': 'Subscribe'})
95- >>> request.method = 'POST'
96- >>> view = getMultiAdapter((question_three, request), name='+subscribe')
97- >>> view.initialize()
98+ >>> view = create_initialized_view(question_three, name='+subscribe')
99+ >>> print view.label
100+ Subscribe to question
101+
102+ >>> print view.page_title
103+ Subscription
104+
105+ >>> form = {'subscribe': 'Subscribe'}
106+ >>> view = create_initialized_view(
107+ ... question_three, name='+subscribe', form=form)
108 >>> question_three.isSubscribed(getUtility(ILaunchBag).user)
109 True
110
111 A notification message is displayed and the view redirect to the question
112 view page.
113
114- >>> for notice in request.notifications:
115+ >>> for notice in view.request.notifications:
116 ... print notice.message
117 You have subscribed to this question.
118- >>> request.response.getHeader('Location')
119+
120+ >>> view.request.response.getHeader('Location')
121 '.../+question/3'
122
123 Unsubscription works in a similar manner.
124
125- >>> request = LaunchpadTestRequest(form={'subscribe': 'Unsubscribe'})
126- >>> request.method = 'POST'
127- >>> view = getMultiAdapter((question_three, request), name='+subscribe')
128- >>> view.initialize()
129+ >>> view = create_initialized_view(question_three, name='+subscribe')
130+ >>> print view.label
131+ Unsubscribe from question
132+
133+ >>> form = {'subscribe': 'Unsubscribe'}
134+ >>> view = create_initialized_view(
135+ ... question_three, name='+subscribe', form=form)
136 >>> question_three.isSubscribed(getUtility(ILaunchBag).user)
137 False
138- >>> for notice in request.notifications:
139+
140+ >>> for notice in view.request.notifications:
141 ... print notice.message
142 You have unsubscribed from this question.
143- >>> request.response.getHeader('Location')
144+
145+ >>> view.request.response.getHeader('Location')
146 '.../+question/3'
147
148 These two actions didn't generate any notification mails:
149@@ -503,6 +515,13 @@
150 >>> print question_three.whiteboard
151 Some note
152
153+The question language can be set to any language registered with
154+Launchpad--it is not restricted to the user's preferred languages.
155+
156+ >>> view = create_initialized_view(question_three, name='+edit')
157+ >>> view.widgets['language'].vocabulary
158+ <canonical.launchpad.vocabularies.dbobjects.LanguageVocabulary ...>
159+
160 In a similar manner, the sourcepackagename field can only be updated on
161 a distribution question:
162
163
164=== modified file 'lib/lp/answers/interfaces/faq.py'
165--- lib/lp/answers/interfaces/faq.py 2009-07-17 00:26:05 +0000
166+++ lib/lp/answers/interfaces/faq.py 2009-12-05 17:20:55 +0000
167@@ -38,7 +38,7 @@
168
169 title = Title(
170 title=_('Title'),
171- description=_('The title describing the FAQ, often a question.'),
172+ description=_('The title describing this FAQ, often a question.'),
173 required=True)
174
175 keywords = TextLine(
176@@ -49,7 +49,7 @@
177 content = Text(
178 title=_('Content'),
179 description=_(
180- 'The answer to the question in plain text. You may choose to '
181+ 'The answer for this FAQ in plain text. You may choose to '
182 'include a URL to an external FAQ.'),
183 required=True)
184
185
186=== modified file 'lib/lp/answers/interfaces/question.py'
187--- lib/lp/answers/interfaces/question.py 2009-07-17 00:26:05 +0000
188+++ lib/lp/answers/interfaces/question.py 2009-12-05 17:20:55 +0000
189@@ -486,7 +486,7 @@
190 message = Text(
191 title=_('Answer Message'),
192 description=_(
193- 'Enter a message that will be added as the question answer. '
194+ 'Enter a comment that will be added as the question comments. '
195 'The title of the FAQ will be automatically appended to this '
196 'message.'),
197 required=True)
198
199=== modified file 'lib/lp/answers/stories/question-subscriptions.txt'
200--- lib/lp/answers/stories/question-subscriptions.txt 2009-09-25 08:39:54 +0000
201+++ lib/lp/answers/stories/question-subscriptions.txt 2009-12-05 17:20:55 +0000
202@@ -7,16 +7,18 @@
203 == Subscribing ==
204
205 To subscribe, users use the 'Subscribe' link and then confirm that
206-they want to subscribe by clicking on the 'Subscribe' button.
207+they want to subscribe by clicking on the 'Subscribe' button. The user
208+sees a link to his subscribed questions.
209
210 >>> user_browser.open(
211 ... 'http://launchpad.dev/firefox/+question/2')
212- >>> link = user_browser.getLink('Subscribe')
213- >>> link.url
214- '.../+question/2/+subscribe'
215- >>> link.click()
216+ >>> user_browser.getLink('Subscribe').click()
217 >>> print user_browser.title
218- Subscription to question...
219+ Subscription : Question #2 ...
220+
221+ >>> print user_browser.getLink('your subscribed questions page')
222+ <Link ...'http://answers.launchpad.dev/~no-priv/+subscribedquestions'>
223+
224 >>> user_browser.getControl('Subscribe').click()
225
226 A message confirming that he was subscribed is displayed and the user
227@@ -26,11 +28,10 @@
228 ... print message
229 You have subscribed to this question.
230
231- >>> portlet = find_tag_by_id(user_browser.contents, 'subscribers')
232- >>> portlet.first('h2')
233- <h2>Subscribers</h2>
234- >>> portlet.first('ul')
235- <ul> ...No Privileges Person...
236+ >>> print extract_text(find_tag_by_id(
237+ ... user_browser.contents, 'subscribers'))
238+ Subscribers
239+ No Privileges Person
240
241
242 == Unsubscribing ==
243@@ -39,14 +40,14 @@
244 becomes an 'Unsubscribe' link. To unsubscribe, the user follows that
245 link and then click on the 'Unsubscribe' button.
246
247- >>> link = user_browser.getLink('Unsubscribe')
248- >>> link.url
249- '.../+question/2/+subscribe'
250- >>> link.click()
251-
252- >>> soup = find_main_content(user_browser.contents)
253- >>> soup.first('h1')
254- <h1>Unsubscribe from question</h1>
255+ >>> link = user_browser.getLink('Unsubscribe').click()
256+ >>> print user_browser.title
257+ Subscription : Question #2 ...
258+
259+ >>> print extract_text(
260+ ... find_tag_by_id(user_browser.contents, 'unsubscribe'))
261+ Unsubscribing from this question ...
262+
263 >>> user_browser.getControl('Unsubscribe').click()
264
265 A confirmation is displayed and the user, which was unsubscribed from
266@@ -56,11 +57,10 @@
267 ... print message
268 You have unsubscribed from this question.
269
270- >>> portlet = find_tag_by_id(user_browser.contents, 'subscribers')
271- >>> portlet.first('p')
272- <p>
273- <i>No subscribers.</i>
274- </p>
275+ >>> print extract_text(find_tag_by_id(
276+ ... user_browser.contents, 'subscribers'))
277+ Subscribers
278+ No subscribers.
279
280
281 == Subscribing While Posting A Message ==
282
283=== modified file 'lib/lp/answers/stories/this-is-a-faq.txt'
284--- lib/lp/answers/stories/this-is-a-faq.txt 2009-11-14 16:30:47 +0000
285+++ lib/lp/answers/stories/this-is-a-faq.txt 2009-12-05 17:20:55 +0000
286@@ -244,9 +244,13 @@
287 There is a 'Message' field that will be used to answer the question.
288 It is pre-filled, but he can change its value:
289
290- >>> print owner_browser.getControl('Message').value
291+ >>> print owner_browser.getControl(
292+ ... 'Additional comment for question #2').value
293 Sample Person suggests this article as an answer to your question:
294- >>> owner_browser.getControl('Message').value = 'Read the Fine Answer:'
295+
296+ >>> owner_browser.getControl(
297+ ... 'Additional comment for question #2').value = (
298+ ... 'Read the Fine Answer:')
299
300 After clicking the 'Create' button, the FAQ is created and the user is
301 returned to the question page.
302
303=== modified file 'lib/lp/answers/templates/question-subscription.pt'
304--- lib/lp/answers/templates/question-subscription.pt 2009-08-12 19:54:50 +0000
305+++ lib/lp/answers/templates/question-subscription.pt 2009-12-05 17:20:55 +0000
306@@ -9,16 +9,20 @@
307
308 <body>
309
310-<tal:heading metal:fill-slot="heading">
311- <h1 tal:content="view/label">Subscribe to question</h1>
312-</tal:heading>
313-
314 <div metal:fill-slot="main">
315
316- <p>
317+ <p id="subscribe"
318+ tal:condition="not: view/subscription">
319 Subscribing to a question makes it show up on
320- <a tal:attributes="href string:/~${request/lp:person/name}/+questions"
321- >your Answers page</a>.
322+ <a tal:attributes="href view/user/menu:navigation/subscribed/fmt:url"
323+ >your subscribed questions page</a>. You will receive email notifications
324+ about updates to this question.
325+ </p>
326+
327+ <p id="unsubscribe"
328+ tal:condition="view/subscription">
329+ Unsubscribing from this question will stop email notifications
330+ about updates to this question.
331 </p>
332
333 <form action="."