launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #23216
[Merge] lp:~cjwatson/launchpad/snapshot-modifying-helper-use-bugs into lp:launchpad
Colin Watson has proposed merging lp:~cjwatson/launchpad/snapshot-modifying-helper-use-bugs into lp:launchpad.
Commit message:
Convert the rest of lp.bugs to notify_modified.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/snapshot-modifying-helper-use-bugs/+merge/361613
--
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~cjwatson/launchpad/snapshot-modifying-helper-use-bugs into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bug.py'
--- lib/lp/bugs/browser/bug.py 2018-07-16 00:46:56 +0000
+++ lib/lp/bugs/browser/bug.py 2019-01-10 11:51:47 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""IBug related view classes."""
@@ -131,6 +131,7 @@
ILaunchBag,
)
from lp.services.webapp.publisher import RedirectionView
+from lp.services.webapp.snapshot import notify_modified
class BugNavigation(Navigation):
@@ -795,11 +796,9 @@
# We handle duplicate changes by hand instead of leaving it to
# the usual machinery because we must use bug.markAsDuplicate().
bug = self.context.bug
- bug_before_modification = Snapshot(bug, providing=providedBy(bug))
- duplicateof = data.pop('duplicateof')
- bug.markAsDuplicate(duplicateof)
- notify(
- ObjectModifiedEvent(bug, bug_before_modification, 'duplicateof'))
+ with notify_modified(bug, ['duplicateof']):
+ duplicateof = data.pop('duplicateof')
+ bug.markAsDuplicate(duplicateof)
# Apply other changes.
self.updateBugFromData(data)
return self._duplicate_action_result()
@@ -812,10 +811,8 @@
def remove_action(self, action, data):
"""Update the bug."""
bug = self.context.bug
- bug_before_modification = Snapshot(bug, providing=providedBy(bug))
- bug.markAsDuplicate(None)
- notify(
- ObjectModifiedEvent(bug, bug_before_modification, 'duplicateof'))
+ with notify_modified(bug, ['duplicateof']):
+ bug.markAsDuplicate(None)
return self._duplicate_action_result()
def _duplicate_action_result(self):
=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
--- lib/lp/bugs/browser/tests/test_bugtask.py 2018-11-12 16:04:10 +0000
+++ lib/lp/bugs/browser/tests/test_bugtask.py 2019-01-10 11:51:47 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -10,8 +10,6 @@
import re
import urllib
-from lazr.lifecycle.event import ObjectModifiedEvent
-from lazr.lifecycle.snapshot import Snapshot
from lazr.restful.interfaces import IJSONRequestCache
from pytz import UTC
import simplejson
@@ -29,9 +27,7 @@
getMultiAdapter,
getUtility,
)
-from zope.event import notify
from zope.formlib.interfaces import ConversionError
-from zope.interface import providedBy
from zope.security.proxy import removeSecurityProxy
from lp.app.enums import InformationType
@@ -76,6 +72,7 @@
ILaunchpadRoot,
)
from lp.services.webapp.servers import LaunchpadTestRequest
+from lp.services.webapp.snapshot import notify_modified
from lp.soyuz.interfaces.component import IComponentSet
from lp.testing import (
ANONYMOUS,
@@ -1739,11 +1736,8 @@
layer = DatabaseFunctionalLayer
def setAttribute(self, obj, attribute, value):
- obj_before_modification = Snapshot(obj, providing=providedBy(obj))
- setattr(removeSecurityProxy(obj), attribute, value)
- notify(ObjectModifiedEvent(
- obj, obj_before_modification, [attribute],
- self.factory.makePerson()))
+ with notify_modified(obj, [attribute], user=self.factory.makePerson()):
+ setattr(removeSecurityProxy(obj), attribute, value)
def test_escapes_assignee(self):
with celebrity_logged_in('admin'):
=== modified file 'lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py'
--- lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py 2013-11-29 12:51:58 +0000
+++ lib/lp/bugs/mail/tests/test_bug_duplicate_notifications.py 2019-01-10 11:51:47 +0000
@@ -1,18 +1,16 @@
-# Copyright 2010 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests for notification strings of duplicate Bugs."""
-from lazr.lifecycle.event import ObjectModifiedEvent
-from lazr.lifecycle.snapshot import Snapshot
import transaction
from zope.component import getUtility
-from zope.event import notify
-from zope.interface import providedBy
from lp.bugs.interfaces.bugtask import BugTaskStatus
-from lp.services.mail import stub
+from lp.bugs.model.bugnotification import BugNotification
+from lp.bugs.scripts.bugnotification import construct_email_notifications
from lp.services.webapp.interfaces import ILaunchBag
+from lp.services.webapp.snapshot import notify_modified
from lp.testing import TestCaseWithFactory
from lp.testing.layers import DatabaseFunctionalLayer
@@ -32,9 +30,6 @@
self.master_bug = self.factory.makeBug(target=self.product)
self.dup_bug = self.factory.makeBug(target=self.product)
self.master_bug_task = self.master_bug.getBugTask(self.product)
- self.master_bug_task_before_modification = Snapshot(
- self.master_bug_task,
- providing=providedBy(self.master_bug_task))
self.person_subscribed_email = 'person@xxxxxxxxxxx'
self.person_subscribed = self.factory.makePerson(
name='subscribed', displayname='Person',
@@ -47,14 +42,14 @@
def test_dup_subscriber_change_notification_message(self):
"""Duplicate bug number in the reason (email footer) for
duplicate subscribers when a master bug is modified."""
- self.assertEqual(len(stub.test_emails), 0, 'emails in queue')
- self.master_bug_task.transitionToStatus(
- BugTaskStatus.CONFIRMED, self.user)
- notify(ObjectModifiedEvent(
- self.master_bug_task, self.master_bug_task_before_modification,
- ['status'], user=self.user))
+ with notify_modified(self.master_bug_task, ['status'], user=self.user):
+ self.master_bug_task.transitionToStatus(
+ BugTaskStatus.CONFIRMED, self.user)
transaction.commit()
- self.assertEqual(len(stub.test_emails), 2, 'email not sent')
+ latest_notification = BugNotification.selectFirst(orderBy='-id')
+ notifications, omitted, messages = construct_email_notifications(
+ [latest_notification])
+ self.assertEqual(
+ len(notifications), 1, 'email notification not created')
rationale = 'duplicate bug report (%i)' % self.dup_bug.id
- msg = stub.test_emails[-1][2]
- self.assertIn(rationale, msg)
+ self.assertIn(rationale, str(messages[-1]))
=== modified file 'lib/lp/bugs/mail/tests/test_bug_task_assignment.py'
--- lib/lp/bugs/mail/tests/test_bug_task_assignment.py 2015-07-21 09:04:01 +0000
+++ lib/lp/bugs/mail/tests/test_bug_task_assignment.py 2019-01-10 11:51:47 +0000
@@ -1,19 +1,16 @@
-# Copyright 2010 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests for Bug task assignment-related email tests."""
-from lazr.lifecycle.event import ObjectModifiedEvent
-from lazr.lifecycle.snapshot import Snapshot
import transaction
from zope.component import getUtility
-from zope.event import notify
-from zope.interface import providedBy
from lp.bugs.model.bugnotification import BugNotification
from lp.bugs.scripts.bugnotification import construct_email_notifications
from lp.services.mail import stub
from lp.services.webapp.interfaces import ILaunchBag
+from lp.services.webapp.snapshot import notify_modified
from lp.testing import TestCaseWithFactory
from lp.testing.layers import DatabaseFunctionalLayer
@@ -32,8 +29,6 @@
name='rebirth')
self.bug = self.factory.makeBug(target=self.product)
self.bug_task = self.bug.getBugTask(self.product)
- self.bug_task_before_modification = Snapshot(self.bug_task,
- providing=providedBy(self.bug_task))
self.person_assigned_email = 'stever@xxxxxxxxxxx'
self.person_assigned = self.factory.makePerson(
name='assigned', displayname='Steve Rogers',
@@ -53,10 +48,8 @@
"""Test notification string when a person is assigned a task by
someone else."""
self.assertEqual(len(stub.test_emails), 0, 'emails in queue')
- self.bug_task.transitionToAssignee(self.person_assigned)
- notify(ObjectModifiedEvent(
- self.bug_task, self.bug_task_before_modification,
- ['assignee'], user=self.user))
+ with notify_modified(self.bug_task, ['assignee'], user=self.user):
+ self.bug_task.transitionToAssignee(self.person_assigned)
transaction.commit()
self.assertEqual(len(stub.test_emails), 1, 'email not sent')
rationale = (
@@ -69,10 +62,8 @@
"""Test notification string when a person is assigned a task by
themselves."""
stub.test_emails = []
- self.bug_task.transitionToAssignee(self.user)
- notify(ObjectModifiedEvent(
- self.bug_task, self.bug_task_before_modification,
- edited_fields=['assignee']))
+ with notify_modified(self.bug_task, ['assignee']):
+ self.bug_task.transitionToAssignee(self.user)
transaction.commit()
self.assertEqual(1, len(stub.test_emails))
rationale = (
@@ -86,10 +77,8 @@
"""Test that a new recipient being assigned a bug task does send
a NEW message."""
self.assertEqual(len(stub.test_emails), 0, 'emails in queue')
- self.bug_task.transitionToAssignee(self.person_assigned)
- notify(ObjectModifiedEvent(
- self.bug_task, self.bug_task_before_modification,
- ['assignee'], user=self.user))
+ with notify_modified(self.bug_task, ['assignee'], user=self.user):
+ self.bug_task.transitionToAssignee(self.person_assigned)
transaction.commit()
self.assertEqual(len(stub.test_emails), 1, 'email not sent')
new_message = '[NEW]'
@@ -100,10 +89,8 @@
def test_assignee_new_subscriber(self):
"""Build a list of people who will receive emails about the bug
task changes and ensure the assignee is not one."""
- self.bug_task.transitionToAssignee(self.person_assigned)
- notify(ObjectModifiedEvent(
- self.bug_task, self.bug_task_before_modification,
- ['assignee'], user=self.user))
+ with notify_modified(self.bug_task, ['assignee'], user=self.user):
+ self.bug_task.transitionToAssignee(self.person_assigned)
latest_notification = BugNotification.selectFirst(orderBy='-id')
notifications, omitted, messages = construct_email_notifications(
[latest_notification])
@@ -117,10 +104,8 @@
"""Assign a team, who is not subscribed to a bug, a bug task and
ensure that team members do not receive an email about the bug
task changes."""
- self.bug_task.transitionToAssignee(self.team_assigned)
- notify(ObjectModifiedEvent(
- self.bug_task, self.bug_task_before_modification,
- ['assignee'], user=self.user))
+ with notify_modified(self.bug_task, ['assignee'], user=self.user):
+ self.bug_task.transitionToAssignee(self.team_assigned)
latest_notification = BugNotification.selectFirst(orderBy='-id')
notifications, omitted, messages = construct_email_notifications(
[latest_notification])
=== modified file 'lib/lp/bugs/mail/tests/test_bug_task_modification.py'
--- lib/lp/bugs/mail/tests/test_bug_task_modification.py 2012-08-08 07:22:51 +0000
+++ lib/lp/bugs/mail/tests/test_bug_task_modification.py 2019-01-10 11:51:47 +0000
@@ -1,19 +1,16 @@
-# Copyright 2010 Canonical Ltd. This software is licensed under the
+# Copyright 2010-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Test for emails sent after bug task modification."""
-from lazr.lifecycle.event import ObjectModifiedEvent
-from lazr.lifecycle.snapshot import Snapshot
import transaction
from zope.component import getUtility
-from zope.event import notify
-from zope.interface import providedBy
from lp.bugs.interfaces.bugtask import BugTaskStatus
from lp.bugs.model.bugnotification import BugNotification
from lp.bugs.scripts.bugnotification import construct_email_notifications
from lp.services.webapp.interfaces import ILaunchBag
+from lp.services.webapp.snapshot import notify_modified
from lp.testing import TestCaseWithFactory
from lp.testing.layers import DatabaseFunctionalLayer
@@ -31,15 +28,12 @@
self.product = self.factory.makeProduct(owner=self.user)
self.bug = self.factory.makeBug(target=self.product)
self.bug_task = self.bug.getBugTask(self.product)
- self.bug_task_before_modification = Snapshot(self.bug_task,
- providing=providedBy(self.bug_task))
def test_for_bug_modifier_header(self):
"""Test X-Launchpad-Bug-Modifier appears when a bug is modified."""
- self.bug_task.transitionToStatus(BugTaskStatus.CONFIRMED, self.user)
- notify(ObjectModifiedEvent(
- self.bug_task, self.bug_task_before_modification,
- ['status'], user=self.user))
+ with notify_modified(self.bug_task, ['status'], user=self.user):
+ self.bug_task.transitionToStatus(
+ BugTaskStatus.CONFIRMED, self.user)
transaction.commit()
latest_notification = BugNotification.selectFirst(orderBy='-id')
notifications, omitted, messages = construct_email_notifications(
=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py 2016-07-27 12:54:40 +0000
+++ lib/lp/bugs/model/bug.py 2019-01-10 11:51:47 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2016 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Launchpad bug-related database table classes."""
@@ -26,10 +26,7 @@
import operator
import re
-from lazr.lifecycle.event import (
- ObjectCreatedEvent,
- ObjectModifiedEvent,
- )
+from lazr.lifecycle.event import ObjectCreatedEvent
from lazr.lifecycle.snapshot import Snapshot
import pytz
from sqlobject import (
@@ -70,10 +67,7 @@
from zope.component import getUtility
from zope.contenttype import guess_content_type
from zope.event import notify
-from zope.interface import (
- implementer,
- providedBy,
- )
+from zope.interface import implementer
from zope.security.interfaces import Unauthorized
from zope.security.proxy import (
ProxyFactory,
@@ -234,6 +228,7 @@
from lp.services.webapp.publisher import (
get_raw_form_value_from_current_request,
)
+from lp.services.webapp.snapshot import notify_modified
from lp.services.xref.interfaces import IXRefSet
@@ -1501,20 +1496,12 @@
'A question cannot be created from this bug without a '
'valid bugtask.')
- bugtask_before_modification = Snapshot(
- bugtask, providing=providedBy(bugtask))
- bugtask.transitionToStatus(BugTaskStatus.INVALID, person)
- edited_fields = ['status']
- if comment is not None:
- self.newMessage(
- owner=person, subject=self.followup_subject(),
- content=comment)
- notify(
- ObjectModifiedEvent(
- object=bugtask,
- object_before_modification=bugtask_before_modification,
- edited_fields=edited_fields,
- user=person))
+ with notify_modified(bugtask, ['status'], user=person):
+ bugtask.transitionToStatus(BugTaskStatus.INVALID, person)
+ if comment is not None:
+ self.newMessage(
+ owner=person, subject=self.followup_subject(),
+ content=comment)
question_target = IQuestionTarget(bugtask.target)
question = question_target.createQuestionFromBug(self)
@@ -1759,11 +1746,8 @@
if bugtask.status == status:
return None
- bugtask_before_modification = Snapshot(
- bugtask, providing=providedBy(bugtask))
- bugtask.transitionToStatus(status, user)
- notify(ObjectModifiedEvent(
- bugtask, bugtask_before_modification, ['status'], user=user))
+ with notify_modified(bugtask, ['status'], user=user):
+ bugtask.transitionToStatus(status, user)
return bugtask
=== modified file 'lib/lp/bugs/model/bugtask.py'
--- lib/lp/bugs/model/bugtask.py 2018-11-12 16:04:10 +0000
+++ lib/lp/bugs/model/bugtask.py 2019-01-10 11:51:47 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Classes that implement IBugTask and its related interfaces."""
@@ -30,11 +30,7 @@
)
import re
-from lazr.lifecycle.event import (
- ObjectDeletedEvent,
- ObjectModifiedEvent,
- )
-from lazr.lifecycle.snapshot import Snapshot
+from lazr.lifecycle.event import ObjectDeletedEvent
import pytz
from sqlobject import (
ForeignKey,
@@ -143,6 +139,7 @@
from lp.services.propertycache import get_property_cache
from lp.services.searchbuilder import any
from lp.services.webapp.interfaces import ILaunchBag
+from lp.services.webapp.snapshot import notify_modified
from lp.services.xref.interfaces import IXRefSet
@@ -839,16 +836,13 @@
# END TEMPORARY BIT FOR BUGTASK AUTOCONFIRM FEATURE FLAG.
):
janitor = getUtility(ILaunchpadCelebrities).janitor
- bugtask_before_modification = Snapshot(
- self, providing=providedBy(self))
- # Create a bug message explaining why the janitor auto-confirmed
- # the bugtask.
- msg = ("Status changed to 'Confirmed' because the bug "
- "affects multiple users.")
- self.bug.newMessage(owner=janitor, content=msg)
- self.transitionToStatus(BugTaskStatus.CONFIRMED, janitor)
- notify(ObjectModifiedEvent(
- self, bugtask_before_modification, ['status'], user=janitor))
+ with notify_modified(self, ['status'], user=janitor):
+ # Create a bug message explaining why the janitor
+ # auto-confirmed the bugtask.
+ msg = ("Status changed to 'Confirmed' because the bug "
+ "affects multiple users.")
+ self.bug.newMessage(owner=janitor, content=msg)
+ self.transitionToStatus(BugTaskStatus.CONFIRMED, janitor)
def canTransitionToStatus(self, new_status, user):
"""See `IBugTask`."""
=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
--- lib/lp/bugs/model/tests/test_bugtask.py 2018-02-14 01:27:28 +0000
+++ lib/lp/bugs/model/tests/test_bugtask.py 2019-01-10 11:51:47 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
__metaclass__ = type
@@ -9,7 +9,6 @@
import subprocess
import unittest
-from lazr.lifecycle.event import ObjectModifiedEvent
from lazr.lifecycle.snapshot import Snapshot
from lazr.restfulclient.errors import Unauthorized
from storm.store import Store
@@ -17,7 +16,6 @@
from testtools.testcase import ExpectedException
import transaction
from zope.component import getUtility
-from zope.event import notify
from zope.interface import providedBy
from zope.security.interfaces import Unauthorized as ZopeUnAuthorized
from zope.security.proxy import removeSecurityProxy
@@ -89,6 +87,7 @@
from lp.services.searchbuilder import any
from lp.services.webapp.authorization import check_permission
from lp.services.webapp.interfaces import ILaunchBag
+from lp.services.webapp.snapshot import notify_modified
from lp.soyuz.interfaces.archive import ArchivePurpose
from lp.testing import (
admin_logged_in,
@@ -563,16 +562,11 @@
ubuntu_team = getUtility(IPersonSet).getByEmail('support@xxxxxxxxxx')
bug_upstream_firefox_crashes.bug.subscribe(ubuntu_team, ubuntu_team)
- old_state = Snapshot(
- bug_upstream_firefox_crashes.bug, providing=IBug)
- self.assertTrue(
- bug_upstream_firefox_crashes.bug.setPrivate(True, foobar))
-
- bug_set_private = ObjectModifiedEvent(
- bug_upstream_firefox_crashes.bug, old_state,
- ["id", "title", "private"])
-
- notify(bug_set_private)
+ with notify_modified(
+ bug_upstream_firefox_crashes.bug, ["id", "title", "private"]):
+ self.assertTrue(
+ bug_upstream_firefox_crashes.bug.setPrivate(True, foobar))
+
flush_database_updates()
# If we now login as someone who was neither implicitly nor explicitly
@@ -2345,11 +2339,10 @@
task = self.factory.makeBugTask(target=old)
p = self.factory.makePerson()
self.assertEqual(old, task.target)
- old_state = Snapshot(task, providing=providedBy(task))
with person_logged_in(task.owner):
- task.bug.subscribe(p, p)
- task.transitionToTarget(new, p)
- notify(ObjectModifiedEvent(task, old_state, ["target"]))
+ with notify_modified(task, ["target"]):
+ task.bug.subscribe(p, p)
+ task.transitionToTarget(new, p)
return task
def assertTransitionWorks(self, a, b):
=== modified file 'lib/lp/bugs/scripts/bugexpire.py'
--- lib/lp/bugs/scripts/bugexpire.py 2012-12-20 14:55:13 +0000
+++ lib/lp/bugs/scripts/bugexpire.py 2019-01-10 11:51:47 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""BugTask expiration rules."""
@@ -10,11 +10,7 @@
from logging import getLogger
-from lazr.lifecycle.event import ObjectModifiedEvent
-from lazr.lifecycle.snapshot import Snapshot
from zope.component import getUtility
-from zope.event import notify
-from zope.interface import providedBy
from lp.app.interfaces.launchpad import ILaunchpadCelebrities
from lp.bugs.interfaces.bugtask import (
@@ -27,6 +23,7 @@
setupInteraction,
)
from lp.services.webapp.interfaces import IPlacelessAuthUtility
+from lp.services.webapp.snapshot import notify_modified
class BugJanitor:
@@ -87,19 +84,16 @@
if bugtask.conjoined_master:
continue
- bugtask_before_modification = Snapshot(
- bugtask, providing=providedBy(bugtask))
- bugtask.transitionToStatus(
- BugTaskStatus.EXPIRED, self.janitor)
- content = message_template % (
- bugtask.bugtargetdisplayname, self.days_before_expiration)
- bugtask.bug.newMessage(
- owner=self.janitor,
- subject=bugtask.bug.followup_subject(),
- content=content)
- notify(ObjectModifiedEvent(
- bugtask, bugtask_before_modification,
- ['status'], user=self.janitor))
+ with notify_modified(bugtask, ['status'], user=self.janitor):
+ bugtask.transitionToStatus(
+ BugTaskStatus.EXPIRED, self.janitor)
+ content = message_template % (
+ bugtask.bugtargetdisplayname,
+ self.days_before_expiration)
+ bugtask.bug.newMessage(
+ owner=self.janitor,
+ subject=bugtask.bug.followup_subject(),
+ content=content)
# We commit after each expiration because emails are sent
# immediately in zopeless. This minimize the risk of
# duplicate expiration emails being sent in case an error
=== modified file 'lib/lp/bugs/tests/test_bugchanges.py'
--- lib/lp/bugs/tests/test_bugchanges.py 2018-01-02 10:54:31 +0000
+++ lib/lp/bugs/tests/test_bugchanges.py 2019-01-10 11:51:47 +0000
@@ -1,20 +1,15 @@
-# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests for recording changes done to a bug."""
-from lazr.lifecycle.event import (
- ObjectCreatedEvent,
- ObjectModifiedEvent,
- )
-from lazr.lifecycle.snapshot import Snapshot
+from lazr.lifecycle.event import ObjectCreatedEvent
from testtools.matchers import (
MatchesStructure,
StartsWith,
)
from zope.component import getUtility
from zope.event import notify
-from zope.interface import providedBy
from lp.app.enums import InformationType
from lp.bugs.enums import BugNotificationLevel
@@ -27,6 +22,7 @@
from lp.bugs.scripts.bugnotification import construct_email_notifications
from lp.services.librarian.browser import ProxiedLibraryFileAlias
from lp.services.webapp.publisher import canonical_url
+from lp.services.webapp.snapshot import notify_modified
from lp.testing import (
api_url,
launchpadlib_for,
@@ -100,15 +96,13 @@
:return: The value of `attribute` before modification.
"""
- obj_before_modification = Snapshot(obj, providing=providedBy(obj))
- if attribute == 'duplicateof':
- obj.markAsDuplicate(new_value)
- else:
- setattr(obj, attribute, new_value)
- notify(ObjectModifiedEvent(
- obj, obj_before_modification, [attribute], self.user))
-
- return getattr(obj_before_modification, attribute)
+ with notify_modified(
+ obj, [attribute], user=self.user) as obj_before_modification:
+ if attribute == 'duplicateof':
+ obj.markAsDuplicate(new_value)
+ else:
+ setattr(obj, attribute, new_value)
+ return getattr(obj_before_modification, attribute)
def getNewNotifications(self, bug=None):
if bug is None:
@@ -673,12 +667,9 @@
# log and notifications.
bug = self.factory.makeBug()
self.saveOldChanges(bug=bug)
- bug_before_modification = Snapshot(bug, providing=providedBy(bug))
- bug.transitionToInformationType(
- InformationType.PRIVATESECURITY, self.user)
- notify(ObjectModifiedEvent(
- bug, bug_before_modification, ['information_type'],
- user=self.user))
+ with notify_modified(bug, ['information_type'], user=self.user):
+ bug.transitionToInformationType(
+ InformationType.PRIVATESECURITY, self.user)
information_type_change_activity = {
'person': self.user,
@@ -998,13 +989,9 @@
def test_change_bugtask_importance(self):
# When a bugtask's importance is changed, BugActivity and
# BugNotification get updated.
- bug_task_before_modification = Snapshot(
- self.bug_task, providing=providedBy(self.bug_task))
- self.bug_task.transitionToImportance(
- BugTaskImportance.HIGH, user=self.user)
- notify(ObjectModifiedEvent(
- self.bug_task, bug_task_before_modification,
- ['importance'], user=self.user))
+ with notify_modified(self.bug_task, ['importance'], user=self.user):
+ self.bug_task.transitionToImportance(
+ BugTaskImportance.HIGH, user=self.user)
# This checks the activity's attribute and target attributes.
activity = self.bug.activity[-1]
@@ -1033,13 +1020,9 @@
def test_change_bugtask_status(self):
# When a bugtask's status is changed, BugActivity and
# BugNotification get updated.
- bug_task_before_modification = Snapshot(
- self.bug_task, providing=providedBy(self.bug_task))
- self.bug_task.transitionToStatus(
- BugTaskStatus.FIXCOMMITTED, user=self.user)
- notify(ObjectModifiedEvent(
- self.bug_task, bug_task_before_modification, ['status'],
- user=self.user))
+ with notify_modified(self.bug_task, ['status'], user=self.user):
+ self.bug_task.transitionToStatus(
+ BugTaskStatus.FIXCOMMITTED, user=self.user)
expected_activity = {
'person': self.user,
@@ -1063,16 +1046,13 @@
def test_target_bugtask_to_product(self):
# When a bugtask's target is changed, BugActivity and
# BugNotification get updated.
- bug_task_before_modification = Snapshot(
- self.bug_task, providing=providedBy(self.bug_task))
-
- new_target = self.factory.makeProduct(owner=self.user)
- target_lifecycle_subscriber = self.newSubscriber(
- new_target, "target-lifecycle", BugNotificationLevel.LIFECYCLE)
- self.bug_task.transitionToTarget(new_target, self.user)
- notify(ObjectModifiedEvent(
- self.bug_task, bug_task_before_modification,
- ['target', 'product'], user=self.user))
+ with notify_modified(
+ self.bug_task, ['target', 'product'],
+ user=self.user) as bug_task_before_modification:
+ new_target = self.factory.makeProduct(owner=self.user)
+ target_lifecycle_subscriber = self.newSubscriber(
+ new_target, "target-lifecycle", BugNotificationLevel.LIFECYCLE)
+ self.bug_task.transitionToTarget(new_target, self.user)
expected_activity = {
'person': self.user,
@@ -1115,14 +1095,10 @@
owner=self.user, target=target)
self.saveOldChanges(source_package_bug)
- bug_task_before_modification = Snapshot(
- source_package_bug_task,
- providing=providedBy(source_package_bug_task))
- source_package_bug_task.transitionToTarget(new_target, self.user)
-
- notify(ObjectModifiedEvent(
- source_package_bug_task, bug_task_before_modification,
- ['target', 'sourcepackagename'], user=self.user))
+ with notify_modified(
+ source_package_bug_task, ['target', 'sourcepackagename'],
+ user=self.user) as bug_task_before_modification:
+ source_package_bug_task.transitionToTarget(new_target, self.user)
expected_activity = {
'person': self.user,
@@ -1221,13 +1197,8 @@
def test_assign_bugtask(self):
# Assigning a bug task to someone adds entries to the bug
# activity and notifications sets.
- bug_task_before_modification = Snapshot(
- self.bug_task, providing=providedBy(self.bug_task))
-
- self.bug_task.transitionToAssignee(self.user)
- notify(ObjectModifiedEvent(
- self.bug_task, bug_task_before_modification,
- ['assignee'], user=self.user))
+ with notify_modified(self.bug_task, ['assignee'], user=self.user):
+ self.bug_task.transitionToAssignee(self.user)
expected_activity = {
'person': self.user,
@@ -1257,14 +1228,8 @@
# bug activity and notifications sets.
old_assignee = bug_task.assignee
- bug_task_before_modification = Snapshot(
- bug_task, providing=providedBy(bug_task))
-
- bug_task.transitionToAssignee(None)
-
- notify(ObjectModifiedEvent(
- bug_task, bug_task_before_modification,
- ['assignee'], user=self.user))
+ with notify_modified(bug_task, ['assignee'], user=self.user):
+ bug_task.transitionToAssignee(None)
expected_activity = {
'person': self.user,
=== modified file 'lib/lp/bugs/tests/test_bugnotification.py'
--- lib/lp/bugs/tests/test_bugnotification.py 2018-02-02 10:06:24 +0000
+++ lib/lp/bugs/tests/test_bugnotification.py 2019-01-10 11:51:47 +0000
@@ -1,4 +1,4 @@
-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
+# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests related to bug notifications."""
@@ -7,20 +7,13 @@
from datetime import datetime
-from lazr.lifecycle.event import ObjectModifiedEvent
-from lazr.lifecycle.snapshot import Snapshot
import pytz
from storm.store import Store
import transaction
from zope.component import getUtility
-from zope.event import notify
-from zope.interface import providedBy
from lp.answers.tests.test_question_notifications import pop_questionemailjobs
-from lp.bugs.interfaces.bugtask import (
- BugTaskStatus,
- IBugTask,
- )
+from lp.bugs.interfaces.bugtask import BugTaskStatus
from lp.bugs.mail.bugnotificationrecipients import BugNotificationRecipients
from lp.bugs.model.bugnotification import (
BugNotification,
@@ -32,6 +25,7 @@
from lp.services.config import config
from lp.services.messages.interfaces.message import IMessageSet
from lp.services.messages.model.message import MessageSet
+from lp.services.webapp.snapshot import notify_modified
from lp.testing import (
person_logged_in,
TestCaseWithFactory,
@@ -67,11 +61,9 @@
# Ensure that notifications are sent to subscribers of a
# question linked to the expired bug.
bugtask = self.bug.default_bugtask
- bugtask_before_modification = Snapshot(bugtask, providing=IBugTask)
- bugtask.transitionToStatus(BugTaskStatus.EXPIRED, self.product.owner)
- bug_modified = ObjectModifiedEvent(
- bugtask, bugtask_before_modification, ["status"])
- notify(bug_modified)
+ with notify_modified(bugtask, ["status"]):
+ bugtask.transitionToStatus(
+ BugTaskStatus.EXPIRED, self.product.owner)
recipients = [
job.metadata['recipient_set'] for job in pop_questionemailjobs()]
self.assertContentEqual(
@@ -388,12 +380,9 @@
def test_duplicate_edit_notifications(self):
# Bug edits for a duplicate are sent to duplicate subscribers only.
- bug_before_modification = Snapshot(
- self.dupe_bug, providing=providedBy(self.dupe_bug))
- self.dupe_bug.description = 'A changed description'
- notify(ObjectModifiedEvent(
- self.dupe_bug, bug_before_modification, ['description'],
- user=self.dupe_bug.owner))
+ with notify_modified(
+ self.dupe_bug, ['description'], user=self.dupe_bug.owner):
+ self.dupe_bug.description = 'A changed description'
latest_notification = BugNotification.selectFirst(orderBy='-id')
recipients = set(
recipient.person
Follow ups