You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by rj...@apache.org on 2014/06/20 02:34:20 UTC
svn commit: r1604057 [1/3] - in
/bloodhound/branches/bep_0007_embeddable_objects: ./ bloodhound_dashboard/
bloodhound_dashboard/bhdashboard/widgets/templates/
bloodhound_multiproduct/ bloodhound_multiproduct/multiproduct/
bloodhound_multiproduct/multip...
Author: rjollos
Date: Fri Jun 20 00:34:19 2014
New Revision: 1604057
URL: http://svn.apache.org/r1604057
Log:
Merged from trunk.
Added:
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_product_edit.html
- copied unchanged from r1604056, bloodhound/trunk/bloodhound_theme/bhtheme/templates/bh_product_edit.html
Modified:
bloodhound/branches/bep_0007_embeddable_objects/ (props changed)
bloodhound/branches/bep_0007_embeddable_objects/RELEASE_NOTES
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/setup.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/hooks.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/product_admin.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/templates/admin_products.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/ticket/query.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/setup.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/admin/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/db/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/mimeview/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/ticket/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/versioncontrol/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/web/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/wiki/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/README
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/TESTING_README
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/api.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/db_default.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/model.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/notification.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/relations_manage.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/__init__.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/api.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/base.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/mocks.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/notification.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/search.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/validation.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/web_ui.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/validation.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/web_ui.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/relations.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/api.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/milestone_search.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/ticket_search.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/wiki_search.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/security.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/api.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_suggestion.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/security.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/web_ui.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/whoosh_backend.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/web_ui.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/whoosh_backend.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/setup.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/bloodhound.css
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/js/theme.js
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_products.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_query.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_report_list.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_roadmap.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bloodhound_theme.html
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/theme.py
bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/setup.py
bloodhound/branches/bep_0007_embeddable_objects/installer/bloodhound_setup.py
bloodhound/branches/bep_0007_embeddable_objects/trac/ (props changed)
bloodhound/branches/bep_0007_embeddable_objects/trac/trac/db/postgres_backend.py
bloodhound/branches/bep_0007_embeddable_objects/trac/trac/hooks.py
bloodhound/branches/bep_0007_embeddable_objects/trac/trac/resource.py
bloodhound/branches/bep_0007_embeddable_objects/trac/trac/web/main.py
Propchange: bloodhound/branches/bep_0007_embeddable_objects/
------------------------------------------------------------------------------
Merged /bloodhound/trunk:r1572403-1604056
Modified: bloodhound/branches/bep_0007_embeddable_objects/RELEASE_NOTES
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/RELEASE_NOTES?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/RELEASE_NOTES (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/RELEASE_NOTES Fri Jun 20 00:34:19 2014
@@ -1,3 +1,29 @@
+0.8
+ * i18n internationalization.
+ * Multiproduct support for CommitTicketUpdater.
+ * Quick Create Ticket form sets product based on context and forwards
+ values to the ticket form when "More fields" is selected.
+ * Fixed caching issue that prevented product-scope trac-admin commands
+ from taking effect immediately.
+ * Improved presentation of the Products page.
+ * Improvements to ticket timeline (comments section).
+ * BloodhoundSearch now supports Whoosh >= 2.5.1 (upgraded from 2.4.1).
+ * Fixed errors in BloodhoundRelations validation logic.
+ * Bootstrap template for the Roadmap and Edit Product views.
+ * Bloodhound installer support for MySQL database.
+ * Numerous other important fixes and minor enhancements.
+
+
+ * Not fixed for this release
+ * Cache is not properly refreshed for resources including wiki pages,
+ milestones, components and permissions; leading to stale data being
+ displayed after INSERTs and DELETEs (#613, #614, #620, #681, #719, #748).
+ * Products cannot be deleted (#517).
+ * Duplicate relation is not added when batch modifying tickets (#761).
+ * TicketDeleter component can't be used with BloodhoundTheme (#427).
+ * No product-scope permission checks on the global dashboard (#572).
+ * Inconsistencies in query views when running PostgreSQL (#730).
+
0.7
* Duplicate ticket relation is integrated to the ticket workflow.
* Several fixes for multiproduct installations with products that map to subdomains.
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/bhdashboard/widgets/templates/widget_cloud.html Fri Jun 20 00:34:19 2014
@@ -45,10 +45,7 @@
</span>
</py:def>
- <py:if test="heading is not None">
- <h3 style="display: inline;">$heading</h3>
- <br/>
- </py:if>
+ <h3 py:if="heading is not None and items" style="display: inline;">$heading</h3>
<py:if test="_view != view">
<xi:include href="widget_alert.html"
py:with="msglabel = 'Warning'; msgbody = 'Unknown view ' + view" />
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/setup.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/setup.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_dashboard/setup.py Fri Jun 20 00:34:19 2014
@@ -132,8 +132,8 @@ ENTRY_POINTS = r"""
"""
extra = {}
try:
- from trac.util.dist import get_l10n_js_cmdclass
- cmdclass = get_l10n_js_cmdclass()
+ from trac.util.dist import get_l10n_cmdclass
+ cmdclass = get_l10n_cmdclass()
if cmdclass:
extra['cmdclass'] = cmdclass
extractors = [
@@ -158,10 +158,6 @@ setup(
url = "https://bloodhound.apache.org/",
requires = ['trac'],
tests_require = ['dutest>=0.2.4', 'TracXMLRPC'],
- install_requires = [
- 'setuptools>=0.6b1',
- 'Trac>=0.11',
- ],
package_dir = dict([p, i[0]] for p, i in PKG_INFO.iteritems()),
packages = PKG_INFO.keys(),
package_data = dict([p, i[1]] for p, i in PKG_INFO.iteritems()),
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/hooks.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/hooks.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/hooks.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/hooks.py Fri Jun 20 00:34:19 2014
@@ -19,22 +19,22 @@
# these imports monkey patch classes required to enable
# multi product support
-import multiproduct.env
-import multiproduct.dbcursor
-import multiproduct.versioncontrol
-import multiproduct.ticket.query
-import multiproduct.ticket.batch
import re
-from trac.core import TracError
from trac.hooks import EnvironmentFactoryBase, RequestFactoryBase
-from trac.perm import PermissionCache
from trac.web.href import Href
from trac.web.main import RequestWithSession
+import multiproduct.env
+import multiproduct.dbcursor
+import multiproduct.ticket.batch
+import multiproduct.ticket.query
+import multiproduct.versioncontrol
+
PRODUCT_RE = re.compile(r'^/products(?:/(?P<pid>[^/]*)(?P<pathinfo>.*))?')
+
class MultiProductEnvironmentFactory(EnvironmentFactoryBase):
def open_environment(self, environ, env_path, global_env, use_cache=False):
environ.setdefault('SCRIPT_NAME', '') # bh:ticket:594
@@ -78,19 +78,9 @@ class MultiProductEnvironmentFactory(Env
class ProductizedHref(Href):
- PATHS_NO_TRANSFORM = ['chrome',
- 'login',
- 'logout',
- 'prefs',
- 'products',
- 'verify_email',
- 'reset_password',
- 'register',
- ]
- STATIC_PREFIXES = ['js/',
- 'css/',
- 'img/',
- ]
+ PATHS_NO_TRANSFORM = ['chrome', 'login', 'logout', 'prefs', 'products',
+ 'register', 'reset_password', 'verify_email']
+ STATIC_PREFIXES = ['css/', 'img/', 'js/']
def __init__(self, global_href, base):
self.super = super(ProductizedHref, self)
@@ -120,4 +110,4 @@ class ProductRequestWithSession(RequestW
class ProductRequestFactory(RequestFactoryBase):
def create_request(self, env, environ, start_response):
return ProductRequestWithSession(env, environ, start_response) \
- if env else RequestWithSession(environ, start_response)
+ if env else RequestWithSession(environ, start_response)
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/product_admin.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/product_admin.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/product_admin.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/product_admin.py Fri Jun 20 00:34:19 2014
@@ -85,6 +85,7 @@ class ProductAdminPanel(TicketAdminPanel
'description':description,
'owner':owner,
}
+ data = {}
# Detail view?
if product:
@@ -105,27 +106,37 @@ class ProductAdminPanel(TicketAdminPanel
default = self.config.get('ticket', 'default_product')
if req.method == 'POST':
# Add Product
- if req.args.get('add') and req.args.get('prefix'):
+ if req.args.get('add'):
req.perm.require('PRODUCT_CREATE')
- if not owner:
- add_warning(req, _('All fields are required!'))
- req.redirect(req.href.admin(cat, page))
-
- try:
- prod = Product(self.env, keys)
- except ResourceNotFound:
- prod = Product(self.env)
- prod.update_field_dict(keys)
- prod.update_field_dict(field_data)
- prod.insert()
- add_notice(req, _('The product "%(id)s" has been added.',
- id=prefix))
- req.redirect(req.href.admin(cat, page))
+ if not (prefix and name and owner):
+ if not prefix:
+ add_warning(req, _("You must provide a prefix "
+ "for the product."))
+ if not name:
+ add_warning(req, _("You must provide a name "
+ "for the product."))
+ if not owner:
+ add_warning(req, _("You must provide an owner "
+ "for the product."))
+ data['prefix'] = prefix
+ data['name'] = name
+ data['owner'] = owner
else:
- if prod.prefix is None:
- raise TracError(_('Invalid product id.'))
- raise TracError(_("Product %(id)s already exists.",
- id=prefix))
+ try:
+ prod = Product(self.env, keys)
+ except ResourceNotFound:
+ prod = Product(self.env)
+ prod.update_field_dict(keys)
+ prod.update_field_dict(field_data)
+ prod.insert()
+ add_notice(req, _('The product "%(id)s" has been '
+ 'added.', id=prefix))
+ req.redirect(req.href.admin(cat, page))
+ else:
+ if prod.prefix is None:
+ raise TracError(_('Invalid product id.'))
+ raise TracError(_("Product %(id)s already exists.",
+ id=prefix))
# Remove product
elif req.args.get('remove'):
@@ -149,10 +160,9 @@ class ProductAdminPanel(TicketAdminPanel
_save_config(self.config, req, self.log)
req.redirect(req.href.admin(cat, page))
- products = Product.select(self.env)
- data = {'view': 'list',
- 'products': products,
- 'default': default}
+ data['view'] = 'list'
+ data['products'] = Product.select(self.env)
+ data['default'] = default
if self.config.getbool('ticket', 'restrict_owner'):
perm = PermissionSystem(self.env)
def valid_owner(username):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/templates/admin_products.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/templates/admin_products.html?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/templates/admin_products.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/templates/admin_products.html Fri Jun 20 00:34:19 2014
@@ -86,12 +86,12 @@ $product.description</textarea>
<fieldset>
<legend>Add Product:</legend>
<div class="field">
- <label>Prefix:<br /><input type="text" name="prefix" /></label>
+ <label>Prefix:<br /><input type="text" name="prefix" value="$prefix" /></label>
</div>
<div class="field">
- <label>Name:<br /><input type="text" name="name" /></label>
+ <label>Name:<br /><input type="text" name="name" value="$name" /></label>
</div>
- ${owner_field()}
+ ${owner_field(owner)}
<div class="buttons">
<input type="submit" name="add" value="${_('Add')}"/>
</div>
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/ticket/query.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/ticket/query.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/ticket/query.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/multiproduct/ticket/query.py Fri Jun 20 00:34:19 2014
@@ -72,9 +72,13 @@ class ProductQuery(Query):
return self.cols
def _get_ticket_href(self, prefix, tid):
- env = lookup_product_env(self.env, prefix)
- href = resolve_product_href(env, self.env)
- return href.ticket(tid)
+ try:
+ env = lookup_product_env(self.env, prefix)
+ except LookupError:
+ return '#invalid-product-' + prefix
+ else:
+ href = resolve_product_href(env, self.env)
+ return href.ticket(tid)
def get_href(self, href, id=None, order=None, desc=None, format=None,
max=None, page=None):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/setup.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/setup.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/setup.py Fri Jun 20 00:34:19 2014
@@ -36,8 +36,8 @@ if __name__ == '__main__':
extra = {}
try:
- from trac.util.dist import get_l10n_js_cmdclass
- cmdclass = get_l10n_js_cmdclass()
+ from trac.util.dist import get_l10n_cmdclass
+ cmdclass = get_l10n_cmdclass()
if cmdclass:
extra['cmdclass'] = cmdclass
extractors = [
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/admin/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/admin/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/admin/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/admin/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,9 +17,13 @@
# specific language governing permissions and limitations
# under the License.
-"""Tests for Apache(TM) Bloodhound's administration in product environments"""
-
+import unittest
from tests import TestLoader
+
def test_suite():
- return TestLoader().discover_package(__name__, pattern='*.py')
+ return TestLoader().discover_package(__package__, pattern='*.py')
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/db/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/db/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/db/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/db/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,7 +17,13 @@
# specific language governing permissions and limitations
# under the License.
+import unittest
from tests import TestLoader
+
def test_suite():
- return TestLoader().discover_package(__name__, pattern='*.py')
+ return TestLoader().discover_package(__package__, pattern='*.py')
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/mimeview/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/mimeview/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/mimeview/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/mimeview/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,9 +17,13 @@
# specific language governing permissions and limitations
# under the License.
-"""Tests for Apache(TM) Bloodhound's MIME API in product environments"""
-
+import unittest
from tests import TestLoader
+
def test_suite():
- return TestLoader().discover_package(__name__, pattern='*.py')
+ return TestLoader().discover_package(__package__, pattern='*.py')
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/ticket/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/ticket/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/ticket/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/ticket/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,9 +17,13 @@
# specific language governing permissions and limitations
# under the License.
-"""Tests for Apache(TM) Bloodhound's tickets in product environments"""
-
+import unittest
from tests import TestLoader
+
def test_suite():
- return TestLoader().discover_package(__name__, pattern='*.py')
+ return TestLoader().discover_package(__package__, pattern='*.py')
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/versioncontrol/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/versioncontrol/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/versioncontrol/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/versioncontrol/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,9 +17,13 @@
# specific language governing permissions and limitations
# under the License.
-"""Tests for Apache(TM) Bloodhound's version control in product environments"""
-
+import unittest
from tests import TestLoader
+
def test_suite():
- return TestLoader().discover_package(__name__, pattern='*.py')
+ return TestLoader().discover_package(__package__, pattern='*.py')
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/web/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/web/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/web/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/web/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,9 +17,13 @@
# specific language governing permissions and limitations
# under the License.
-"""Tests for Apache(TM) Bloodhound web API in product environments"""
-
+import unittest
from tests import TestLoader
+
def test_suite():
- return TestLoader().discover_package(__name__, pattern='*.py')
+ return TestLoader().discover_package(__package__, pattern='*.py')
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/wiki/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/wiki/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/wiki/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_multiproduct/tests/wiki/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,9 +17,13 @@
# specific language governing permissions and limitations
# under the License.
-"""Tests for Apache(TM) Bloodhound's wiki subsystem in product environments"""
-
+import unittest
from tests import TestLoader
+
def test_suite():
- return TestLoader().discover_package(__name__, pattern='*.py')
+ return TestLoader().discover_package(__package__, pattern='*.py')
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/README
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/README?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/README (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/README Fri Jun 20 00:34:19 2014
@@ -28,4 +28,4 @@ If you have any issues, please create a
== The Trac ticket-links branch
Bloodhound Relations plugin contains the code from the Trac ticket-links branch, which
-is licensed under the same license as Trac (http://trac.edgewall.org/wiki/TracLicense).
\ No newline at end of file
+is licensed under the same license as Trac (http://trac.edgewall.org/wiki/TracLicense).
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/TESTING_README
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/TESTING_README?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/TESTING_README (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/TESTING_README Fri Jun 20 00:34:19 2014
@@ -1,5 +1,5 @@
-= Testing Bloodhound Search plugin =
+= Testing Bloodhound Relations plugin =
== Overview ==
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/api.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/api.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/api.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/api.py Fri Jun 20 00:34:19 2014
@@ -16,30 +16,34 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import itertools
+import itertools
import re
from datetime import datetime
from pkg_resources import resource_filename
+
+from trac.config import OrderedExtensionsOption, Option
+from trac.core import Component, ExtensionPoint, Interface, TracError, \
+ implements
+from trac.db import DatabaseManager
+from trac.env import IEnvironmentSetupParticipant
+from trac.resource import Neighborhood, Resource, ResourceNotFound, \
+ ResourceSystem, get_resource_shortname
+from trac.ticket.api import ITicketChangeListener, ITicketManipulator, \
+ TicketSystem
+from trac.ticket.model import Ticket
+from trac.util.datefmt import to_utimestamp, utc
+from trac.web.chrome import ITemplateProvider
+
+from multiproduct.api import ISupportMultiProductEnvironment
+from multiproduct.model import Product
+from multiproduct.env import ProductEnvironment
+
from bhrelations import db_default
from bhrelations.model import Relation
from bhrelations.utils import unique
from bhrelations.utils.translation import _, add_domain
-from multiproduct.api import ISupportMultiProductEnvironment
-from multiproduct.model import Product
-from multiproduct.env import ProductEnvironment
-from trac.config import OrderedExtensionsOption, Option
-from trac.core import (Component, implements, TracError, Interface,
- ExtensionPoint)
-from trac.env import IEnvironmentSetupParticipant
-from trac.db import DatabaseManager
-from trac.resource import (ResourceSystem, Resource, ResourceNotFound,
- get_resource_shortname, Neighborhood)
-from trac.ticket import Ticket, ITicketManipulator, ITicketChangeListener
-from trac.ticket.api import TicketSystem
-from trac.util.datefmt import utc, to_utimestamp
-from trac.web.chrome import ITemplateProvider
PLUGIN_NAME = 'Bloodhound Relations Plugin'
RELATIONS_CONFIG_NAME = 'bhrelations_links'
@@ -114,6 +118,8 @@ class EnvironmentSetup(Component):
implements(IEnvironmentSetupParticipant, ISupportMultiProductEnvironment,
ITemplateProvider)
+ # IEnvironmentSetupParticipant methods
+
def environment_created(self):
self.upgrade_environment(self.env.db_transaction)
@@ -123,10 +129,9 @@ class EnvironmentSetup(Component):
db_version = db_default.DB_VERSION
if db_installed_version > db_version:
- raise TracError('''Current db version (%d) newer than supported by
- this version of the %s (%d).''' % (db_installed_version,
- PLUGIN_NAME,
- db_version))
+ raise TracError("""Current db version (%d) newer than supported
+ by this version of the %s (%d)."""
+ % (db_installed_version, PLUGIN_NAME, db_version))
needs_upgrade = db_installed_version < db_version or \
not list(self.config.options(RELATIONS_CONFIG_NAME))
return needs_upgrade
@@ -149,25 +154,21 @@ class EnvironmentSetup(Component):
def _get_version(self, db):
"""Finds the current version of the bloodhound database schema"""
- rows = db("""
- SELECT value FROM system WHERE name = %s
- """, (db_default.DB_SYSTEM_KEY,))
+ rows = db("""SELECT value FROM system WHERE name = %s
+ """, (db_default.DB_SYSTEM_KEY,))
return int(rows[0][0]) if rows else -1
def _update_db_version(self, db, version):
old_version = self._get_version(db)
if old_version != -1:
- self.log.info(
- "Updating %s database schema from version %d to %d",
- PLUGIN_NAME, old_version, version)
+ self.log.info("Updating %s database schema from version %d to %d",
+ PLUGIN_NAME, old_version, version)
db("""UPDATE system SET value=%s
- WHERE name=%s""", (version, db_default.DB_SYSTEM_KEY))
+ WHERE name=%s""", (version, db_default.DB_SYSTEM_KEY))
else:
- self.log.info(
- "Initial %s database schema set to version %d",
- PLUGIN_NAME, version)
- db("""
- INSERT INTO system (name, value) VALUES ('%s','%s')
+ self.log.info("Initial %s database schema set to version %d",
+ PLUGIN_NAME, version)
+ db("""INSERT INTO system (name, value) VALUES ('%s','%s')
""" % (db_default.DB_SYSTEM_KEY, version))
return version
@@ -180,6 +181,7 @@ class EnvironmentSetup(Component):
db(statement)
# ITemplateProviderMethods
+
def get_templates_dirs(self):
"""provide the plugin templates"""
return [resource_filename(__name__, 'templates')]
@@ -336,15 +338,19 @@ class RelationsSystem(Component):
return self._select_relations(resource_full_id)
def _select_relations(
- self, source, resource_type=None):
+ self, source=None, resource_type=None, destination=None):
#todo: add optional paging for possible umbrella tickets with
#a lot of child tickets
- where = dict(source=source)
+ where = dict()
+ if source:
+ where["source"] = source
if resource_type:
where["type"] = resource_type
order_by = ["destination"]
else:
order_by = ["type", "destination"]
+ if destination:
+ where["destination"] = destination
return Relation.select(
self.env,
where=where,
@@ -453,9 +459,9 @@ class ResourceIdSerializer(object):
* resource_full_id: fully qualified resource id in format
"product:ticket:123". In case of global environment it is ":ticket:123"
"""
- nbhprefix, realm, resource_id = cls.split_full_id(resource_full_id)
- if nbhprefix:
- neighborhood = Neighborhood('product', nbhprefix)
+ nbh_prefix, realm, resource_id = cls.split_full_id(resource_full_id)
+ if nbh_prefix:
+ neighborhood = Neighborhood('product', nbh_prefix)
return neighborhood.child(realm, id=resource_id)
else:
return Resource(realm, id=resource_id)
@@ -479,10 +485,10 @@ class ResourceIdSerializer(object):
if ticket.id is None:
raise ValueError("Cannot get resource id for ticket "
"that does not exist yet.")
- nbhprefix = ticket["product"]
+ nbh_prefix = ticket["product"]
resource_full_id = cls.RESOURCE_ID_DELIMITER.join(
- (nbhprefix, resource.realm, unicode(resource.id))
+ (nbh_prefix, resource.realm, unicode(resource.id))
)
return resource_full_id
@@ -500,7 +506,7 @@ class TicketRelationsSpecifics(Component
def ticket_changed(self, ticket, comment, author, old_values):
if self._closed_as_duplicate(ticket) and \
self.rls.duplicate_relation_type and \
- hasattr(ticket, 'duplicate'): # workaround for comment:5:ticket:710
+ hasattr(ticket, 'duplicate'): # workaround for comment:5:ticket:710
try:
self.rls.add(ticket, ticket.duplicate,
self.rls.duplicate_relation_type,
@@ -545,7 +551,7 @@ class TicketRelationsSpecifics(Component
operations = self._get_operations_for_action(req, ticket, action)
if 'set_resolution' in operations:
for relation in [r for r in self.rls.get_relations(ticket)
- if r['type'] == self.rls.CHILDREN_RELATION_TYPE]:
+ if r['type'] == self.rls.PARENT_RELATION_TYPE]:
child_ticket = \
self._create_ticket_by_full_id(relation['destination'])
if child_ticket['status'] != 'closed':
@@ -600,7 +606,8 @@ class TicketRelationsSpecifics(Component
for p in Product.select(self.env):
if p.prefix != self.env.product.prefix:
# TODO: check for PRODUCT_VIEW permissions
- penv = ProductEnvironment(self.env.parent, p.prefix)
+ penv = ProductEnvironment(self.env.parent,
+ p.prefix)
try:
ticket = Ticket(penv, tid)
except ResourceNotFound:
@@ -633,8 +640,8 @@ class TicketRelationsSpecifics(Component
def _get_env_for_resource(self, resource):
if hasattr(resource, "neighborhood"):
- env = ResourceSystem(self.env).load_component_manager(
- resource.neighborhood)
+ env = ResourceSystem(self.env). \
+ load_component_manager(resource.neighborhood)
else:
env = self.env
return env
@@ -673,12 +680,12 @@ class TicketChangeRecordUpdater(Componen
)
def _get_ticket_id_and_product(self, resource_full_id):
- nbhprefix, realm, resource_id = ResourceIdSerializer.split_full_id(
- resource_full_id)
+ nbh_prefix, realm, resource_id = \
+ ResourceIdSerializer.split_full_id(resource_full_id)
ticket_id = None
if realm == "ticket":
ticket_id = int(resource_id)
- return ticket_id, nbhprefix
+ return ticket_id, nbh_prefix
def _add_ticket_change_record(
self, db, relation, relation_system, is_delete, when_ts):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/db_default.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/db_default.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/db_default.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/db_default.py Fri Jun 20 00:34:19 2014
@@ -16,6 +16,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+
from bhrelations.model import Relation
DB_SYSTEM_KEY = 'bhrelations'
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/model.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/model.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/model.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/model.py Fri Jun 20 00:34:19 2014
@@ -17,10 +17,11 @@
# specific language governing permissions and limitations
# under the License.
-from bhdashboard.model import ModelBase
from trac.resource import Resource
from trac.util.datefmt import to_utimestamp, from_utimestamp
+from bhdashboard.model import ModelBase
+
class Relation(ModelBase):
"""The Relation table"""
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/notification.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/notification.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/notification.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/notification.py Fri Jun 20 00:34:19 2014
@@ -16,9 +16,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+
from trac.notification import NotifyEmail
-from trac.ticket.notification import (get_ticket_notification_recipients,
- TicketNotifyEmail)
+from trac.ticket.notification import TicketNotifyEmail, \
+ get_ticket_notification_recipients
from trac.util.datefmt import from_utimestamp
from trac.web.chrome import Chrome
@@ -67,7 +68,7 @@ class RelationNotifyEmail(TicketNotifyEm
to, cc = [], []
for resource in (source, destination):
if resource.realm == 'ticket':
- (torecipients, ccrecipients, reporter, owner) = \
+ torecipients, ccrecipients, reporter, owner = \
get_ticket_notification_recipients(self.env, self.config,
resource.id, [])
to.extend(torecipients)
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/relations_manage.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/relations_manage.html?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/relations_manage.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/relations_manage.html Fri Jun 20 00:34:19 2014
@@ -70,7 +70,7 @@
<div class="control-group">
<label class="control-label" for="comment">Comment</label>
<div class="controls">
- <textarea name="comment" rows="3" class="span4">${relation.comment}</textarea>
+ <textarea id="comment" name="comment" rows="3" class="span4">${relation.comment}</textarea>
</div>
</div>
@@ -127,4 +127,3 @@
</div>
</body>
</html>
-
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/__init__.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/__init__.py Fri Jun 20 00:34:19 2014
@@ -17,11 +17,6 @@
# specific language governing permissions and limitations
# under the License.
-# import sys
-# if sys.version < (2, 7):
-# import unittest2 as unittest
-# else:
-# import unittest
import unittest
from bhrelations.tests import api, notification, search, validation, web_ui
@@ -36,6 +31,7 @@ def suite():
test_suite.addTest(web_ui.suite())
return test_suite
+
if __name__ == '__main__':
unittest.main(defaultTest='suite')
else:
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/api.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/api.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/api.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/api.py Fri Jun 20 00:34:19 2014
@@ -16,162 +16,147 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-from datetime import datetime
+
import unittest
+from datetime import datetime
+
+from trac.core import TracError
+from trac.ticket.model import Ticket
+from trac.util.datefmt import utc
+
+from multiproduct.env import ProductEnvironment
+
from bhrelations.api import TicketRelationsSpecifics
from bhrelations.tests.mocks import TestRelationChangingListener
from bhrelations.validation import ValidationError
-from bhrelations.tests.base import BaseRelationsTestCase
-from multiproduct.env import ProductEnvironment
-from trac.ticket.model import Ticket
-from trac.core import TracError
-from trac.util.datefmt import utc
+from bhrelations.tests.base import BaseRelationsTestCase, BLOCKED_BY, \
+ BLOCKS, CHILD, DEPENDENCY_OF, DEPENDS_ON, \
+ DUPLICATE_OF, MULTIPRODUCT_REL, PARENT, \
+ REFERS_TO
class ApiTestCase(BaseRelationsTestCase):
def test_can_add_two_ways_relations(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
- dependent = self._insert_and_load_ticket("A2")
+ ticket2 = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(
- ticket, dependent, "dependent")
- #assert
- relations = relations_system.get_relations(ticket)
- self.assertEqual("dependent", relations[0]["type"])
- self.assertEqual(unicode(dependent.id), relations[0]["destination"].id)
+ self.add_relation(ticket, DEPENDENCY_OF, ticket2)
+ #assert
+ relations = self.get_relations(ticket)
+ self.assertEqual(DEPENDENCY_OF, relations[0]["type"])
+ self.assertEqual(unicode(ticket2.id), relations[0]["destination"].id)
- relations = relations_system.get_relations(dependent)
- self.assertEqual("dependson", relations[0]["type"])
+ relations = self.get_relations(ticket2)
+ self.assertEqual(DEPENDS_ON, relations[0]["type"])
self.assertEqual(unicode(ticket.id), relations[0]["destination"].id)
def test_can_add_single_way_relations(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
- referred = self._insert_and_load_ticket("A2")
+ ticket2 = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(ticket, referred, "refersto")
+ self.add_relation(ticket, REFERS_TO, ticket2)
#assert
- relations = relations_system.get_relations(ticket)
- self.assertEqual("refersto", relations[0]["type"])
- self.assertEqual(unicode(referred.id), relations[0]["destination"].id)
+ relations = self.get_relations(ticket)
+ self.assertEqual(1, len(relations))
+ self.assertEqual(REFERS_TO, relations[0]["type"])
+ self.assertEqual(unicode(ticket2.id), relations[0]["destination"].id)
- relations = relations_system.get_relations(referred)
- self.assertEqual(0, len(relations))
+ self.assertEqual(0, len(self.get_relations(ticket2)))
def test_can_add_multiple_relations(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
- dependent1 = self._insert_and_load_ticket("A2")
- dependent2 = self._insert_and_load_ticket("A3")
+ ticket2 = self._insert_and_load_ticket("A2")
+ ticket3 = self._insert_and_load_ticket("A3")
#act
- relations_system = self.relations_system
- relations_system.add(
- ticket, dependent1, "dependent")
- relations_system.add(
- ticket, dependent2, "dependent")
+ self.add_relation(ticket, DEPENDS_ON, ticket2)
+ self.add_relation(ticket, DEPENDS_ON, ticket3)
#assert
- relations = relations_system.get_relations(ticket)
- self.assertEqual(2, len(relations))
+ self.assertEqual(2, len(self.get_relations(ticket)))
+ self.assertEqual(1, len(self.get_relations(ticket2)))
+ self.assertEqual(1, len(self.get_relations(ticket3)))
def test_will_not_create_more_than_one_identical_relations(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
- dependent1 = self._insert_and_load_ticket("A2")
+ ticket2 = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(
- ticket, dependent1, "dependent")
+ self.add_relation(ticket, DEPENDS_ON, ticket2)
self.assertRaisesRegexp(
TracError,
"already exists",
- relations_system.add,
- ticket, dependent1, "dependent")
+ self.add_relation,
+ ticket, DEPENDS_ON, ticket2
+ )
def test_will_not_create_more_than_one_identical_relations_db_level(self):
sql = """INSERT INTO bloodhound_relations (source, destination, type)
VALUES (%s, %s, %s)"""
with self.env.db_transaction as db:
- db(sql, ["1", "2", "dependson"])
+ db(sql, ["1", "2", DEPENDS_ON])
self.assertRaises(
self.env.db_exc.IntegrityError,
db,
sql,
- ["1", "2", "dependson"])
+ ["1", "2", DEPENDS_ON]
+ )
def test_can_add_one_way_relations(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
- referred_ticket = self._insert_and_load_ticket("A2")
+ ticket2 = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(
- ticket, referred_ticket, "refersto")
- #assert
- relations = relations_system.get_relations(ticket)
- self.assertEqual("refersto", relations[0]["type"])
- self.assertEqual(unicode(referred_ticket.id),
+ self.add_relation(ticket, REFERS_TO, ticket2)
+ #assert
+ relations = self.get_relations(ticket)
+ self.assertEqual(REFERS_TO, relations[0]["type"])
+ self.assertEqual(unicode(ticket2.id),
relations[0]["destination"].id)
- relations = relations_system.get_relations(referred_ticket)
- self.assertEqual(0, len(relations))
+ self.assertEqual(0, len(self.get_relations(ticket2)))
def test_can_delete_two_ways_relation(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
- dependent_ticket = self._insert_and_load_ticket("A2")
- relations_system = self.relations_system
- relations_system.add(
- ticket, dependent_ticket, "dependson")
- relations = relations_system.get_relations(ticket)
+ ticket2 = self._insert_and_load_ticket("A2")
+ self.add_relation(ticket, DEPENDS_ON, ticket2)
+
+ relations = self.get_relations(ticket)
self.assertEqual(1, len(relations))
+ self.assertEqual(1, len(self.get_relations(ticket2)))
+
#act
- relation_to_delete = relations[0]
- relations_system.delete(relation_to_delete["relation_id"])
+ self.delete_relation(relations[0])
#assert
- relations = relations_system.get_relations(ticket)
- self.assertEqual(0, len(relations))
+ self.assertEqual(0, len(self.get_relations(ticket)))
+ self.assertEqual(0, len(self.get_relations(ticket2)))
def test_can_delete_single_way_relation(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
- referred = self._insert_and_load_ticket("A2")
+ ticket2 = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(ticket, referred, "refersto")
-
- ticket = self._insert_and_load_ticket("A1")
- dependent_ticket = self._insert_and_load_ticket("A2")
- relations_system = self.relations_system
- relations_system.add(
- ticket, dependent_ticket, "dependson")
- relations = relations_system.get_relations(ticket)
+ self.add_relation(ticket, REFERS_TO, ticket2)
+ relations = self.get_relations(ticket)
self.assertEqual(1, len(relations))
- reverted_relations = relations_system.get_relations(dependent_ticket)
- self.assertEqual(1, len(reverted_relations))
+ self.assertEqual(0, len(self.get_relations(ticket2)))
#act
- # self._debug_select()
- relation_to_delete = relations[0]
- relations_system.delete(relation_to_delete["relation_id"])
- #assert
- relations = relations_system.get_relations(ticket)
- self.assertEqual(0, len(relations))
- reverted_relations = relations_system.get_relations(dependent_ticket)
- self.assertEqual(0, len(reverted_relations))
+ self.delete_relation(relations[0])
+ #assert
+ self.assertEqual(0, len(self.get_relations(ticket)))
def test_can_not_add_cycled_immediate_relations(self):
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(ticket1, ticket2, "dependson")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
try:
- relations_system.add(ticket2, ticket1, "dependson")
+ self.add_relation(ticket2, DEPENDS_ON, ticket1)
self.fail("Should throw an exception")
except ValidationError as ex:
self.assertSequenceEqual(
@@ -183,23 +168,22 @@ class ApiTestCase(BaseRelationsTestCase)
ticket2 = self._insert_and_load_ticket("A2")
ticket3 = self._insert_and_load_ticket("A3")
#act
- relations_system = self.relations_system
- relations_system.add(ticket1, ticket2, "dependson")
- relations_system.add(ticket1, ticket3, "dependson")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
+ self.add_relation(ticket1, DEPENDS_ON, ticket3)
+
+ self.assertEqual(2, len(self.get_relations(ticket1)))
def test_can_not_add_cycled_in_different_direction(self):
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(ticket1, ticket2, "dependson")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
self.assertRaises(
ValidationError,
- relations_system.add,
- ticket1,
- ticket2,
- "dependent")
+ self.add_relation,
+ ticket1, DEPENDENCY_OF, ticket2
+ )
def test_can_not_add_cycled_relations(self):
#arrange
@@ -207,60 +191,53 @@ class ApiTestCase(BaseRelationsTestCase)
ticket2 = self._insert_and_load_ticket("A2")
ticket3 = self._insert_and_load_ticket("A3")
#act
- relations_system = self.relations_system
- relations_system.add(ticket1, ticket2, "dependson")
- relations_system.add(ticket2, ticket3, "dependson")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
+ self.add_relation(ticket2, DEPENDS_ON, ticket3)
self.assertRaises(
ValidationError,
- relations_system.add,
- ticket3,
- ticket1,
- "dependson")
+ self.add_relation,
+ ticket3, DEPENDS_ON, ticket1
+ )
- def test_can_not_add_more_than_one_parents(self):
+ def test_can_not_add_more_than_one_parent(self):
#arrange
child = self._insert_and_load_ticket("A1")
parent1 = self._insert_and_load_ticket("A2")
parent2 = self._insert_and_load_ticket("A3")
#act
- relations_system = self.relations_system
- relations_system.add(child, parent1, "parent")
+ self.add_relation(parent1, PARENT, child)
self.assertRaises(
ValidationError,
- relations_system.add,
- child,
- parent2,
- "parent")
+ self.add_relation,
+ parent2, PARENT, child
+ )
- def test_can_not_add_more_than_one_parents_via_children(self):
- #arrange
- child = self._insert_and_load_ticket("A1")
- parent1 = self._insert_and_load_ticket("A2")
- parent2 = self._insert_and_load_ticket("A3")
- #act
- relations_system = self.relations_system
- relations_system.add(parent1, child, "children")
self.assertRaises(
ValidationError,
- relations_system.add,
- parent2,
- child,
- "children")
+ self.add_relation,
+ child, CHILD, parent2
+ )
+
+ def test_can_add_more_than_one_child(self):
+ parent = self._insert_and_load_ticket("A1")
+ child1 = self._insert_and_load_ticket("A2")
+ child2 = self._insert_and_load_ticket("A3")
+
+ self.add_relation(parent, PARENT, child1)
+ self.add_relation(parent, PARENT, child2)
+ self.assertEqual(2, len(self.get_relations(parent)))
def test_ticket_can_be_resolved(self):
#arrange
- child = self._insert_and_load_ticket("A1")
- parent1 = self._insert_and_load_ticket("A2")
- parent2 = self._insert_and_load_ticket("A3")
+ parent = self._insert_and_load_ticket("A1")
+ child = self._insert_and_load_ticket("A2")
#act
- relations_system = self.relations_system
- relations_system.add(parent1, child, "children")
- self.assertRaises(
- ValidationError,
- relations_system.add,
- parent2,
- child,
- "children")
+ self.add_relation(parent, PARENT, child)
+
+ self.req.args['action'] = 'resolve'
+ warnings = \
+ TicketRelationsSpecifics(self.env).validate_ticket(self.req, child)
+ self.assertEqual(0, len(list(warnings)))
def test_can_save_and_load_relation_time(self):
#arrange
@@ -268,8 +245,8 @@ class ApiTestCase(BaseRelationsTestCase)
ticket2 = self._insert_and_load_ticket("A2")
#act
time = datetime.now(utc)
- self.relations_system.add(ticket1, ticket2, "dependent", when=time)
- relations = self.relations_system.get_relations(ticket1)
+ self.add_relation(ticket1, DEPENDS_ON, ticket2, when=time)
+ relations = self.get_relations(ticket1)
#assert
self.assertEqual(time, relations[0]["when"])
@@ -277,7 +254,7 @@ class ApiTestCase(BaseRelationsTestCase)
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- self.relations_system.add(ticket1, ticket2, "dependson")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
#act
self.req.args["action"] = 'resolve'
warnings = TicketRelationsSpecifics(self.env).validate_ticket(
@@ -289,7 +266,7 @@ class ApiTestCase(BaseRelationsTestCase)
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2", status="closed")
- self.relations_system.add(ticket1, ticket2, "dependson")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
#act
self.req.args["action"] = 'resolve'
warnings = TicketRelationsSpecifics(self.env).validate_ticket(
@@ -301,13 +278,13 @@ class ApiTestCase(BaseRelationsTestCase)
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- relations_system = self.relations_system
- relations_system.add(ticket1, ticket2, "dependent")
- self.assertEqual(1, len(relations_system.get_relations(ticket2)))
+
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
+ self.assertEqual(1, len(self.get_relations(ticket2)))
#act
ticket1.delete()
#assert
- self.assertEqual(0, len(relations_system.get_relations(ticket2)))
+ self.assertEqual(0, len(self.get_relations(ticket2)))
def test_that_no_error_when_deleting_ticket_without_relations(self):
#arrange
@@ -316,19 +293,17 @@ class ApiTestCase(BaseRelationsTestCase)
ticket1.delete()
def test_can_add_multi_product_relations(self):
- #arrange
- ticket1 = self._insert_and_load_ticket("A1")
+ ticket1 = self._insert_and_load_ticket("A1")
product2 = "tp2"
self._load_product_from_data(self.global_env, product2)
p2_env = ProductEnvironment(self.global_env, product2)
ticket2 = self._insert_and_load_ticket_with_env(p2_env, "A2")
- relations_system = self.relations_system
- #act
- relations_system.add(ticket1, ticket2, "mprel")
- #assert
- self.assertEqual(1, len(relations_system.get_relations(ticket1)))
- self.assertEqual(1, len(relations_system.get_relations(ticket2)))
+
+ self.add_relation(ticket1, MULTIPRODUCT_REL, ticket2)
+
+ self.assertEqual(1, len(self.get_relations(ticket1)))
+ self.assertEqual(1, len(self.get_relations(ticket2)))
def _debug_select(self):
"""
@@ -344,38 +319,34 @@ class ApiTestCase(BaseRelationsTestCase)
def test_parent_relation_is_incompatible_with_two_way_relations(self):
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- self.relations_system.add(ticket1, ticket2, "dependent")
+ self.add_relation(ticket2, DEPENDS_ON, ticket1)
self.assertRaises(
ValidationError,
- self.relations_system.add,
- ticket1,
- ticket2,
- "parent")
+ self.add_relation,
+ ticket1, PARENT, ticket2
+ )
self.assertRaises(
ValidationError,
- self.relations_system.add,
- ticket1,
- ticket2,
- "children")
+ self.add_relation,
+ ticket1, CHILD, ticket2
+ )
def test_parent_relation_is_incompatible_with_one_way_relations(self):
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- self.relations_system.add(ticket1, ticket2, "refersto")
+ self.add_relation(ticket1, REFERS_TO, ticket2)
self.assertRaises(
ValidationError,
- self.relations_system.add,
- ticket1,
- ticket2,
- "parent")
+ self.add_relation,
+ ticket1, PARENT, ticket2
+ )
self.assertRaises(
ValidationError,
- self.relations_system.add,
- ticket1,
- ticket2,
- "children")
+ self.add_relation,
+ ticket1, CHILD, ticket2
+ )
def test_parent_must_be_in_same_product(self):
ticket1 = self._insert_and_load_ticket("A1")
@@ -386,75 +357,82 @@ class ApiTestCase(BaseRelationsTestCase)
self.assertRaises(
ValidationError,
- self.relations_system.add,
- ticket1, ticket2, "parent"
+ self.add_relation,
+ ticket1, PARENT, ticket2
)
self.assertRaises(
ValidationError,
- self.relations_system.add,
- ticket1, ticket2, "children"
+ self.add_relation,
+ ticket1, CHILD, ticket2
)
def test_cannot_create_other_relations_between_descendants(self):
t1, t2, t3, t4, t5 = map(self._insert_and_load_ticket, "12345")
- self.relations_system.add(t4, t2, "parent") # t1 -> t2
- self.relations_system.add(t3, t2, "parent") # / \
- self.relations_system.add(t2, t1, "parent") # t3 t4
+ self.add_relation(t1, PARENT, t2) # t1 -> t2
+ self.add_relation(t2, PARENT, t3) # / \
+ self.add_relation(t2, PARENT, t4) # t3 t4
self.assertRaises(
ValidationError,
- self.relations_system.add, t1, t2, "dependent"
+ self.add_relation,
+ t2, DEPENDS_ON, t1
)
self.assertRaises(
ValidationError,
- self.relations_system.add, t2, t1, "dependent"
+ self.add_relation,
+ t1, DEPENDS_ON, t2
)
self.assertRaises(
ValidationError,
- self.relations_system.add, t1, t4, "dependent"
+ self.add_relation,
+ t4, DEPENDS_ON, t1
)
self.assertRaises(
ValidationError,
- self.relations_system.add, t3, t1, "dependent"
+ self.add_relation,
+ t1, DEPENDS_ON, t3
)
try:
- self.relations_system.add(t1, t5, "dependent")
- self.relations_system.add(t3, t4, "dependent")
+ self.add_relation(t1, DEPENDS_ON, t5)
+ self.add_relation(t3, DEPENDS_ON, t4)
except ValidationError:
self.fail("Could not add valid relation.")
def test_cannot_add_parent_if_this_would_cause_invalid_relations(self):
t1, t2, t3, t4, t5 = map(self._insert_and_load_ticket, "12345")
- self.relations_system.add(t4, t2, "parent") # t1 -> t2
- self.relations_system.add(t3, t2, "parent") # / \
- self.relations_system.add(t2, t1, "parent") # t3 t4 t5
- self.relations_system.add(t2, t5, "dependent")
+ self.add_relation(t1, PARENT, t2) # t1 -> t2
+ self.add_relation(t2, PARENT, t3) # / \
+ self.add_relation(t2, PARENT, t4) # t3 t4 t5
+ self.add_relation(t2, DEPENDS_ON, t5)
self.assertRaises(
ValidationError,
- self.relations_system.add, t5, t2, "parent"
+ self.add_relation,
+ t2, PARENT, t5
)
self.assertRaises(
ValidationError,
- self.relations_system.add, t5, t3, "parent"
+ self.add_relation,
+ t3, PARENT, t5
)
self.assertRaises(
ValidationError,
- self.relations_system.add, t1, t5, "parent"
+ self.add_relation,
+ t5, PARENT, t1,
)
try:
- self.relations_system.add(t5, t1, "parent")
+ self.add_relation(t1, PARENT, t5)
except ValidationError:
self.fail("Could not add valid relation.")
def test_cannot_close_ticket_with_open_children(self):
- t1 = self._insert_and_load_ticket("1") # t1
- t2 = self._insert_and_load_ticket("2", status='closed') # / | \
- t3 = self._insert_and_load_ticket("3") # t2 t3 t4
+ t1 = self._insert_and_load_ticket("1") # t1
+ t2 = self._insert_and_load_ticket("2", status='closed') # / | \
+ t3 = self._insert_and_load_ticket("3") # t2 t3 t4
t4 = self._insert_and_load_ticket("4")
- self.relations_system.add(t2, t1, "parent")
- self.relations_system.add(t3, t1, "parent")
- self.relations_system.add(t4, t1, "parent")
+ self.add_relation(t1, PARENT, t2)
+ self.add_relation(t1, PARENT, t3)
+ self.add_relation(t1, PARENT, t4)
# A warning is be returned for each open ticket
self.req.args["action"] = 'resolve'
@@ -469,36 +447,46 @@ class ApiTestCase(BaseRelationsTestCase)
self.assertRaises(
ValidationError,
- self.relations_system.add,
- t1,
- t2,
- "duplicateof",
+ self.add_relation,
+ t1, DUPLICATE_OF, t2
)
- self.relations_system.add(t2, t1, "duplicateof")
+ self.add_relation(t2, DUPLICATE_OF, t1)
def test_detects_blocker_cycles(self):
t1, t2, t3, t4, t5 = map(self._insert_and_load_ticket, "12345")
- self.relations_system.add(t1, t2, "blocks")
- self.relations_system.add(t3, t2, "dependson")
- self.relations_system.add(t4, t3, "blockedby")
- self.relations_system.add(t4, t5, "dependent")
-
- self.assertRaises(ValidationError,
- self.relations_system.add, t2, t1, "blocks")
- self.assertRaises(ValidationError,
- self.relations_system.add, t3, t1, "dependent")
- self.assertRaises(ValidationError,
- self.relations_system.add, t1, t2, "blockedby")
- self.assertRaises(ValidationError,
- self.relations_system.add, t1, t5, "dependson")
-
- self.relations_system.add(t1, t2, "dependent")
- self.relations_system.add(t2, t3, "blocks")
- self.relations_system.add(t4, t3, "dependson")
- self.relations_system.add(t5, t4, "blockedby")
+ self.add_relation(t1, BLOCKS, t2)
+ self.add_relation(t3, DEPENDS_ON, t2)
+ self.add_relation(t4, BLOCKED_BY, t3)
+ self.add_relation(t4, DEPENDENCY_OF, t5)
- self.relations_system.add(t1, t2, "refersto")
- self.relations_system.add(t2, t1, "refersto")
+ self.assertRaises(
+ ValidationError,
+ self.add_relation,
+ t2, BLOCKS, t1
+ )
+ self.assertRaises(
+ ValidationError,
+ self.add_relation,
+ t3, DEPENDENCY_OF, t1
+ )
+ self.assertRaises(
+ ValidationError,
+ self.add_relation,
+ t1, BLOCKED_BY, t2
+ )
+ self.assertRaises(
+ ValidationError,
+ self.add_relation,
+ t1, DEPENDS_ON, t5
+ )
+
+ self.add_relation(t1, DEPENDENCY_OF, t2)
+ self.add_relation(t2, BLOCKS, t3)
+ self.add_relation(t4, DEPENDS_ON, t3)
+ self.add_relation(t5, BLOCKED_BY, t4)
+
+ self.add_relation(t1, REFERS_TO, t2)
+ self.add_relation(t2, REFERS_TO, t1)
def test_can_find_ticket_by_id_from_same_env(self):
""" Can find ticket given #id"""
@@ -542,30 +530,27 @@ class RelationChangingListenerTestCase(B
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- relations_system = self.relations_system
test_changing_listener = self.env[TestRelationChangingListener]
#act
- relations_system.add(ticket1, ticket2, "dependent")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
#assert
self.assertEqual("adding_relation", test_changing_listener.action)
relation = test_changing_listener.relation
- self.assertEqual("dependent", relation.type)
+ self.assertEqual(DEPENDS_ON, relation.type)
def test_can_sent_deleting_event(self):
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- relations_system = self.relations_system
test_changing_listener = self.env[TestRelationChangingListener]
- relations_system.add(ticket1, ticket2, "dependent")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
#act
- relations = relations_system.get_relations(ticket1)
- relation_to_delete = relations[0]
- relations_system.delete(relation_to_delete["relation_id"])
+ relations = self.get_relations(ticket1)
+ self.delete_relation(relations[0])
#assert
self.assertEqual("deleting_relation", test_changing_listener.action)
relation = test_changing_listener.relation
- self.assertEqual("dependent", relation.type)
+ self.assertEqual(DEPENDS_ON, relation.type)
class TicketChangeRecordUpdaterTestCase(BaseRelationsTestCase):
@@ -573,9 +558,8 @@ class TicketChangeRecordUpdaterTestCase(
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- relations_system = self.relations_system
#act
- relations_system.add(ticket1, ticket2, "dependent")
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
#assert
change_log1 = Ticket(self.env, ticket1.id).get_changelog()
self.assertEquals(1, len(change_log1))
@@ -587,12 +571,11 @@ class TicketChangeRecordUpdaterTestCase(
#arrange
ticket1 = self._insert_and_load_ticket("A1")
ticket2 = self._insert_and_load_ticket("A2")
- relations_system = self.relations_system
- relations_system.add(ticket1, ticket2, "dependent")
- relations = relations_system.get_relations(ticket1)
+
+ self.add_relation(ticket1, DEPENDS_ON, ticket2)
+ relations = self.get_relations(ticket1)
#act
- relation_to_delete = relations[0]
- relations_system.delete(relation_to_delete["relation_id"])
+ self.delete_relation(relations[0])
#assert
change_log1 = Ticket(self.env, ticket1.id).get_changelog()
self.assertEquals(2, len(change_log1))
@@ -620,7 +603,7 @@ class TicketChangeRecordUpdaterTestCase(
if ticket_id:
sql = """SELECT time, author, field, oldvalue, newvalue
- FROM ticket_change WHERE ticket=%s"""
+ FROM ticket_change WHERE ticket=%s"""
print "db_transaction select by ticket_id result:"
with self.env.db_transaction:
for row in self.env.db_query(sql, (ticket_id, )):
@@ -629,11 +612,9 @@ class TicketChangeRecordUpdaterTestCase(
def suite():
test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(ApiTestCase, 'test'))
- test_suite.addTest(unittest.makeSuite(
- RelationChangingListenerTestCase, 'test'))
- test_suite.addTest(unittest.makeSuite(
- TicketChangeRecordUpdaterTestCase, 'test'))
+ test_suite.addTest(unittest.makeSuite(ApiTestCase))
+ test_suite.addTest(unittest.makeSuite(RelationChangingListenerTestCase))
+ test_suite.addTest(unittest.makeSuite(TicketChangeRecordUpdaterTestCase))
return test_suite
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/base.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/base.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/base.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/base.py Fri Jun 20 00:34:19 2014
@@ -18,21 +18,35 @@
# under the License.
from tests.env import MultiproductTestCase
-from multiproduct.env import ProductEnvironment
-from bhrelations.api import RelationsSystem, EnvironmentSetup, \
- RELATIONS_CONFIG_NAME
from trac.test import EnvironmentStub, Mock, MockPerm
from trac.ticket import Ticket
from trac.util.datefmt import utc
+from multiproduct.env import ProductEnvironment
+
+from bhrelations.api import EnvironmentSetup, RelationsSystem, \
+ RELATIONS_CONFIG_NAME
+
try:
from babel import Locale
-
locale_en = Locale.parse('en_US')
except ImportError:
locale_en = None
+PARENT = "parent"
+CHILD = "child"
+REFERS_TO = "refersto"
+DEPENDS_ON = "dependson"
+DEPENDENCY_OF = "dependent"
+DUPLICATE_OF = "duplicateof"
+DUPLICATED_BY = "duplicatedby"
+BLOCKED_BY = "blockedby"
+BLOCKS = "blocks"
+MULTIPRODUCT_REL = "mprel"
+MULTIPRODUCT_BACKREL = "mpbackrel"
+
+
class BaseRelationsTestCase(MultiproductTestCase):
def setUp(self, enabled=()):
env = EnvironmentStub(
@@ -46,24 +60,28 @@ class BaseRelationsTestCase(Multiproduct
env.config.set('bhrelations', 'duplicate_relation',
'duplicateof')
config_name = RELATIONS_CONFIG_NAME
- env.config.set(config_name, 'dependency', 'dependson,dependent')
+ env.config.set(config_name, 'dependency',
+ ','.join([DEPENDS_ON, DEPENDENCY_OF]))
env.config.set(config_name, 'dependency.validators',
'NoCycles,SingleProduct')
env.config.set(config_name, 'dependson.blocks', 'true')
- env.config.set(config_name, 'parent_children', 'parent,children')
+ env.config.set(config_name, 'parent_children',
+ ','.join([PARENT, CHILD]))
env.config.set(config_name, 'parent_children.validators',
'OneToMany,SingleProduct,NoCycles')
env.config.set(config_name, 'children.label', 'Overridden')
env.config.set(config_name, 'parent.copy_fields',
'summary, foo')
env.config.set(config_name, 'parent.exclusive', 'true')
- env.config.set(config_name, 'multiproduct_relation', 'mprel,mpbackrel')
- env.config.set(config_name, 'oneway', 'refersto')
- env.config.set(config_name, 'duplicate', 'duplicateof,duplicatedby')
+ env.config.set(config_name, 'multiproduct_relation',
+ ','.join([MULTIPRODUCT_REL, MULTIPRODUCT_BACKREL]))
+ env.config.set(config_name, 'oneway', REFERS_TO)
+ env.config.set(config_name, 'duplicate',
+ ','.join([DUPLICATE_OF, DUPLICATED_BY]))
env.config.set(config_name, 'duplicate.validators', 'ReferencesOlder')
env.config.set(config_name, 'duplicateof.label', 'is a duplicate of')
env.config.set(config_name, 'duplicatedby.label', 'duplicates')
- env.config.set(config_name, 'blocker', 'blockedby,blocks')
+ env.config.set(config_name, 'blocker', ','.join([BLOCKED_BY, BLOCKS]))
env.config.set(config_name, 'blockedby.blocks', 'true')
self.global_env = env
@@ -105,3 +123,13 @@ class BaseRelationsTestCase(Multiproduct
def _insert_and_load_ticket_with_env(self, env, summary, **kw):
return Ticket(env, self._insert_ticket(env, summary, **kw))
+
+ def add_relation(self, source, reltype, destination, *args, **kwargs):
+ return self.relations_system.add(source, destination, reltype,
+ *args, **kwargs)
+
+ def get_relations(self, ticket):
+ return self.relations_system.get_relations(ticket)
+
+ def delete_relation(self, relation):
+ self.relations_system.delete(relation["relation_id"])
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/mocks.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/mocks.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/mocks.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/mocks.py Fri Jun 20 00:34:19 2014
@@ -16,9 +16,11 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-from bhrelations.api import IRelationChangingListener
+
from trac.core import Component, implements
+from bhrelations.api import IRelationChangingListener
+
class TestRelationChangingListener(Component):
implements(IRelationChangingListener)
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/notification.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/notification.py?rev=1604057&r1=1604056&r2=1604057&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/notification.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/notification.py Fri Jun 20 00:34:19 2014
@@ -16,15 +16,18 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
+
import unittest
+
from trac.tests.notification import SMTPServerStore, SMTPThreadedServer
-from trac.ticket.tests.notification import (
- SMTP_TEST_PORT, smtp_address, parse_smtp_message)
-from bhrelations.tests.base import BaseRelationsTestCase
+from trac.ticket.tests.notification import SMTP_TEST_PORT, smtp_address
+
+from bhrelations.tests.base import DEPENDENCY_OF, BaseRelationsTestCase
from bhrelations.notification import RelationNotifyEmail
class NotificationTestCase(BaseRelationsTestCase):
+
@classmethod
def setUpClass(cls):
cls.smtpd = CustomSMTPThreadedServer(SMTP_TEST_PORT)
@@ -54,7 +57,7 @@ class NotificationTestCase(BaseRelations
"""To/Cc recipients"""
ticket = self._insert_and_load_ticket(
'Foo',
- reporter= '"Joe User" < joe.user@example.org >',
+ reporter='"Joe User" < joe.user@example.org >',
owner='joe.user@example.net',
cc='joe.user@example.com, joe.bar@example.org, '
'joe.bar@example.net'
@@ -65,8 +68,7 @@ class NotificationTestCase(BaseRelations
owner='bob.user@example.net',
cc='bob.user@example.com, bob.bar@example.org, '
'bob.bar@example.net')
- relation = self.relations_system.add(
- ticket, ticket2, "dependent")
+ relation = self.add_relation(ticket, DEPENDENCY_OF, ticket2)
self.notifier.notify(relation)
@@ -93,7 +95,7 @@ class NotificationTestCase(BaseRelations
ticket = self._insert_and_load_ticket('Foo', reporter='anonymous')
ticket2 = self._insert_and_load_ticket('Bar', reporter='anonymous')
- relation = self.relations_system.add(ticket, ticket2, "dependent")
+ relation = self.add_relation(ticket, DEPENDENCY_OF, ticket2)
self.notifier.notify(relation)
sender = self.smtpd.get_sender()
@@ -108,7 +110,7 @@ class NotificationTestCase(BaseRelations
ticket = self._insert_and_load_ticket('Foo', reporter='anonymous')
ticket2 = self._insert_and_load_ticket('Bar', reporter='anonymous')
- relation = self.relations_system.add(ticket, ticket2, "dependent")
+ relation = self.add_relation(ticket, DEPENDENCY_OF, ticket2)
self.notifier.notify(relation)
relations = self.env.db_direct_query(
@@ -151,8 +153,9 @@ class CustomSMTPThreadedServer(SMTPThrea
def suite():
test_suite = unittest.TestSuite()
- test_suite.addTest(unittest.makeSuite(NotificationTestCase, 'test'))
+ test_suite.addTest(unittest.makeSuite(NotificationTestCase))
return test_suite
+
if __name__ == '__main__':
unittest.main()