← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/bugnotification-testcases into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/bugnotification-testcases into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/bugnotification-testcases/+merge/116402

Clean up tests related to bug notification to prepare for the work that will force structural subscriptions to work with private bugs. I have removed xx-initial-bug-contacts.txt for being a doctest, due to that once the aforementioned structural subscription work lands, it will no longer match reality, and so I can claw back some LoC credit for this branch. I have removed three tests from test_bugnotifications which were frankly horrible, and also won't match reality after the aforementioned work lands.
-- 
https://code.launchpad.net/~stevenk/launchpad/bugnotification-testcases/+merge/116402
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/bugnotification-testcases into lp:launchpad.
=== removed file 'lib/lp/bugs/stories/initial-bug-contacts/xx-initial-bug-contacts.txt'
--- lib/lp/bugs/stories/initial-bug-contacts/xx-initial-bug-contacts.txt	2012-07-19 15:51:37 +0000
+++ lib/lp/bugs/stories/initial-bug-contacts/xx-initial-bug-contacts.txt	1970-01-01 00:00:00 +0000
@@ -1,237 +0,0 @@
-To set a bug supervisor for a distribution, we need to go to the Bug page
-of that distribution:
-
-  >>> browser.open('http://launchpad.dev/ubuntu/+bugs')
-
-But the link is not available if you are not logged in with permission
-to change the bug supervisor.
-
-  >>> browser.getLink("Change bug supervisor")
-  Traceback (most recent call last):
-  ...
-  LinkNotFoundError
-
-Colin is an Ubuntu owner and can set the bug supervisor role.
-
-  >>> colin_browser = setupBrowser(
-  ...     auth='Basic colin.watson@xxxxxxxxxxxxxxx:test')
-  >>> colin_browser.open('http://bugs.launchpad.dev/ubuntu/+bugs')
-
-...and he can see that the link on Ubuntu's bugs page.
-
-  >>> bug_supervisor_link = colin_browser.getLink("Change bug supervisor")
-  >>> bug_supervisor_link.url
-  'http://bugs.launchpad.dev/ubuntu/+bugsupervisor'
-
-Anyone with launchpad.Edit permission can edit the distribution bug
-supervisor, but most users can select only themselves and the teams they
-administer. In this example, Colin will set himself as the distribution
-bug supervisor.
-
-  >>> bug_supervisor_link.click()
-  >>> colin_browser.url
-  'http://bugs.launchpad.dev/ubuntu/+bugsupervisor'
-
-The bug supervisor page takes just one simple value: the bug supervisor email
-or nickname. Let's set colin.watson@xxxxxxxxxxxxxxx as the bug supervisor for
-Ubuntu.
-
-  >>> colin_browser.getControl("Bug Supervisor").value = (
-  ...     ' colin.watson@xxxxxxxxxxxxxxx ')
-  >>> colin_browser.getControl("Change").click()
-
-And then Colin is redirected to the distribution bugs page.
-
-    >>> print extract_text(find_tag_by_id(
-    ...     colin_browser.contents, 'bug-supervisor'))
-    Bug supervisor: Colin Watson
-
-== Setting Upstream Bug Supervisor ==
-
-Setting the bug supervisor for an upstream requires launchpad.Edit
-permission on the product. But regular users can only appoint
-themselves as bug supervisors and teams they administer.
-
-    >>> sample_browser = setupBrowser()
-    >>> sample_browser.addHeader("Authorization",
-    ...                          "Basic test@xxxxxxxxxxxxx:test")
-
-    >>> sample_browser.open(
-    ...     "http://bugs.launchpad.dev/firefox/+bugsupervisor";)
-    >>> sample_browser.getControl(name="field.bug_supervisor").value = (
-    ...                           "test@xxxxxxxxxxxxx")
-    >>> sample_browser.getControl("Change").click()
-
-He is now redirected to the main product page, and he sees a confirmation
-message.
-
-    >>> print extract_text(find_tag_by_id(
-    ...     sample_browser.contents, 'bug-supervisor'))
-    Bug supervisor: Sample Person
-
-Another example, this time with a team that has no "preferred email" set.
-
-    >>> sample_browser.open(
-    ...     "http://bugs.launchpad.dev/firefox/+bugsupervisor";)
-    >>> sample_browser.getControl(name="field.bug_supervisor").value = (
-    ...     "landscape-developers")
-    >>> sample_browser.getControl("Change").click()
-    >>> print extract_text(find_tag_by_id(
-    ...     sample_browser.contents, 'bug-supervisor'))
-    Bug supervisor: Landscape Developers
-
-Launchpad administrators can appoint anybody.
-
-    >>> admin_browser = setupBrowser()
-    >>> admin_browser.addHeader("Authorization",
-    ...                          "Basic foo.bar@xxxxxxxxxxxxx:test")
-
-    >>> admin_browser.open("http://bugs.launchpad.dev/firefox/+bugsupervisor";)
-    >>> admin_browser.getControl(name="field.bug_supervisor").value = (
-    ...                           "robertc@xxxxxxxxxxxxxxxxx")
-    >>> admin_browser.getControl("Change").click()
-    >>> print extract_text(find_tag_by_id(
-    ...     admin_browser.contents, 'bug-supervisor'))
-    Bug supervisor: Robert Collins
-
-Filing a public bug on an upstream will subscribe the bug supervisor, as
-well.
-
-    >>> browser.addHeader("Authorization", "Basic mark@xxxxxxxxxxx:test")
-
-    >>> browser.open("http://launchpad.dev/firefox/+filebug";)
-
-    >>> browser.getControl(name="field.title", index=0).value = "bug supervisor test"
-    >>> browser.getControl('Continue').click()
-
-    >>> browser.getControl(name="field.comment").value = "a public bug"
-    >>> browser.getControl("Submit Bug Report").click()
-
-    >>> bug_id = browser.url.split("/")[-1]
-    >>> print browser.url.replace(bug_id, "BUG-ID")
-    http://bugs.launchpad.dev/firefox/+bug/BUG-ID
-
-Now mark (because he's the bug reporter), Sample Person (a former bug
-supervisor), Landscape Developers (another former bug supervisor) and
-Robert Collins (the current bug supervisor) are subscribed to this bug:
-
-    >>> from itertools import chain
-    >>> from zope.component import getUtility
-    >>> from lp.bugs.interfaces.bug import IBugSet
-    >>> from lp.testing import login, logout, ANONYMOUS
-
-    >>> def subscriber_names(bug):
-    ...     subscribers = chain(
-    ...         bug.getDirectSubscribers(),
-    ...         bug.getIndirectSubscribers())
-    ...     return sorted(subscriber.displayname for subscriber in subscribers)
-
-    >>> login(ANONYMOUS)
-    >>> bugset = getUtility(IBugSet)
-    >>> subscriber_names(bugset.get(bug_id))
-    [u'Landscape Developers', u'Mark Shuttleworth', u'Robert Collins',
-    u'Sample Person']
-
-For a security bug, only the reporter and the registrant gets
-subscribed, because Firefox does not have a security contact.
-
-    >>> from lp.registry.interfaces.product import IProductSet
-
-    >>> login(ANONYMOUS)
-    >>> firefox = getUtility(IProductSet).getByName("firefox")
-    >>> firefox.security_contact is None
-    True
-    >>> logout()
-
-    >>> browser.open("http://launchpad.dev/firefox/+filebug";)
-
-    >>> browser.getControl(name="field.title", index=0).value = "bug supervisor test"
-    >>> browser.getControl('Continue').click()
-
-    >>> browser.getControl(name="field.comment").value = "a PRIVATE bug"
-    >>> browser.getControl("Private Security").selected = True
-    >>> browser.getControl("Submit Bug Report").click()
-
-    >>> other_bug_id = browser.url.split("/")[-1]
-    >>> print browser.url.replace(other_bug_id, "BUG-ID")
-    http://bugs.launchpad.dev/firefox/+bug/BUG-ID
-
-    >>> login("mark@xxxxxxxxxxx")
-
-    >>> subscriber_names(bugset.get(other_bug_id))
-    [u'Mark Shuttleworth', u'Sample Person']
-
-    >>> logout()
-
-Filing a public bug on a distribution source package subscribes the bug
-reporter, the distribution bug supervisor, if there is one, and all the
-package subscribers, if there are any.
-
-    >>> browser.addHeader("Authorization", "Basic mark@xxxxxxxxxxx:test")
-
-    >>> browser.open(
-    ...     "http://localhost:9000/ubuntu/+source/mozilla-firefox/";
-    ...     "+filebug")
-
-    >>> browser.getControl(name="field.title", index=0).value = "a public bug"
-    >>> browser.getControl('Continue').click()
-
-    >>> browser.getControl(name="field.comment").value = (
-    ...     "anyone can see this")
-    >>> browser.getControl("Submit Bug Report").click()
-
-    >>> bug_id = browser.url.split("/")[-1]
-    >>> print browser.url.replace(bug_id, "BUG-ID")
-    http://bugs.launchpad.dev/ubuntu/+source/mozilla-firefox/+bug/BUG-ID
-
-We should have three subscribers now. The bug reporter (also a package
-subscriber), mark, the distro bug supervisor kamion, and foobar, who is
-subscribed to the distribution.
-
-    >>> from zope.component import getUtility
-    >>> from lp.bugs.interfaces.bug import IBugSet
-    >>> from lp.testing import login, logout, ANONYMOUS
-
-    >>> def subscriber_names(bug):
-    ...     subscribers = chain(
-    ...         bug.getDirectSubscribers(),
-    ...         bug.getIndirectSubscribers())
-    ...     return sorted(subscriber.name for subscriber in subscribers)
-
-    >>> login(ANONYMOUS)
-
-    >>> bugset = getUtility(IBugSet)
-    >>> subscriber_names(bugset.get(bug_id))
-    [u'kamion', u'mark', u'name16']
-
-
-When filing a security bug, only the bug reporter and registrant are explicitly
-Cc'd, because the Ubuntu distribution does not have a security contact.
-
-    >>> from lp.registry.interfaces.distribution import IDistributionSet
-
-    >>> ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
-    >>> ubuntu.security_contact is None
-    True
-    >>> logout()
-
-    >>> browser.open(
-    ...     "http://localhost:9000/ubuntu/+source/mozilla-firefox/";
-    ...     "+filebug")
-    >>> browser.getControl(name="field.title", index=0).value = "a PRIVATE bug"
-    >>> browser.getControl('Continue').click()
-
-    >>> browser.getControl(name="field.comment").value = "top sekrit"
-    >>> browser.getControl("Private Security").selected = True
-    >>> browser.getControl("Submit Bug Report").click()
-
-    >>> other_bug_id = browser.url.split("/")[-1]
-    >>> print browser.url.replace(other_bug_id, "BUG-ID")
-    http://bugs.launchpad.dev/ubuntu/+source/mozilla-firefox/+bug/BUG-ID
-
-    >>> login("mark@xxxxxxxxxxx")
-
-    >>> subscriber_names(bugset.get(other_bug_id))
-    [u'mark', u'ubuntu-team']
-
-    >>> logout()

