Merge lp:~gmb/launchpad/non-js-muting-bug-734732 into lp:launchpad

Proposed by Graham Binns
Status: Merged
Merged at revision: 12624
Proposed branch: lp:~gmb/launchpad/non-js-muting-bug-734732
Merge into: lp:launchpad
Diff against target: 170 lines (+110/-3)
5 files modified
lib/lp/bugs/browser/bug.py (+1/-3)
lib/lp/bugs/browser/bugsubscription.py (+34/-0)
lib/lp/bugs/browser/configure.zcml (+6/-0)
lib/lp/bugs/browser/tests/test_bugsubscription_views.py (+37/-0)
lib/lp/bugs/templates/bug-mute.pt (+32/-0)
To merge this branch: bzr merge lp:~gmb/launchpad/non-js-muting-bug-734732
Reviewer Review Type Date Requested Status
Brad Crittenden (community) code Approve
Review via email: mp+53981@code.launchpad.net

Commit message

[r=bac][bug=734732] There is now a non-JS process for muting mail from a bug.

Description of the change

This branch adds a BugTask:+mute view, so that stick-in-the muds who use
console-based browsers (RMS, I'm looking at you here) and people who use
browsers that don't play nice with YUI 3 (IE, now I'm looking at you)
can still use the mute / unmute functionality.

The +mute view presents a single button that allows the user to mute or
unmute bug mail for a bug. If the +mute page is visited by a user who
already holds a mute on the bug, they'll be redirected to the +subscribe
page, which handles the unmuting (and resubscribing if desired) story.

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

Looks good, Graham, nice and simple.

I have a few issues:

1) You are inconsistent in text presented to the user of "mail" vs. "email" but definitely not "e-mail".

2) The phrase "Bug mail for bug X" is wordy. s/Bug mail/Mail or Email.

3) In test_bug_mute_self_view_mutes_bug it would be nice to see the user is not muted before you exercise the form.

review: Approve (code)
Revision history for this message
Graham Binns (gmb) wrote :

