Merge lp:~danilo/launchpad/bug-772763-remove-nothing into lp:launchpad/db-devel

Proposed by Данило Шеган
Status: Merged
Approved by: Данило Шеган
Approved revision: no longer in the source branch.
Merged at revision: 10563
Proposed branch: lp:~danilo/launchpad/bug-772763-remove-nothing
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~danilo/launchpad/proper-bug-muting
Diff against target: 578 lines (+52/-188)
15 files modified
lib/lp/bugs/browser/bugsubscription.py (+4/-12)
lib/lp/bugs/browser/bugsubscriptionfilter.py (+8/-19)
lib/lp/bugs/browser/tests/test_bug_context_menu.py (+2/-1)
lib/lp/bugs/browser/tests/test_bugsubscription_views.py (+1/-79)
lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py (+3/-39)
lib/lp/bugs/enum.py (+0/-11)
lib/lp/bugs/interfaces/bug.py (+1/-2)
lib/lp/bugs/model/bug.py (+3/-3)
lib/lp/bugs/model/personsubscriptioninfo.py (+16/-6)
lib/lp/bugs/model/tests/test_bug.py (+4/-4)
lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py (+2/-2)
lib/lp/bugs/model/tests/test_personsubscriptioninfo.py (+1/-3)
lib/lp/bugs/stories/webservice/xx-bug.txt (+2/-2)
lib/lp/bugs/tests/test_bug.py (+2/-2)
lib/lp/bugs/tests/test_structuralsubscription.py (+3/-3)
To merge this branch: bzr merge lp:~danilo/launchpad/bug-772763-remove-nothing
Reviewer Review Type Date Requested Status
Stuart Bishop (community) Abstain
Graham Binns (community) code Approve
Review via email: mp+61251@code.launchpad.net

Commit message

[r=gmb][bug=772763][incr] Remove BugNotificationLevel.NOTHING enum option since we don't use it for muting anymore.

Description of the change

= Bug 772763: Remove BugNotificationLevel.NOTHING =

Remove BugNotificationLevel.NOTHING value from the enum and adapt the code to not depend on it. Previous (prerequisite) branch has already changed bug muting to not use this level, so now it's mostly about removing it from the tests and bits of UI code, and as the default level for a bunch of methods.

In a few tests, I had to replace the old call (used to be compatible with bug.mute()) bug.subscribe(..., level=NOTHING) with the appropriate bug.mute(...) call.

Most of the code is simplified with this removal.

I didn't fix lint issues in xx-bug.txt because it simply has too many of them.

== Tests ==

bin/test -cvvm lp.bugs

== Demo and Q/A ==

Go to a bug page and play with muting/unmuting a bug.
You'll need to turn the malone.advanced-subscriptions.enabled feature flag to on.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py
  lib/lp/bugs/model/bugnotification.py
  lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py
  database/schema/patch-2208-70-0.sql
  lib/lp/bugs/configure.zcml
  lib/lp/bugs/tests/test_structuralsubscription.py
  lib/lp/bugs/model/tests/test_bug.py
  lib/lp/bugs/enum.py
  database/schema/comments.sql
  lib/lp/bugs/tests/test_bugnotification.py
  database/schema/security.cfg
  lib/lp/bugs/stories/webservice/xx-bug.txt
  lib/lp/bugs/model/bugsubscriptionfilter.py
  lib/lp/bugs/scripts/tests/test_bugnotification.py
  lib/lp/bugs/browser/bugsubscriptionfilter.py
  lib/lp/bugs/model/bug.py
  lib/lp/bugs/browser/tests/test_bugsubscription_views.py
  lib/lp/bugs/browser/bugsubscription.py
  lib/lp/bugs/tests/test_bugchanges.py
  lib/lp/bugs/model/personsubscriptioninfo.py
  lib/lp/bugs/scripts/bugnotification.py
  lib/lp/bugs/model/tests/test_personsubscriptioninfo.py
  lib/lp/bugs/tests/test_bug.py
  lib/lp/registry/model/person.py
  lib/lp/bugs/browser/tests/test_bug_context_menu.py
  lib/lp/bugs/interfaces/bugnotification.py
  lib/lp/bugs/interfaces/bug.py

