Merge lp:~bac/launchpad/bug-770248 into lp:launchpad

Proposed by Brad Crittenden
Status: Merged
Approved by: Brad Crittenden
Approved revision: no longer in the source branch.
Merged at revision: 12920
Proposed branch: lp:~bac/launchpad/bug-770248
Merge into: lp:launchpad
Diff against target: 139 lines (+63/-8)
4 files modified
.bzrignore (+1/-0)
lib/lp/bugs/browser/tests/test_bug_views.py (+54/-5)
lib/lp/bugs/browser/tests/test_bugsubscription_views.py (+0/-1)
lib/lp/bugs/model/bug.py (+8/-2)
To merge this branch: bzr merge lp:~bac/launchpad/bug-770248
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+59047@code.launchpad.net

Commit message

[r=gmb][bug=770248] Show mute link on a bug page if a person is in a team with a structural subscription.

Description of the change

= Summary =

If a user's team has a structural subscription to a pillar then the mute
link should be shown.

== Proposed fix ==

Fix Bug. personIsAlsoNotifiedSubscriber to take team membership into
account.

== Pre-implementation notes ==

Chat with Gary.

== Implementation details ==

As above.

== Tests ==

bin/test -vvm -t test_bug_views

== Demo and Q/A ==

Create a structural subscription on a product for a team you administer.
 Go to a bug where you have no other subscriptions. See mute link.
Dance a little jig.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/bugs/browser/tests/test_bug_views.py
  lib/lp/bugs/model/bug.py
  lib/lp/bugs/browser/tests/test_bugsubscription_views.py

To post a comment you must log in.
Revision history for this message
Graham Binns (gmb) wrote :

Hi Brad,

Just one comment:

[1]

52 + def test_bug_mute_for_individual_structural_subscription(self):