=== added file 'lib/lp/bugs/tests/test_bug_notification_recipients.py'
--- lib/lp/bugs/tests/test_bug_notification_recipients.py	1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/tests/test_bug_notification_recipients.py	2012-07-24 05:15:26 +0000
@@ -0,0 +1,156 @@
+# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests related to bug notification recipients."""
+
+__metaclass__ = type
+
+from lp.registry.enums import InformationType
+from lp.testing import (
+    person_logged_in,
+    TestCaseWithFactory,
+    )
+from lp.testing.layers import DatabaseFunctionalLayer
+
+
+class TestBugNotificationRecipients(TestCaseWithFactory):
+
+    layer = DatabaseFunctionalLayer
+
+    def test_public_bug(self):
+        bug = self.factory.makeBug()
+        self.assertContentEqual(
+            [bug.owner], bug.getBugNotificationRecipients())
+
+    def test_public_bug_with_subscriber(self):
+        bug = self.factory.makeBug()
+        subscriber = self.factory.makePerson()
+        with person_logged_in(bug.owner):
+            bug.subscribe(subscriber, bug.owner)
+        self.assertContentEqual(
+            [bug.owner, subscriber], bug.getBugNotificationRecipients())
+
+    def test_public_bug_with_structural_subscriber(self):
+        subscriber = self.factory.makePerson()
+        product = self.factory.makeProduct()
+        with person_logged_in(subscriber):
+            product.addBugSubscription(subscriber, subscriber)
+        bug = self.factory.makeBug(product=product)
+        self.assertContentEqual(
+            [bug.owner, subscriber], bug.getBugNotificationRecipients())
+
+    def test_public_bug_assignee(self):
+        assignee = self.factory.makePerson()
+        bug = self.factory.makeBug()
+        with person_logged_in(bug.owner):
+            bug.default_bugtask.transitionToAssignee(assignee)
+        self.assertContentEqual(
+            [bug.owner, assignee], bug.getBugNotificationRecipients())
+
+    def test_public_bug_with_duplicate_different_pillar_subscriber(self):
+        subscriber = self.factory.makePerson()
+        bug = self.factory.makeBug()
+        dupe = self.factory.makeBug()
+        with person_logged_in(dupe.owner):
+            dupe.subscribe(subscriber, dupe.owner)
+            dupe.markAsDuplicate(bug)
+        self.assertContentEqual(
+            [bug.owner, dupe.owner, subscriber],
+            bug.getBugNotificationRecipients())
+
+    def test_public_bug_with_duplicate_same_pillar_subscriber(self):
+        owner = self.factory.makePerson()
+        subscriber = self.factory.makePerson()
+        product = self.factory.makeProduct()
+        bug = self.factory.makeBug(product=product, owner=owner)
+        dupe = self.factory.makeBug(product=product, owner=owner)
+        with person_logged_in(owner):
+            dupe.subscribe(subscriber, owner)
+            dupe.markAsDuplicate(bug)
+        self.assertContentEqual(
+            [owner, subscriber], bug.getBugNotificationRecipients())
+
+    def test_public_bug_linked_to_question(self):
+        question = self.factory.makeQuestion()
+        bug = self.factory.makeBug()
+        with person_logged_in(question.owner):
+            question.linkBug(bug)
+        self.assertContentEqual(
+            [bug.owner, question.owner], bug.getBugNotificationRecipients())
+
+    def test_private_bug(self):
+        owner = self.factory.makePerson()
+        bug = self.factory.makeBug(
+            owner=owner, information_type=InformationType.USERDATA)
+        with person_logged_in(owner):
+            self.assertContentEqual(
+                [owner], bug.getBugNotificationRecipients())
+
+    def test_private_bug_with_subscriber(self):
+        owner = self.factory.makePerson()
+        subscriber = self.factory.makePerson()
+        bug = self.factory.makeBug(
+            owner=owner, information_type=InformationType.USERDATA)
+        with person_logged_in(owner):
+            bug.subscribe(subscriber, owner)
+            self.assertContentEqual(
+                [owner, subscriber], bug.getBugNotificationRecipients())
+
+    def test_private_bug_with_structural_subscriber(self):
+        owner = self.factory.makePerson()
+        subscriber = self.factory.makePerson()
+        product = self.factory.makeProduct()
+        with person_logged_in(subscriber):
+            product.addBugSubscription(subscriber, subscriber)
+        bug = self.factory.makeBug(
+            product=product, owner=owner,
+            information_type=InformationType.USERDATA)
+        with person_logged_in(owner):
+            self.assertContentEqual(
+                [owner], bug.getBugNotificationRecipients())
+
+    def test_private_bug_assignee(self):
+        owner = self.factory.makePerson()
+        assignee = self.factory.makePerson()
+        bug = self.factory.makeBug(
+            owner=owner, information_type=InformationType.USERDATA)
+        with person_logged_in(owner):
+            bug.default_bugtask.transitionToAssignee(assignee)
+            self.assertContentEqual(
+                [owner], bug.getBugNotificationRecipients())
+
+    def test_private_bug_with_duplicate_different_pillar_subscriber(self):
+        owner = self.factory.makePerson()
+        subscriber = self.factory.makePerson()
+        bug = self.factory.makeBug(
+            owner=owner, information_type=InformationType.USERDATA)
+        dupe = self.factory.makeBug(owner=owner)
+        with person_logged_in(owner):
+            dupe.subscribe(subscriber, owner)
+            dupe.markAsDuplicate(bug)
+            self.assertContentEqual(
+                [owner], bug.getBugNotificationRecipients())
+
+    def test_private_bug_with_duplicate_same_pillar_subscriber(self):
+        owner = self.factory.makePerson()
+        subscriber = self.factory.makePerson()
+        product = self.factory.makeProduct()
+        bug = self.factory.makeBug(
+            product=product, owner=owner,
+            information_type=InformationType.USERDATA)
+        dupe = self.factory.makeBug(owner=owner, product=product)
+        with person_logged_in(owner):
+            dupe.subscribe(subscriber, owner)
+            dupe.markAsDuplicate(bug)
+            self.assertContentEqual(
+                [owner], bug.getBugNotificationRecipients())
+
+    def test_private_bug_linked_to_question(self):
+        owner = self.factory.makePerson()
+        question = self.factory.makeQuestion(owner=owner)
+        bug = self.factory.makeBug(
+            owner=owner, information_type=InformationType.USERDATA)
+        with person_logged_in(owner):
+            question.linkBug(bug)
+            self.assertContentEqual(
+                [owner], bug.getBugNotificationRecipients())