./lib/lp/bugs/stories/webservice/xx-bug.txt
      13: source has bad indentation.
      53: want exceeds 78 characters.
      61: source has bad indentation.
      67: source has bad indentation.
      74: source has bad indentation.
     165: source has bad indentation.
     170: source exceeds 78 characters.
     176: source exceeds 78 characters.
     182: source has bad indentation.
     194: source has bad indentation.
     205: source has bad indentation.
     211: source has bad indentation.
     221: source has bad indentation.
     232: source has bad indentation.
     250: source has bad indentation.
     253: source has bad indentation.
     260: source has bad indentation.
     265: source exceeds 78 characters.
     265: source has bad indentation.
     271: source has bad indentation.
     281: source has bad indentation.
     292: source has bad indentation.
     301: source has bad indentation.
     316: source has bad indentation.
     322: source has bad indentation.
     349: want exceeds 78 characters.
     354: source has bad indentation.
     359: source has bad indentation.
     364: source has bad indentation.
     370: source has bad indentation.
     374: source has bad indentation.
     378: source has bad indentation.
     385: source has bad indentation.
     389: source has bad indentation.
     395: source has bad indentation.
     398: source has bad indentation.
     402: source has bad indentation.
     408: source has bad indentation.
     414: source has bad indentation.
     418: source has bad indentation.
     426: source has bad indentation.
     429: source has bad indentation.
     434: source has bad indentation.
     440: source has bad indentation.
     446: source has bad indentation.
     452: source has bad indentation.
     460: source has bad indentation.
     473: source has bad indentation.
     482: source has bad indentation.
     492: source has bad indentation.
     502: source has bad indentation.
     512: source has bad indentation.
     523: source has bad indentation.
     549: source has bad indentation.
     559: source has bad indentation.
     568: source has bad indentation.
     578: source has bad indentation.
     827: source has bad indentation.
     851: source has bad indentation.
     863: source exceeds 78 characters.
     863: source has bad indentation.
    1057: source has bad indentation.
    1062: source has bad indentation.
    1066: source has bad indentation.
    1085: source has bad indentation.
    1091: source has bad indentation.
    1096: source has bad indentation.
    1099: source has bad indentation.
    1103: source has bad indentation.
    1109: source has bad indentation.
    1122: source has bad indentation.
    1136: source has bad indentation.
    1160: source has bad indentation.
    1162: source has bad indentation.
    1175: want exceeds 78 characters.
    1180: source has bad indentation.
    1201: source has bad indentation.
    1212: source has bad indentation.
    1217: want exceeds 78 characters.
    1253: source has bad indentation.
    1263: source has bad indentation.
    1276: source has bad indentation.
    1295: source has bad indentation.
    1309: source has bad indentation.
    1317: source has bad indentation.
    1319: source has bad indentation.
    1326: source has bad indentation.
    1329: source has bad indentation.
    1332: source has bad indentation.
    1338: source has bad indentation.
    1340: want exceeds 78 characters.
    1353: source has bad indentation.
    1364: source has bad indentation.
    1370: source has bad indentation.
    1382: source has bad indentation.
    1388: source has bad indentation.
    1391: want exceeds 78 characters.
    1646: source exceeds 78 characters.
    2019: source exceeds 78 characters.
    2079: narrative exceeds 78 characters.
    2124: source has bad indentation.
    2135: source has bad indentation.
./lib/lp/registry/model/person.py
    3849: local variable 'karma_total' is assigned to but never used

To post a comment you must log in.
Revision history for this message
Данило Шеган (danilo) wrote :

Stuart, no need for you to review this branch, lp-propose added you automatically because a pre-requisite branch has a DB patch I guess.