This test is missing a comment stating the expected behaviour.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2011-03-30 20:39:26 +0000
3+++ .bzrignore 2011-04-26 13:02:35 +0000
4@@ -81,3 +81,4 @@
5 run.gdb
6 lib/canonical/launchpad/icing/icon-sprites
7 lib/canonical/launchpad/icing/icon-sprites.positioning
8+.emacs.desktop
9
10=== modified file 'lib/lp/bugs/browser/tests/test_bug_views.py'
11--- lib/lp/bugs/browser/tests/test_bug_views.py 2011-04-11 21:52:02 +0000
12+++ lib/lp/bugs/browser/tests/test_bug_views.py 2011-04-26 13:02:35 +0000
13@@ -17,7 +17,6 @@
14 from lp.services.features import get_relevant_feature_controller
15 from lp.testing import (
16 BrowserTestCase,
17- feature_flags,
18 person_logged_in,
19 TestCaseWithFactory,
20 )
21@@ -50,10 +49,14 @@
22 class TestBugPortletSubscribers(TestCaseWithFactory):
23
24 layer = DatabaseFunctionalLayer
25+ feature_flag_1 = 'malone.advanced-subscriptions.enabled'
26+ feature_flag_2 = 'malone.advanced-structural-subscriptions.enabled'
27
28 def setUp(self):
29 super(TestBugPortletSubscribers, self).setUp()
30- self.bug = self.factory.makeBug()
31+ self.target = self.factory.makeProduct()
32+ bug_owner = self.factory.makePerson(name="bug-owner")
33+ self.bug = self.factory.makeBug(owner=bug_owner, product=self.target)
34 # We need to put the Bug and default BugTask into the LaunchBag
35 # because BugContextMenu relies on the LaunchBag to populate its
36 # context property
37@@ -66,7 +69,7 @@
38 # the mute link will not be displayed to them.
39 person = self.factory.makePerson()
40 with person_logged_in(person):
41- with feature_flags():
42+ with FeatureFixture({self.feature_flag_2: None}):
43 # The user isn't subscribed or muted already.
44 self.assertFalse(self.bug.isSubscribed(person))
45 self.assertFalse(self.bug.isMuted(person))
46@@ -82,8 +85,7 @@
47 self.assertFalse('mute_subscription' in html)
48
49 def test_edit_subscriptions_link_shown_when_feature_enabled(self):
50- flag = 'malone.advanced-structural-subscriptions.enabled'
51- with FeatureFixture({flag: 'on'}):
52+ with FeatureFixture({self.feature_flag_2: 'on'}):
53 request = LaunchpadTestRequest()
54 request.features = get_relevant_feature_controller()
55 view = create_initialized_view(
56@@ -98,3 +100,50 @@
57 html = view.render()
58 self.assertTrue('menu-link-editsubscriptions' not in html)
59 self.assertTrue('/+subscriptions' not in html)
60+
61+ def test_bug_mute_for_individual_structural_subscription(self):
62+ # If the person has a structural subscription to the pillar,
63+ # then the mute link will be displayed to them.
64+ person = self.factory.makePerson(name="a-person")
65+ with FeatureFixture({self.feature_flag_1: 'on'}):
66+ with person_logged_in(person):
67+ self.target.addBugSubscription(person, person)
68+ self.assertFalse(self.bug.isMuted(person))
69+ view = create_initialized_view(
70+ self.bug, name="+portlet-subscribers")
71+ self.assertTrue(view.user_should_see_mute_link,
72+ "User should see mute link.")
73+ contents = view.render()
74+ self.assertTrue('mute_subscription' in contents,
75+ "'mute_subscription' not in contents.")
76+ create_initialized_view(
77+ self.bug.default_bugtask, name="+mute",
78+ form={'field.actions.mute': 'Mute bug mail'})
79+ self.assertTrue(self.bug.isMuted(person))
80+
81+ def test_mute_subscription_link_shown_for_team_subscription(self):
82+ # If the person belongs to a team with a structural subscription,
83+ # then the mute link will be displayed to them.
84+ person = self.factory.makePerson(name="a-person")
85+ team_owner = self.factory.makePerson(name="team-owner")
86+ team = self.factory.makeTeam(owner=team_owner, name="subscribed-team")
87+ with FeatureFixture({self.feature_flag_1: 'on'}):
88+ with person_logged_in(team_owner):
89+ team.addMember(person, team_owner)
90+ self.target.addBugSubscription(team, team_owner)
91+ with person_logged_in(person):
92+ self.assertFalse(self.bug.isMuted(person))
93+ self.assertTrue(
94+ self.bug.personIsAlsoNotifiedSubscriber(
95+ person), "Person should be a notified subscriber")
96+ view = create_initialized_view(
97+ self.bug, name="+portlet-subscribers")
98+ self.assertTrue(view.user_should_see_mute_link,
99+ "User should see mute link.")
100+ contents = view.render()
101+ self.assertTrue('mute_subscription' in contents,
102+ "'mute_subscription' not in contents.")
103+ create_initialized_view(
104+ self.bug.default_bugtask, name="+mute",
105+ form={'field.actions.mute': 'Mute bug mail'})
106+ self.assertTrue(self.bug.isMuted(person))
107
108=== modified file 'lib/lp/bugs/browser/tests/test_bugsubscription_views.py'
109--- lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2011-04-21 18:29:18 +0000
110+++ lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2011-04-26 13:02:35 +0000
111@@ -36,7 +36,6 @@
112 super(BugSubscriptionAdvancedFeaturesTestCase, self).setUp()
113 self.bug = self.factory.makeBug()
114 self.person = self.factory.makePerson()
115- self.team = self.factory.makeTeam()
116
117 def test_subscribe_uses_bug_notification_level(self):
118 # When a user subscribes to a bug using the advanced features on
119
120=== modified file 'lib/lp/bugs/model/bug.py'
121--- lib/lp/bugs/model/bug.py 2011-04-19 18:30:12 +0000
122+++ lib/lp/bugs/model/bug.py 2011-04-26 13:02:35 +0000
123@@ -1894,8 +1894,14 @@
124 # and assignees. As such, it's not possible to get them all with
125 # one query.
126 also_notified_subscribers = self.getAlsoNotifiedSubscribers()
127-
128- return person in also_notified_subscribers
129+ if person in also_notified_subscribers:
130+ return True
131+ # Otherwise check to see if the person is a member of any of the
132+ # subscribed teams.
133+ for subscriber in also_notified_subscribers:
134+ if subscriber.is_team and person.inTeam(subscriber):
135+ return True
136+ return False
137
138 def personIsSubscribedToDuplicate(self, person):
139 """See `IBug`."""