=== modified file 'lib/lp/bugs/tests/test_bugnotification.py'
--- lib/lp/bugs/tests/test_bugnotification.py	2012-07-19 04:40:03 +0000
+++ lib/lp/bugs/tests/test_bugnotification.py	2012-07-24 05:15:26 +0000
@@ -7,7 +7,6 @@
 
 from datetime import datetime
 from itertools import chain
-import unittest
 
 from lazr.lifecycle.event import ObjectModifiedEvent
 from lazr.lifecycle.snapshot import Snapshot
@@ -32,90 +31,21 @@
     BugNotificationSet,
     )
 from lp.bugs.model.bugsubscriptionfilter import BugSubscriptionFilterMute
-from lp.registry.enums import InformationType
 from lp.services.config import config
 from lp.services.messages.interfaces.message import IMessageSet
 from lp.services.messages.model.message import MessageSet
 from lp.testing import (
-    login,
     person_logged_in,
     TestCaseWithFactory,
     )
 from lp.testing.dbuser import switch_dbuser
-from lp.testing.factory import LaunchpadObjectFactory
 from lp.testing.layers import (
     DatabaseFunctionalLayer,
-    LaunchpadFunctionalLayer,
     LaunchpadZopelessLayer,
     )
 from lp.testing.matchers import Contains
 
 
