launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #11007
[Merge] lp:~stevenk/launchpad/no-structsub-for-bug-supervisor into lp:launchpad
Steve Kowalik has proposed merging lp:~stevenk/launchpad/no-structsub-for-bug-supervisor into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~stevenk/launchpad/no-structsub-for-bug-supervisor/+merge/119831
No longer give bug supervisors an unconditional structural subscription on the target when they are set. Due to this, bug supervisor no longer has to have such a draconian validation method, since setting it will no longer spam them with tonnes of mail.
I have done a bunch of drive-bys in this branch too. Mostly whitespace related.
--
https://code.launchpad.net/~stevenk/launchpad/no-structsub-for-bug-supervisor/+merge/119831
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/no-structsub-for-bug-supervisor into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bugrole.py'
--- lib/lp/bugs/browser/bugrole.py 2012-02-09 04:28:33 +0000
+++ lib/lp/bugs/browser/bugrole.py 2012-08-16 04:34:22 +0000
@@ -41,47 +41,6 @@
else:
return self.OTHER_USER
- def validateBugSupervisor(self, data):
- """Validates the new bug supervisor.
-
- Verify that the value is None, the user, or a team he administers,
- otherwise, set a field error.
- """
- field_state = self._getFieldState(
- self.context.bug_supervisor, 'bug_supervisor', data)
- if field_state is self.INVALID_PERSON:
- error = (
- 'You must choose a valid person or team to be the '
- 'bug supervisor for %s.' % self.context.displayname)
- elif field_state is self.OTHER_TEAM:
- supervisor = data['bug_supervisor']
- team_url = canonical_url(
- supervisor, rootsite='mainsite', view_name='+members')
- error = structured(
- 'You cannot set %(team)s as the bug supervisor for '
- '%(target)s because you are not an administrator of that '
- 'team.<br />If you believe that %(team)s should be the '
- 'bug supervisor for %(target)s, notify one of the '
- '<a href="%(url)s">%(team)s administrators</a>. See '
- '<a href="https://help.launchpad.net/BugSupervisors">'
- 'the help wiki</a> for information about setting a bug '
- 'supervisor.',
- team=supervisor.displayname,
- target=self.context.displayname,
- url=team_url)
- elif field_state is self.OTHER_USER:
- error = structured(
- 'You cannot set another person as the bug supervisor for '
- '%(target)s.<br />See '
- '<a href="https://help.launchpad.net/BugSupervisors">'
- 'the help wiki</a> for information about setting a bug '
- 'supervisor.',
- target=self.context.displayname)
- else:
- # field_state is self.OK.
- return
- self.setFieldError('bug_supervisor', error)
-
def changeBugSupervisor(self, bug_supervisor):
if self.context.bug_supervisor != bug_supervisor:
self.context.setBugSupervisor(bug_supervisor, self.user)
=== modified file 'lib/lp/bugs/browser/bugsupervisor.py'
--- lib/lp/bugs/browser/bugsupervisor.py 2012-02-28 04:24:19 +0000
+++ lib/lp/bugs/browser/bugsupervisor.py 2012-08-16 04:34:22 +0000
@@ -60,10 +60,6 @@
cancel_url = next_url
- def validate(self, data):
- """See `LaunchpadFormView`."""
- self.validateBugSupervisor(data)
-
@action('Change', name='change')
def change_action(self, action, data):
"""Redirect to the target page with a success message."""
@@ -74,9 +70,5 @@
"Successfully cleared the bug supervisor. "
"You can set the bug supervisor again at any time.")
else:
- message = structured(
- 'A bug mail subscription was created for the bug supervisor. '
- 'You can <a href="%s">edit bug mail</a> '
- 'to change which notifications will be sent.',
- canonical_url(self.context, view_name='+subscriptions'))
+ message = structured('Bug supervisor privilege granted.')
self.request.response.addNotification(message)
=== modified file 'lib/lp/bugs/browser/bugtarget.py'
--- lib/lp/bugs/browser/bugtarget.py 2012-08-03 00:30:51 +0000
+++ lib/lp/bugs/browser/bugtarget.py 2012-08-16 04:34:22 +0000
@@ -218,7 +218,6 @@
"""Constrain bug expiration to Launchpad Bugs tracker."""
super(ProductConfigureBugTrackerView, self).validate(data)
if check_permission("launchpad.Edit", self.context):
- self.validateBugSupervisor(data)
self.validateSecurityContact(data)
# enable_bug_expiration is disabled by JavaScript when bugtracker
# is not 'In Launchpad'. The constraint is enforced here in case the
=== modified file 'lib/lp/bugs/browser/tests/test_bugsupervisor.py'
--- lib/lp/bugs/browser/tests/test_bugsupervisor.py 2012-08-14 23:27:07 +0000
+++ lib/lp/bugs/browser/tests/test_bugsupervisor.py 2012-08-16 04:34:22 +0000
@@ -5,7 +5,6 @@
__metaclass__ = type
-from zope.app.form.interfaces import ConversionError
from zope.component import getUtility
from lp.bugs.browser.bugsupervisor import BugSupervisorEditSchema
@@ -14,7 +13,6 @@
from lp.services.webapp.publisher import canonical_url
from lp.testing import (
BrowserTestCase,
- login,
login_person,
TestCaseWithFactory,
)
@@ -70,10 +68,7 @@
self.assertEqual(self.product.bug_supervisor, self.owner)
notifications = view.request.response.notifications
self.assertEqual(1, len(notifications))
- expected = (
- 'A bug mail subscription was created for the bug supervisor. '
- 'You can <a href="http://launchpad.dev/boing/+subscriptions">'
- 'edit bug mail</a> to change which notifications will be sent.')
+ expected = 'Bug supervisor privilege granted.'
self.assertEqual(expected, notifications.pop().message)
def test_owner_appoint_self_from_another(self):
@@ -115,77 +110,6 @@
self.assertEqual([], view.errors)
self.assertEqual(private_team, self.product.bug_supervisor)
- def test_owner_cannot_appoint_another_team(self):
- team = self.factory.makeTeam(name='smack', displayname='<smack />')
- form = self._makeForm(team)
- view = create_initialized_view(
- self.product, name='+bugsupervisor', form=form)
- self.assertEqual(1, len(view.errors))
- expected = (
- 'You cannot set <smack /> as the bug supervisor for '
- '<boing /> because you are not an administrator of that '
- 'team.<br />If you believe that <smack /> should be the '
- 'bug supervisor for <boing />, notify one of the '
- '<a href="http://launchpad.dev/~smack/+members"><smack /> '
- 'administrators</a>. See '
- '<a href="https://help.launchpad.net/BugSupervisors">the '
- 'help wiki</a> for information about setting a bug supervisor.')
- self.assertEqual(expected, view.errors.pop())
-
- def test_owner_cannot_appoint_a_nonvalid_user(self):
- # The vocabulary only accepts valid users.
- form = self._makeForm(None)
- form['field.bug_supervisor'] = 'fnord'
- view = create_initialized_view(
- self.product, name='+bugsupervisor', form=form)
- self.assertEqual(2, len(view.errors))
- expected = (
- 'You must choose a valid person or team to be the bug supervisor '
- 'for <boing />.')
- self.assertEqual(expected, view.errors.pop())
- self.assertTrue(isinstance(view.errors.pop(), ConversionError))
-
- def test_owner_cannot_appoint_another_user(self):
- another_user = self.factory.makePerson()
- form = self._makeForm(another_user)
- view = create_initialized_view(
- self.product, name='+bugsupervisor', form=form)
- self.assertEqual(1, len(view.errors))
- expected = (
- 'You cannot set another person as the bug supervisor for '
- '<boing />.<br />See '
- '<a href="https://help.launchpad.net/BugSupervisors">the help '
- 'wiki</a> for information about setting a bug supervisor.')
- self.assertEqual(expected, view.errors.pop())
-
- def test_admin_appoint_another_user(self):
- another_user = self.factory.makePerson()
- login('admin@xxxxxxxxxxxxx')
- form = self._makeForm(another_user)
- view = create_initialized_view(
- self.product, name='+bugsupervisor', form=form)
- self.assertEqual([], view.errors)
- self.assertEqual(another_user, self.product.bug_supervisor)
-
- def test_admin_appoint_another_team(self):
- another_team = self.factory.makeTeam()
- login('admin@xxxxxxxxxxxxx')
- form = self._makeForm(another_team)
- view = create_initialized_view(
- self.product, name='+bugsupervisor', form=form)
- self.assertEqual([], view.errors)
- self.assertEqual(another_team, self.product.bug_supervisor)
-
- def test_admin_appoint_private_team(self):
- private_team = self.factory.makeTeam(
- visibility=PersonVisibility.PRIVATE)
- login('admin@xxxxxxxxxxxxx')
- form = self._makeForm(private_team)
- view = create_initialized_view(
- self.product, name='+bugsupervisor', form=form)
- self.assertEqual([], view.errors)
- self.assertEqual(private_team, self.product.bug_supervisor)
-
class TestBugSupervisorLink(BrowserTestCase):
=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_configure.py'
--- lib/lp/bugs/browser/tests/test_bugtarget_configure.py 2012-08-13 19:34:10 +0000
+++ lib/lp/bugs/browser/tests/test_bugtarget_configure.py 2012-08-16 04:34:22 +0000
@@ -92,17 +92,6 @@
self.product.bug_reported_acknowledgement)
self.assertFalse(self.product.enable_bugfiling_duplicate_search)
- def test_bug_supervisor_invalid(self):
- # Verify that invalid bug_supervisor states are reported.
- # This is a sanity check. The bug_supervisor is rigorously tested
- # in its own test.
- other_person = self.factory.makePerson()
- form = self._makeForm()
- form['field.bug_supervisor'] = other_person.name
- view = create_initialized_view(
- self.product, name='+configure-bugtracker', form=form)
- self.assertEqual(1, len(view.errors))
-
def test_security_contact_invalid(self):
# Verify that invalid security_contact states are reported.
# This is a sanity check. The security_contact is rigorously tested
=== modified file 'lib/lp/bugs/doc/bugsubscription.txt'
--- lib/lp/bugs/doc/bugsubscription.txt 2012-08-07 13:50:53 +0000
+++ lib/lp/bugs/doc/bugsubscription.txt 2012-08-16 04:34:22 +0000
@@ -199,13 +199,11 @@
>>> print_displayname(linux_source_bug.getIndirectSubscribers())
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
@@ -216,13 +214,11 @@
>>> print_displayname(linux_source_bug.getIndirectSubscribers())
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
@@ -232,13 +228,11 @@
>>> print_displayname(linux_source_bug.getIndirectSubscribers())
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
@@ -267,28 +261,24 @@
>>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
... level=BugNotificationLevel.COMMENTS))
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getIndirectSubscribers(
... level=BugNotificationLevel.COMMENTS))
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
... level=BugNotificationLevel.LIFECYCLE))
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getIndirectSubscribers(
... level=BugNotificationLevel.LIFECYCLE))
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
@@ -305,26 +295,22 @@
>>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
... level=BugNotificationLevel.LIFECYCLE))
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getIndirectSubscribers(
... level=BugNotificationLevel.LIFECYCLE))
No Privileges Person
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
... level=BugNotificationLevel.METADATA))
- Robert Collins
Sample Person
Ubuntu Team
>>> print_displayname(linux_source_bug.getIndirectSubscribers(
... level=BugNotificationLevel.METADATA))
- Robert Collins
Sample Person
Ubuntu Team
@@ -357,7 +343,6 @@
>>> print_displayname(linux_source_bug.getIndirectSubscribers())
No Privileges Person
- Robert Collins
Sample Person
Scott James Remnant
Ubuntu Team
@@ -710,7 +695,7 @@
recipients list.
>>> getSubscribers(new_bug)
- ['foo.bar@xxxxxxxxxxxxx', 'mark@xxxxxxxxxxx', 'robertc@xxxxxxxxxxxxxxxxx']
+ ['foo.bar@xxxxxxxxxxxxx']
If we create a bug task on Ubuntu in the same bug, the Ubuntu bug
supervisor will be subscribed:
@@ -720,8 +705,6 @@
>>> print '\n'.join(getSubscribers(new_bug))
foo.bar@xxxxxxxxxxxxx
- mark@xxxxxxxxxxx
- robertc@xxxxxxxxxxxxxxxxx
support@xxxxxxxxxx
test@xxxxxxxxxxxxx
@@ -753,8 +736,6 @@
>>> print '\n'.join(getSubscribers(new_bug))
foo.bar@xxxxxxxxxxxxx
- mark@xxxxxxxxxxx
- robertc@xxxxxxxxxxxxxxxxx
The upstream maintainer will be subscribed to security-related private
bugs, because upstream has no security contact, in this case.
@@ -769,8 +750,6 @@
>>> print '\n'.join(getSubscribers(new_bug))
foo.bar@xxxxxxxxxxxxx
- mark@xxxxxxxxxxx
- robertc@xxxxxxxxxxxxxxxxx
test@xxxxxxxxxxxxx
Now let's create a bug on a specific package, which has no package bug
=== modified file 'lib/lp/bugs/doc/initial-bug-contacts.txt'
--- lib/lp/bugs/doc/initial-bug-contacts.txt 2012-05-22 12:05:51 +0000
+++ lib/lp/bugs/doc/initial-bug-contacts.txt 2012-08-16 04:34:22 +0000
@@ -305,8 +305,7 @@
>>> mozilla_firefox.setBugSupervisor(foobar, foobar)
-Then we'll reassign bug #2 in Ubuntu to be in Firefox, noting that Foo
-Bar gets subscribed to the bug in the process:
+Then we'll reassign bug #2 in Ubuntu to be in Firefox:
>>> bug_two_in_ubuntu = getUtility(IBugTaskSet).get(3)
>>> print bug_two_in_ubuntu.bug.id
@@ -330,46 +329,6 @@
>>> notify(product_changed)
>>> transaction.commit()
-With the product changed, we can see that Foo Bar is now subscribed:
-
- >>> print '\n'.join(subscriber_names(bug_two_in_ubuntu.bug))
- Foo Bar
- Sample Person
- Steve Alexander
- Ubuntu Team
-
-And Foo Bar gets an email containing complete information about the bug
-report. It states that he received the email because he is the bug
-supervisor for Mozilla Firefox.
-
- >>> test_emails = list(stub.test_emails)
- >>> test_emails.sort(by_to_addrs)
-
- >>> len(test_emails)
- 1
-
- >>> from_addr, to_addr, raw_message = test_emails.pop()
- >>> print from_addr
- bounces@xxxxxxxxxxxxx
-
- >>> print to_addr
- ['foo.bar@xxxxxxxxxxxxx']
-
- >>> msg = email.message_from_string(raw_message)
- >>> msg['Subject']
- '[Bug 2] [NEW] Blackhole Trash folder'
-
- >>> print msg.get_payload(decode=True)
- You have been subscribed to a public bug:
- ...
- ** Affects: firefox
- ...
- --
- Blackhole Trash folder
- http://bugs.launchpad.dev/bugs/2
- You received this bug notification because you
- are subscribed to Mozilla Firefox.
-
Teams as bug supervisors
------------------------
=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
--- lib/lp/bugs/interfaces/bugtask.py 2012-08-07 03:47:15 +0000
+++ lib/lp/bugs/interfaces/bugtask.py 2012-08-16 04:34:22 +0000
@@ -785,7 +785,7 @@
"""
def userHasDriverPrivileges(user):
- """Does the user have driver privledges on the current bugtask?
+ """Does the user have driver privileges on the current bugtask?
:return: A boolean.
"""
=== modified file 'lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py'
--- lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py 2012-08-08 07:22:51 +0000
+++ lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py 2012-08-16 04:34:22 +0000
@@ -392,8 +392,7 @@
# the assignee, supervisor and structural subscriber do.
found_subscribers = self.getInfo().also_notified_subscribers
self.assertContentEqual(
- [assignee, supervisor, structural_subscriber],
- found_subscribers)
+ [assignee, structural_subscriber], found_subscribers)
def test_also_notified_subscribers_muted(self):
# If someone is muted, they are not listed in the
@@ -405,13 +404,10 @@
# when they are not muted.
found_subscribers = self.getInfo().also_notified_subscribers
self.assertContentEqual(
- [assignee, supervisor, structural_subscriber],
- found_subscribers)
+ [assignee, structural_subscriber], found_subscribers)
# Now we mute all of the subscribers.
with person_logged_in(assignee):
self.bug.mute(assignee, assignee)
- with person_logged_in(supervisor):
- self.bug.mute(supervisor, supervisor)
with person_logged_in(structural_subscriber):
self.bug.mute(structural_subscriber, structural_subscriber)
# Now we don't see them.
=== removed file 'lib/lp/bugs/tests/has-bug-supervisor.txt'
--- lib/lp/bugs/tests/has-bug-supervisor.txt 2010-10-14 18:42:19 +0000
+++ lib/lp/bugs/tests/has-bug-supervisor.txt 1970-01-01 00:00:00 +0000
@@ -1,66 +0,0 @@
-= IHasBugSupervisor =
-
-Bug supervisors are people or teams who are responsible for dealing with
-bugs pertaining to a target. All objects with a bug supervisor are also
-structural subscription targets. When the bug supervisor for such an object
-is set, a new bug subscription is created as well.
-
- >>> list(target.bug_subscriptions)
- []
-
- >>> print target.bug_supervisor
- None
-
- >>> from lp.registry.interfaces.person import IPersonSet
- >>> personset = getUtility(IPersonSet)
- >>> no_priv = personset.getByEmail("no-priv@xxxxxxxxxxxxx")
- >>> foo_bar = personset.getByEmail("foo.bar@xxxxxxxxxxxxx")
-
- >>> login("foo.bar@xxxxxxxxxxxxx")
-
-We set no_priv as the bug supervisor for the target.
-
- >>> target.setBugSupervisor(no_priv, foo_bar)
-
-The bug supervisor can be retrieved using the `bug_supervisor` property.
-
- >>> print target.bug_supervisor.preferredemail.email
- no-priv@xxxxxxxxxxxxx
-
-But we can't use it to set the bug supervisor.
-
- >>> target.bug_supervisor = None
- Traceback (most recent call last):
- ...
- ForbiddenAttribute: ('bug_supervisor', <...>)
-
-After setting no_priv as the bug supervisor, a bug subscription is created
-for the target.
-
- >>> for bug_subscription in target.bug_subscriptions:
- ... print bug_subscription.subscriber.preferredemail.email
- no-priv@xxxxxxxxxxxxx
-
-And now no_priv is an indirect subscriber to any bug filed on
-the target.
-
- >>> bug = filebug(target, 'test bug')
- >>> no_priv in bug.getIndirectSubscribers()
- True
-
-If no_priv unsubscribes, he is still set as the bug supervisor.
-
- >>> target.removeBugSubscription(no_priv, no_priv)
- >>> print target.bug_supervisor.preferredemail.email
- no-priv@xxxxxxxxxxxxx
- >>> no_priv in bug.getIndirectSubscribers()
- False
-
-But we can remove the bug supervisor by setting it to None.
-
- >>> target.setBugSupervisor(None, None)
- >>> print target.bug_supervisor
- None
-
-Note that removing a person as a bug contact supervisor not remove their
-subscription to the target, if it exists.
=== renamed file 'lib/lp/bugs/tests/test_bugcontact.py' => 'lib/lp/bugs/tests/test_bugsupervisor.py'
--- lib/lp/bugs/tests/test_bugcontact.py 2012-06-06 16:04:34 +0000
+++ lib/lp/bugs/tests/test_bugsupervisor.py 2012-08-16 04:34:22 +0000
@@ -1,40 +1,45 @@
# Copyright 2009 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
-"""Test harness for running tests against IHasBugcontact
-implementations.
-"""
-
-import unittest
-
-from lp.bugs.tests.test_structuralsubscriptiontarget import (
- distributionSetUp,
- productSetUp,
+"""Run tests against IHasBugSupervisor implementations."""
+
+from zope.security.interfaces import ForbiddenAttribute
+
+from lp.testing import (
+ person_logged_in,
+ TestCaseWithFactory,
)
from lp.testing.layers import DatabaseFunctionalLayer
-from lp.testing.systemdocs import (
- LayeredDocFileSuite,
- tearDown,
- )
-
-
-def test_suite():
- """Return the `IHasBugSupervisor` TestSuite."""
- suite = unittest.TestSuite()
-
- setUpMethods = [
- productSetUp,
- distributionSetUp,
- ]
-
- testname = 'has-bug-supervisor.txt'
- for setUpMethod in setUpMethods:
- id_ext = "%s-%s" % (testname, setUpMethod.func_name)
- test = LayeredDocFileSuite(
- testname,
- id_extensions=[id_ext],
- setUp=setUpMethod, tearDown=tearDown,
- layer=DatabaseFunctionalLayer)
- suite.addTest(test)
-
- return suite
+
+
+class BugSupervisorMixin:
+
+ def test_cannot_be_set_directly(self):
+ # The bug_supervisor attribute can not be directly set.
+ self.assertRaises(
+ ForbiddenAttribute, setattr, self.target, 'bug_supervisor', None)
+
+ def test_set_bug_supervisor(self):
+ # The bug_supervisor attribute can be set by calling .setBugSupervisor.
+ person = self.factory.makePerson()
+ with person_logged_in(self.target.owner):
+ self.target.setBugSupervisor(person, None)
+ self.assertEqual(person, self.target.bug_supervisor)
+
+
+class TestProductBugSupervisor(TestCaseWithFactory, BugSupervisorMixin):
+
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(TestProductBugSupervisor, self).setUp()
+ self.target = self.factory.makeProduct()
+
+
+class TestDistributionBugSupervisor(TestCaseWithFactory, BugSupervisorMixin):
+
+ layer = DatabaseFunctionalLayer
+
+ def setUp(self):
+ super(TestDistributionBugSupervisor, self).setUp()
+ self.target = self.factory.makeDistribution()
=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py 2012-08-11 02:18:44 +0000
+++ lib/lp/registry/browser/product.py 2012-08-16 04:34:22 +0000
@@ -114,7 +114,6 @@
from lp.app.widgets.itemswidgets import (
CheckBoxMatrixWidget,
LaunchpadRadioWidget,
- LaunchpadRadioWidgetWithDescription,
)
from lp.app.widgets.popup import PersonPickerWidget
from lp.app.widgets.product import (
@@ -612,8 +611,7 @@
return Link('+branchvisibility', text, icon='edit')
-class ProductBugsMenu(PillarBugsMenu,
- ProductEditLinksMixin):
+class ProductBugsMenu(PillarBugsMenu, ProductEditLinksMixin):
usedfor = IProduct
facet = 'bugs'
@@ -1543,10 +1541,7 @@
else:
return canonical_url(getUtility(IProductSet))
- @property
- def cancel_url(self):
- """See `LaunchpadFormView`."""
- return self.next_url
+ cancel_url = next_url
class ProductValidationMixin:
=== modified file 'lib/lp/registry/model/distribution.py'
--- lib/lp/registry/model/distribution.py 2012-08-08 05:36:44 +0000
+++ lib/lp/registry/model/distribution.py 2012-08-16 04:34:22 +0000
@@ -81,7 +81,6 @@
DB_UNRESOLVED_BUGTASK_STATUSES,
)
from lp.bugs.interfaces.bugtaskfilter import OrderedBugTask
-from lp.bugs.model.bug import BugSet
from lp.bugs.model.bugtarget import (
BugTargetBase,
OfficialBugTagTargetMixin,
@@ -1581,8 +1580,6 @@
def setBugSupervisor(self, bug_supervisor, user):
"""See `IHasBugSupervisor`."""
self.bug_supervisor = bug_supervisor
- if bug_supervisor is not None:
- self.addBugSubscription(bug_supervisor, user)
def getAllowedBugInformationTypes(self):
"""See `IDistribution.`"""
=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py 2012-08-10 06:39:58 +0000
+++ lib/lp/registry/model/product.py 2012-08-16 04:34:22 +0000
@@ -92,7 +92,6 @@
from lp.bugs.interfaces.bugsummary import IBugSummaryDimension
from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor
from lp.bugs.interfaces.bugtaskfilter import OrderedBugTask
-from lp.bugs.model.bug import BugSet
from lp.bugs.model.bugtarget import (
BugTargetBase,
OfficialBugTagTargetMixin,
@@ -1387,8 +1386,6 @@
def setBugSupervisor(self, bug_supervisor, user):
"""See `IHasBugSupervisor`."""
self.bug_supervisor = bug_supervisor
- if bug_supervisor is not None:
- self.addBugSubscription(bug_supervisor, user)
def composeCustomLanguageCodeMatch(self):
"""See `HasCustomLanguageCodesMixin`."""
Follow ups