trac-mq / t11148 / t11148_r11784_IEntityListener_compat_ticket.diff

# HG changeset patch
# Parent 2c0e5eb15b91dc6952dcb8c0866631ff7cb9fcab
Trac #11148 : 'ITicketChangeListener' , 'IMilestoneChangeListener' notifications powered by 'ListenerNotifier.notify'

diff -r 2c0e5eb15b91 trac/ticket/api.py
--- a/trac/ticket/api.py	Sat Apr 27 16:50:19 2013 -0500
+++ b/trac/ticket/api.py	Sat Apr 27 23:03:14 2013 -0500
@@ -131,6 +131,8 @@
     """Extension point interface for components that require notification
     when tickets are created, modified, or deleted."""
 
+    _entity_listener_prefix = 'ticket'
+
     def ticket_created(ticket):
         """Called when a ticket is created."""
 
@@ -164,6 +166,8 @@
     """Extension point interface for components that require notification
     when milestones are created, modified, or deleted."""
 
+    _entity_listener_prefix = 'milestone'
+
     def milestone_created(milestone):
         """Called when a milestone is created."""
 
diff -r 2c0e5eb15b91 trac/ticket/model.py
--- a/trac/ticket/model.py	Sat Apr 27 16:50:19 2013 -0500
+++ b/trac/ticket/model.py	Sat Apr 27 23:03:14 2013 -0500
@@ -28,10 +28,11 @@
 from trac.core import (Interface, IEntityChangeListener, ListenerNotifier,
                        TracError)
 from trac.resource import Resource, ResourceNotFound
-from trac.ticket.api import TicketSystem, IMilestoneChangeListener, \
-                            ITypeChangeListener, IResolutionChangeListener, \
-                            IPriorityChangeListener, ISeverityChangeListener,\
-                            IComponentChangeListener, IVersionChangeListener
+from trac.ticket.api import IComponentChangeListener, IMilestoneChangeListener,\
+                            IPriorityChangeListener, IResolutionChangeListener,\
+                            ISeverityChangeListener, ITypeChangeListener, \
+                            ITicketChangeListener, IVersionChangeListener, \
+                            TicketSystem
 from trac.util import embedded_numbers, partition
 from trac.util.text import empty
 from trac.util.datefmt import from_utimestamp, parse_date, to_utimestamp, \
@@ -288,8 +289,8 @@
         self.resource = self.resource(id=tkt_id)
         self._old = {}
 
-        for listener in TicketSystem(self.env).change_listeners:
-            listener.ticket_created(self)
+        ListenerNotifier(self.env).notify(ITicketChangeListener.ticket_created,
+                                          entity=self)
 
         return self.id
 
@@ -401,8 +402,9 @@
         self._old = {}
         self.values['changetime'] = when
 
-        for listener in TicketSystem(self.env).change_listeners:
-            listener.ticket_changed(self, comment, author, old_values)
+        ListenerNotifier(self.env).notify(ITicketChangeListener.ticket_changed, 
+                                          entity=self, comment=comment,
+                                          author=author, old_values=old_values)
         return int(cnum.rsplit('.', 1)[-1])
 
     def _to_db_types(self, values):
@@ -478,8 +480,8 @@
             db("DELETE FROM ticket_change WHERE ticket=%s", (self.id,))
             db("DELETE FROM ticket_custom WHERE ticket=%s", (self.id,))
 
-        for listener in TicketSystem(self.env).change_listeners:
-            listener.ticket_deleted(self)
+        ListenerNotifier(self.env).notify(ITicketChangeListener.ticket_deleted,
+                                          entity=self)
 
     def get_change(self, cnum=None, cdate=None, db=None):
         """Return a ticket change by its number or date.
@@ -1116,8 +1118,8 @@
             del self.cache.milestones
             TicketSystem(self.env).reset_ticket_fields()
 
-        for listener in TicketSystem(self.env).milestone_change_listeners:
-            listener.milestone_deleted(self)
+        ListenerNotifier(self.env).notify(
+                IMilestoneChangeListener.milestone_deleted, entity=self)
 
     def insert(self, db=None):
         """Insert a new milestone.
@@ -1138,8 +1140,8 @@
             self.checkin()
             TicketSystem(self.env).reset_ticket_fields()
 