Revision history for this message
Graham Binns (gmb) :
review: Approve (code)
Revision history for this message
Stuart Bishop (stub) :
review: Abstain

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/browser/bugsubscription.py'
2--- lib/lp/bugs/browser/bugsubscription.py 2011-05-17 15:51:37 +0000
3+++ lib/lp/bugs/browser/bugsubscription.py 2011-05-17 16:31:11 +0000
4@@ -43,7 +43,7 @@
5 from lp.bugs.browser.structuralsubscription import (
6 expose_structural_subscription_data_to_js,
7 )
8-from lp.bugs.enum import BugNotificationLevel, HIDDEN_BUG_NOTIFICATION_LEVELS
9+from lp.bugs.enum import BugNotificationLevel
10 from lp.bugs.interfaces.bugsubscription import IBugSubscription
11 from lp.bugs.model.personsubscriptioninfo import PersonSubscriptions
12 from lp.bugs.model.structuralsubscription import (
13@@ -121,17 +121,12 @@
14 SimpleTerm(
15 level, level.title,
16 self._bug_notification_level_descriptions[level])
17- # We reorder the items so that COMMENTS comes first. We also
18- # drop the NOTHING option since it just makes the UI
19- # confusing.
20- for level in sorted(BugNotificationLevel.items, reverse=True)
21- if level not in HIDDEN_BUG_NOTIFICATION_LEVELS]
22+ # We reorder the items so that COMMENTS comes first.
23+ for level in sorted(BugNotificationLevel.items, reverse=True)]
24 bug_notification_vocabulary = SimpleVocabulary(
25 bug_notification_level_terms)
26
27- if (self.current_user_subscription is not None and
28- self.current_user_subscription.bug_notification_level not in
29- HIDDEN_BUG_NOTIFICATION_LEVELS):
30+ if self.current_user_subscription is not None:
31 default_value = (
32 self.current_user_subscription.bug_notification_level)
33 else:
34@@ -556,9 +551,6 @@
35 for subscription in direct_subscriptions:
36 if not check_permission('launchpad.View', subscription.person):
37 continue
38- if (subscription.bug_notification_level ==
39- BugNotificationLevel.NOTHING):
40- continue
41 if subscription.person == self.user:
42 can_unsubscribe = [subscription] + can_unsubscribe
43 elif subscription.canBeUnsubscribedByUser(self.user):
44
45=== modified file 'lib/lp/bugs/browser/bugsubscriptionfilter.py'
46--- lib/lp/bugs/browser/bugsubscriptionfilter.py 2011-02-08 16:21:39 +0000
47+++ lib/lp/bugs/browser/bugsubscriptionfilter.py 2011-05-17 16:31:11 +0000
48@@ -65,16 +65,10 @@
49 description = self.context.description
50 return u"" if description is None else description.strip()
51
52- @property
53- def filters_everything(self):
54- """Return a boolean as to whether the filter masks everything.
55-
56- Right now the only thing we check is the bug_notification_level. We
57- could check more later--in particular, if no importances are checked,
58- or no statuses.
59- """
60- return (self.context.bug_notification_level ==
61- BugNotificationLevel.NOTHING)
62+ # At the moment, we never filter everything.
63+ # We could turn it into a property and check more later--
64+ # in particular, if no importances are checked, or no statuses.
65+ filters_everything = False
66
67 @property
68 def conditions(self):
69@@ -82,15 +76,10 @@
70 conditions = []
71 bug_notification_level = self.context.bug_notification_level
72 if bug_notification_level < BugNotificationLevel.COMMENTS:
73- if bug_notification_level == BugNotificationLevel.NOTHING:
74- return conditions # The template should use
75- # filters_everything to determine whether the conditions
76- # should be rendered.
77- else:
78- mapping = bug_notification_level_description_mapping(
79- 'the bug')
80- conditions.append(
81- mapping[bug_notification_level].lower()[:-1])
82+ mapping = bug_notification_level_description_mapping(
83+ 'the bug')
84+ conditions.append(
85+ mapping[bug_notification_level].lower()[:-1])
86 statuses = self.context.statuses
87 if len(statuses) > 0:
88 conditions.append(
89
90=== modified file 'lib/lp/bugs/browser/tests/test_bug_context_menu.py'
91--- lib/lp/bugs/browser/tests/test_bug_context_menu.py 2011-05-17 11:42:14 +0000
92+++ lib/lp/bugs/browser/tests/test_bug_context_menu.py 2011-05-17 16:31:11 +0000
93@@ -74,7 +74,8 @@
94 with feature_flags():
95 with person_logged_in(person):
96 self.bug.subscribe(
97- person, person, level=BugNotificationLevel.NOTHING)
98+ person, person, level=BugNotificationLevel.METADATA)
99+ self.bug.mute(person, person)
100 request = LaunchpadTestRequest()
101 request.features = get_relevant_feature_controller()
102 view = create_initialized_view(
103
104=== modified file 'lib/lp/bugs/browser/tests/test_bugsubscription_views.py'
105--- lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2011-05-17 11:42:14 +0000
106+++ lib/lp/bugs/browser/tests/test_bugsubscription_views.py 2011-05-17 16:31:11 +0000
107@@ -49,12 +49,9 @@
108 with person_logged_in(bug.owner):
109 bug.unsubscribe(bug.owner, bug.owner)
110
111- # We don't display BugNotificationLevel.NOTHING as an option.
112- # This is tested below.
113 with FeatureFixture({self.feature_flag: ON}):
114 displayed_levels = [
115- level for level in BugNotificationLevel.items
116- if level != BugNotificationLevel.NOTHING]
117+ level for level in BugNotificationLevel.items]
118 for level in displayed_levels:
119 person = self.factory.makePerson()
120 with person_logged_in(person):
121@@ -74,28 +71,6 @@
122 level.title,
123 subscription.bug_notification_level.title))
124
125- def test_nothing_is_not_a_valid_level(self):
126- # BugNotificationLevel.NOTHING isn't considered valid when
127- # someone is trying to subscribe.
128- bug = self.factory.makeBug()
129- person = self.factory.makePerson()
130- with FeatureFixture({self.feature_flag: ON}):
131- with person_logged_in(person):
132- level = BugNotificationLevel.NOTHING
133- harness = LaunchpadFormHarness(
134- bug.default_bugtask, BugSubscriptionSubscribeSelfView)
135- form_data = {
136- 'field.subscription': person.name,
137- 'field.bug_notification_level': level.title,
138- }
139- harness.submit('continue', form_data)
140- self.assertTrue(harness.hasErrors())
141- self.assertEqual(
142- 'Invalid value',
143- harness.getFieldError('bug_notification_level'),
144- "The view should treat BugNotificationLevel.NOTHING "
145- "as an invalid value.")
146-
147 def test_user_can_update_subscription(self):
148 # A user can update their bug subscription using the
149 # BugSubscriptionSubscribeSelfView.
150@@ -255,31 +230,6 @@
151 self.assertFalse(
152 harness.view.widgets['bug_notification_level'].visible)
153
154- def test_bug_721400(self):
155- # If a subscription exists with a BugNotificationLevel of
156- # NOTHING the view will still render correctly, even though
157- # NOTHING is not accepted as a valid value for the
158- # bug_notification_level field.
159- # This is a regression test for bug 721400.
160- bug = self.factory.makeBug()
161- person = self.factory.makePerson()
162- with person_logged_in(person):
163- bug.subscribe(
164- person, person, level=BugNotificationLevel.NOTHING)
165-
166- with FeatureFixture({self.feature_flag: ON}):
167- with person_logged_in(person):
168- subscribe_view = create_initialized_view(
169- bug.default_bugtask, name='+subscribe')
170- self.assertEqual(0, len(subscribe_view.errors))
171- bug_notification_level_widget = (
172- subscribe_view.widgets['bug_notification_level'])
173- default_notification_level_value = (
174- bug_notification_level_widget._getDefault())
175- self.assertEqual(
176- BugNotificationLevel.COMMENTS,
177- default_notification_level_value)
178-
179 def test_muted_subs_have_unmute_option(self):
180 # If a user has a muted subscription, the
181 # BugSubscriptionSubscribeSelfView's subscription field will
182@@ -449,34 +399,6 @@
183 harness.view.initialize()
184
185
186-class BugPortletSubscribersContentsTestCase(TestCaseWithFactory):
187- """Tests for the BugPortletSubscribersContents view."""
188-
189- layer = LaunchpadFunctionalLayer
190-
191- def setUp(self):
192- super(BugPortletSubscribersContentsTestCase, self).setUp()
193- self.bug = self.factory.makeBug()
194- self.subscriber = self.factory.makePerson()
195-
196- def test_sorted_direct_subscriptions_doesnt_show_mutes(self):
197- # BugPortletSubscribersContents.sorted_direct_subscriptions does
198- # not return muted subscriptions.
199- with person_logged_in(self.subscriber):
200- subscription = self.bug.subscribe(
201- self.subscriber, self.subscriber,
202- level=BugNotificationLevel.NOTHING)
203- view = create_initialized_view(
204- self.bug, name="+bug-portlet-subscribers-content")
205- # Loop over the results of sorted_direct_subscriptions to
206- # extract the subscriptions from their
207- # SubscriptionAttrDecorator intances.
208- sorted_subscriptions = [
209- decorator.subscription for decorator in
210- view.sorted_direct_subscriptions]
211- self.assertFalse(subscription in sorted_subscriptions)
212-
213-
214 class BugMuteSelfViewTestCase(TestCaseWithFactory):
215 """Tests for the BugMuteSelfView."""
216
217
218=== modified file 'lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py'
219--- lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py 2011-03-30 15:20:46 +0000
220+++ lib/lp/bugs/browser/tests/test_bugsubscriptionfilter.py 2011-05-17 16:31:11 +0000
221@@ -251,18 +251,6 @@
222 # If nothing is set the conditions list is empty.
223 self.assertEqual([], self.view.conditions)
224
225- def test_conditions_with_no_events_subscribed(self):
226- with person_logged_in(self.owner):
227- self.subscription_filter.bug_notification_level = (
228- BugNotificationLevel.NOTHING)
229- self.assertEqual([], self.view.conditions)
230-
231- def test_filters_everything_with_no_events_subscribed(self):
232- with person_logged_in(self.owner):
233- self.subscription_filter.bug_notification_level = (
234- BugNotificationLevel.NOTHING)
235- self.failUnless(self.view.filters_everything)
236-
237 def test_not_filters_everything_normally(self):
238 self.failIf(self.view.filters_everything)
239
240@@ -384,9 +372,7 @@
241 u"There are no filter conditions!")
242
243 def test_render_with_no_events_allowed(self):
244- with person_logged_in(self.owner):
245- self.subscription_filter.bug_notification_level = (
246- BugNotificationLevel.NOTHING)
247+ self.view.filters_everything = True
248 self.assertRender(
249 u"This filter allows no mail through.",
250 u"")
251@@ -507,10 +493,8 @@
252 # When advanced features are turned on for subscriptions a user
253 # can specify a bug_notification_level on the +filter form.
254 with feature_flags():
255- # We don't display BugNotificationLevel.NOTHING as an option.
256 displayed_levels = [
257- level for level in BugNotificationLevel.items
258- if level != BugNotificationLevel.NOTHING]
259+ level for level in BugNotificationLevel.items]
260 for level in displayed_levels:
261 person = self.factory.makePerson()
262 with person_logged_in(person):
263@@ -526,7 +510,7 @@
264 'field.bug_notification_level': level.title,
265 "field.actions.create": "Create",
266 }
267- view = create_initialized_view(
268+ create_initialized_view(
269 subscription, name="+new-filter", form=form)
270
271 filters = subscription.bug_filters
272@@ -539,26 +523,6 @@
273 "is actually %s." % (
274 level.name, new_filter.bug_notification_level.name))
275
276- def test_nothing_is_not_a_valid_level(self):
277- # BugNotificationLevel.NOTHING isn't considered valid when a
278- # user is subscribing via the web UI.
279- person = self.factory.makePerson()
280- with person_logged_in(person):
281- subscription = self.target.addBugSubscription(person, person)
282- form = {
283- "field.description": "New description",
284- "field.statuses": ["NEW", "INCOMPLETE"],
285- "field.importances": ["LOW", "MEDIUM"],
286- "field.tags": u"foo bar",
287- "field.find_all_tags": "on",
288- 'field.bug_notification_level': BugNotificationLevel.NOTHING,
289- "field.actions.create": "Create",
290- }
291- with feature_flags():
292- view = create_initialized_view(
293- subscription, name="+new-filter", form=form)
294- self.assertTrue(view.errors)
295-
296 def test_extra_features_hidden_without_feature_flag(self):
297 # If the malone.advanced-subscriptions.enabled flag is turned
298 # off, the bug_notification_level field doesn't appear on the
299
300=== modified file 'lib/lp/bugs/enum.py'
301--- lib/lp/bugs/enum.py 2011-03-05 03:28:12 +0000
302+++ lib/lp/bugs/enum.py 2011-05-17 16:31:11 +0000
303@@ -7,7 +7,6 @@
304 __all__ = [
305 'BugNotificationLevel',
306 'BugNotificationStatus',
307- 'HIDDEN_BUG_NOTIFICATION_LEVELS',
308 ]
309
310 from lazr.enum import (
311@@ -22,12 +21,6 @@
312 The type and volume of bug notification email sent to subscribers.
313 """
314
315- NOTHING = DBItem(10, """
316- Nothing
317-
318- Don't send any notifications about bugs.
319- """)
320-
321 LIFECYCLE = DBItem(20, """
322 Lifecycle
323
324@@ -51,10 +44,6 @@
325 """)
326
327
328-# The set of bug notification levels that won't be displayed in the UI.
329-HIDDEN_BUG_NOTIFICATION_LEVELS = [BugNotificationLevel.NOTHING]
330-
331-
332 class BugNotificationStatus(DBEnumeratedType):
333 """The status of a bug notification.
334
335
336=== modified file 'lib/lp/bugs/interfaces/bug.py'
337--- lib/lp/bugs/interfaces/bug.py 2011-05-17 15:51:37 +0000
338+++ lib/lp/bugs/interfaces/bug.py 2011-05-17 16:31:11 +0000
339@@ -492,8 +492,7 @@
340 def isMuted(person):
341 """Does person have a muted subscription on this bug?
342
343- :returns: True if the user has a direct subscription to this bug
344- with a BugNotificationLevel of NOTHING.
345+ :returns: True if the user has muted all email from this bug.
346 """
347
348 @operation_parameters(
349
350=== modified file 'lib/lp/bugs/model/bug.py'
351--- lib/lp/bugs/model/bug.py 2011-05-17 15:51:37 +0000
352+++ lib/lp/bugs/model/bug.py 2011-05-17 16:31:11 +0000
353@@ -902,7 +902,7 @@
354 BugSubscription.bug_id == self.id).order_by(BugSubscription.id)
355 return DecoratedResultSet(results, operator.itemgetter(1))
356
357- def getSubscriptionInfo(self, level=BugNotificationLevel.NOTHING):
358+ def getSubscriptionInfo(self, level=BugNotificationLevel.LIFECYCLE):
359 """See `IBug`."""
360 return BugSubscriptionInfo(self, level)
361
362@@ -919,7 +919,7 @@
363 it.
364 """
365 if level is None:
366- level = BugNotificationLevel.NOTHING
367+ level = BugNotificationLevel.LIFECYCLE
368 subscriptions = self.getSubscriptionInfo(level).direct_subscriptions
369 if recipients is not None:
370 for subscriber in subscriptions.subscribers:
371@@ -974,7 +974,7 @@
372 return []
373
374 if level is None:
375- level = BugNotificationLevel.NOTHING
376+ level = BugNotificationLevel.LIFECYCLE
377 info = self.getSubscriptionInfo(level)
378
379 if recipients is not None:
380
381=== modified file 'lib/lp/bugs/model/personsubscriptioninfo.py'
382--- lib/lp/bugs/model/personsubscriptioninfo.py 2011-04-15 10:24:58 +0000
383+++ lib/lp/bugs/model/personsubscriptioninfo.py 2011-05-17 16:31:11 +0000
384@@ -11,9 +11,8 @@
385 from zope.interface import implements
386 from zope.proxy import sameProxiedObjects
387
388-from lp.bugs.enum import BugNotificationLevel
389 from lp.bugs.model.bugsubscription import BugSubscription
390-from lp.bugs.model.bug import Bug
391+from lp.bugs.model.bug import Bug, BugMute
392 from lp.bugs.interfaces.personsubscriptioninfo import (
393 IAbstractSubscriptionInfoCollection,
394 IRealSubscriptionInfoCollection,
395@@ -219,6 +218,18 @@
396 pillar.security_contact, pillar.bug_supervisor)
397 return (direct, duplicates)
398
399+ def _isMuted(self, person, bug):
400+ store = Store.of(person)
401+ mutes = store.find(
402+ BugMute,
403+ BugMute.bug == bug,
404+ BugMute.person == person)
405+ is_muted = mutes.one()
406+ if is_muted is None:
407+ return False
408+ else:
409+ return True
410+
411 def loadSubscriptionsFor(self, person, bug):
412 self.person = person
413 self.administrated_teams = person.getAdministratedTeams()
414@@ -228,6 +239,9 @@
415 direct, from_duplicate = (
416 self._getDirectAndDuplicateSubscriptions(person, bug))
417
418+ # Then get the 'muted' flag.
419+ self.muted = self._isMuted(person, bug)
420+
421 # Then get owner and assignee virtual subscriptions.
422 as_owner = VirtualSubscriptionInfoCollection(
423 self.person, self.administrated_teams)
424@@ -241,10 +255,6 @@
425 assignee = bugtask.assignee
426 if person.inTeam(assignee):
427 as_assignee.add(assignee, bug, pillar, bugtask)
428- self.muted = bool(
429- direct.personal and
430- direct.personal[0].subscription.bug_notification_level
431- == BugNotificationLevel.NOTHING)
432 self.count = 0
433 for name, collection in (
434 ('direct', direct), ('from_duplicate', from_duplicate),
435
436=== modified file 'lib/lp/bugs/model/tests/test_bug.py'
437--- lib/lp/bugs/model/tests/test_bug.py 2011-04-20 14:58:11 +0000
438+++ lib/lp/bugs/model/tests/test_bug.py 2011-05-17 16:31:11 +0000
439@@ -181,7 +181,7 @@
440
441 def test_get_direct_subscribers_default_level(self):
442 # If no `level` parameter is passed to getDirectSubscribers(),
443- # the assumed `level` is BugNotification.NOTHING.
444+ # the assumed `level` is BugNotification.LIFECYCLE.
445 bug = self.factory.makeBug()
446 # We unsubscribe the bug's owner because if we don't there will
447 # be two COMMENTS-level subscribers.
448@@ -196,7 +196,7 @@
449
450 # All the subscribers should be returned by
451 # getDirectSubscribers() because it defaults to returning
452- # subscribers at level NOTHING, which everything is higher than.
453+ # subscribers at level LIFECYCLE, which everything is higher than.
454 direct_subscribers = bug.getDirectSubscribers()
455 self.assertEqual(
456 set(subscribers), set(direct_subscribers),
457@@ -241,7 +241,7 @@
458 subscriber = self.factory.makePerson()
459 with person_logged_in(subscriber):
460 bug.subscribe(
461- subscriber, subscriber, level=BugNotificationLevel.NOTHING)
462+ subscriber, subscriber, level=BugNotificationLevel.LIFECYCLE)
463 duplicate_bug.subscribe(
464 subscriber, subscriber, level=BugNotificationLevel.METADATA)
465 duplicate_subscribers = bug.getSubscribersFromDuplicates()
466@@ -256,7 +256,7 @@
467 info = bug.getSubscriptionInfo()
468 self.assertIsInstance(info, BugSubscriptionInfo)
469 self.assertEqual(bug, info.bug)
470- self.assertEqual(BugNotificationLevel.NOTHING, info.level)
471+ self.assertEqual(BugNotificationLevel.LIFECYCLE, info.level)
472 # A level can also be specified.
473 with person_logged_in(bug.owner):
474 info = bug.getSubscriptionInfo(BugNotificationLevel.METADATA)
475
476=== modified file 'lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py'
477--- lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py 2011-04-27 16:01:06 +0000
478+++ lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py 2011-05-17 16:31:11 +0000
479@@ -130,7 +130,7 @@
480
481 def getInfo(self):
482 return BugSubscriptionInfo(
483- self.bug, BugNotificationLevel.NOTHING)
484+ self.bug, BugNotificationLevel.LIFECYCLE)
485
486 def test_direct(self):
487 # The set of direct subscribers.
488@@ -370,7 +370,7 @@
489 self.target = self.factory.makeProduct()
490 self.bug = self.factory.makeBug(product=self.target)
491 self.info = BugSubscriptionInfo(
492- self.bug, BugNotificationLevel.NOTHING)
493+ self.bug, BugNotificationLevel.LIFECYCLE)
494 # Get the Storm cache into a known state.
495 self.store = Store.of(self.bug)
496 self.store.invalidate()
497
498=== modified file 'lib/lp/bugs/model/tests/test_personsubscriptioninfo.py'
499--- lib/lp/bugs/model/tests/test_personsubscriptioninfo.py 2011-04-15 10:24:58 +0000
500+++ lib/lp/bugs/model/tests/test_personsubscriptioninfo.py 2011-05-17 16:31:11 +0000
501@@ -8,7 +8,6 @@
502 from zope.security.proxy import removeSecurityProxy
503
504 from canonical.testing import DatabaseFunctionalLayer
505-from lp.bugs.enum import BugNotificationLevel
506 from lp.bugs.interfaces.personsubscriptioninfo import (
507 IRealSubscriptionInfo,
508 IRealSubscriptionInfoCollection,
509@@ -482,8 +481,7 @@
510 def test_is_muted(self):
511 # Subscribed directly to the bug, muted.
512 with person_logged_in(self.subscriber):
513- self.bug.subscribe(self.subscriber, self.subscriber,
514- level=BugNotificationLevel.NOTHING)
515+ self.bug.mute(self.subscriber, self.subscriber)
516
517 # Load a `PersonSubscriptionInfo`s for subscriber and a bug.
518 self.subscriptions.reload()
519
520=== modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt'
521--- lib/lp/bugs/stories/webservice/xx-bug.txt 2011-04-12 11:36:11 +0000
522+++ lib/lp/bugs/stories/webservice/xx-bug.txt 2011-05-17 16:31:11 +0000
523@@ -902,13 +902,13 @@
524
525 They can also update the subscription's bug_notification_level directly.
526
527- >>> patch = {u'bug_notification_level': u'Nothing'}
528+ >>> patch = {u'bug_notification_level': u'Lifecycle'}
529 >>> pprint_entry(
530 ... webservice.patch(
531 ... new_subscription['self_link'], 'application/json',
532 ... dumps(patch), api_version="devel").jsonBody())
533 bug_link: u'.../bugs/1'
534- bug_notification_level: u'Nothing'...
535+ bug_notification_level: u'Lifecycle'...
536
537 If one person tries to unsubscribe another individual, the web
538 service will return an unauthorized error.
539
540=== modified file 'lib/lp/bugs/tests/test_bug.py'
541--- lib/lp/bugs/tests/test_bug.py 2011-05-17 15:51:37 +0000
542+++ lib/lp/bugs/tests/test_bug.py 2011-05-17 16:31:11 +0000
543@@ -46,8 +46,8 @@
544 self.assertEqual(True, self.bug.isMuted(self.person))
545
546 def test_is_muted_returns_false_for_direct_subscribers(self):
547- # Bug.isMuted() will return False if the user has a subscription
548- # with BugNotificationLevel that's not NOTHING.
549+ # Bug.isMuted() will return False if the user has a
550+ # regular subscription.
551 with person_logged_in(self.person):
552 self.bug.subscribe(
553 self.person, self.person, level=BugNotificationLevel.METADATA)
554
555=== modified file 'lib/lp/bugs/tests/test_structuralsubscription.py'
556--- lib/lp/bugs/tests/test_structuralsubscription.py 2011-04-03 00:53:10 +0000
557+++ lib/lp/bugs/tests/test_structuralsubscription.py 2011-05-17 16:31:11 +0000
558@@ -154,7 +154,7 @@
559 self.initial_filter = self.subscription.bug_filters[0]
560
561 def assertSubscribers(
562- self, expected_subscribers, level=BugNotificationLevel.NOTHING):
563+ self, expected_subscribers, level=BugNotificationLevel.LIFECYCLE):
564 observed_subscribers = list(
565 get_structural_subscribers(self.bugtask, None, level))
566 self.assertEqual(expected_subscribers, observed_subscribers)
567@@ -208,9 +208,9 @@
568 self.initial_filter.bug_notification_level = (
569 BugNotificationLevel.METADATA)
570
571- # The subscription is found when looking for NOTHING or above.
572+ # The subscription is found when looking for LIFECYCLE or above.
573 self.assertSubscribers(
574- [self.ordinary_subscriber], BugNotificationLevel.NOTHING)
575+ [self.ordinary_subscriber], BugNotificationLevel.LIFECYCLE)
576 # The subscription is found when looking for METADATA or above.
577 self.assertSubscribers(
578 [self.ordinary_subscriber], BugNotificationLevel.METADATA)

Subscribers

People subscribed via source and target branches

to status/vote changes: