Merge lp:~bac/launchpad/bugjam-579502 into lp:launchpad

Proposed by Brad Crittenden
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 12145
Proposed branch: lp:~bac/launchpad/bugjam-579502
Merge into: lp:launchpad
Diff against target: 588 lines (+159/-59)
11 files modified
lib/lp/bugs/doc/bug-heat.txt (+12/-14)
lib/lp/bugs/doc/bugnotification-sending.txt (+10/-12)
lib/lp/bugs/doc/bugzilla-import.txt (+0/-3)
lib/lp/bugs/doc/initial-bug-contacts.txt (+0/-1)
lib/lp/bugs/model/bug.py (+10/-6)
lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt (+0/-5)
lib/lp/bugs/subscribers/bug.py (+1/-1)
lib/lp/bugs/tests/test_bugchanges.py (+4/-3)
lib/lp/bugs/tests/test_bugnotification.py (+114/-7)
lib/lp/bugs/tests/test_bugs_webservice.py (+6/-6)
lib/lp/bugs/tests/test_bugtask_search.py (+2/-1)
To merge this branch: bzr merge lp:~bac/launchpad/bugjam-579502
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+44302@code.launchpad.net

Commit message

[r=sinzui][ui=none][bug=579502] Do not send bug email to distro owner if the distro does not use Lauchpad for bugs.

Description of the change

= Summary =

If product or distro does not use Launchpad for bugs then the owner
should not be notified of bug state changes.

== Proposed fix ==

Check official_malone before adding the registrant.

== Pre-implementation notes ==

Talk with Curtis.

== Implementation details ==

As above.

== Tests ==

bin/test -vvm lp.bugs -t test_bugnotification

== Demo and Q/A ==

Create a distribution doesn't use Launchpad for bugs. Create a bugtask
affecting the distro as a different user. Ensure the distro owner does
not get an email. (Will this work? Need to find out about qastaging and
sending email.)

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/bugs/subscribers/bug.py
  lib/lp/bugs/tests/test_bugnotification.py
  lib/lp/bugs/model/bug.py

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

This looks good to land. I think this will do a lot to stop the avalanche of email.

review: Approve (code)
Revision history for this message
Brad Crittenden (bac) wrote :

