Merge lp:~benji/launchpad/bug-784575-message-db-devel into lp:launchpad/db-devel
- bug-784575-message-db-devel
- Merge into db-devel
Proposed by
Benji York
Status: | Merged |
---|---|
Approved by: | Benji York |
Approved revision: | no longer in the source branch. |
Merged at revision: | 10611 |
Proposed branch: | lp:~benji/launchpad/bug-784575-message-db-devel |
Merge into: | lp:launchpad/db-devel |
Diff against target: |
1073 lines (+344/-362) 7 files modified
lib/lp/bugs/doc/bugnotification-sending.txt (+17/-80) lib/lp/bugs/emailtemplates/bug-notification-verbose.txt (+1/-1) lib/lp/bugs/emailtemplates/bug-notification.txt (+1/-1) lib/lp/bugs/scripts/bugnotification.py (+12/-10) lib/lp/bugs/scripts/tests/test_bugnotification.py (+52/-12) lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt (+247/-251) lib/lp/bugs/stories/xx-bugs-statistics-portlet.txt (+14/-7) |
To merge this branch: | bzr merge lp:~benji/launchpad/bug-784575-message-db-devel |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Benji York (community) | Approve | ||
Review via email: mp+62672@code.launchpad.net |
Commit message
[r=benji][bug=784575] add a pointer to the subscription management UI to emailed bug notifications
Description of the change
This MP is just to retarget https:/
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/bugs/doc/bugnotification-sending.txt' |
2 | --- lib/lp/bugs/doc/bugnotification-sending.txt 2011-05-18 13:00:11 +0000 |
3 | +++ lib/lp/bugs/doc/bugnotification-sending.txt 2011-05-27 13:35:12 +0000 |
4 | @@ -76,12 +76,6 @@ |
5 | a comment. |
6 | <BLANKLINE> |
7 | ... |
8 | - You received this bug notification because you are subscribed to |
9 | - mozilla-firefox in Ubuntu. |
10 | - http://bugs.launchpad.dev/bugs/1 |
11 | - <BLANKLINE> |
12 | - Title: |
13 | - Firefox does not support SVG |
14 | ---------------------------------------------------------------------- |
15 | To: mark@example.com |
16 | From: Sample Person <1@bugs.launchpad.net> |
17 | @@ -91,11 +85,6 @@ |
18 | a comment. |
19 | <BLANKLINE> |
20 | ... |
21 | - You received this bug notification because you are a bug assignee. |
22 | - http://bugs.launchpad.dev/bugs/1 |
23 | - <BLANKLINE> |
24 | - Title: |
25 | - Firefox does not support SVG |
26 | ---------------------------------------------------------------------- |
27 | To: support@ubuntu.com |
28 | From: Sample Person <1@bugs.launchpad.net> |
29 | @@ -104,13 +93,7 @@ |
30 | <BLANKLINE> |
31 | a comment. |
32 | <BLANKLINE> |
33 | - -- |
34 | - You received this bug notification because you are a member of Ubuntu |
35 | - Team, which is the registrant for Ubuntu. |
36 | - http://bugs.launchpad.dev/bugs/1 |
37 | - <BLANKLINE> |
38 | - Title: |
39 | - Firefox does not support SVG |
40 | + ... |
41 | ---------------------------------------------------------------------- |
42 | To: test@canonical.com |
43 | From: Sample Person <1@bugs.launchpad.net> |
44 | @@ -120,14 +103,6 @@ |
45 | a comment. |
46 | <BLANKLINE> |
47 | ... |
48 | - You received this bug notification because you are a direct subscriber |
49 | - of the bug. |
50 | - http://bugs.launchpad.dev/bugs/1 |
51 | - <BLANKLINE> |
52 | - Title: |
53 | - Firefox does not support SVG |
54 | - <BLANKLINE> |
55 | - ... |
56 | ---------------------------------------------------------------------- |
57 | |
58 | You can see that the message above contains the bug's initial comment's |
59 | @@ -192,13 +167,7 @@ |
60 | <BLANKLINE> |
61 | a new comment. |
62 | <BLANKLINE> |
63 | - -- |
64 | - You received this bug notification because you are a member of Ubuntu |
65 | - Team, which is the registrant for Ubuntu. |
66 | - http://bugs.launchpad.dev/bugs/1 |
67 | - <BLANKLINE> |
68 | - Title: |
69 | - Firefox does not support SVG |
70 | + ... |
71 | ---------------------------------------------------------------------- |
72 | To: test@canonical.com |
73 | ... |
74 | @@ -242,13 +211,8 @@ |
75 | <BLANKLINE> |
76 | ** Visibility changed to: Private |
77 | <BLANKLINE> |
78 | + -- |
79 | ... |
80 | - You received this bug notification because you are a member of Ubuntu |
81 | - Team, which is the registrant for Ubuntu. |
82 | - http://bugs.launchpad.dev/bugs/1 |
83 | - <BLANKLINE> |
84 | - Title: |
85 | - Firefox does not support SVG |
86 | ---------------------------------------------------------------------- |
87 | To: test@canonical.com |
88 | ... |
89 | @@ -300,12 +264,7 @@ |
90 | + Another summary |
91 | <BLANKLINE> |
92 | -- |
93 | - You received this bug notification because you are a member of Ubuntu |
94 | - Team, which is the registrant for Ubuntu. |
95 | - http://bugs.launchpad.dev/bugs/1 |
96 | - <BLANKLINE> |
97 | - Title: |
98 | - Firefox does not support SVG |
99 | + ... |
100 | ---------------------------------------------------------------------- |
101 | To: test@canonical.com |
102 | ... |
103 | @@ -445,16 +404,7 @@ |
104 | <BLANKLINE> |
105 | *** This bug is a duplicate of bug 1 *** |
106 | http://bugs.launchpad.dev/bugs/1 |
107 | - <BLANKLINE> |
108 | - a comment. |
109 | - <BLANKLINE> |
110 | - -- |
111 | - You received this bug notification because you are a member of Ubuntu |
112 | - Team, which is the registrant for Ubuntu. |
113 | - http://bugs.launchpad.dev/bugs/16 |
114 | - <BLANKLINE> |
115 | - Title: |
116 | - new bug |
117 | + ... |
118 | ---------------------------------------------------------------------- |
119 | To: test@canonical.com |
120 | From: Sample Person <16@bugs.launchpad.net> |
121 | @@ -463,19 +413,7 @@ |
122 | <BLANKLINE> |
123 | *** This bug is a duplicate of bug 1 *** |
124 | http://bugs.launchpad.dev/bugs/1 |
125 | - <BLANKLINE> |
126 | - a comment. |
127 | - <BLANKLINE> |
128 | - -- |
129 | - You received this bug notification because you are a direct subscriber |
130 | - of the bug. |
131 | - http://bugs.launchpad.dev/bugs/16 |
132 | - <BLANKLINE> |
133 | - Title: |
134 | - new bug |
135 | - <BLANKLINE> |
136 | - To unsubscribe from this bug, go to: |
137 | - http://bugs.launchpad.dev/ubuntu/+bug/16/+subscribe |
138 | + ... |
139 | ---------------------------------------------------------------------- |
140 | |
141 | >>> flush_notifications() |
142 | @@ -585,7 +523,8 @@ |
143 | ... ten_minutes_ago, sample_person, "title", |
144 | ... True, False)) |
145 | |
146 | - >>> notifications = getUtility(IBugNotificationSet).getNotificationsToSend() |
147 | + >>> notifications = getUtility( |
148 | + ... IBugNotificationSet).getNotificationsToSend() |
149 | >>> len(notifications) |
150 | 8 |
151 | |
152 | @@ -660,12 +599,7 @@ |
153 | <BLANKLINE> |
154 | -- = |
155 | <BLANKLINE> |
156 | - You received this bug notification because you are subscribed to |
157 | - mozilla-firefox in Ubuntu. |
158 | - http://bugs.launchpad.dev/bugs/1 |
159 | - <BLANKLINE> |
160 | - Title: |
161 | - Firefox does not support SVG |
162 | + You received this bug notification because... |
163 | INFO Notifying mark@example.com about bug 1. |
164 | ... |
165 | INFO Notifying owner@example.com about bug 1. |
166 | @@ -1051,7 +985,7 @@ |
167 | >>> print_notification(collated_messages['concise@example.com'][0]) |
168 | To: concise@example.com |
169 | ... |
170 | - To unsubscribe from this bug, go to:... |
171 | + To manage notifications about this bug go to:... |
172 | |
173 | Verbose Team Person gets a concise email, even though they belong to a team |
174 | that gets verbose email. |
175 | @@ -1099,8 +1033,8 @@ |
176 | will be automatically wrapped by the BugNotification |
177 | machinery. Ain't technology great? |
178 | <BLANKLINE> |
179 | - To unsubscribe from this bug, go to: |
180 | - http://bugs.launchpad.dev/.../+bug/.../+subscribe |
181 | + To manage notifications about this bug go to: |
182 | + http://bugs.launchpad.dev/.../+bug/.../+subscriptions |
183 | ---------------------------------------------------------------------- |
184 | |
185 | And Concise Team Person does too, even though his team doesn't want them: |
186 | @@ -1128,6 +1062,9 @@ |
187 | This is a long description of the bug, which |
188 | will be automatically wrapped by the BugNotification |
189 | machinery. Ain't technology great? |
190 | + <BLANKLINE> |
191 | + To manage notifications about this bug go to: |
192 | + http://bugs.launchpad.dev/.../+bug/.../+subscriptions |
193 | ---------------------------------------------------------------------- |
194 | |
195 | It's important to note that the bug title and description are wrapped |
196 | @@ -1143,7 +1080,7 @@ |
197 | ... |
198 | 'Bug description:', |
199 | ' This is a long description of the bug, which will be automatically', |
200 | - " wrapped by the BugNotification machinery. Ain't technology great?"] |
201 | + " wrapped by the BugNotification machinery. Ain't technology great?"...] |
202 | |
203 | The title is also wrapped and indented in normal notifications. |
204 | |
205 | @@ -1153,7 +1090,7 @@ |
206 | [... |
207 | 'Title:', |
208 | ' In the beginning, the universe was created. This has made a lot of', |
209 | - ' people very angry and has been widely regarded as a bad move'] |
210 | + ' people very angry and has been widely regarded as a bad move'...] |
211 | |
212 | Self-Generated Bug Notifications |
213 | -------------------------------- |
214 | |
215 | === modified file 'lib/lp/bugs/emailtemplates/bug-notification-verbose.txt' |
216 | --- lib/lp/bugs/emailtemplates/bug-notification-verbose.txt 2011-03-02 16:22:36 +0000 |
217 | +++ lib/lp/bugs/emailtemplates/bug-notification-verbose.txt 2011-05-27 13:35:12 +0000 |
218 | @@ -12,4 +12,4 @@ |
219 | Bug description: |
220 | %(bug_description)s |
221 | |
222 | -%(unsubscribe_notice)s |
223 | +%(subscriptions_message)s |
224 | |
225 | === modified file 'lib/lp/bugs/emailtemplates/bug-notification.txt' |
226 | --- lib/lp/bugs/emailtemplates/bug-notification.txt 2011-03-02 16:22:36 +0000 |
227 | +++ lib/lp/bugs/emailtemplates/bug-notification.txt 2011-05-27 13:35:12 +0000 |
228 | @@ -7,4 +7,4 @@ |
229 | Title: |
230 | %(bug_title)s |
231 | |
232 | -%(unsubscribe_notice)s |
233 | +%(subscriptions_message)s |
234 | |
235 | === modified file 'lib/lp/bugs/scripts/bugnotification.py' |
236 | --- lib/lp/bugs/scripts/bugnotification.py 2011-05-11 10:53:37 +0000 |
237 | +++ lib/lp/bugs/scripts/bugnotification.py 2011-05-27 13:35:12 +0000 |
238 | @@ -193,25 +193,27 @@ |
239 | data['filter descriptions']) |
240 | else: |
241 | filters_text = u"" |
242 | - # XXX deryck 2009-11-17 Bug #484319 |
243 | - # This should be refactored to add a link inside the |
244 | - # code where we build `reason`. However, this will |
245 | - # require some extra work, and this small change now |
246 | - # will ease pain for a lot of unhappy users. |
247 | - if 'direct subscriber' in reason and 'member of' not in reason: |
248 | - unsubscribe_notice = ('To unsubscribe from this bug, go to:\n' |
249 | - '%s/+subscribe' % canonical_url(bug.bugtasks[0])) |
250 | + |
251 | + # In the rare case of a bug with no bugtasks, we can't generate the |
252 | + # subscription management URL so just leave off the subscription |
253 | + # management message entirely. |
254 | + if len(bug.bugtasks): |
255 | + bug_url = canonical_url(bug.bugtasks[0]) |
256 | + notification_url = bug_url + '/+subscriptions' |
257 | + subscriptions_message = ( |
258 | + "To manage notifications about this bug go to:\n%s" |
259 | + % notification_url) |
260 | else: |
261 | - unsubscribe_notice = '' |
262 | + subscriptions_message = '' |
263 | |
264 | data_wrapper = MailWrapper(width=72, indent=' ') |
265 | body_data = { |
266 | 'content': mail_wrapper.format(content), |
267 | 'bug_title': data_wrapper.format(bug.title), |
268 | 'bug_url': canonical_url(bug), |
269 | - 'unsubscribe_notice': unsubscribe_notice, |
270 | 'notification_rationale': mail_wrapper.format(reason), |
271 | 'subscription_filters': filters_text, |
272 | + 'subscriptions_message': subscriptions_message, |
273 | } |
274 | |
275 | # If the person we're sending to receives verbose notifications |
276 | |
277 | === modified file 'lib/lp/bugs/scripts/tests/test_bugnotification.py' |
278 | --- lib/lp/bugs/scripts/tests/test_bugnotification.py 2011-05-19 13:13:17 +0000 |
279 | +++ lib/lp/bugs/scripts/tests/test_bugnotification.py 2011-05-27 13:35:12 +0000 |
280 | @@ -5,6 +5,7 @@ |
281 | __metaclass__ = type |
282 | |
283 | from datetime import datetime, timedelta |
284 | +import re |
285 | import unittest |
286 | |
287 | import pytz |
288 | @@ -20,7 +21,10 @@ |
289 | sqlvalues, |
290 | ) |
291 | from canonical.launchpad.ftests import login |
292 | -from canonical.launchpad.helpers import get_contact_email_addresses |
293 | +from canonical.launchpad.helpers import ( |
294 | + get_contact_email_addresses, |
295 | + get_email_template, |
296 | + ) |
297 | from canonical.launchpad.interfaces.lpstorm import IStore |
298 | from lp.services.messages.interfaces.message import IMessageSet |
299 | from canonical.testing.layers import LaunchpadZopelessLayer |
300 | @@ -930,7 +934,7 @@ |
301 | |
302 | def setUp(self): |
303 | super(TestEmailNotificationsWithFilters, self).setUp() |
304 | - self.bug=self.factory.makeBug() |
305 | + self.bug = self.factory.makeBug() |
306 | subscriber = self.factory.makePerson() |
307 | self.subscription = self.bug.default_bugtask.target.addSubscription( |
308 | subscriber, subscriber) |
309 | @@ -1105,6 +1109,14 @@ |
310 | self.getSubscriptionEmailHeaders()) |
311 | |
312 | |
313 | +def fetch_notifications(subscriber, bug): |
314 | + return IStore(BugNotification).find( |
315 | + BugNotification, |
316 | + BugNotification.id == BugNotificationRecipient.bug_notificationID, |
317 | + BugNotificationRecipient.personID == subscriber.id, |
318 | + BugNotification.bug == bug) |
319 | + |
320 | + |
321 | class TestEmailNotificationsWithFiltersWhenBugCreated(TestCaseWithFactory): |
322 | # See bug 720147. |
323 | |
324 | @@ -1129,11 +1141,7 @@ |
325 | comment=message, owner=self.submitter, |
326 | status=BugTaskStatus.NEW) |
327 | bug = self.product.createBug(params) |
328 | - notification = IStore(BugNotification).find( |
329 | - BugNotification, |
330 | - BugNotification.id==BugNotificationRecipient.bug_notificationID, |
331 | - BugNotificationRecipient.personID == self.subscriber.id, |
332 | - BugNotification.bug == bug).one() |
333 | + notification = fetch_notifications(self.subscriber, bug).one() |
334 | self.assertEqual(notification.message.text_contents, message) |
335 | |
336 | def test_filters_do_not_match_when_bug_is_created(self): |
337 | @@ -1144,9 +1152,41 @@ |
338 | status=BugTaskStatus.TRIAGED, |
339 | importance=BugTaskImportance.HIGH) |
340 | bug = self.product.createBug(params) |
341 | - notifications = IStore(BugNotification).find( |
342 | - BugNotification, |
343 | - BugNotification.id==BugNotificationRecipient.bug_notificationID, |
344 | - BugNotificationRecipient.personID == self.subscriber.id, |
345 | - BugNotification.bug == bug) |
346 | + notifications = fetch_notifications(self.subscriber, bug) |
347 | self.assertTrue(notifications.is_empty()) |
348 | + |
349 | + |
350 | +class TestManageNotificationsMessage(TestCaseWithFactory): |
351 | + |
352 | + layer = LaunchpadZopelessLayer |
353 | + |
354 | + def test_manage_notifications_message_is_included(self): |
355 | + # Set up a subscription to a product. |
356 | + subscriber = self.factory.makePerson() |
357 | + submitter = self.factory.makePerson() |
358 | + product = self.factory.makeProduct( |
359 | + bug_supervisor=submitter) |
360 | + product.addSubscription(subscriber, subscriber) |
361 | + # Create a bug that will match the subscription. |
362 | + bug = product.createBug(CreateBugParams( |
363 | + title=self.factory.getUniqueString(), |
364 | + comment=self.factory.getUniqueString(), |
365 | + owner=submitter)) |
366 | + notification = fetch_notifications(subscriber, bug).one() |
367 | + _, _, (message,) = construct_email_notifications([notification]) |
368 | + payload = message.get_payload() |
369 | + self.assertThat(payload, Contains( |
370 | + 'To manage notifications about this bug go to:\nhttp://')) |
371 | + |
372 | + |
373 | +class TestNotificationSignatureSeparator(TestCase): |
374 | + |
375 | + def test_signature_separator(self): |
376 | + # Email signatures are often separated from the body of a message by a |
377 | + # special separator so user agents can identify the signature for |
378 | + # special treatment (hiding, stripping when replying, colorizing, |
379 | + # etc.). The bug notification messages follow the convention. |
380 | + names = ['bug-notification-verbose.txt', 'bug-notification.txt'] |
381 | + for name in names: |
382 | + template = get_email_template(name, 'bugs') |
383 | + self.assertTrue(re.search('^-- $', template, re.MULTILINE)) |
384 | |
385 | === modified file 'lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt' |
386 | --- lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt 2010-12-23 12:55:53 +0000 |
387 | +++ lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt 2011-05-27 13:35:12 +0000 |
388 | @@ -1,178 +1,178 @@ |
389 | -= Personal Subscriptions = |
390 | +Personal Subscriptions |
391 | +====================== |
392 | |
393 | Users can subscribe to bugs reported in Launchpad, via the "Subscribe" link |
394 | in the actions portlet. |
395 | |
396 | - >>> from lp.bugs.tests.bug import ( |
397 | - ... print_direct_subscribers, print_also_notified, |
398 | - ... print_subscribers_from_duplicates) |
399 | + >>> from lp.bugs.tests.bug import ( |
400 | + ... print_direct_subscribers, print_also_notified, |
401 | + ... print_subscribers_from_duplicates) |
402 | |
403 | - >>> browser = setupBrowser(auth='Basic foo.bar@canonical.com:test') |
404 | - >>> browser.open('http://bugs.launchpad.dev/firefox/+bug/1') |
405 | - >>> browser.url |
406 | - 'http://bugs.launchpad.dev/firefox/+bug/1' |
407 | + >>> browser = setupBrowser(auth='Basic foo.bar@canonical.com:test') |
408 | + >>> browser.open('http://bugs.launchpad.dev/firefox/+bug/1') |
409 | + >>> browser.url |
410 | + 'http://bugs.launchpad.dev/firefox/+bug/1' |
411 | |
412 | >>> browser.getLink('Subscribe').click() |
413 | |
414 | - >>> subscription_widget = browser.getControl(name='field.subscription') |
415 | - >>> subscription_widget.options |
416 | - ['name16'] |
417 | - >>> subscription_widget.value |
418 | - ['name16'] |
419 | + >>> subscription_widget = browser.getControl(name='field.subscription') |
420 | + >>> subscription_widget.options |
421 | + ['name16'] |
422 | + >>> subscription_widget.value |
423 | + ['name16'] |
424 | |
425 | - >>> submit = browser.getControl('Continue') |
426 | + >>> submit = browser.getControl('Continue') |
427 | |
428 | Clicking "Continue" subscribes the user to the bug, and tells the user |
429 | this. |
430 | |
431 | - >>> submit.click() |
432 | - |
433 | - >>> browser.url |
434 | - 'http://bugs.launchpad.dev/firefox/+bug/1' |
435 | - |
436 | - >>> for tag in find_tags_by_class(browser.contents, "informational message"): |
437 | - ... print tag.renderContents() |
438 | - You have been subscribed to this bug. |
439 | + >>> submit.click() |
440 | + |
441 | + >>> browser.url |
442 | + 'http://bugs.launchpad.dev/firefox/+bug/1' |
443 | + |
444 | + >>> tags = find_tags_by_class(browser.contents, "informational message") |
445 | + >>> for tag in tags: |
446 | + ... print tag.renderContents() |
447 | + You have been subscribed to this bug. |
448 | |
449 | There's also now a link to unsubscribe the user next to the name. It's a |
450 | relative URL to +subscribe, so it will only work when the portlet is |
451 | in the context of the bug page. |
452 | |
453 | - >>> browser.open( |
454 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
455 | - >>> print_direct_subscribers(browser.contents) |
456 | - Foo Bar (Self-subscribed) (Unsubscribe Foo Bar) |
457 | - Sample Person (Subscribed by Launchpad Janitor) |
458 | - Steve Alexander (Subscribed by Launchpad Janitor) |
459 | - |
460 | - >>> browser.open( |
461 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
462 | - >>> link = browser.getLink(id='unsubscribe-subscriber-16') |
463 | - >>> print link.mech_link.url |
464 | - +subscribe |
465 | - |
466 | - >>> browser.open('http://bugs.launchpad.dev/firefox/+bug/1/') |
467 | - >>> browser.getLink('Unsubscribe').click() |
468 | - >>> print browser.title |
469 | - Bug #1... |
470 | - >>> browser.url |
471 | - 'http://bugs.launchpad.dev/firefox/+bug/1/+subscribe' |
472 | + >>> bug_1 = 'http://bugs.launchpad.dev/bugs/1/' |
473 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
474 | + >>> print_direct_subscribers(browser.contents) |
475 | + Foo Bar (Self-subscribed) (Unsubscribe Foo Bar) |
476 | + Sample Person (Subscribed by Launchpad Janitor) |
477 | + Steve Alexander (Subscribed by Launchpad Janitor) |
478 | + |
479 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
480 | + >>> link = browser.getLink(id='unsubscribe-subscriber-16') |
481 | + >>> print link.mech_link.url |
482 | + +subscribe |
483 | + |
484 | + >>> browser.open(bug_1) |
485 | + >>> browser.getLink('Unsubscribe').click() |
486 | + >>> print browser.title |
487 | + Bug #1... |
488 | + >>> browser.url |
489 | + 'http://bugs.launchpad.dev/firefox/+bug/1/+subscribe' |
490 | |
491 | |
492 | Clicking the "Continue" button from the +subscribe page will unsubscribe |
493 | the user this time, and inform the user. |
494 | |
495 | - >>> subscription_widget.value |
496 | - ['name16'] |
497 | - >>> submit = browser.getControl('Continue') |
498 | - >>> submit.click() |
499 | - |
500 | - >>> browser.url |
501 | - 'http://bugs.launchpad.dev/firefox/+bug/1/' |
502 | - |
503 | - >>> for tag in find_tags_by_class(browser.contents, 'informational message'): |
504 | - ... print tag.renderContents() |
505 | - You have been unsubscribed from bug 1. |
506 | + >>> subscription_widget.value |
507 | + ['name16'] |
508 | + >>> submit = browser.getControl('Continue') |
509 | + >>> submit.click() |
510 | + |
511 | + >>> browser.url |
512 | + 'http://bugs.launchpad.dev/firefox/+bug/1' |
513 | + |
514 | + >>> tags = find_tags_by_class(browser.contents, 'informational message') |
515 | + >>> for tag in tags: |
516 | + ... print tag.renderContents() |
517 | + You have been unsubscribed from bug 1. |
518 | |
519 | Users can unsubscribe teams to which they belong. Let's demonstrate by |
520 | first subscribing one of Foo Bar's teams. |
521 | |
522 | - >>> browser.getLink('Subscribe someone else').click() |
523 | - >>> browser.url |
524 | - 'http://bugs.launchpad.dev/firefox/+bug/1/+addsubscriber' |
525 | + >>> browser.getLink('Subscribe someone else').click() |
526 | + >>> browser.url |
527 | + 'http://bugs.launchpad.dev/firefox/+bug/1/+addsubscriber' |
528 | |
529 | - >>> browser.getControl('Person').value = 'launchpad' |
530 | - >>> browser.getControl('Subscribe user').click() |
531 | - >>> browser.url |
532 | - 'http://bugs.launchpad.dev/firefox/+bug/1' |
533 | + >>> browser.getControl('Person').value = 'launchpad' |
534 | + >>> browser.getControl('Subscribe user').click() |
535 | + >>> browser.url |
536 | + 'http://bugs.launchpad.dev/firefox/+bug/1' |
537 | |
538 | There's an unsubscribe link next to the team name. |
539 | |
540 | - >>> browser.open( |
541 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
542 | - >>> print_direct_subscribers(browser.contents) |
543 | - Launchpad Developers (Subscribed by Foo Bar) (Unsubscribe Launchpad |
544 | - Developers) |
545 | - Sample Person (Subscribed by Launchpad Janitor) |
546 | - Steve Alexander (Subscribed by Launchpad Janitor) |
547 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
548 | + >>> print_direct_subscribers(browser.contents) |
549 | + Launchpad Developers (Subscribed by Foo Bar) (Unsubscribe Launchpad |
550 | + Developers) |
551 | + Sample Person (Subscribed by Launchpad Janitor) |
552 | + Steve Alexander (Subscribed by Launchpad Janitor) |
553 | |
554 | Clicking either the subscribe link (for subscribing the user to the bug) |
555 | or the unsubscribe link for the team gives us the option of both |
556 | subscribing Foo Bar, and unsubscribing the Launchpad team. |
557 | |
558 | - >>> browser.open( |
559 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
560 | - >>> browser.getLink(id='unsubscribe-subscriber-57').mech_link.url |
561 | - '+subscribe' |
562 | - |
563 | - >>> browser.open('http://bugs.launchpad.dev/firefox/+bug/1') |
564 | - >>> browser.getLink('Subscribe').click() |
565 | - >>> browser.url |
566 | - 'http://bugs.launchpad.dev/firefox/+bug/1/+subscribe' |
567 | - |
568 | - >>> subscription_widget = browser.getControl(name='field.subscription') |
569 | - >>> subscription_widget.options |
570 | - ['name16', 'launchpad'] |
571 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
572 | + >>> browser.getLink(id='unsubscribe-subscriber-57').mech_link.url |
573 | + '+subscribe' |
574 | + |
575 | + >>> browser.open(bug_1) |
576 | + >>> browser.getLink('Subscribe').click() |
577 | + >>> browser.url |
578 | + 'http://bugs.launchpad.dev/firefox/+bug/1/+subscribe' |
579 | + |
580 | + >>> subscription_widget = browser.getControl(name='field.subscription') |
581 | + >>> subscription_widget.options |
582 | + ['name16', 'launchpad'] |
583 | |
584 | Let's unsubscribe the Launchpad team. |
585 | |
586 | - >>> subscription_widget.value = ['launchpad'] |
587 | - >>> browser.getControl('Continue').click() |
588 | - |
589 | - >>> browser.url |
590 | - 'http://bugs.launchpad.dev/firefox/+bug/1' |
591 | - |
592 | - >>> for tag in find_tags_by_class(browser.contents, 'informational message'): |
593 | - ... print tag.renderContents() |
594 | - Launchpad Developers has been unsubscribed from bug 1. |
595 | - |
596 | - >>> browser.open( |
597 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
598 | - >>> print_direct_subscribers(browser.contents) |
599 | - Sample Person (Subscribed by Launchpad Janitor) |
600 | - Steve Alexander (Subscribed by Launchpad Janitor) |
601 | + >>> subscription_widget.value = ['launchpad'] |
602 | + >>> browser.getControl('Continue').click() |
603 | + |
604 | + >>> browser.url |
605 | + 'http://bugs.launchpad.dev/firefox/+bug/1' |
606 | + |
607 | + >>> tags = find_tags_by_class(browser.contents, 'informational message') |
608 | + >>> for tag in tags: |
609 | + ... print tag.renderContents() |
610 | + Launchpad Developers has been unsubscribed from bug 1. |
611 | + |
612 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
613 | + >>> print_direct_subscribers(browser.contents) |
614 | + Sample Person (Subscribed by Launchpad Janitor) |
615 | + Steve Alexander (Subscribed by Launchpad Janitor) |
616 | |
617 | On the subscribe page there's a Cancel link as well, that will return |
618 | the browser to the bug page. |
619 | |
620 | - >>> browser.open( |
621 | - ... 'http://bugs.launchpad.dev/firefox/+bug/1/') |
622 | - >>> browser.getLink('Subscribe').click() |
623 | - >>> browser.url |
624 | - 'http://bugs.launchpad.dev/firefox/+bug/1/+subscribe' |
625 | + >>> browser.open(bug_1) |
626 | + >>> browser.getLink('Subscribe').click() |
627 | + >>> browser.url |
628 | + 'http://bugs.launchpad.dev/firefox/+bug/1/+subscribe' |
629 | |
630 | - >>> subscription_widget = browser.getControl(name='field.subscription') |
631 | - >>> subscription_widget.value |
632 | - ['name16'] |
633 | - >>> browser.getLink('Cancel').click() |
634 | - >>> browser.url |
635 | - 'http://bugs.launchpad.dev/firefox/+bug/1/' |
636 | + >>> subscription_widget = browser.getControl(name='field.subscription') |
637 | + >>> subscription_widget.value |
638 | + ['name16'] |
639 | + >>> browser.getLink('Cancel').click() |
640 | + >>> browser.url |
641 | + 'http://bugs.launchpad.dev/firefox/+bug/1' |
642 | |
643 | Foo Bar wasn't subscribed to the bug. |
644 | |
645 | - >>> len(find_tags_by_class(browser.contents, 'informational message')) |
646 | - 0 |
647 | - >>> browser.open( |
648 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
649 | - >>> print_direct_subscribers(browser.contents) |
650 | - Sample Person (Subscribed by Launchpad Janitor) |
651 | - Steve Alexander (Subscribed by Launchpad Janitor) |
652 | + >>> len(find_tags_by_class(browser.contents, 'informational message')) |
653 | + 0 |
654 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
655 | + >>> print_direct_subscribers(browser.contents) |
656 | + Sample Person (Subscribed by Launchpad Janitor) |
657 | + Steve Alexander (Subscribed by Launchpad Janitor) |
658 | |
659 | Subscribers which the current user may unsubscribe (the current user and teams |
660 | -they are a member of) display first in the list, before all other subscriptions. |
661 | - |
662 | - >>> browser.open('http://bugs.launchpad.dev/firefox/+bug/1/+addsubscriber') |
663 | - >>> browser.getControl('Person').value = 'testing-spanish-team' |
664 | - >>> browser.getControl('Subscribe user').click() |
665 | - >>> browser.open( |
666 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
667 | - >>> print_direct_subscribers(browser.contents) |
668 | - testing Spanish team (Subscribed by Foo Bar) |
669 | - (Unsubscribe testing Spanish team) |
670 | - Sample Person (Subscribed by Launchpad Janitor) |
671 | - Steve Alexander (Subscribed by Launchpad Janitor) |
672 | - |
673 | -== Subscriptions and Duplicate Bugs == |
674 | +they are a member of) display first in the list, before all other |
675 | +subscriptions. |
676 | + |
677 | + >>> browser.open( |
678 | + ... 'http://bugs.launchpad.dev/firefox/+bug/1/+addsubscriber') |
679 | + >>> browser.getControl('Person').value = 'testing-spanish-team' |
680 | + >>> browser.getControl('Subscribe user').click() |
681 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
682 | + >>> print_direct_subscribers(browser.contents) |
683 | + testing Spanish team (Subscribed by Foo Bar) |
684 | + (Unsubscribe testing Spanish team) |
685 | + Sample Person (Subscribed by Launchpad Janitor) |
686 | + Steve Alexander (Subscribed by Launchpad Janitor) |
687 | + |
688 | +Subscriptions and Duplicate Bugs |
689 | +-------------------------------- |
690 | |
691 | Because we auto-subscribe users that are directly subscribed to dupes of |
692 | a bug, we give the option to unsubscribe from dupe target bugs. Behind |
693 | @@ -183,13 +183,12 @@ |
694 | |
695 | >>> stevea_browser = setupBrowser( |
696 | ... auth="Basic steve.alexander@ubuntulinux.com:test") |
697 | - >>> stevea_browser.open( |
698 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content") |
699 | + >>> bug_3 = 'http://launchpad.dev/bugs/3/' |
700 | + >>> stevea_browser.open(bug_3 + "+bug-portlet-dupe-subscribers-content") |
701 | >>> print_subscribers_from_duplicates(stevea_browser.contents) |
702 | From duplicates: |
703 | |
704 | - >>> stevea_browser.open( |
705 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content") |
706 | + >>> stevea_browser.open(bug_3 + "+bug-portlet-subscribers-content") |
707 | >>> print_also_notified(stevea_browser.contents) |
708 | Also notified: |
709 | |
710 | @@ -197,98 +196,92 @@ |
711 | a dupe of bug #3, then Steve gets indirectly subscribed to bug #3, and |
712 | is presented with the Unsubscribe link instead. |
713 | |
714 | - >>> stevea_browser.open( |
715 | - ... "http://launchpad.dev/tomcat/+bug/2/+duplicate") |
716 | - |
717 | - >>> stevea_browser.getControl("Duplicate Of").value = "3" |
718 | - >>> stevea_browser.getControl("Change").click() |
719 | - |
720 | - >>> stevea_browser.open( |
721 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content") |
722 | - >>> print_subscribers_from_duplicates(stevea_browser.contents) |
723 | - From duplicates: |
724 | - Steve Alexander (Subscribed to bug 2 by Launchpad Janitor) |
725 | - (Unsubscribe Steve Alexander) |
726 | - |
727 | - >>> stevea_browser.getLink(id='unsubscribe-subscriber-11').mech_link.url |
728 | - '+subscribe' |
729 | + >>> bug_2 = 'http://launchpad.dev/tomcat/+bug/2/' |
730 | + >>> stevea_browser.open(bug_2 + "+duplicate") |
731 | + |
732 | + >>> stevea_browser.getControl("Duplicate Of").value = "3" |
733 | + >>> stevea_browser.getControl("Change").click() |
734 | + |
735 | + >>> stevea_browser.open(bug_3 + "+bug-portlet-dupe-subscribers-content") |
736 | + >>> print_subscribers_from_duplicates(stevea_browser.contents) |
737 | + From duplicates: |
738 | + Steve Alexander (Subscribed to bug 2 by Launchpad Janitor) |
739 | + (Unsubscribe Steve Alexander) |
740 | + |
741 | + >>> stevea_browser.getLink(id='unsubscribe-subscriber-11').mech_link.url |
742 | + '+subscribe' |
743 | |
744 | When he chooses to unsubscribe, he will be unsubscribed from bug #2, the |
745 | dupe of bug #3, so he'll no longer get mail from bug #3. |
746 | |
747 | - >>> stevea_browser.open("http://launchpad.dev/bugs/3") |
748 | - >>> stevea_browser.getLink('Unsubscribe').click() |
749 | - >>> stevea_browser.getControl("Continue").click() |
750 | + >>> stevea_browser.open("http://launchpad.dev/bugs/3") |
751 | + >>> stevea_browser.getLink('Unsubscribe').click() |
752 | + >>> stevea_browser.getControl("Continue").click() |
753 | |
754 | # XXX: Brad Bollenbach 2006-09-27 bug=62634: Printing the tag here, |
755 | # instead of tag.string. |
756 | |
757 | - >>> for tag in find_tags_by_class( |
758 | - ... stevea_browser.contents, 'informational message'): |
759 | - ... print tag.renderContents() |
760 | - You have been unsubscribed from bug 3 and 1 duplicate (<a...#2</a>)... |
761 | + >>> for tag in find_tags_by_class( |
762 | + ... stevea_browser.contents, 'informational message'): |
763 | + ... print tag.renderContents() |
764 | + You have been unsubscribed from bug 3 and 1 duplicate (<a...#2</a>)... |
765 | |
766 | (Except for Mark, who has a structural subscription to the target, |
767 | there are no longer any indirect subscribers, because Steve was |
768 | unsubscribed from the dupes and thus is no longer indirectly subscribed |
769 | to bug #3.) |
770 | |
771 | - >>> stevea_browser.open( |
772 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content") |
773 | - >>> print_subscribers_from_duplicates(stevea_browser.contents) |
774 | - From duplicates: |
775 | + >>> stevea_browser.open(bug_3 + "+bug-portlet-dupe-subscribers-content") |
776 | + >>> print_subscribers_from_duplicates(stevea_browser.contents) |
777 | + From duplicates: |
778 | |
779 | - >>> stevea_browser.open( |
780 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content") |
781 | - >>> print_also_notified(stevea_browser.contents) |
782 | - Also notified: |
783 | + >>> stevea_browser.open(bug_3 + "+bug-portlet-subscribers-content") |
784 | + >>> print_also_notified(stevea_browser.contents) |
785 | + Also notified: |
786 | |
787 | Let's repeat this example, with Steve subscribed to two different dupes, |
788 | to see how the unsubscribe notification changes slightly, because he |
789 | gets unsubscribed from more than one duplicate. |
790 | |
791 | - >>> stevea_browser.open( |
792 | - ... "http://launchpad.dev/firefox/+bug/1/+duplicate") |
793 | - >>> stevea_browser.getControl("Duplicate Of").value = "3" |
794 | - >>> stevea_browser.getControl("Change").click() |
795 | + >>> stevea_browser.open( |
796 | + ... "http://launchpad.dev/firefox/+bug/1/+duplicate") |
797 | + >>> stevea_browser.getControl("Duplicate Of").value = "3" |
798 | + >>> stevea_browser.getControl("Change").click() |
799 | |
800 | (Resubscribe Steve to bug #2, because he was unsubscribed in the |
801 | previous example.) |
802 | |
803 | - >>> stevea_browser.open( |
804 | - ... "http://launchpad.dev/tomcat/+bug/2/+addsubscriber") |
805 | - >>> stevea_browser.getControl('Person').value = 'stevea' |
806 | - >>> stevea_browser.getControl('Subscribe user').click() |
807 | - |
808 | - >>> stevea_browser.open( |
809 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content") |
810 | - >>> print_subscribers_from_duplicates(stevea_browser.contents) |
811 | - From duplicates: |
812 | - Sample Person (Subscribed ...) |
813 | - Steve Alexander (Subscribed ...) (Unsubscribe Steve Alexander) |
814 | - testing Spanish team (Subscribed to bug 1 by Foo Bar) |
815 | - |
816 | - >>> stevea_browser.open( |
817 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content") |
818 | - >>> print_also_notified(stevea_browser.contents) |
819 | - Also notified: |
820 | - |
821 | - >>> stevea_browser.open("http://launchpad.dev/bugs/3") |
822 | - >>> stevea_browser.getLink("Unsubscribe").click() |
823 | - >>> stevea_browser.getControl("Continue").click() |
824 | - |
825 | - >>> for tag in find_tags_by_class( |
826 | - ... stevea_browser.contents, 'informational message'): |
827 | - ... print tag.renderContents() |
828 | - You have been unsubscribed from bug 3 and 2 duplicates (<a...#1</a>, <a...#2</a>)... |
829 | + >>> stevea_browser.open(bug_2 + "+addsubscriber") |
830 | + >>> stevea_browser.getControl('Person').value = 'stevea' |
831 | + >>> stevea_browser.getControl('Subscribe user').click() |
832 | + |
833 | + >>> stevea_browser.open(bug_3 + "+bug-portlet-dupe-subscribers-content") |
834 | + >>> print_subscribers_from_duplicates(stevea_browser.contents) |
835 | + From duplicates: |
836 | + Sample Person (Subscribed ...) |
837 | + Steve Alexander (Subscribed ...) (Unsubscribe Steve Alexander) |
838 | + testing Spanish team (Subscribed to bug 1 by Foo Bar) |
839 | + |
840 | + >>> stevea_browser.open(bug_3 + "+bug-portlet-subscribers-content") |
841 | + >>> print_also_notified(stevea_browser.contents) |
842 | + Also notified: |
843 | + |
844 | + >>> stevea_browser.open("http://launchpad.dev/bugs/3") |
845 | + >>> stevea_browser.getLink("Unsubscribe").click() |
846 | + >>> stevea_browser.getControl("Continue").click() |
847 | + |
848 | + >>> for tag in find_tags_by_class( |
849 | + ... stevea_browser.contents, 'informational message'): |
850 | + ... print tag.renderContents() |
851 | + You have been unsubscribed from bug 3 and 2 duplicates (<a...#1</a>, <a...#2</a>)... |
852 | |
853 | (Let's undupe bug #1 from bug #3, since it's unneeded for the examples |
854 | that follow.) |
855 | |
856 | - >>> stevea_browser.open( |
857 | - ... "http://launchpad.dev/firefox/+bug/1/+duplicate") |
858 | - >>> stevea_browser.getControl("Duplicate Of").value = "" |
859 | - >>> stevea_browser.getControl("Change").click() |
860 | + >>> stevea_browser.open( |
861 | + ... "http://launchpad.dev/firefox/+bug/1/+duplicate") |
862 | + >>> stevea_browser.getControl("Duplicate Of").value = "" |
863 | + >>> stevea_browser.getControl("Change").click() |
864 | |
865 | This unsubscribe behaviour is team-aware too, so you can unsubscribe |
866 | your teams from a bug, even when the team's subscription comes from a |
867 | @@ -296,76 +289,79 @@ |
868 | bug #2, and notice how bug #3's indirect subscriptions are update to |
869 | include that team. |
870 | |
871 | - >>> foobar_browser = setupBrowser(auth="Basic foo.bar@canonical.com:test") |
872 | - >>> foobar_browser.open("http://launchpad.dev/bugs/2") |
873 | - >>> foobar_browser.getLink('Subscribe someone else').click() |
874 | - >>> foobar_browser.getControl("Person").value = "ubuntu-team" |
875 | - >>> foobar_browser.getControl("Subscribe user").click() |
876 | - |
877 | - >>> foobar_browser.open( |
878 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content") |
879 | - |
880 | - >>> print_subscribers_from_duplicates(foobar_browser.contents) |
881 | - From duplicates: |
882 | - Ubuntu Team (Subscribed to bug 2 by Foo Bar) (Unsubscribe Ubuntu Team) |
883 | - |
884 | - >>> foobar_browser.open( |
885 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content") |
886 | - |
887 | - >>> print_also_notified(foobar_browser.contents) |
888 | - Also notified: |
889 | + >>> foobar_browser = setupBrowser(auth="Basic foo.bar@canonical.com:test") |
890 | + >>> foobar_browser.open("http://launchpad.dev/bugs/2") |
891 | + >>> foobar_browser.getLink('Subscribe someone else').click() |
892 | + >>> foobar_browser.getControl("Person").value = "ubuntu-team" |
893 | + >>> foobar_browser.getControl("Subscribe user").click() |
894 | + |
895 | + >>> foobar_browser.open(bug_3 + "+bug-portlet-dupe-subscribers-content") |
896 | + |
897 | + >>> print_subscribers_from_duplicates(foobar_browser.contents) |
898 | + From duplicates: |
899 | + Ubuntu Team (Subscribed to bug 2 by Foo Bar) (Unsubscribe Ubuntu Team) |
900 | + |
901 | + >>> foobar_browser.open( |
902 | + ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content") |
903 | + |
904 | + >>> print_also_notified(foobar_browser.contents) |
905 | + Also notified: |
906 | |
907 | The subscribe link for Foo Bar still says "Subscribe", because |
908 | Foo Bar can subscribe himself directly to this bug. For unsubscribing |
909 | the team, the (-) icon can be used. In reality, the two links point to |
910 | the same page, but that is changed when the page is AJAX enabled. |
911 | |
912 | - >>> foobar_browser.open("http://launchpad.dev/bugs/3") |
913 | - >>> foobar_browser.getLink('Subscribe').click() |
914 | + >>> foobar_browser.open("http://launchpad.dev/bugs/3") |
915 | + >>> foobar_browser.getLink('Subscribe').click() |
916 | |
917 | Foo Bar can unsubscribe ubuntu-team, and ubuntu-team will no longer show |
918 | up in the indirect subscriptions. |
919 | |
920 | - >>> subscription_field = foobar_browser.getControl(name="field.subscription") |
921 | - >>> subscription_field.value = ["ubuntu-team"] |
922 | - >>> foobar_browser.getControl("Continue").click() |
923 | + >>> subscription_field = foobar_browser.getControl( |
924 | + ... name="field.subscription") |
925 | + >>> subscription_field.value = ["ubuntu-team"] |
926 | + >>> foobar_browser.getControl("Continue").click() |
927 | |
928 | - >>> for tag in find_tags_by_class( |
929 | - ... foobar_browser.contents, 'informational message'): |
930 | - ... print tag.renderContents() |
931 | - Ubuntu Team has been unsubscribed from bug 3 and 1 duplicate (<a...#2</a>)... |
932 | + >>> for tag in find_tags_by_class( |
933 | + ... foobar_browser.contents, 'informational message'): |
934 | + ... print tag.renderContents() |
935 | + Ubuntu Team has been unsubscribed from bug 3 and 1 duplicate (<a...#2</a>)... |
936 | |
937 | (ubuntu-team is no longer an indirect subscriber.) |
938 | |
939 | - >>> foobar_browser.open( |
940 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-dupe-subscribers-content") |
941 | - >>> print_subscribers_from_duplicates(foobar_browser.contents) |
942 | - From duplicates: |
943 | - |
944 | - >>> foobar_browser.open( |
945 | - ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content") |
946 | - >>> print_also_notified(foobar_browser.contents) |
947 | - Also notified: |
948 | - |
949 | - |
950 | -== Displaying subscribers == |
951 | + >>> foobar_browser.open(bug_3 + "+bug-portlet-dupe-subscribers-content") |
952 | + >>> print_subscribers_from_duplicates(foobar_browser.contents) |
953 | + From duplicates: |
954 | + |
955 | + >>> foobar_browser.open( |
956 | + ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content") |
957 | + >>> print_also_notified(foobar_browser.contents) |
958 | + Also notified: |
959 | + |
960 | + |
961 | +Displaying subscribers |
962 | +---------------------- |
963 | |
964 | The display names of subscribers are escaped in the subscribers list, they are |
965 | -also trimmed to 20 characters, so that they fit alongside the unsubscribe icon. |
966 | - |
967 | - >>> login(ANONYMOUS) |
968 | - >>> abuser = factory.makePerson( |
969 | - ... name='abuser', |
970 | - ... displayname='<script>javascript:alert("YO")</script>') |
971 | - >>> logout() |
972 | - >>> browser.open('http://bugs.launchpad.dev/firefox/+bug/1/+addsubscriber') |
973 | - >>> browser.getControl('Person').value = 'abuser' |
974 | - >>> browser.getControl('Subscribe user').click() |
975 | - >>> browser.open( |
976 | - ... 'http://bugs.launchpad.dev/bugs/1/+bug-portlet-subscribers-content') |
977 | - >>> subscriber_list = find_tag_by_id( |
978 | - ... browser.contents, 'subscribers-direct') |
979 | - >>> for subscriber in subscriber_list.findAll('div'): |
980 | - ... if '~abuser' in subscriber.a['href']: |
981 | - ... print subscriber.a.contents[2].strip() |
982 | - <script>javascrip... |
983 | +also trimmed to 20 characters, so that they fit alongside the unsubscribe |
984 | +icon. |
985 | + |
986 | + >>> login(ANONYMOUS) |
987 | + >>> abuser = factory.makePerson( |
988 | + ... name='abuser', |
989 | + ... displayname='<script>javascript:alert("YO")</script>') |
990 | + >>> logout() |
991 | + >>> browser.open( |
992 | + ... 'http://bugs.launchpad.dev/firefox/+bug/1/+addsubscriber') |
993 | + >>> browser.getControl('Person').value = 'abuser' |
994 | + >>> browser.getControl('Subscribe user').click() |
995 | + >>> bug_1 = 'http://bugs.launchpad.dev/bugs/1/' |
996 | + >>> browser.open(bug_1 + '+bug-portlet-subscribers-content') |
997 | + >>> subscriber_list = find_tag_by_id( |
998 | + ... browser.contents, 'subscribers-direct') |
999 | + >>> for subscriber in subscriber_list.findAll('div'): |
1000 | + ... if '~abuser' in subscriber.a['href']: |
1001 | + ... print subscriber.a.contents[2].strip() |
1002 | + <script>javascrip... |
1003 | + |
1004 | |
1005 | === modified file 'lib/lp/bugs/stories/xx-bugs-statistics-portlet.txt' |
1006 | --- lib/lp/bugs/stories/xx-bugs-statistics-portlet.txt 2011-03-10 17:03:32 +0000 |
1007 | +++ lib/lp/bugs/stories/xx-bugs-statistics-portlet.txt 2011-05-27 13:35:12 +0000 |
1008 | @@ -1,4 +1,5 @@ |
1009 | -= Bug statistics portlet = |
1010 | +Bug statistics portlet |
1011 | +====================== |
1012 | |
1013 | The distribution, project group and project bug listings contain a |
1014 | portlet that shows bug statistics for the target. Each statistic is a |
1015 | @@ -6,7 +7,8 @@ |
1016 | served in a separate request; the request is issued via Javascript and |
1017 | inserted into the page later. |
1018 | |
1019 | -== Distribution == |
1020 | +Distribution |
1021 | +------------ |
1022 | |
1023 | >>> path = 'debian' |
1024 | |
1025 | @@ -77,7 +79,8 @@ |
1026 | http://bugs.launchpad.dev/debian/+cve |
1027 | |
1028 | |
1029 | -== Distribution Series == |
1030 | +Distribution Series |
1031 | +------------------- |
1032 | |
1033 | >>> path = 'debian/woody' |
1034 | |
1035 | @@ -149,7 +152,8 @@ |
1036 | http://bugs.launchpad.dev/debian/woody/+cve |
1037 | |
1038 | |
1039 | -== Distribution Source Package == |
1040 | +Distribution Source Package |
1041 | +--------------------------- |
1042 | |
1043 | >>> path = 'debian/+source/mozilla-firefox' |
1044 | |
1045 | @@ -219,7 +223,8 @@ |
1046 | LinkNotFoundError |
1047 | |
1048 | |
1049 | -== Source Package in Distribution Series == |
1050 | +Source Package in Distribution Series |
1051 | +------------------------------------- |
1052 | |
1053 | >>> path = 'debian/woody/+source/mozilla-firefox' |
1054 | |
1055 | @@ -286,7 +291,8 @@ |
1056 | LinkNotFoundError |
1057 | |
1058 | |
1059 | -== Project group == |
1060 | +Project group |
1061 | +------------- |
1062 | |
1063 | >>> path = 'mozilla' |
1064 | |
1065 | @@ -356,7 +362,8 @@ |
1066 | LinkNotFoundError |
1067 | |
1068 | |
1069 | -== Project == |
1070 | +Project |
1071 | +------- |
1072 | |
1073 | >>> path = 'firefox' |
1074 |
See MP description.