Author: jure
Date: Tue Mar 12 08:29:15 2013
New Revision: 1455438
URL: http://svn.apache.org/r1455438
Log:
Sync merge from trunk
Added:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_prefs_language.html
- copied unchanged from r1455437,
incubator/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_language.html
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_prefs_userinterface.html
- copied unchanged from r1455437,
incubator/bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_prefs_userinterface.html
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/ (props changed)
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/ (props changed)
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/resource.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/resource.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/tests/model.py
Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/
------------------------------------------------------------------------------
Merged /incubator/bloodhound/trunk:r1455109-1455437
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_diff_view.html
Tue Mar 12 08:29:15 2013
@@ -33,7 +33,7 @@
<body>
<div id="content" class="${resource.realm} row">
- <h1 py:choose="">
+ <h1 class="span12" py:choose="">
<py:when test="old_version"><i18n:msg params="old, new, name">Changes
between
<a href="${old_url or url_of(resource,
version=old_version)}">Version $old_version</a> and
<a href="${new_url or url_of(resource,
version=new_version)}">Version $new_version</a> of
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_history_view.html
Tue Mar 12 08:29:15 2013
@@ -32,7 +32,9 @@
<body>
<div id="content" class="ticket row">
- <h1 i18n:msg="name">Change History for <a href="${url or
url_of(resource)}">${name or name_of(resource)}</a></h1>
+ <h1 class="span12" i18n:msg="name">
+ Change History for <a href="${url or url_of(resource)}">${name or
name_of(resource)}</a>
+ </h1>
<br/>
<div class="span12">
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/templates/bh_wiki_diff.html
Tue Mar 12 08:29:15 2013
@@ -25,7 +25,7 @@
xmlns:xi="http://www.w3.org/2001/XInclude" py:strip="">
<py:match path="div[@id='content']" once="true"><div py:attrs="select('@*')">
${select('*|text()')}
- <div class="span9 offset3">
+ <div class="span12">
<form py:if="'WIKI_DELETE' in perm(page.resource) and
(not changes[0].diffs or new_version == latest_version)"
method="get" action="${href.wiki(page.name)}">
@@ -33,10 +33,12 @@
<input type="hidden" name="version" value="$new_version" />
<input type="hidden" name="old_version" value="$old_version" />
<div class="control-group">
- <py:choose>
- <input py:when="new_version - old_version > 1" type="submit"
name="delete_version" value="${_('Delete version %(old_version)d to version
%(version)d', old_version=(old_version + 1), version=new_version)}" class="btn"
/>
- <input py:otherwise="" type="submit" name="delete_version"
value="${_('Delete version %(version)d', version=new_version)}" class="btn" />
- </py:choose>
+ <div class="controls">
+ <py:choose>
+ <input py:when="new_version - old_version > 1" type="submit"
name="delete_version" value="${_('Delete version %(old_version)d to version
%(version)d', old_version=(old_version + 1), version=new_version)}" class="btn"
/>
+ <input py:otherwise="" type="submit" name="delete_version"
value="${_('Delete version %(version)d', version=new_version)}" class="btn" />
+ </py:choose>
+ </div>
</div>
</form>
</div>
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/bloodhound_theme/bhtheme/theme.py
Tue Mar 12 08:29:15 2013
@@ -87,11 +87,14 @@ class BloodhoundTheme(ThemeBase):
'admin_users.html' : ('admin_users.html', '_modify_admin_breadcrumb'),
# Preferences
+ 'prefs.html' : ('bh_prefs.html', None),
'prefs_advanced.html' : ('bh_prefs_advanced.html', None),
'prefs_datetime.html' : ('bh_prefs_datetime.html', None),
'prefs_general.html' : ('bh_prefs_general.html', None),
+ 'prefs_language.html' : ('bh_prefs_language.html', None),
'prefs_keybindings.html' : ('bh_prefs_keybindings.html', None),
'prefs_pygments.html' : ('bh_prefs_pygments.html', None),
+ 'prefs_userinterface.html' : ('bh_prefs_userinterface.html', None),
# Search
'search.html' : ('bh_search.html', '_modify_search_data'),
@@ -214,7 +217,7 @@ class BloodhoundTheme(ThemeBase):
def pre_process_request(self, req, handler):
"""Pre process request filter"""
def hwiki(*args, **kw):
-
+
def new_name(name):
new_name = wiki.new_name(name)
if new_name != name:
@@ -223,11 +226,11 @@ class BloodhoundTheme(ThemeBase):
self._wiki_pages = wiki_admin.get_wiki_list()
if new_name in self._wiki_pages:
return new_name
- return name
-
+ return name
+
a = tuple([new_name(x) for x in args])
- return req.href.__call__("wiki", *a)
-
+ return req.href.__call__("wiki", *a, **kw)
+
req.href.wiki = hwiki
return handler
Propchange: incubator/bloodhound/branches/bep_0003_multiproduct/trac/
------------------------------------------------------------------------------
Merged /incubator/bloodhound/trunk/trac:r1450762-1455437
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py
(original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/attachment.py
Tue Mar 12 08:29:15 2013
@@ -221,7 +221,7 @@ class Attachment(object):
with self.env.db_transaction as db:
db("""
DELETE FROM attachment WHERE type=%s AND id=%s AND filename=%s
- """, (self.parent_realm, self.parent_id, self.filename))
+ """, (self.parent_realm, self.parent_id, self.filename))
path = self.path
if os.path.isfile(path):
try:
@@ -235,8 +235,7 @@ class Attachment(object):
self.env.log.info("Attachment removed: %s" % self.title)
- for listener in AttachmentModule(self.env).change_listeners:
- listener.attachment_deleted(self)
+ ResourceSystem(self.env).resource_deleted(self)
def reparent(self, new_realm, new_id):
assert self.filename, "Cannot reparent non-existent attachment"
@@ -284,9 +283,8 @@ class Attachment(object):
self.env.log.info("Attachment reparented: %s" % self.title)
- for listener in AttachmentModule(self.env).change_listeners:
- if hasattr(listener, 'attachment_reparented'):
- listener.attachment_reparented(self, old_realm, old_id)
+ old_values = dict(parent_realm=old_realm, parent_id=old_id)
+ ResourceSystem(self.env).resource_changed(self, old_values=old_values)
def insert(self, filename, fileobj, size, t=None, db=None):
"""Create a new Attachment record and save the file content.
@@ -330,8 +328,7 @@ class Attachment(object):
self.env.log.info("New attachment: %s by %s", self.title,
self.author)
- for listener in AttachmentModule(self.env).change_listeners:
- listener.attachment_added(self)
+ ResourceSystem(self.env).resource_created(self)
@classmethod
@@ -1101,3 +1098,30 @@ class AttachmentAdmin(Component):
if destination is not None:
output.close()
+class ResourceToAttachmentChangeListenerAdapter(Component):
+ """
+ The class provides backward compatibility for components implementing
+ IAttachmentChangeListener interface.
+ """
+ implements(IResourceChangeListener)
+ def match_resource(self, resource):
+ return isinstance(resource, Attachment)
+
+ def resource_created(self, resource, context):
+ for listener in AttachmentModule(self.env).change_listeners:
+ listener.attachment_added(resource)
+
+ def resource_changed(self, resource, old_values, context):
+ for listener in AttachmentModule(self.env).change_listeners:
+ if hasattr(listener, 'attachment_reparented'):
+ listener.attachment_reparented(
+ resource,
+ old_values.get("parent_realm"),
+ old_values.get("parent_id"))
+
+ def resource_deleted(self, resource, context):
+ for listener in AttachmentModule(self.env).change_listeners:
+ listener.attachment_deleted(resource)
+
+ def resource_version_deleted(self, resource, context):
+ pass
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/resource.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/resource.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/resource.py
(original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/resource.py
Tue Mar 12 08:29:15 2013
@@ -217,6 +217,38 @@ class Resource(object):
"""
return Resource(realm, id, version, self)
+class IResourceChangeListener(Interface):
+ """Extension point interface for components that require notification
+ when resources are created, modified, or deleted.
+
+ 'resource' parameters is instance of the a resource e.g. ticket, milestone
+ etc.
+ 'context' is an action context, may contain author, comment etc. Context
+ content depends on a resource type.
+ """
+
+ def match_resource(resource):
+ """Return whether the listener wants to process the given resource."""
+
+ def resource_created(resource, context):
+ """
+ Called when a resource is created.
+ """
+
+ def resource_changed(resource, old_values, context):
+ """Called when a resource is modified.
+
+ `old_values` is a dictionary containing the previous values of the
+ resource properties that changed. Properties are specific for resource
+ type.
+ """
+
+ def resource_deleted(resource, context):
+ """Called when a resource is deleted."""
+
+ def resource_version_deleted(resource, context):
+ """Called when a version of a resource has been deleted."""
+
class ResourceSystem(Component):
"""Resource identification and description manager.
@@ -226,6 +258,8 @@ class ResourceSystem(Component):
"""
resource_managers = ExtensionPoint(IResourceManager)
+ change_listeners = ExtensionPoint(IResourceChangeListener)
+
def __init__(self):
self._resource_managers_map = None
@@ -255,6 +289,25 @@ class ResourceSystem(Component):
realms.append(realm)
return realms
+ def resource_created(self, resource, context=None):
+ for listener in self.change_listeners:
+ if listener.match_resource(resource):
+ listener.resource_created(resource, context)
+
+ def resource_changed(self, resource, old_values, context=None):
+ for listener in self.change_listeners:
+ if listener.match_resource(resource):
+ listener.resource_changed(resource, old_values, context)
+
+ def resource_deleted(self, resource, context=None):
+ for listener in self.change_listeners:
+ if listener.match_resource(resource):
+ listener.resource_deleted(resource, context)
+
+ def resource_version_deleted(self, resource, context=None):
+ for listener in self.change_listeners:
+ if listener.match_resource(resource):
+ listener.resource_version_deleted(resource, context)
# -- Utilities for manipulating resources in a generic way
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/attachment.py
Tue Mar 12 08:29:15 2013
@@ -6,11 +6,13 @@ from StringIO import StringIO
import tempfile
import unittest
-from trac.attachment import Attachment, AttachmentModule
+from trac.attachment import (Attachment, AttachmentModule,
+ IAttachmentChangeListener)
from trac.core import Component, implements, TracError
from trac.perm import IPermissionPolicy, PermissionCache
from trac.resource import Resource, resource_exists
from trac.test import EnvironmentStub
+from trac.tests.resource import TestResourceChangeListener
hashes = {
@@ -28,6 +30,24 @@ hashes = {
u'ÃberSicht': 'a16c6837f6d3d2cc3addd68976db1c55deb694c8',
}
+class TestAttachmentChangeListener(Component):
+ implements(IAttachmentChangeListener)
+
+ def attachment_added(self, attachment):
+ self.action = "added"
+ self.attachment = attachment
+
+ def attachment_deleted(self, attachment):
+ self.action = "deleted"
+ self.attachment = attachment
+
+ def attachment_reparented(
+ self, attachment, old_parent_realm, old_parent_id):
+ self.action = "reparented"
+ self.attachment = attachment
+ self.old_parent_realm = old_parent_realm
+ self.old_parent_id = old_parent_id
+
class TicketOnlyViewsTicket(Component):
implements(IPermissionPolicy)
@@ -221,10 +241,94 @@ class AttachmentTestCase(unittest.TestCa
att.insert('file.txt', StringIO(''), 1)
self.assertTrue(resource_exists(self.env, att.resource))
+ def test_change_listener_created(self):
+ listener = TestAttachmentChangeListener(self.env)
+ attachment = self._create_attachment()
+ self.assertEqual('added', listener.action)
+ self.assertEqual(attachment, listener.attachment)
+
+ def test_change_listener_deleted(self):
+ listener = TestAttachmentChangeListener(self.env)
+ attachment = self._create_attachment()
+ attachment.delete()
+ self.assertEqual('deleted', listener.action)
+ self.assertEqual(attachment, listener.attachment)
+
+ def test_change_listener_deleted(self):
+ listener = TestAttachmentChangeListener(self.env)
+ attachment = self._create_attachment()
+ old_parent_realm = attachment.parent_realm
+ old_parent_id = attachment.parent_id
+ attachment.reparent("wiki", "SomePage")
+ self.assertEqual('reparented', listener.action)
+ self.assertEqual(attachment, listener.attachment)
+ self.assertEqual(old_parent_realm, listener.old_parent_realm)
+ self.assertEqual(old_parent_id, listener.old_parent_id)
+
+ def _create_attachment(self):
+ attachment = Attachment(self.env, 'wiki', 'WikiStart')
+ attachment.insert('file.txt', StringIO(''), 1)
+ return attachment
+
+
+class AttachmentResourceChangeListenerTestCase(unittest.TestCase):
+ DUMMY_PARENT_REALM = "wiki"
+ DUMMY_PARENT_ID = "WikiStart"
+
+ def setUp(self):
+ self.env = EnvironmentStub(default_data=True)
+ self.listener = TestResourceChangeListener(self.env)
+ self.listener.resource_type = Attachment
+ self.listener.callback = self.listener_callback
+
+ def tearDown(self):
+ self.env.reset_db()
+
+ def test_change_listener_created(self):
+ attachment = self._create_attachment()
+ self.assertEqual('created', self.listener.action)
+ self.assertIsInstance(self.listener.resource, Attachment)
+ self.assertEqual(attachment.filename, self.filename)
+ self.assertEqual(attachment.parent_realm, self.parent_realm)
+ self.assertEqual(attachment.parent_id, self.parent_id)
+
+ def test_change_listener_reparent(self):
+ attachment = self._create_attachment()
+ attachment.reparent(self.DUMMY_PARENT_REALM, "SomePage")
+
+ self.assertEqual('changed', self.listener.action)
+ self.assertIsInstance(self.listener.resource, Attachment)
+ self.assertEqual(attachment.filename, self.filename)
+ self.assertEqual(attachment.parent_realm, self.parent_realm)
+ self.assertEqual("SomePage", self.parent_id)
+ self.assertEqual(
+ self.DUMMY_PARENT_REALM, self.listener.old_values["parent_realm"])
+ self.assertEqual(
+ self.DUMMY_PARENT_ID, self.listener.old_values["parent_id"])
+
+ def test_change_listener_deleted(self):
+ attachment = self._create_attachment()
+ attachment.delete()
+ self.assertEqual('deleted', self.listener.action)
+ self.assertIsInstance(self.listener.resource, Attachment)
+ self.assertEqual(attachment.filename, self.filename)
+
+ def _create_attachment(self):
+ attachment = Attachment(
+ self.env, self.DUMMY_PARENT_REALM, self.DUMMY_PARENT_ID)
+ attachment.insert('file.txt', StringIO(''), 1)
+ return attachment
+
+ def listener_callback(self, action, resource, context, old_values = None):
+ self.parent_realm = resource.parent_realm
+ self.parent_id = resource.parent_id
+ self.filename = resource.filename
def suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(AttachmentTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(
+ AttachmentResourceChangeListenerTestCase, 'test'))
return suite
if __name__ == '__main__':
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/resource.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/resource.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/resource.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/tests/resource.py
Tue Mar 12 08:29:15 2013
@@ -15,6 +15,8 @@ import doctest
import unittest
from trac import resource
+from trac.resource import IResourceChangeListener
+from trac.core import implements, Component
class ResourceTestCase(unittest.TestCase):
@@ -42,6 +44,46 @@ class ResourceTestCase(unittest.TestCase
r2.parent = r2.parent(version=42)
self.assertNotEqual(r1, r2)
+class TestResourceChangeListener(Component):
+ implements(IResourceChangeListener)
+
+ def __init__(self):
+ self.resource_type = None
+
+ def callback(self, action, resource, context, old_values = None):
+ pass
+
+ def match_resource(self, resource):
+ if self.resource_type is None:
+ return False
+ return isinstance(resource, self.resource_type)
+
+ def resource_created(self, resource, context):
+ self.action = "created"
+ self.resource = resource
+ self.context = context
+ self.callback(self.action, resource, context)
+
+ def resource_changed(self, resource, old_values, context):
+ self.action = "changed"
+ self.resource = resource
+ self.old_values = old_values
+ self.context = context
+ self.callback(
+ self.action, resource, context, old_values=self.old_values)
+
+ def resource_deleted(self, resource, context):
+ self.action = "deleted"
+ self.resource = resource
+ self.context = context
+ self.callback(self.action, resource, context)
+
+ def resource_version_deleted(self, resource, context):
+ self.action = "version_deleted"
+ self.resource = resource
+ self.context = context
+ self.callback(self.action, resource, context)
+
def suite():
suite = unittest.TestSuite()
suite.addTest(doctest.DocTestSuite(resource))
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py
(original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/api.py
Tue Mar 12 08:29:15 2013
@@ -156,31 +156,6 @@ class IMilestoneChangeListener(Interface
def milestone_deleted(milestone):
"""Called when a milestone is deleted."""
-class IResourceChangeListener(Interface):
- """Extension point interface for components that require notification
- when resources are created, modified, or deleted.
-
- 'resource' instance of the a resource e.g. ticket, milestone etc.
- 'context' action context, may contain author, comment etc. Context
- content depends on a resource type.
- """
-
- def resource_created(resource, context):
- """
- Called when a resource is created.
- """
-
- def resource_changed(resource, old_values, context):
- """Called when a resource is modified.
-
- `old_values` is a dictionary containing the previous values of the
- resource properties that changed. Properties are specific for resource
- type.
- """
-
- def resource_deleted(resource, context):
- """Called when a resource is deleted."""
-
class ITicketFieldProvider(Interface):
"""Extension point interface for components that provide fields for the
ticket system."""
@@ -218,7 +193,6 @@ class TicketSystem(Component):
ticket_field_providers = ExtensionPoint(ITicketFieldProvider)
change_listeners = ExtensionPoint(ITicketChangeListener)
milestone_change_listeners = ExtensionPoint(IMilestoneChangeListener)
- resource_change_listeners = ExtensionPoint(IResourceChangeListener)
ticket_custom_section = ConfigSection('ticket-custom',
"""In this section, you can define additional fields for tickets. See
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/model.py
Tue Mar 12 08:29:15 2013
@@ -25,8 +25,9 @@ from datetime import datetime
from trac.attachment import Attachment
from trac import core
from trac.cache import cached
-from trac.core import TracError
-from trac.resource import Resource, ResourceNotFound
+from trac.core import TracError, implements
+from trac.resource import (Resource, ResourceNotFound, IResourceChangeListener,
+ ResourceSystem)
from trac.ticket.api import TicketSystem
from trac.util import embedded_numbers, partition
from trac.util.text import empty
@@ -252,8 +253,7 @@ class Ticket(object):
self.resource = self.resource(id=tkt_id)
self._old = {}
- for listener in TicketSystem(self.env).change_listeners:
- listener.ticket_created(self)
+ ResourceSystem(self.env).resource_created(self)
return self.id
@@ -361,8 +361,9 @@ class Ticket(object):
self._old = {}
self.values['changetime'] = when
- for listener in TicketSystem(self.env).change_listeners:
- listener.ticket_changed(self, comment, author, old_values)
+ context = dict(comment=comment, author=author)
+ ResourceSystem(self.env).resource_changed(self, old_values, context)
+
return int(cnum.rsplit('.', 1)[-1])
def get_changelog(self, when=None, db=None):
@@ -425,8 +426,7 @@ class Ticket(object):
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)
+ ResourceSystem(self.env).resource_deleted(self)
def get_change(self, cnum=None, cdate=None, db=None):
"""Return a ticket change by its number or date.
@@ -712,6 +712,8 @@ class AbstractEnum(object):
except ValueError:
pass # Ignore cast error for this non-essential operation
TicketSystem(self.env).reset_ticket_fields()
+
+ ResourceSystem(self.env).resource_deleted(self)
self.value = self._old_value = None
self.name = self._old_name = None
@@ -739,6 +741,7 @@ class AbstractEnum(object):
self._old_name = self.name
self._old_value = self.value
+ ResourceSystem(self.env).resource_created(self)
def update(self, db=None):
"""Update the enum value.
@@ -762,8 +765,10 @@ class AbstractEnum(object):
(self.name, self._old_name))
TicketSystem(self.env).reset_ticket_fields()
+ old_values = dict(name=self._old_name, value=self._old_value)
self._old_name = self.name
self._old_value = self.value
+ ResourceSystem(self.env).resource_changed(self, old_values)
@classmethod
def select(cls, env, db=None):
@@ -846,8 +851,7 @@ class Component(object):
db("DELETE FROM component WHERE name=%s", (self.name,))
TicketSystem(self.env).reset_ticket_fields()
- for listener in TicketSystem(self.env).resource_change_listeners:
- listener.resource_deleted(self)
+ ResourceSystem(self.env).resource_deleted(self)
self.name = self._old_name = None
def insert(self, db=None):
@@ -869,8 +873,7 @@ class Component(object):
self._old_name = self.name
TicketSystem(self.env).reset_ticket_fields()
- for listener in TicketSystem(self.env).resource_change_listeners:
- listener.resource_created(self)
+ ResourceSystem(self.env).resource_created(self)
def update(self, db=None):
"""Update the component.
@@ -898,8 +901,7 @@ class Component(object):
TicketSystem(self.env).reset_ticket_fields()
old_values = dict(name=old_name)
- for listener in TicketSystem(self.env).resource_change_listeners:
- listener.resource_changed(self, old_values)
+ ResourceSystem(self.env).resource_changed(self, old_values)
@classmethod
def select(cls, env, db=None):
@@ -1035,8 +1037,7 @@ class Milestone(object):
del self.cache.milestones
TicketSystem(self.env).reset_ticket_fields()
- for listener in TicketSystem(self.env).milestone_change_listeners:
- listener.milestone_deleted(self)
+ ResourceSystem(self.env).resource_deleted(self)
def insert(self, db=None):
"""Insert a new milestone.
@@ -1057,8 +1058,7 @@ class Milestone(object):
self.checkin()
TicketSystem(self.env).reset_ticket_fields()
- for listener in TicketSystem(self.env).milestone_change_listeners:
- listener.milestone_created(self)
+ ResourceSystem(self.env).resource_created(self)
def update(self, db=None):
"""Update the milestone.
@@ -1096,8 +1096,7 @@ class Milestone(object):
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)
+ ResourceSystem(self.env).resource_changed(self, old_values)
@classmethod
def select(cls, env, include_completed=True, db=None):
@@ -1161,9 +1160,11 @@ class Version(object):
with self.env.db_transaction as db:
self.env.log.info("Deleting version %s", self.name)
db("DELETE FROM version WHERE name=%s", (self.name,))
- self.name = self._old_name = None
TicketSystem(self.env).reset_ticket_fields()
+ ResourceSystem(self.env).resource_deleted(self)
+ self.name = self._old_name = None
+
def insert(self, db=None):
"""Insert a new version.
@@ -1182,6 +1183,8 @@ class Version(object):
self._old_name = self.name
TicketSystem(self.env).reset_ticket_fields()
+ ResourceSystem(self.env).resource_created(self)
+
def update(self, db=None):
"""Update the version.
@@ -1193,6 +1196,7 @@ class Version(object):
if not self.name:
raise TracError(_("Invalid version name."))
+ old_name=self._old_name
with self.env.db_transaction as db:
self.env.log.info("Updating version '%s'", self.name)
db("""UPDATE version
@@ -1206,6 +1210,9 @@ class Version(object):
self._old_name = self.name
TicketSystem(self.env).reset_ticket_fields()
+ old_values = dict(name=old_name)
+ ResourceSystem(self.env).resource_changed(self, old_values)
+
@classmethod
def select(cls, env, db=None):
"""
@@ -1223,3 +1230,59 @@ class Version(object):
def version_order(v):
return (v.time or utcmax, embedded_numbers(v.name))
return sorted(versions, key=version_order, reverse=True)
+
+class ResourceToMilestoneChangeListenerAdapter(core.Component):
+ """
+ The class provides backward compatibility for components implementing
+ IMilestoneChangeListener interface.
+ """
+ implements(IResourceChangeListener)
+
+ def match_resource(self, resource):
+ return isinstance(resource, Milestone)
+
+ def resource_created(self, resource, context):
+ for listener in TicketSystem(self.env).milestone_change_listeners:
+ listener.milestone_created(resource)
+
+ def resource_changed(self, resource, old_values, context):
+ for listener in TicketSystem(self.env).milestone_change_listeners:
+ listener.milestone_changed(resource, old_values)
+
+ def resource_deleted(self, resource, context):
+ for listener in TicketSystem(self.env).milestone_change_listeners:
+ listener.milestone_deleted(resource)
+
+ def resource_version_deleted(self, resource, context):
+ pass
+
+class ResourceToTicketChangeListenerAdapter(core.Component):
+ """
+ The class provides backward compatibility for components implementing
+ ITicketChangeListener interface.
+ """
+ implements(IResourceChangeListener)
+ def match_resource(self, resource):
+ return isinstance(resource, Ticket)
+
+ def resource_created(self, resource, context):
+ for listener in TicketSystem(self.env).change_listeners:
+ listener.ticket_created(resource)
+
+ def resource_changed(self, resource, old_values, context):
+ author = None
+ comment = None
+ if context:
+ comment = context.get("comment")
+ author = context.get("author")
+
+ for listener in TicketSystem(self.env).change_listeners:
+ listener.ticket_changed(resource, comment, author, old_values)
+
+ def resource_deleted(self, resource, context):
+ for listener in TicketSystem(self.env).change_listeners:
+ listener.ticket_deleted(resource)
+
+ def resource_version_deleted(self, resource, context):
+ pass
+
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/ticket/tests/model.py
Tue Mar 12 08:29:15 2013
@@ -16,12 +16,11 @@ from trac.ticket.model import (
)
from trac.ticket.api import (
IMilestoneChangeListener, ITicketChangeListener, TicketSystem,
- IResourceChangeListener,
)
from trac.test import EnvironmentStub
+from trac.tests.resource import TestResourceChangeListener
from trac.util.datefmt import from_utimestamp, to_utimestamp, utc
-
class TestTicketChangeListener(core.Component):
implements(ITicketChangeListener)
@@ -1006,28 +1005,6 @@ class MilestoneTestCase(unittest.TestCas
self.assertEqual('deleted', listener.action)
self.assertEqual(milestone, listener.milestone)
-class TestResourceChangeListener(core.Component):
- implements(IResourceChangeListener)
-
- def callback(self, action, resource, old_values = None):
- pass
-
- def resource_created(self, resource):
- self.action = "created"
- self.resource = resource
- self.callback(self.action, self.resource)
-
- def resource_changed(self, resource, old_values):
- self.action = "changed"
- self.resource = resource
- self.old_values = old_values
- self.callback(self.action, self.resource, old_values=self.old_values)
-
- def resource_deleted(self, resource):
- self.action = "deleted"
- self.resource = resource
- self.callback(self.action, self.resource)
-
class ComponentTestCase(unittest.TestCase):
def setUp(self):
@@ -1063,49 +1040,6 @@ class ComponentTestCase(unittest.TestCas
self.assertEqual([('Test', 'joe', None)], self.env.db_query(
"SELECT name, owner, description FROM component WHERE
name='Test'"))
- def test_change_listener_created(self):
- listener = TestResourceChangeListener(self.env)
- self._create_component(name='Component 1')
- self.assertEqual('created', listener.action)
- self.assertIsInstance(listener.resource, Component)
- self.assertEqual('Component 1', listener.resource.name)
-
- def test_change_listener_changed(self):
- listener = TestResourceChangeListener(self.env)
- component = self._create_component(name='Component 1')
- component.name = 'Component 2'
- component.update()
- self.assertEqual('changed', listener.action)
- self.assertIsInstance(listener.resource, Component)
- self.assertEqual('Component 2', listener.resource.name)
- self.assertEqual("Component 1" ,listener.old_values["name"])
-
- def test_change_listener_deleted(self):
- listener = TestResourceChangeListener(self.env)
-
- #component.name property is set to None during delete operation
- #We need mechanism to remember component name
- listener.callback = self.listener_callback
-
- component = self._create_component(name='Component 1')
- component.delete()
- self.assertEqual('deleted', listener.action)
- self.assertIsInstance(listener.resource, Component)
- self.assertEqual('Component 1', self.resource_name)
-
- def listener_callback(self, action, resource, old_values = None):
- self.resource_name = resource.name
-
- def _create_component(self, name, description = None, owner=None):
- component = Component(self.env)
- component.name = name
- if description is None:
- component.description = description
- if owner is None:
- component.owner = owner
- component.insert()
- return component
-
class VersionTestCase(unittest.TestCase):
def setUp(self):
@@ -1140,6 +1074,107 @@ class VersionTestCase(unittest.TestCase)
self.assertEqual([('Test', 0, 'Some text')], self.env.db_query(
"SELECT name, time, description FROM version WHERE name='Test'"))
+class BaseResourceChangeListenerTestCase(unittest.TestCase):
+ DUMMY_RESOURCE_NAME = "Resource 1"
+ resource_type = None
+ name_field = "name"
+
+ def setUp(self):
+ self.env = EnvironmentStub(default_data=True)
+ self.listener = TestResourceChangeListener(self.env)
+ self.listener.resource_type = self.resource_type
+ self.listener.callback = self.listener_callback
+
+ def tearDown(self):
+ self.env.reset_db()
+
+ def test_change_listener_created(self):
+ self._create_resource(self.DUMMY_RESOURCE_NAME)
+ self.assertEqual('created', self.listener.action)
+ self.assertIsInstance(self.listener.resource, self.resource_type)
+ self.assertEqual(
+ self.DUMMY_RESOURCE_NAME,
+ self.resource_name)
+
+ def test_change_listener_changed(self):
+ resource = self._create_resource(self.DUMMY_RESOURCE_NAME)
+ self._rename_resource(resource, "UpdatedName")
+ self.assertEqual('changed', self.listener.action)
+ self.assertIsInstance(self.listener.resource, self.resource_type)
+ self.assertEqual("UpdatedName", self.resource_name)
+ self.assertEqual(
+ self.DUMMY_RESOURCE_NAME,
+ self.listener.old_values[self.name_field])
+
+ def test_change_listener_deleted(self):
+ resource = self._create_resource(self.DUMMY_RESOURCE_NAME)
+ resource.delete()
+ self.assertEqual('deleted', self.listener.action)
+ self.assertIsInstance(self.listener.resource, self.resource_type)
+ self.assertEqual(self.DUMMY_RESOURCE_NAME, self.resource_name)
+
+ def _create_resource(self, name):
+ resource = self.resource_type(self.env)
+ resource.name = name
+ resource.insert()
+ return resource
+
+ def _rename_resource(self, resource, new_name):
+ resource.name = new_name
+ resource.update()
+ return resource
+
+ def _get_resource_name(self, resource):
+ return resource.name
+
+ def listener_callback(self, action, resource, context, old_values = None):
+ self.resource_name = self._get_resource_name(resource)
+
+class ComponentResourceChangeListenerTestCase(
+ BaseResourceChangeListenerTestCase):
+ resource_type = Component
+
+class VersionResourceChangeListenerTestCase(
+ BaseResourceChangeListenerTestCase):
+ resource_type = Version
+
+class PriorityResourceChangeListenerTestCase(
+ BaseResourceChangeListenerTestCase):
+ resource_type = Priority
+
+class MilestoneResourceChangeListenerTestCase(
+ BaseResourceChangeListenerTestCase):
+ resource_type = Milestone
+
+class TicketResourceChangeListenerTestCase(
+ BaseResourceChangeListenerTestCase):
+ resource_type = Ticket
+ name_field = "summary"
+ dummy_author = "anAuthor"
+ dummy_comment = "some comment"
+
+ def test_change_listener_changed(self):
+ super(
+ TicketResourceChangeListenerTestCase,
+ self).test_change_listener_changed()
+
+ self.assertEqual(self.dummy_author, self.listener.context["author"])
+ self.assertEqual(self.dummy_comment, self.listener.context["comment"])
+
+
+ def _create_resource(self, name):
+ ticket = Ticket(self.env)
+ ticket["summary"] = name
+ ticket.insert()
+ return ticket
+
+ def _rename_resource(self, resource, new_name):
+ resource["summary"] = new_name
+ resource.save_changes(self.dummy_author, self.dummy_comment)
+ return resource
+
+ def _get_resource_name(self, resource):
+ return resource["summary"]
def suite():
suite = unittest.TestSuite()
@@ -1150,6 +1185,16 @@ def suite():
suite.addTest(unittest.makeSuite(MilestoneTestCase, 'test'))
suite.addTest(unittest.makeSuite(ComponentTestCase, 'test'))
suite.addTest(unittest.makeSuite(VersionTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(
+ ComponentResourceChangeListenerTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(
+ VersionResourceChangeListenerTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(
+ PriorityResourceChangeListenerTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(
+ MilestoneResourceChangeListenerTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(
+ TicketResourceChangeListenerTestCase, 'test'))
return suite
if __name__ == '__main__':
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
--- incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py
(original)
+++ incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/model.py
Tue Mar 12 08:29:15 2013
@@ -21,7 +21,7 @@ from __future__ import with_statement
from datetime import datetime
from trac.core import *
-from trac.resource import Resource
+from trac.resource import Resource, ResourceSystem, IResourceChangeListener
from trac.util.datefmt import from_utimestamp, to_utimestamp, utc
from trac.util.translation import _
from trac.wiki.api import WikiSystem, validate_page_name
@@ -110,12 +110,9 @@ class WikiPage(object):
# Let change listeners know about the deletion
if not self.exists:
- for listener in WikiSystem(self.env).change_listeners:
- listener.wiki_page_deleted(self)
+ ResourceSystem(self.env).resource_deleted(self)
else:
- for listener in WikiSystem(self.env).change_listeners:
- if hasattr(listener, 'wiki_page_version_deleted'):
- listener.wiki_page_version_deleted(self)
+ ResourceSystem(self.env).resource_version_deleted(self)
def save(self, author, comment, remote_addr, t=None, db=None):
"""Save a new version of a page.
@@ -153,12 +150,23 @@ class WikiPage(object):
self.comment = comment
self.time = t
- for listener in WikiSystem(self.env).change_listeners:
- if self.version == 1:
- listener.wiki_page_added(self)
- else:
- listener.wiki_page_changed(self, self.version, t, comment,
- author, remote_addr)
+ context=dict(
+ version=self.version,
+ time=t,
+ comment=comment,
+ author=author,
+ remote_addr=remote_addr,
+ source_action="save")
+ if self.version == 1:
+ ResourceSystem(self.env).resource_created(self, context)
+ else:
+ ResourceSystem(self.env).resource_changed(
+ self,
+ old_values=dict(
+ name=self.name,
+ readonly = self.old_readonly,
+ text = self.old_text),
+ context = context)
self.old_readonly = self.readonly
self.old_text = self.text
@@ -192,9 +200,15 @@ class WikiPage(object):
self.name = new_name
self.env.log.info('Renamed page %s to %s', old_name, new_name)
- for listener in WikiSystem(self.env).change_listeners:
- if hasattr(listener, 'wiki_page_renamed'):
- listener.wiki_page_renamed(self, old_name)
+
+ ResourceSystem(self.env).resource_changed(
+ self,
+ old_values=dict(
+ name=old_name,
+ readonly = self.readonly,
+ text = self.text),
+ context=dict(source_action="rename")
+ )
def get_history(self, db=None):
"""Retrieve the edit history of a wiki page.
@@ -207,3 +221,42 @@ class WikiPage(object):
WHERE name=%s AND version<=%s ORDER BY version DESC
""", (self.name, self.version)):
yield version, from_utimestamp(ts), author, comment, ipnr
+
+class ResourceToWikiChangeListenerAdapter(Component):
+ """
+ The class provides backward compatibility for components implementing
+ IWikiChangeListener interface.
+ """
+ implements(IResourceChangeListener)
+ def match_resource(self, resource):
+ return isinstance(resource, WikiPage)
+
+ def resource_created(self, resource, context):
+ for listener in WikiSystem(self.env).change_listeners:
+ listener.wiki_page_added(resource)
+
+ def resource_changed(self, resource, old_values, context):
+ if context is not None and context.get("source_action") == "rename":
+ for listener in WikiSystem(self.env).change_listeners:
+ if hasattr(listener, 'wiki_page_renamed'):
+ listener.wiki_page_renamed(
+ resource, old_values.get("name"))
+ else:
+ for listener in WikiSystem(self.env).change_listeners:
+ listener.wiki_page_changed(
+ resource,
+ context.get("version"),
+ context.get("time"),
+ context.get("comment"),
+ context.get("author"),
+ context.get("remote_addr"),
+ )
+
+ def resource_deleted(self, resource, context):
+ for listener in WikiSystem(self.env).change_listeners:
+ listener.wiki_page_deleted(resource)
+
+ def resource_version_deleted(self, resource, context):
+ for listener in WikiSystem(self.env).change_listeners:
+ if hasattr(listener, 'wiki_page_version_deleted'):
+ listener.wiki_page_version_deleted(resource)
Modified:
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/tests/model.py
URL:
http://svn.apache.org/viewvc/incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/tests/model.py?rev=1455438&r1=1455437&r2=1455438&view=diff
==============================================================================
---
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/tests/model.py
(original)
+++
incubator/bloodhound/branches/bep_0003_multiproduct/trac/trac/wiki/tests/model.py
Tue Mar 12 08:29:15 2013
@@ -12,6 +12,7 @@ import unittest
from trac.attachment import Attachment
from trac.core import *
from trac.test import EnvironmentStub
+from trac.tests.resource import TestResourceChangeListener
from trac.util.datefmt import utc, to_utimestamp
from trac.wiki import WikiPage, IWikiChangeListener
@@ -266,9 +267,83 @@ class WikiPageTestCase(unittest.TestCase
page = WikiPage(self.env, 'TestPage')
self.assertRaises(TracError, page.rename, name)
+class WikiResourceChangeListenerTestCase(unittest.TestCase):
+ INITIAL_NAME = "Wiki page 1"
+ INITIAL_TEXT = "some text"
+ INITIAL_AUTHOR = "anAuthor"
+ INITIAL_COMMENT = "some comment"
+ INITIAL_REMOTE_ADDRESS = "::1"
+
+ def setUp(self):
+ self.env = EnvironmentStub(default_data=True)
+ self.listener = TestResourceChangeListener(self.env)
+ self.listener.resource_type = WikiPage
+ self.listener.callback = self.listener_callback
+
+ def tearDown(self):
+ self.env.reset_db()
+
+ def test_change_listener_created(self):
+ self._create_wiki_page(self.INITIAL_NAME)
+ self.assertEqual('created', self.listener.action)
+ self.assertIsInstance(self.listener.resource, WikiPage)
+ self.assertEqual(self.INITIAL_NAME, self.wiki_name)
+ self.assertEqual(self.INITIAL_TEXT, self.wiki_text)
+
+ def test_change_listener_text_changed(self):
+ wiki_page = self._create_wiki_page(self.INITIAL_NAME)
+ CHANGED_TEXT = "some other text"
+ wiki_page.text = CHANGED_TEXT
+ wiki_page.save("author1", "renamed_comment", "::2")
+ self.assertEqual('changed', self.listener.action)
+ self.assertIsInstance(self.listener.resource, WikiPage)
+ self.assertEqual(self.INITIAL_NAME, self.wiki_name)
+ self.assertEqual(CHANGED_TEXT, self.wiki_text)
+ self.assertEqual(
+ dict(text=self.INITIAL_TEXT, readonly=0, name=self.INITIAL_NAME),
+ self.listener.old_values)
+ self.assertEqual("save", self.listener.context["source_action"])
+
+ def test_change_listener_renamed(self):
+ wiki_page = self._create_wiki_page(self.INITIAL_NAME)
+ CHANGED_NAME = "NewWikiName"
+ wiki_page.rename(CHANGED_NAME)
+ self.assertEqual('changed', self.listener.action)
+ self.assertIsInstance(self.listener.resource, WikiPage)
+ self.assertEqual(CHANGED_NAME, self.wiki_name)
+ self.assertEqual(self.INITIAL_TEXT, self.wiki_text)
+ self.assertEqual(
+ dict(text=self.INITIAL_TEXT, readonly=0, name=self.INITIAL_NAME),
+ self.listener.old_values)
+ self.assertEqual("rename", self.listener.context["source_action"])
+
+ def test_change_listener_deleted(self):
+ wiki_page = self._create_wiki_page(self.INITIAL_NAME)
+ wiki_page.delete()
+ self.assertEqual('deleted', self.listener.action)
+ self.assertIsInstance(self.listener.resource, WikiPage)
+ self.assertEqual(self.INITIAL_NAME, self.wiki_name)
+
+ def _create_wiki_page(self, name=None):
+ name = name or self.INITIAL_NAME
+ wiki_page = WikiPage(self.env, name)
+ wiki_page.text = self.INITIAL_TEXT
+ wiki_page.save(
+ self.INITIAL_AUTHOR,
+ self.INITIAL_COMMENT,
+ self.INITIAL_REMOTE_ADDRESS)
+ return wiki_page
+
+ def listener_callback(self, action, resource, context, old_values = None):
+ self.wiki_name = resource.name
+ self.wiki_text = resource.text
def suite():
- return unittest.makeSuite(WikiPageTestCase, 'test')
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(WikiPageTestCase, 'test'))
+ suite.addTest(unittest.makeSuite(
+ WikiResourceChangeListenerTestCase, 'test'))
+ return suite
if __name__ == '__main__':
unittest.main(defaultTest='suite')