-class TestNotificationRecipientsOfPrivateBugs(unittest.TestCase):
-    """Test who get notified of changes to private bugs."""
-
-    layer = LaunchpadFunctionalLayer
-
-    def setUp(self):
-        login('foo.bar@xxxxxxxxxxxxx')
-        factory = LaunchpadObjectFactory()
-        self.product_owner = factory.makePerson(name="product-owner")
-        self.product = factory.makeProduct(owner=self.product_owner)
-        self.product_subscriber = factory.makePerson(
-            name="product-subscriber")
-        self.product.addBugSubscription(
-            self.product_subscriber, self.product_subscriber)
-        self.bug_subscriber = factory.makePerson(name="bug-subscriber")
-        self.bug_owner = factory.makePerson(name="bug-owner")
-        self.private_bug = factory.makeBug(
-            product=self.product, owner=self.bug_owner,
-            information_type=InformationType.USERDATA)
-        self.reporter = self.private_bug.owner
-        self.private_bug.subscribe(self.bug_subscriber, self.reporter)
-        [self.product_bugtask] = self.private_bug.bugtasks
-        self.direct_subscribers = set(
-            person.name for person in [self.bug_subscriber, self.reporter])
-
-    def test_status_change(self):
-        # Status changes are sent to the direct subscribers only.
-        bugtask_before_modification = Snapshot(
-            self.product_bugtask, providing=providedBy(self.product_bugtask))
-        self.product_bugtask.transitionToStatus(
-            BugTaskStatus.INVALID, self.private_bug.owner)
-        notify(ObjectModifiedEvent(
-            self.product_bugtask, bugtask_before_modification, ['status'],
-            user=self.reporter))
-        latest_notification = BugNotification.selectFirst(orderBy='-id')
-        notified_people = set(
-            recipient.person.name
-            for recipient in latest_notification.recipients)
-        self.assertEqual(self.direct_subscribers, notified_people)
-
-    def test_add_comment(self):
-        # Comment additions are sent to the direct subscribers only.
-        self.private_bug.newMessage(
-            self.reporter, subject='subject', content='content')
-        latest_notification = BugNotification.selectFirst(orderBy='-id')
-        notified_people = set(
-            recipient.person.name
-            for recipient in latest_notification.recipients)
-        self.assertEqual(self.direct_subscribers, notified_people)
-
-    def test_bug_edit(self):
-        # Bug edits are sent to direct the subscribers only.
-        bug_before_modification = Snapshot(
-            self.private_bug, providing=providedBy(self.private_bug))
-        self.private_bug.description = 'description'
-        notify(ObjectModifiedEvent(
-            self.private_bug, bug_before_modification, ['description'],
-            user=self.reporter))
-        latest_notification = BugNotification.selectFirst(orderBy='-id')
-        notified_people = set(
-            recipient.person.name
-            for recipient in latest_notification.recipients)
-        self.assertEqual(self.direct_subscribers, notified_people)
-
-
 class TestNotificationsSentForBugExpiration(TestCaseWithFactory):
     """Ensure that question subscribers are notified about bug expiration."""
 


Follow ups