Curtis I discovered many more test that depended upon the pillar owner receiving email notification. The diff for the fixes is at http://pastebin.ubuntu.com/546917/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/doc/bug-heat.txt'
--- lib/lp/bugs/doc/bug-heat.txt 2010-12-22 20:46:21 +0000
+++ lib/lp/bugs/doc/bug-heat.txt 2010-12-23 19:45:24 +0000
@@ -80,52 +80,52 @@
8080
81 >>> changed = bug.setPrivate(True, bug_owner)81 >>> changed = bug.setPrivate(True, bug_owner)
82 >>> bug.heat82 >>> bug.heat
83 15883 156
8484
85Setting the bug as security related adds another 250 heat points.85Setting the bug as security related adds another 250 heat points.
8686
87 >>> changed = bug.setSecurityRelated(True)87 >>> changed = bug.setSecurityRelated(True)
88 >>> bug.heat88 >>> bug.heat
89 40889 406
9090
91Marking the bug public removes 150 heat points.91Marking the bug public removes 150 heat points.
9292
93 >>> changed = bug.setPrivate(False, bug_owner)93 >>> changed = bug.setPrivate(False, bug_owner)
94 >>> bug.heat94 >>> bug.heat
95 25895 256
9696
97And marking it not security-related removes 250 points.97And marking it not security-related removes 250 points.
9898
99 >>> changed = bug.setSecurityRelated(False)99 >>> changed = bug.setSecurityRelated(False)
100 >>> bug.heat100 >>> bug.heat
101 8101 6
102102
103Adding a subscriber to the bug increases its heat by 2 points.103Adding a subscriber to the bug increases its heat by 2 points.
104104
105 >>> new_subscriber = factory.makePerson()105 >>> new_subscriber = factory.makePerson()
106 >>> subscription = bug.subscribe(new_subscriber, new_subscriber)106 >>> subscription = bug.subscribe(new_subscriber, new_subscriber)
107 >>> bug.heat107 >>> bug.heat
108 10108 8
109109
110When a user unsubscribes, the bug loses 2 points of heat.110When a user unsubscribes, the bug loses 2 points of heat.
111111
112 >>> bug.unsubscribe(new_subscriber, new_subscriber)112 >>> bug.unsubscribe(new_subscriber, new_subscriber)
113 >>> bug.heat113 >>> bug.heat
114 8114 6
115115
116Should a user mark themselves as affected by the bug, it will gain 4116Should a user mark themselves as affected by the bug, it will gain 4
117points of heat.117points of heat.
118118
119 >>> bug.markUserAffected(new_subscriber)119 >>> bug.markUserAffected(new_subscriber)
120 >>> bug.heat120 >>> bug.heat
121 12121 10
122122
123If a user who was previously affected marks themself as not affected,123If a user who was previously affected marks themself as not affected,
124the bug loses 4 points of heat.124the bug loses 4 points of heat.
125125
126 >>> bug.markUserAffected(new_subscriber, False)126 >>> bug.markUserAffected(new_subscriber, False)
127 >>> bug.heat127 >>> bug.heat
128 8128 6
129129
130If a user who wasn't affected by the bug marks themselve as explicitly130If a user who wasn't affected by the bug marks themselve as explicitly
131unaffected, the bug's heat doesn't change.131unaffected, the bug's heat doesn't change.
@@ -133,7 +133,7 @@
133 >>> unaffected_person = factory.makePerson()133 >>> unaffected_person = factory.makePerson()
134 >>> bug.markUserAffected(unaffected_person, False)134 >>> bug.markUserAffected(unaffected_person, False)
135 >>> bug.heat135 >>> bug.heat
136 8136 6
137137
138Marking the bug as a duplicate will set its heat to zero, whilst also138Marking the bug as a duplicate will set its heat to zero, whilst also
139adding 10 points of heat to the bug it duplicates, 6 points for the139adding 10 points of heat to the bug it duplicates, 6 points for the
@@ -149,14 +149,14 @@
149 0149 0
150150
151 >>> duplicated_bug.heat151 >>> duplicated_bug.heat
152 16152 14
153153
154Unmarking the bug as a duplicate restores its heat and updates the154Unmarking the bug as a duplicate restores its heat and updates the
155duplicated bug's heat.155duplicated bug's heat.
156156
157 >>> bug.markAsDuplicate(None)157 >>> bug.markAsDuplicate(None)
158 >>> bug.heat158 >>> bug.heat
159 8159 6
160160
161 >>> duplicated_bug.heat161 >>> duplicated_bug.heat
162 6162 6
@@ -184,7 +184,7 @@
184 ... old_value=bug.description, new_value='Some text')184 ... old_value=bug.description, new_value='Some text')
185 >>> bug.addChange(change)185 >>> bug.addChange(change)
186 >>> bug.heat186 >>> bug.heat
187 8187 6
188188
189189
190Getting bugs whose heat is outdated190Getting bugs whose heat is outdated
@@ -359,5 +359,3 @@
359 123359 123
360 >>> print distro.max_bug_heat360 >>> print distro.max_bug_heat
361 456361 456
362
363
364362
=== modified file 'lib/lp/bugs/doc/bugnotification-sending.txt'
--- lib/lp/bugs/doc/bugnotification-sending.txt 2010-12-06 17:43:53 +0000
+++ lib/lp/bugs/doc/bugnotification-sending.txt 2010-12-23 19:45:24 +0000
@@ -303,7 +303,7 @@
303 <BLANKLINE>303 <BLANKLINE>
304 ** Visibility changed to: Public.304 ** Visibility changed to: Public.
305 <BLANKLINE>305 <BLANKLINE>
306 -- 306 --
307 You received this bug notification because you are a member of Ubuntu307 You received this bug notification because you are a member of Ubuntu
308 Team, which is the registrant for Ubuntu.308 Team, which is the registrant for Ubuntu.
309 http://bugs.launchpad.dev/bugs/1309 http://bugs.launchpad.dev/bugs/1
@@ -582,8 +582,6 @@
582 0582 0
583 >>> print err583 >>> print err
584 DEBUG ...584 DEBUG ...
585 INFO Notifying mark@example.com about bug 2.
586 ...
587 INFO Notifying support@ubuntu.com about bug 2.585 INFO Notifying support@ubuntu.com about bug 2.
588 ...586 ...
589 INFO Notifying test@canonical.com about bug 2.587 INFO Notifying test@canonical.com about bug 2.
@@ -727,15 +725,12 @@
727 >>> for message in trigger_and_get_email_messages(bug_three):725 >>> for message in trigger_and_get_email_messages(bug_three):
728 ... message.get_all('X-Launchpad-Bug-Tags')726 ... message.get_all('X-Launchpad-Bug-Tags')
729 [u'layout-test']727 [u'layout-test']
730 [u'layout-test']
731728
732If we add a tag to bug three that will also be included in the header.729If we add a tag to bug three that will also be included in the header.
733The tags will be space-separated to allow the list to be wrapped if it730The tags will be space-separated to allow the list to be wrapped if it
734gets over-long.731gets over-long.
735732
736 >>> switch_db_to_launchpad()733 >>> switch_db_to_launchpad()
737
738 >>> bug_three.unsubscribe(sample_person, sample_person)
739 >>> bug_three.tags = [u'layout-test', u'another-tag', u'yet-another']734 >>> bug_three.tags = [u'layout-test', u'another-tag', u'yet-another']
740735
741 >>> switch_db_to_bugnotification()736 >>> switch_db_to_bugnotification()
@@ -756,6 +751,9 @@
756 >>> for message in trigger_and_get_email_messages(bug_three):751 >>> for message in trigger_and_get_email_messages(bug_three):
757 ... message.get_all('X-Launchpad-Bug-Tags')752 ... message.get_all('X-Launchpad-Bug-Tags')
758753
754 >>> switch_db_to_launchpad()
755 >>> #bug_three.unsubscribe(sample_person, sample_person)
756
759757
760The X-Launchpad-Bug-Private header758The X-Launchpad-Bug-Private header
761----------------------------------759----------------------------------
@@ -769,7 +767,7 @@
769767
770 >>> for message in trigger_and_get_email_messages(bug_three):768 >>> for message in trigger_and_get_email_messages(bug_three):
771 ... print message['To'], message.get_all('X-Launchpad-Bug-Private')769 ... print message['To'], message.get_all('X-Launchpad-Bug-Private')
772 mark@example.com ['no']770 test@canonical.com ['no']
773771
774Predictably, private bugs are sent with a slightly different header:772Predictably, private bugs are sent with a slightly different header:
775773
@@ -780,7 +778,7 @@
780778
781 >>> for message in trigger_and_get_email_messages(bug_three):779 >>> for message in trigger_and_get_email_messages(bug_three):
782 ... print message['To'], message.get_all('X-Launchpad-Bug-Private')780 ... print message['To'], message.get_all('X-Launchpad-Bug-Private')
783 mark@example.com ['yes']781 test@canonical.com ['yes']
784782
785783
786The X-Launchpad-Bug-Security-Vulnerability header784The X-Launchpad-Bug-Security-Vulnerability header
@@ -796,7 +794,7 @@
796 >>> for message in trigger_and_get_email_messages(bug_three):794 >>> for message in trigger_and_get_email_messages(bug_three):
797 ... print message['To'], (795 ... print message['To'], (
798 ... message.get_all('X-Launchpad-Bug-Security-Vulnerability'))796 ... message.get_all('X-Launchpad-Bug-Security-Vulnerability'))
799 mark@example.com ['no']797 test@canonical.com ['no']
800798
801The presence of the security flag on a bug is, surprise, denoted by a799The presence of the security flag on a bug is, surprise, denoted by a
802simple "yes":800simple "yes":
@@ -809,7 +807,7 @@
809 >>> for message in trigger_and_get_email_messages(bug_three):807 >>> for message in trigger_and_get_email_messages(bug_three):
810 ... print message['To'], (808 ... print message['To'], (
811 ... message.get_all('X-Launchpad-Bug-Security-Vulnerability'))809 ... message.get_all('X-Launchpad-Bug-Security-Vulnerability'))
812 mark@example.com ['yes']810 test@canonical.com ['yes']
813811
814812
815The X-Launchpad-Bug-Commenters header813The X-Launchpad-Bug-Commenters header
@@ -1238,7 +1236,7 @@
1238 <BLANKLINE>1236 <BLANKLINE>
1239 ** Summary changed to: whatever.1237 ** Summary changed to: whatever.
1240 <BLANKLINE>1238 <BLANKLINE>
1241 -- 1239 --
1242 You received this bug notification because you are subscribed to Mozilla1240 You received this bug notification because you are subscribed to Mozilla
1243 Firefox.1241 Firefox.
1244 ...1242 ...
@@ -1287,7 +1285,7 @@
1287 <BLANKLINE>1285 <BLANKLINE>
1288 ** Summary changed to: something.1286 ** Summary changed to: something.
1289 <BLANKLINE>1287 <BLANKLINE>
1290 -- 1288 --
1291 You received this bug notification because you are a member of ShipIt1289 You received this bug notification because you are a member of ShipIt
1292 Administrators, which is a direct subscriber.1290 Administrators, which is a direct subscriber.
1293 http://bugs.launchpad.dev/bugs/11291 http://bugs.launchpad.dev/bugs/1
12941292
=== modified file 'lib/lp/bugs/doc/bugzilla-import.txt'
--- lib/lp/bugs/doc/bugzilla-import.txt 2010-10-18 22:24:59 +0000
+++ lib/lp/bugs/doc/bugzilla-import.txt 2010-12-23 19:45:24 +0000
@@ -363,7 +363,6 @@
363 Reporter: Sample Person363 Reporter: Sample Person
364 Created: 2005-04-04 00:00:00+00:00364 Created: 2005-04-04 00:00:00+00:00
365 Subscribers:365 Subscribers:
366 Mark Shuttleworth
367 Sample Person366 Sample Person
368 Ubuntu Team367 Ubuntu Team
369 Task: Evolution368 Task: Evolution
@@ -540,5 +539,3 @@
540 True539 True
541 >>> bug4.duplicateof == bug3540 >>> bug4.duplicateof == bug3
542 True541 True
543
544
545542
=== modified file 'lib/lp/bugs/doc/initial-bug-contacts.txt'
--- lib/lp/bugs/doc/initial-bug-contacts.txt 2010-10-18 22:24:59 +0000
+++ lib/lp/bugs/doc/initial-bug-contacts.txt 2010-12-23 19:45:24 +0000
@@ -348,7 +348,6 @@
348348
349 >>> print '\n'.join(subscriber_names(bug_two_in_ubuntu.bug))349 >>> print '\n'.join(subscriber_names(bug_two_in_ubuntu.bug))
350 Foo Bar350 Foo Bar
351 Mark Shuttleworth
352 Sample Person351 Sample Person
353 Steve Alexander352 Steve Alexander
354 Ubuntu Team353 Ubuntu Team
355354
=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py 2010-11-05 09:16:14 +0000
+++ lib/lp/bugs/model/bug.py 2010-12-23 19:45:24 +0000
@@ -988,10 +988,10 @@
988 # If the target's bug supervisor isn't set,988 # If the target's bug supervisor isn't set,
989 # we add the owner as a subscriber.989 # we add the owner as a subscriber.
990 pillar = bugtask.pillar990 pillar = bugtask.pillar
991 if pillar.bug_supervisor is None:991 if pillar.bug_supervisor is None and pillar.official_malone:
992 also_notified_subscribers.add(pillar.owner)992 also_notified_subscribers.add(pillar.owner)
993 if recipients is not None:993 if recipients is not None:
994 recipients.addRegistrant(pillar.owner, pillar)994 recipients.addRegistrant(pillar.owner, pillar)
995995
996 # Structural subscribers.996 # Structural subscribers.
997 also_notified_subscribers.update(997 also_notified_subscribers.update(
@@ -1790,8 +1790,12 @@
17901790
1791 @cachedproperty1791 @cachedproperty
1792 def _known_viewers(self):1792 def _known_viewers(self):
1793 """A dict of of known persons able to view this bug."""1793 """A set of known persons able to view this bug.
1794 return set()1794
1795 Seed it by including the list of all owners of bugtasks for the bug.
1796 """
1797 bugtask_owners = [bt.pillar.owner.id for bt in self.bugtasks]
1798 return set(bugtask_owners)
17951799
1796 def userCanView(self, user):1800 def userCanView(self, user):
1797 """See `IBug`.1801 """See `IBug`.
17981802
=== modified file 'lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt'
--- lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt 2010-10-19 14:55:46 +0000
+++ lib/lp/bugs/stories/bugs/xx-bug-personal-subscriptions.txt 2010-12-23 19:45:24 +0000
@@ -192,7 +192,6 @@
192 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")192 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
193 >>> print_also_notified(stevea_browser.contents)193 >>> print_also_notified(stevea_browser.contents)
194 Also notified:194 Also notified:
195 Mark Shuttleworth
196195
197But if bug #2, a bug that Steve is directly subscribed to, is marked as196But if bug #2, a bug that Steve is directly subscribed to, is marked as
198a dupe of bug #3, then Steve gets indirectly subscribed to bug #3, and197a dupe of bug #3, then Steve gets indirectly subscribed to bug #3, and
@@ -243,7 +242,6 @@
243 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")242 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
244 >>> print_also_notified(stevea_browser.contents)243 >>> print_also_notified(stevea_browser.contents)
245 Also notified:244 Also notified:
246 Mark Shuttleworth
247245
248Let's repeat this example, with Steve subscribed to two different dupes,246Let's repeat this example, with Steve subscribed to two different dupes,
249to see how the unsubscribe notification changes slightly, because he247to see how the unsubscribe notification changes slightly, because he
@@ -274,7 +272,6 @@
274 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")272 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
275 >>> print_also_notified(stevea_browser.contents)273 >>> print_also_notified(stevea_browser.contents)
276 Also notified:274 Also notified:
277 Mark Shuttleworth
278275
279 >>> stevea_browser.open("http://launchpad.dev/bugs/3")276 >>> stevea_browser.open("http://launchpad.dev/bugs/3")
280 >>> stevea_browser.getLink("Unsubscribe").click()277 >>> stevea_browser.getLink("Unsubscribe").click()
@@ -317,7 +314,6 @@
317314
318 >>> print_also_notified(foobar_browser.contents)315 >>> print_also_notified(foobar_browser.contents)
319 Also notified:316 Also notified:
320 Mark Shuttleworth
321317
322The subscribe link for Foo Bar still says "Subscribe", because318The subscribe link for Foo Bar still says "Subscribe", because
323Foo Bar can subscribe himself directly to this bug. For unsubscribing319Foo Bar can subscribe himself directly to this bug. For unsubscribing
@@ -350,7 +346,6 @@
350 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")346 ... "http://launchpad.dev/bugs/3/+bug-portlet-subscribers-content")
351 >>> print_also_notified(foobar_browser.contents)347 >>> print_also_notified(foobar_browser.contents)
352 Also notified:348 Also notified:
353 Mark Shuttleworth
354349
355350
356== Displaying subscribers ==351== Displaying subscribers ==
357352
=== modified file 'lib/lp/bugs/subscribers/bug.py'
--- lib/lp/bugs/subscribers/bug.py 2010-10-25 13:22:46 +0000
+++ lib/lp/bugs/subscribers/bug.py 2010-12-23 19:45:24 +0000
@@ -187,7 +187,7 @@
187 # If the target's bug supervisor isn't set,187 # If the target's bug supervisor isn't set,
188 # we add the owner as a subscriber.188 # we add the owner as a subscriber.
189 pillar = bugtask.pillar189 pillar = bugtask.pillar
190 if pillar.bug_supervisor is None:190 if pillar.bug_supervisor is None and pillar.official_malone:
191 also_notified_subscribers.add(pillar.owner)191 also_notified_subscribers.add(pillar.owner)
192 if recipients is not None:192 if recipients is not None:
193 recipients.addRegistrant(pillar.owner, pillar)193 recipients.addRegistrant(pillar.owner, pillar)
194194
=== modified file 'lib/lp/bugs/tests/test_bugchanges.py'
--- lib/lp/bugs/tests/test_bugchanges.py 2010-10-04 19:50:45 +0000
+++ lib/lp/bugs/tests/test_bugchanges.py 2010-12-23 19:45:24 +0000
@@ -932,7 +932,8 @@
932 new_target = self.factory.makeDistributionSourcePackage(932 new_target = self.factory.makeDistributionSourcePackage(
933 distribution=target.distribution)933 distribution=target.distribution)
934934
935 source_package_bug = self.factory.makeBug(owner=self.user)935 source_package_bug = self.factory.makeBug(
936 owner=self.user)
936 source_package_bug_task = source_package_bug.addTask(937 source_package_bug_task = source_package_bug.addTask(
937 owner=self.user, target=target)938 owner=self.user, target=target)
938 self.saveOldChanges(source_package_bug)939 self.saveOldChanges(source_package_bug)
@@ -956,8 +957,8 @@
956 expected_recipients = [self.user, metadata_subscriber]957 expected_recipients = [self.user, metadata_subscriber]
957 expected_recipients.extend(958 expected_recipients.extend(
958 bug_task.pillar.owner959 bug_task.pillar.owner
959 for bug_task in source_package_bug.bugtasks)960 for bug_task in source_package_bug.bugtasks
960961 if bug_task.pillar.official_malone)
961 expected_notification = {962 expected_notification = {
962 'text': u"** Package changed: %s => %s" % (963 'text': u"** Package changed: %s => %s" % (
963 bug_task_before_modification.bugtargetname,964 bug_task_before_modification.bugtargetname,
964965
=== modified file 'lib/lp/bugs/tests/test_bugnotification.py'
--- lib/lp/bugs/tests/test_bugnotification.py 2010-10-19 22:06:16 +0000
+++ lib/lp/bugs/tests/test_bugnotification.py 2010-12-23 19:45:24 +0000
@@ -9,6 +9,7 @@
99
10from lazr.lifecycle.event import ObjectModifiedEvent10from lazr.lifecycle.event import ObjectModifiedEvent
11from lazr.lifecycle.snapshot import Snapshot11from lazr.lifecycle.snapshot import Snapshot
12from testtools.matchers import Not
12from zope.event import notify13from zope.event import notify
13from zope.interface import providedBy14from zope.interface import providedBy
1415
@@ -30,6 +31,7 @@
30 )31 )
31from lp.testing import TestCaseWithFactory32from lp.testing import TestCaseWithFactory
32from lp.testing.factory import LaunchpadObjectFactory33from lp.testing.factory import LaunchpadObjectFactory
34from lp.testing.matchers import Contains
33from lp.testing.mail_helpers import pop_notifications35from lp.testing.mail_helpers import pop_notifications
3436
3537
@@ -41,12 +43,16 @@
41 def setUp(self):43 def setUp(self):
42 login('foo.bar@canonical.com')44 login('foo.bar@canonical.com')
43 factory = LaunchpadObjectFactory()45 factory = LaunchpadObjectFactory()
44 self.product = factory.makeProduct()46 self.product_owner = factory.makePerson(name="product-owner")
45 self.product_subscriber = factory.makePerson()47 self.product = factory.makeProduct(owner=self.product_owner)
48 self.product_subscriber = factory.makePerson(
49 name="product-subscriber")
46 self.product.addBugSubscription(50 self.product.addBugSubscription(
47 self.product_subscriber, self.product_subscriber)51 self.product_subscriber, self.product_subscriber)
48 self.bug_subscriber = factory.makePerson()52 self.bug_subscriber = factory.makePerson(name="bug-subscriber")
49 self.private_bug = factory.makeBug(product=self.product, private=True)53 self.bug_owner = factory.makePerson(name="bug-owner")
54 self.private_bug = factory.makeBug(
55 product=self.product, private=True, owner=self.bug_owner)
50 self.reporter = self.private_bug.owner56 self.reporter = self.private_bug.owner
51 self.private_bug.subscribe(self.bug_subscriber, self.reporter)57 self.private_bug.subscribe(self.bug_subscriber, self.reporter)
52 [self.product_bugtask] = self.private_bug.bugtasks58 [self.product_bugtask] = self.private_bug.bugtasks
@@ -66,7 +72,7 @@
66 notified_people = set(72 notified_people = set(
67 recipient.person.name73 recipient.person.name
68 for recipient in latest_notification.recipients)74 for recipient in latest_notification.recipients)
69 self.assertEqual(notified_people, self.direct_subscribers)75 self.assertEqual(self.direct_subscribers, notified_people)
7076
71 def test_add_comment(self):77 def test_add_comment(self):
72 # Comment additions are sent to the direct subscribers only.78 # Comment additions are sent to the direct subscribers only.
@@ -76,7 +82,7 @@
76 notified_people = set(82 notified_people = set(
77 recipient.person.name83 recipient.person.name
78 for recipient in latest_notification.recipients)84 for recipient in latest_notification.recipients)
79 self.assertEqual(notified_people, self.direct_subscribers)85 self.assertEqual(self.direct_subscribers, notified_people)
8086
81 def test_bug_edit(self):87 def test_bug_edit(self):
82 # Bug edits are sent to direct the subscribers only.88 # Bug edits are sent to direct the subscribers only.
@@ -90,7 +96,7 @@
90 notified_people = set(96 notified_people = set(
91 recipient.person.name97 recipient.person.name
92 for recipient in latest_notification.recipients)98 for recipient in latest_notification.recipients)
93 self.assertEqual(notified_people, self.direct_subscribers)99 self.assertEqual(self.direct_subscribers, notified_people)
94100
95101
96class TestNotificationsSentForBugExpiration(TestCaseWithFactory):102class TestNotificationsSentForBugExpiration(TestCaseWithFactory):
@@ -206,3 +212,104 @@
206 recipient.person212 recipient.person
207 for recipient in latest_notification.recipients)213 for recipient in latest_notification.recipients)
208 self.assertEqual(self.dupe_subscribers, recipients)214 self.assertEqual(self.dupe_subscribers, recipients)
215
216
217class NotificationForRegistrantsMixin:
218 """Mixin for testing when registrants get notified."""
219
220 layer = DatabaseFunctionalLayer
221
222 def setUp(self):
223 super(NotificationForRegistrantsMixin, self).setUp(
224 user='foo.bar@canonical.com')
225 self.pillar_owner = self.factory.makePerson(name="distro-owner")
226 self.bug_owner = self.factory.makePerson(name="bug-owner")
227 self.pillar = self.makePillar()
228 self.bug = self.makeBug()
229
230 def test_notification_uses_malone(self):
231 self.pillar.official_malone = True
232 direct = self.bug.getDirectSubscribers()
233 indirect = self.bug.getIndirectSubscribers()
234 self.assertThat(direct, Not(Contains(self.pillar_owner)))
235 self.assertThat(indirect, Contains(self.pillar_owner))
236
237 def test_notification_does_not_use_malone(self):
238 self.pillar.official_malone = False
239 direct = self.bug.getDirectSubscribers()
240 indirect = self.bug.getIndirectSubscribers()
241 self.assertThat(direct, Not(Contains(self.pillar_owner)))
242 self.assertThat(indirect, Not(Contains(self.pillar_owner)))
243
244 def test_status_change_uses_malone(self):
245 # Status changes are sent to the direct and indirect subscribers.
246 self.pillar.official_malone = True
247 [bugtask] = self.bug.bugtasks
248 all_subscribers = set(
249 [person.name for person in
250 self.bug.getDirectSubscribers() +
251 self.bug.getIndirectSubscribers()])
252 bugtask_before_modification = Snapshot(
253 bugtask, providing=providedBy(bugtask))
254 bugtask.transitionToStatus(
255 BugTaskStatus.INVALID, self.bug.owner)
256 notify(ObjectModifiedEvent(
257 bugtask, bugtask_before_modification, ['status'],
258 user=self.bug.owner))
259 latest_notification = BugNotification.selectFirst(orderBy='-id')
260 notified_people = set(
261 recipient.person.name
262 for recipient in latest_notification.recipients)
263 self.assertEqual(all_subscribers, notified_people)
264 self.assertThat(all_subscribers, Contains(self.pillar_owner.name))
265
266 def test_status_change_does_not_use_malone(self):
267 # Status changes are sent to the direct and indirect subscribers.
268 self.pillar.official_malone = False
269 [bugtask] = self.bug.bugtasks
270 all_subscribers = set(
271 [person.name for person in
272 self.bug.getDirectSubscribers() +
273 self.bug.getIndirectSubscribers()])
274 bugtask_before_modification = Snapshot(
275 bugtask, providing=providedBy(bugtask))
276 bugtask.transitionToStatus(
277 BugTaskStatus.INVALID, self.bug.owner)
278 notify(ObjectModifiedEvent(
279 bugtask, bugtask_before_modification, ['status'],
280 user=self.bug.owner))
281 latest_notification = BugNotification.selectFirst(orderBy='-id')
282 notified_people = set(
283 recipient.person.name
284 for recipient in latest_notification.recipients)
285 self.assertEqual(all_subscribers, notified_people)
286 self.assertThat(
287 all_subscribers, Not(Contains(self.pillar_owner.name)))
288
289
290class TestNotificationsForRegistrantsForDistros(
291 NotificationForRegistrantsMixin, TestCaseWithFactory):
292 """Test when distribution registrants get notified."""
293
294 def makePillar(self):
295 return self.factory.makeDistribution(
296 owner=self.pillar_owner)
297
298 def makeBug(self):
299 return self.factory.makeBug(
300 distribution=self.pillar,
301 owner=self.bug_owner)
302
303
304class TestNotificationsForRegistrantsForProducts(
305 NotificationForRegistrantsMixin, TestCaseWithFactory):
306 """Test when product registrants get notified."""
307
308 def makePillar(self):
309 return self.factory.makeProduct(
310 owner=self.pillar_owner)
311
312 def makeBug(self):
313 return self.factory.makeBug(
314 product=self.pillar,
315 owner=self.bug_owner)
209316
=== modified file 'lib/lp/bugs/tests/test_bugs_webservice.py'
--- lib/lp/bugs/tests/test_bugs_webservice.py 2010-10-04 19:50:45 +0000
+++ lib/lp/bugs/tests/test_bugs_webservice.py 2010-12-23 19:45:24 +0000
@@ -166,18 +166,18 @@
166 collector.register()166 collector.register()
167 self.addCleanup(collector.unregister)167 self.addCleanup(collector.unregister)
168 url = '/bugs/%d/attachments?ws.size=75' % self.bug.id168 url = '/bugs/%d/attachments?ws.size=75' % self.bug.id
169 #First request169 # First request.
170 store.flush()170 store.flush()
171 store.reset()171 store.reset()
172 response = webservice.get(url)172 response = webservice.get(url)
173 self.assertThat(collector, HasQueryCount(LessThan(21)))173 self.assertThat(collector, HasQueryCount(LessThan(22)))
174 with_2_count = collector.count174 with_2_count = collector.count
175 self.failUnlessEqual(response.status, 200)175 self.failUnlessEqual(response.status, 200)
176 login(USER_EMAIL)176 login(USER_EMAIL)
177 for i in range(5):177 for i in range(5):
178 self.factory.makeBugAttachment(self.bug)178 self.factory.makeBugAttachment(self.bug)
179 logout()179 logout()
180 #Second request180 # Second request.
181 store.flush()181 store.flush()
182 store.reset()182 store.reset()
183 response = webservice.get(url)183 response = webservice.get(url)
@@ -202,11 +202,11 @@
202 collector.register()202 collector.register()
203 self.addCleanup(collector.unregister)203 self.addCleanup(collector.unregister)
204 url = '/bugs/%d/messages?ws.size=75' % bug.id204 url = '/bugs/%d/messages?ws.size=75' % bug.id
205 #First request205 # First request.
206 store.flush()206 store.flush()
207 store.reset()207 store.reset()
208 response = webservice.get(url)208 response = webservice.get(url)
209 self.assertThat(collector, HasQueryCount(LessThan(21)))209 self.assertThat(collector, HasQueryCount(LessThan(22)))
210 with_2_count = collector.count210 with_2_count = collector.count
211 self.failUnlessEqual(response.status, 200)211 self.failUnlessEqual(response.status, 200)
212 login(USER_EMAIL)212 login(USER_EMAIL)
@@ -214,7 +214,7 @@
214 self.factory.makeBugComment(bug)214 self.factory.makeBugComment(bug)
215 self.factory.makeBugAttachment(bug)215 self.factory.makeBugAttachment(bug)
216 logout()216 logout()
217 #Second request217 # Second request.
218 store.flush()218 store.flush()
219 store.reset()219 store.reset()
220 response = webservice.get(url)220 response = webservice.get(url)
221221
=== modified file 'lib/lp/bugs/tests/test_bugtask_search.py'
--- lib/lp/bugs/tests/test_bugtask_search.py 2010-12-14 02:18:32 +0000
+++ lib/lp/bugs/tests/test_bugtask_search.py 2010-12-23 19:45:24 +0000
@@ -91,7 +91,8 @@
91 # search result.91 # search result.
92 user = self.factory.makePerson()92 user = self.factory.makePerson()
93 with person_logged_in(self.owner):93 with person_logged_in(self.owner):
94 self.bugtasks[-1].bug.subscribe(user, self.owner)94 bug = self.bugtasks[-1].bug
95 bug.subscribe(user, self.owner)
95 params = self.getBugTaskSearchParams(user=user)96 params = self.getBugTaskSearchParams(user=user)
96 self.assertSearchFinds(params, self.bugtasks)97 self.assertSearchFinds(params, self.bugtasks)
9798