Thanks Brad, I've updated the code as you've suggested.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/browser/bug.py'
--- lib/lp/bugs/browser/bug.py 2011-03-10 12:42:35 +0000
+++ lib/lp/bugs/browser/bug.py 2011-03-18 13:42:19 +0000
@@ -281,10 +281,8 @@
281 else:281 else:
282 text = "Mute bug mail"282 text = "Mute bug mail"
283283
284 # We link to '#' here because we don't yet have a view to handle
285 # this link.
286 return Link(284 return Link(
287 '#', text, icon='remove', summary=(285 '+mute', text, icon='remove', summary=(
288 "Mute this bug so that you will never receive emails "286 "Mute this bug so that you will never receive emails "
289 "about it."))287 "about it."))
290288
291289
=== modified file 'lib/lp/bugs/browser/bugsubscription.py'
--- lib/lp/bugs/browser/bugsubscription.py 2011-03-16 13:26:30 +0000
+++ lib/lp/bugs/browser/bugsubscription.py 2011-03-18 13:42:19 +0000
@@ -6,6 +6,7 @@
6__metaclass__ = type6__metaclass__ = type
7__all__ = [7__all__ = [
8 'AdvancedSubscriptionMixin',8 'AdvancedSubscriptionMixin',
9 'BugMuteSelfView',
9 'BugPortletDuplicateSubcribersContents',10 'BugPortletDuplicateSubcribersContents',
10 'BugPortletSubcribersContents',11 'BugPortletSubcribersContents',
11 'BugSubscriptionAddView',12 'BugSubscriptionAddView',
@@ -584,3 +585,36 @@
584 @property585 @property
585 def structural_subscriptions(self):586 def structural_subscriptions(self):
586 return self.context.bug.getStructuralSubscriptionsForPerson(self.user)587 return self.context.bug.getStructuralSubscriptionsForPerson(self.user)
588
589
590class BugMuteSelfView(LaunchpadFormView):
591 """A view to mute a user's bug mail for a given bug."""
592
593 schema = IBugSubscription
594 field_names = []
595
596 @property
597 def label(self):
598 return "Mute bug mail for bug %s" % self.context.bug.id
599
600 page_title = label
601
602 @property
603 def next_url(self):
604 return canonical_url(self.context)
605
606 cancel_url = next_url
607
608 def initialize(self):
609 super(BugMuteSelfView, self).initialize()
610 # If the user is already muted, redirect them to the +subscribe
611 # page, since there's no point doing its work twice.
612 if self.context.bug.isMuted(self.user):
613 self.request.response.redirect(
614 canonical_url(self.context, view_name="+subscribe"))
615
616 @action('Mute bug mail', name='mute')
617 def mute_action(self, action, data):
618 self.context.bug.mute(self.user, self.user)
619 self.request.response.addInfoNotification(
620 "Mail for bug #%s has been muted." % self.context.bug.id)
587621
=== modified file 'lib/lp/bugs/browser/configure.zcml'
--- lib/lp/bugs/browser/configure.zcml 2011-03-15 02:17:01 +0000
+++ lib/lp/bugs/browser/configure.zcml 2011-03-18 13:42:19 +0000
@@ -713,6 +713,12 @@
713 permission="launchpad.AnyPerson"713 permission="launchpad.AnyPerson"
714 template="../templates/bug-subscription.pt"/>714 template="../templates/bug-subscription.pt"/>
715 <browser:page715 <browser:page
716 for="lp.bugs.interfaces.bugtask.IBugTask"
717 name="+mute"
718 class="lp.bugs.browser.bugsubscription.BugMuteSelfView"
719 permission="launchpad.AnyPerson"
720 template="../templates/bug-mute.pt"/>
721 <browser:page
716 name="+linkcve"722 name="+linkcve"
717 for="lp.bugs.interfaces.bugtask.IBugTask"723 for="lp.bugs.interfaces.bugtask.IBugTask"
718 class="lp.bugs.browser.cve.CveLinkView"724 class="lp.bugs.browser.cve.CveLinkView"
719725
=== modified file 'lib/lp/bugs/browser/tests/test_bugsubscription_views.py'
--- lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2011-03-16 13:26:30 +0000
+++ lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2011-03-18 13:42:19 +0000
@@ -6,6 +6,7 @@
6__metaclass__ = type6__metaclass__ = type
77
8from canonical.launchpad.ftests import LaunchpadFormHarness8from canonical.launchpad.ftests import LaunchpadFormHarness
9from canonical.launchpad.webapp import canonical_url
9from canonical.testing.layers import LaunchpadFunctionalLayer10from canonical.testing.layers import LaunchpadFunctionalLayer
1011
11from lp.bugs.browser.bugsubscription import (12from lp.bugs.browser.bugsubscription import (
@@ -444,3 +445,39 @@
444 decorator.subscription for decorator in445 decorator.subscription for decorator in
445 view.sorted_direct_subscriptions]446 view.sorted_direct_subscriptions]
446 self.assertFalse(subscription in sorted_subscriptions)447 self.assertFalse(subscription in sorted_subscriptions)
448
449
450class BugMuteSelfViewTestCase(TestCaseWithFactory):
451 """Tests for the BugMuteSelfView."""
452
453 layer = LaunchpadFunctionalLayer
454
455 def setUp(self):
456 super(BugMuteSelfViewTestCase, self).setUp()
457 self.bug = self.factory.makeBug()
458 self.person = self.factory.makePerson()
459
460 def test_bug_mute_self_view_mutes_bug(self):
461 # The BugMuteSelfView mutes bug mail for the current user when
462 # its form is submitted.
463 with person_logged_in(self.person):
464 self.assertFalse(self.bug.isMuted(self.person))
465 mute_view = create_initialized_view(
466 self.bug.default_bugtask, name="+mute",
467 form={'field.actions.mute': 'Mute bug mail'})
468 self.assertTrue(self.bug.isMuted(self.person))
469
470 def test_bug_mute_self_view_redirects_muted_users(self):
471 # The BugMuteSelfView redirects muted users to the +subscribe
472 # page, where they can remove their muted subscription or change
473 # their BugNotificationLevel.
474 with person_logged_in(self.person):
475 self.bug.mute(self.person, self.person)
476 mute_view = create_initialized_view(
477 self.bug.default_bugtask, name="+mute")
478 response = mute_view.request.response
479 self.assertEqual(302, response.getStatus())
480 self.assertEqual(
481 canonical_url(self.bug.default_bugtask,
482 view_name="+subscribe"),
483 response.getHeader('Location'))
447484
=== added file 'lib/lp/bugs/templates/bug-mute.pt'
--- lib/lp/bugs/templates/bug-mute.pt 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/templates/bug-mute.pt 2011-03-18 13:42:19 +0000
@@ -0,0 +1,32 @@
1<html
2 xmlns="http://www.w3.org/1999/xhtml"
3 xmlns:tal="http://xml.zope.org/namespaces/tal"
4 xmlns:metal="http://xml.zope.org/namespaces/metal"
5 xmlns:i18n="http://xml.zope.org/namespaces/i18n"
6 xml:lang="en"
7 lang="en"
8 dir="ltr"
9 metal:use-macro="view/macro:page/main_only"
10 i18n:domain="malone"
11>
12
13<body>
14 <div metal:fill-slot="main">
15
16 <div id="maincontent">
17 <div id="nonportlets" class="readable">
18 <p>
19 If you mute a bug you will receive no mail about the the bug
20 at all until you unmute it again.
21 </p>
22
23 <div metal:use-macro="context/@@launchpad_form/form">
24 </div>
25
26 </div>
27 </div>
28
29 </div>
30
31</body>
32</html>