-        for listener in TicketSystem(self.env).milestone_change_listeners:
-            listener.milestone_created(self)
+        ListenerNotifier(self.env).notify(
+                IMilestoneChangeListener.milestone_created, entity=self)
 
     def update(self, db=None):
         """Update the milestone.
@@ -1177,8 +1179,9 @@
 
         old_values = dict((k, v) for k, v in old.iteritems()
                           if getattr(self, k) != v)
-        for listener in TicketSystem(self.env).milestone_change_listeners:
-            listener.milestone_changed(self, old_values)
+        ListenerNotifier(self.env).notify(
+                IMilestoneChangeListener.milestone_changed,
+                entity=self, old_values=old_values)
 
     @classmethod
     def select(cls, env, include_completed=True, db=None):
diff -r 2c0e5eb15b91 trac/ticket/tests/model.py
--- a/trac/ticket/tests/model.py	Sat Apr 27 16:50:19 2013 -0500
+++ b/trac/ticket/tests/model.py	Sat Apr 27 23:03:14 2013 -0500
@@ -402,14 +402,21 @@
 
     def test_change_listener_created(self):
         listener = TestTicketChangeListener(self.env)
+        generic_listener = GenericEntitiesChangeListenerMock(self.env)
+
         ticket = self._create_a_ticket()
         ticket.insert()
         self.assertEqual('created', listener.action)
         self.assertEqual(ticket, listener.ticket)
         self.assertEqual(ticket.id, ticket.resource.id)
 
+        self.assertEqual([{'action' : 'created', 'entity' : ticket}],
+                         generic_listener.details)
+
     def test_change_listener_changed(self):
         listener = TestTicketChangeListener(self.env)
+        generic_listener = GenericEntitiesChangeListenerMock(self.env)
+
         data = {'component': 'foo', 'milestone': 'bar'}
         tkt_id = self._insert_ticket('Hello World', reporter='john', **data)
 
@@ -426,14 +433,29 @@
         for key, value in data.iteritems():
             self.assertEqual(value, listener.old_values[key])
 
+        self.assertEqual(2, len(generic_listener.details))
+        self.assertEqual('created', generic_listener.details[0]['action'])
+        self.assertEqual(tkt_id, generic_listener.details[0]['entity'].id)
+        self.assertEqual({'action' : 'changed', 'entity' : ticket,
+                          'comment' : comment, 'author' : 'author',
+                          'old_values' : data},
+                         generic_listener.details[1])
+
+
     def test_change_listener_deleted(self):
         listener = TestTicketChangeListener(self.env)
+        generic_listener = GenericEntitiesChangeListenerMock(self.env)
+
         ticket = self._create_a_ticket()
         ticket.insert()
         ticket.delete()
         self.assertEqual('deleted', listener.action)
         self.assertEqual(ticket, listener.ticket)
 
+        self.assertEqual([{'action' : 'created', 'entity' : ticket},
+                          {'action' : 'deleted', 'entity' : ticket}],
+                         generic_listener.details)
+
 
 class TicketCommentTestCase(unittest.TestCase):
 
@@ -993,13 +1015,20 @@
 
     def test_change_listener_created(self):
         listener = TestMilestoneChangeListener(self.env)
+        generic_listener = GenericEntitiesChangeListenerMock(self.env)
+
         milestone = self._create_milestone(name='Milestone 1')
         milestone.insert()
         self.assertEqual('created', listener.action)
         self.assertEqual(milestone, listener.milestone)
 
+        self.assertEqual([{'action' : 'created', 'entity' : milestone}], 
+                         generic_listener.details)
+
     def test_change_listener_changed(self):
         listener = TestMilestoneChangeListener(self.env)
+        generic_listener = GenericEntitiesChangeListenerMock(self.env)
+
         milestone = self._create_milestone(
             name='Milestone 1',
             due=datetime(2001, 01, 01, tzinfo=utc),
@@ -1017,8 +1046,18 @@
                           'description': 'The milestone description'},
                          listener.old_values)
 
+        self.assertEqual([{'action' : 'created', 'entity' : milestone},
+                          {'action' : 'changed', 'entity' : milestone,
+                           'old_values' : {'name': 'Milestone 1', 
+                                           'completed': None,
+                                           'description': 'The milestone '
+                                                          'description'}}], 
+                         generic_listener.details)
+
     def test_change_listener_deleted(self):
         listener = TestMilestoneChangeListener(self.env)
+        generic_listener = GenericEntitiesChangeListenerMock(self.env)
+
         milestone = self._create_milestone(name='Milestone 1')
         milestone.insert()
         self.assertEqual(True, milestone.exists)
@@ -1028,6 +1067,10 @@
         self.assertEqual('deleted', listener.action)
         self.assertEqual(milestone, listener.milestone)
 
+        self.assertEqual([{'action' : 'created', 'entity' : milestone},
+                          {'action' : 'deleted', 'entity' : milestone}], 
+                         generic_listener.details)
+
 
 class ComponentTestCase(unittest.TestCase):
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.