You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bloodhound.apache.org by ah...@apache.org on 2013/07/28 19:22:24 UTC
svn commit: r1507818 [2/3] - in
/bloodhound/branches/bep_0007_embeddable_objects: ./ bloodhound_dashboard/
bloodhound_dashboard/bhdashboard/ bloodhound_dashboard/bhdashboard/widgets/
bloodhound_dashboard/bhdashboard/widgets/templates/ bloodhound_multip...
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/manage.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/manage.html?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/manage.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/templates/manage.html Sun Jul 28 17:22:23 2013
@@ -1,127 +1,127 @@
-<!--!
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-
-<!DOCTYPE html
- PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:xi="http://www.w3.org/2001/XInclude"
- xmlns:py="http://genshi.edgewall.org/"
- xmlns:i18n="http://genshi.edgewall.org/i18n"
- xmlns:bh="http://issues.apache.org/bloodhound/wiki/Ui/Dashboard">
- <xi:include href="layout.html" />
- <xi:include href="widget_macros.html" />
-
- <head>
- <title py:choose="">Ticket relations for #${ticket.id}</title>
- </head>
-
- <body>
- <h1>Manage relations for ticket <a href="${href.ticket(ticket.id)}">#$ticket.id</a></h1>
-
- <div class="row">
- <div class="span8">
- <py:if test='error'>
- <div class="alert alert-error">
- <span class="label label-important">Oops !</span>
- Could not create relation.
- $error
- </div>
- </py:if>
-
- <form id="addrelation" class="well form-horizontal" method="post" action="">
- <fieldset>
- <legend>Add relation:</legend>
- </fieldset>
-
- <div class="control-group">
- <label class="control-label" for="dest_tid">Related ticket:</label>
- <div class="controls">
- <input type="text" id="dest_tid" class="span4" name="dest_tid" value="$relation.destination" />
- </div>
- </div>
-
- <div class="control-group">
- <label class="control-label" for="reltype">Relation type:</label>
- <div class="controls">
- <select class="span4" id="reltype" name="reltype">
- <option py:for="reltype,label in reltypes.iteritems()" value="$reltype" selected="${True if reltype == relation.type else None}">$label</option>
- </select>
- </div>
- </div>
-
- <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>
- </div>
- </div>
-
- <div class="control-group">
- <div class="controls">
- <input type="submit" class="btn" name="add" value="${_('Add')}" />
- </div>
- </div>
- </form>
- </div>
- </div>
-
- <div class="row">
- <div class="span8">
- <py:choose>
- <form py:when="relations" id="rmrelations" class="form-horizontal" method="post" action="">
- <table class="table table-condensed table-bordered">
- <thead>
- <tr>
- <th class="sel"><i class="icon-check"></i></th>
- <th>Type</th><th>Product</th><th>Ticket</th><th>Comment</th><th>Author</th><th class="hidden-phone">Changed</th>
- </tr>
- </thead>
- <tbody py:for="relgroup,items in relations.iteritems()">
- <tr py:for="item in items">
- <td class="sel"><input type="checkbox" name="sel" value="${item.relation_id}" /></td>
- <td>${relgroup if items.index(item) == 0 else None}</td>
- <td>
- <a href="${href.products(item['destticket'].env.product.prefix)}">
- <span class="hidden-phone">${item['destticket'].env.product.name} (${item['destticket'].env.product.prefix})</span>
- <span class="visible-phone">${item['destticket'].env.product.prefix}</span>
- </a>
- </td>
- <td><a href="${item['desthref']}">#${item['destticket'].id}</a> - ${item['destticket'].summary}</td>
- <td>$item.comment</td>
- <td>$item.author</td>
- <td class="hidden-phone">${pretty_dateinfo(item.when)}</td>
- </tr>
- </tbody>
- </table>
-
- <div class="control-group">
- <input type="submit" class="btn" name="remove" value="${_('Remove selected relations')}" />
- </div>
- </form>
-
- <div py:otherwise="" class="alert alert-info">
- No defined relations for this ticket.
- </div>
- </py:choose>
- </div>
- </div>
- </body>
-</html>
-
+<!--!
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"
+ xmlns:py="http://genshi.edgewall.org/"
+ xmlns:i18n="http://genshi.edgewall.org/i18n"
+ xmlns:bh="http://issues.apache.org/bloodhound/wiki/Ui/Dashboard">
+ <xi:include href="layout.html" />
+ <xi:include href="widget_macros.html" />
+
+ <head>
+ <title py:choose="">Ticket relations for #${ticket.id}</title>
+ </head>
+
+ <body>
+ <h1>Manage relations for ticket <a href="${href.ticket(ticket.id)}">#$ticket.id</a></h1>
+
+ <div class="row">
+ <div class="span8">
+ <py:if test='error'>
+ <div class="alert alert-error">
+ <span class="label label-important">Oops !</span>
+ Could not create relation.
+ $error
+ </div>
+ </py:if>
+
+ <form id="addrelation" class="well form-horizontal" method="post" action="">
+ <fieldset>
+ <legend>Add relation:</legend>
+ </fieldset>
+
+ <div class="control-group">
+ <label class="control-label" for="dest_tid">Related ticket:</label>
+ <div class="controls">
+ <input type="text" id="dest_tid" class="span4" name="dest_tid" value="$relation.destination" />
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label class="control-label" for="reltype">Relation type:</label>
+ <div class="controls">
+ <select class="span4" id="reltype" name="reltype">
+ <option py:for="reltype,label in reltypes.iteritems()" value="$reltype" selected="${True if reltype == relation.type else None}">$label</option>
+ </select>
+ </div>
+ </div>
+
+ <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>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <div class="controls">
+ <input type="submit" class="btn" name="add" value="${_('Add')}" />
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="span8">
+ <py:choose>
+ <form py:when="relations" id="rmrelations" class="form-horizontal" method="post" action="">
+ <table class="table table-condensed table-bordered">
+ <thead>
+ <tr>
+ <th class="sel"><i class="icon-check"></i></th>
+ <th>Type</th><th>Product</th><th>Ticket</th><th>Comment</th><th>Author</th><th class="hidden-phone">Changed</th>
+ </tr>
+ </thead>
+ <tbody py:for="relgroup,items in relations.iteritems()">
+ <tr py:for="item in items">
+ <td class="sel"><input type="checkbox" name="sel" value="${item.relation_id}" /></td>
+ <td>${relgroup if items.index(item) == 0 else None}</td>
+ <td>
+ <a href="${href.products(item['destticket'].env.product.prefix)}">
+ <span class="hidden-phone">${item['destticket'].env.product.name} (${item['destticket'].env.product.prefix})</span>
+ <span class="visible-phone">${item['destticket'].env.product.prefix}</span>
+ </a>
+ </td>
+ <td><a href="${item['desthref']}">#${item['destticket'].id}</a> - ${item['destticket'].summary}</td>
+ <td>$item.comment</td>
+ <td>$item.author</td>
+ <td class="hidden-phone">${pretty_dateinfo(item.when)}</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div class="control-group">
+ <input type="submit" class="btn" name="remove" value="${_('Remove selected relations')}" />
+ </div>
+ </form>
+
+ <div py:otherwise="" class="alert alert-info">
+ No defined relations for this ticket.
+ </div>
+ </py:choose>
+ </div>
+ </div>
+ </body>
+</html>
+
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=1507818&r1=1507817&r2=1507818&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 Sun Jul 28 17:22:23 2013
@@ -18,99 +18,19 @@
# specific language governing permissions and limitations
# under the License.
from datetime import datetime
-from _sqlite3 import OperationalError, IntegrityError
+from _sqlite3 import IntegrityError
import unittest
-from bhrelations.api import (EnvironmentSetup, RelationsSystem,
- TicketRelationsSpecifics)
+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 tests.env import MultiproductTestCase
from trac.ticket.model import Ticket
-from trac.test import EnvironmentStub, Mock, MockPerm
from trac.core import TracError
from trac.util.datefmt import utc
-try:
- from babel import Locale
- locale_en = Locale.parse('en_US')
-except ImportError:
- locale_en = None
-
-
-class BaseApiApiTestCase(MultiproductTestCase):
- def setUp(self, enabled=()):
- env = EnvironmentStub(
- default_data=True,
- enable=(['trac.*', 'multiproduct.*', 'bhrelations.*'] +
- list(enabled))
- )
- env.config.set('bhrelations', 'global_validators',
- 'NoSelfReferenceValidator,ExclusiveValidator,'
- 'BlockerValidator')
- config_name = RelationsSystem.RELATIONS_CONFIG_NAME
- env.config.set(config_name, 'dependency', 'dependson,dependent')
- 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.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, 'duplicate.validators', 'ReferencesOlder')
- env.config.set(config_name, 'duplicateof.label', 'Duplicate of')
- env.config.set(config_name, 'duplicatedby.label', 'Duplicated by')
- env.config.set(config_name, 'blocker', 'blockedby,blocks')
- env.config.set(config_name, 'blockedby.blocks', 'true')
-
- self.global_env = env
- self._upgrade_mp(self.global_env)
- self._setup_test_log(self.global_env)
- self._load_product_from_data(self.global_env, self.default_product)
- self.env = ProductEnvironment(self.global_env, self.default_product)
-
- self.req = Mock(href=self.env.href, authname='anonymous', tz=utc,
- args=dict(action='dummy'),
- locale=locale_en, lc_time=locale_en)
- self.req.perm = MockPerm()
- self.relations_system = RelationsSystem(self.env)
- self._upgrade_env()
-
- def tearDown(self):
- self.global_env.reset_db()
-
- def _upgrade_env(self):
- environment_setup = EnvironmentSetup(self.env)
- try:
- environment_setup.upgrade_environment(self.env.db_transaction)
- except OperationalError:
- # table remains but database version is deleted
- pass
-
- @classmethod
- def _insert_ticket(cls, env, summary, **kw):
- """Helper for inserting a ticket into the database"""
- ticket = Ticket(env)
- ticket["Summary"] = summary
- for k, v in kw.items():
- ticket[k] = v
- return ticket.insert()
-
- def _insert_and_load_ticket(self, summary, **kw):
- return Ticket(self.env, self._insert_ticket(self.env, summary, **kw))
-
- def _insert_and_load_ticket_with_env(self, env, summary, **kw):
- return Ticket(env, self._insert_ticket(env, summary, **kw))
-
-
-class ApiTestCase(BaseApiApiTestCase):
+class ApiTestCase(BaseRelationsTestCase):
def test_can_add_two_ways_relations(self):
#arrange
ticket = self._insert_and_load_ticket("A1")
@@ -475,7 +395,7 @@ class ApiTestCase(BaseApiApiTestCase):
)
def test_cannot_create_other_relations_between_descendants(self):
- t1, t2, t3, t4, t5 = map(self._insert_and_load_ticket, range(5))
+ 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
@@ -503,7 +423,7 @@ class ApiTestCase(BaseApiApiTestCase):
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, range(5))
+ 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
@@ -553,7 +473,7 @@ class ApiTestCase(BaseApiApiTestCase):
self.relations_system.add(t2, t1, "duplicateof")
def test_detects_blocker_cycles(self):
- t1, t2, t3, t4, t5 = map(self._insert_and_load_ticket, range(5))
+ 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")
@@ -577,7 +497,7 @@ class ApiTestCase(BaseApiApiTestCase):
self.relations_system.add(t2, t1, "refersto")
-class RelationChangingListenerTestCase(BaseApiApiTestCase):
+class RelationChangingListenerTestCase(BaseRelationsTestCase):
def test_can_sent_adding_event(self):
#arrange
ticket1 = self._insert_and_load_ticket("A1")
@@ -608,7 +528,7 @@ class RelationChangingListenerTestCase(B
self.assertEqual("dependent", relation.type)
-class TicketChangeRecordUpdaterTestCase(BaseApiApiTestCase):
+class TicketChangeRecordUpdaterTestCase(BaseRelationsTestCase):
def test_can_update_ticket_history_on_relation_add_on(self):
#arrange
ticket1 = self._insert_and_load_ticket("A1")
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=1507818&r1=1507817&r2=1507818&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 Sun Jul 28 17:22:23 2013
@@ -21,11 +21,11 @@ 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 bhrelations.notification import RelationNotifyEmail
-from bhrelations.tests.api import BaseApiApiTestCase
-class NotificationTestCase(BaseApiApiTestCase):
+class NotificationTestCase(BaseRelationsTestCase):
@classmethod
def setUpClass(cls):
cls.smtpd = CustomSMTPThreadedServer(SMTP_TEST_PORT)
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/search.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/search.py Sun Jul 28 17:22:23 2013
@@ -21,25 +21,25 @@ import shutil
import tempfile
import unittest
-from bhrelations.tests.api import BaseApiApiTestCase
from bhsearch.api import BloodhoundSearchApi
# TODO: Figure how to get trac to load components from these modules
import bhsearch.query_parser, bhsearch.search_resources.ticket_search, \
bhsearch.whoosh_backend
import bhrelations.search
+from bhrelations.tests.base import BaseRelationsTestCase
-class SearchIntegrationTestCase(BaseApiApiTestCase):
+class SearchIntegrationTestCase(BaseRelationsTestCase):
def setUp(self):
- BaseApiApiTestCase.setUp(self, enabled=['bhsearch.*'])
+ BaseRelationsTestCase.setUp(self, enabled=['bhsearch.*'])
self.global_env.path = tempfile.mkdtemp('bhrelations-tempenv')
self.search_api = BloodhoundSearchApi(self.env)
self.search_api.upgrade_environment(self.env.db_transaction)
def tearDown(self):
shutil.rmtree(self.env.path)
- BaseApiApiTestCase.tearDown(self)
+ BaseRelationsTestCase.tearDown(self)
def test_relations_are_indexed_on_creation(self):
t1 = self._insert_and_load_ticket("Foo")
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/validation.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/validation.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/validation.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/validation.py Sun Jul 28 17:22:23 2013
@@ -20,10 +20,10 @@
import unittest
from bhrelations.validation import Validator
-from bhrelations.tests.api import BaseApiApiTestCase
+from bhrelations.tests.base import BaseRelationsTestCase
-class GraphFunctionsTestCase(BaseApiApiTestCase):
+class GraphFunctionsTestCase(BaseRelationsTestCase):
edges = [
('A', 'B', 'p'), # A H
('A', 'C', 'p'), # / \ /
@@ -35,7 +35,7 @@ class GraphFunctionsTestCase(BaseApiApiT
]
def setUp(self):
- BaseApiApiTestCase.setUp(self)
+ BaseRelationsTestCase.setUp(self)
# bhrelations point from destination to source
for destination, source, type in self.edges:
self.env.db_direct_transaction(
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/web_ui.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/web_ui.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/tests/web_ui.py Sun Jul 28 17:22:23 2013
@@ -18,27 +18,31 @@
# specific language governing permissions and limitations
# under the License.
import unittest
-
+from bhrelations.api import ResourceIdSerializer
from bhrelations.web_ui import RelationManagementModule
-from bhrelations.tests.api import BaseApiApiTestCase
+from bhrelations.tests.base import BaseRelationsTestCase
+
+from multiproduct.ticket.web_ui import TicketModule
+from trac.ticket import Ticket
+from trac.util.datefmt import to_utimestamp
+from trac.web import RequestDone
-class RelationManagementModuleTestCase(BaseApiApiTestCase):
+class RelationManagementModuleTestCase(BaseRelationsTestCase):
def setUp(self):
- BaseApiApiTestCase.setUp(self)
+ BaseRelationsTestCase.setUp(self)
ticket_id = self._insert_ticket(self.env, "Foo")
- args=dict(action='add', id=ticket_id, dest_tid='', reltype='', comment='')
- self.req.method = 'GET',
+ self.req.method = 'POST'
self.req.args['id'] = ticket_id
def test_can_process_empty_request(self):
+ self.req.method = 'GET'
data = self.process_request()
self.assertSequenceEqual(data['relations'], [])
self.assertEqual(len(data['reltypes']), 11)
def test_handles_missing_ticket_id(self):
- self.req.method = "POST"
self.req.args['add'] = 'add'
data = self.process_request()
@@ -46,8 +50,7 @@ class RelationManagementModuleTestCase(B
self.assertIn("Invalid ticket", data["error"])
def test_handles_invalid_ticket_id(self):
- self.req.method = "POST"
- self.req.args['add'] = 'add'
+ self.req.args['add'] = True
self.req.args['dest_tid'] = 'no such ticket'
data = self.process_request()
@@ -56,8 +59,7 @@ class RelationManagementModuleTestCase(B
def test_handles_missing_relation_type(self):
t2 = self._insert_ticket(self.env, "Bar")
- self.req.method = "POST"
- self.req.args['add'] = 'add'
+ self.req.args['add'] = True
self.req.args['dest_tid'] = str(t2)
data = self.process_request()
@@ -66,8 +68,7 @@ class RelationManagementModuleTestCase(B
def test_handles_invalid_relation_type(self):
t2 = self._insert_ticket(self.env, "Bar")
- self.req.method = "POST"
- self.req.args['add'] = 'add'
+ self.req.args['add'] = True
self.req.args['dest_tid'] = str(t2)
self.req.args['reltype'] = 'no such relation'
@@ -77,8 +78,7 @@ class RelationManagementModuleTestCase(B
def test_shows_relation_that_was_just_added(self):
t2 = self._insert_ticket(self.env, "Bar")
- self.req.method = "POST"
- self.req.args['add'] = 'add'
+ self.req.args['add'] = True
self.req.args['dest_tid'] = str(t2)
self.req.args['reltype'] = 'dependson'
@@ -92,6 +92,117 @@ class RelationManagementModuleTestCase(B
return data
+class ResolveTicketIntegrationTestCase(BaseRelationsTestCase):
+ def setUp(self):
+ BaseRelationsTestCase.setUp(self)
+
+ self.mock_request()
+ self.configure()
+
+ self.req.redirect = self.redirect
+ self.redirect_url = None
+ self.redirect_permanent = None
+
+ def test_creates_duplicate_relation_from_duplicate_id(self):
+ t1 = self._insert_and_load_ticket("Foo")
+ t2 = self._insert_and_load_ticket("Bar")
+
+ self.assertRaises(RequestDone,
+ self.resolve_as_duplicate,
+ t2, self.get_id(t1))
+ relations = self.relations_system.get_relations(t2)
+ self.assertEqual(len(relations), 1)
+ relation = relations[0]
+ self.assertEqual(relation['destination_id'], self.get_id(t1))
+ self.assertEqual(relation['type'], 'duplicateof')
+
+ def test_prefills_duplicate_id_if_relation_exists(self):
+ t1 = self._insert_and_load_ticket("Foo")
+ t2 = self._insert_and_load_ticket("Bar")
+ self.relations_system.add(t2, t1, 'duplicateof')
+ self.req.path_info = '/ticket/%d' % t2.id
+
+ data = self.process_request()
+
+ self.assertIn('ticket_duplicate_of', data)
+ t1id = ResourceIdSerializer.get_resource_id_from_instance(self.env, t1)
+ self.assertEqual(data['ticket_duplicate_of'], t1id)
+
+ def test_can_set_duplicate_resolution_even_if_relation_exists(self):
+ t1 = self._insert_and_load_ticket("Foo")
+ t2 = self._insert_and_load_ticket("Bar")
+ self.relations_system.add(t2, t1, 'duplicateof')
+
+ self.assertRaises(RequestDone,
+ self.resolve_as_duplicate,
+ t2, self.get_id(t1))
+ t2 = Ticket(self.env, t2.id)
+ self.assertEqual(t2['status'], 'closed')
+ self.assertEqual(t2['resolution'], 'duplicate')
+
+ def test_post_process_request_does_not_break_ticket(self):
+ t1 = self._insert_and_load_ticket("Foo")
+ self.req.path_info = '/ticket/%d' % t1.id
+ self.process_request()
+
+ def test_post_process_request_does_not_break_newticket(self):
+ self.req.path_info = '/newticket'
+ self.process_request()
+
+ def test_post_process_request_can_handle_none_data(self):
+ self.req.path_info = '/source'
+ RelationManagementModule(self.env).post_process_request(
+ self.req, '', None, '')
+
+ def resolve_as_duplicate(self, ticket, duplicate_id):
+ self.req.method = 'POST'
+ self.req.path_info = '/ticket/%d' % ticket.id
+ self.req.args['id'] = ticket.id
+ self.req.args['action'] = 'resolve'
+ self.req.args['action_resolve_resolve_resolution'] = 'duplicate'
+ self.req.args['duplicate_id'] = duplicate_id
+ self.req.args['view_time'] = str(to_utimestamp(ticket['changetime']))
+ self.req.args['submit'] = True
+
+ return self.process_request()
+
+ def process_request(self):
+ ticket_module = TicketModule(self.env)
+
+ ticket_module.match_request(self.req)
+ template, data, content_type = ticket_module.process_request(self.req)
+ template, data, content_type = \
+ RelationManagementModule(self.env).post_process_request(
+ self.req, template, data, content_type)
+ return data
+
+ def mock_request(self):
+ self.req.method = 'GET'
+ self.req.get_header = lambda x: None
+ self.req.authname = 'x'
+ self.req.session = {}
+ self.req.chrome = {'warnings': []}
+ self.req.form_token = ''
+
+ def configure(self):
+ config = self.env.config
+ config['ticket-workflow'].set('resolve', 'new -> closed')
+ config['ticket-workflow'].set('resolve.operations', 'set_resolution')
+ config['ticket-workflow'].set('resolve.permissions', 'TICKET_MODIFY')
+ with self.env.db_transaction as db:
+ db("INSERT INTO enum VALUES "
+ "('resolution', 'duplicate', 'duplicate')")
+
+ def redirect(self, url, permanent=False):
+ self.redirect_url = url
+ self.redirect_permanent = permanent
+ raise RequestDone
+
+ def get_id(self, ticket):
+ return ResourceIdSerializer.get_resource_id_from_instance(self.env,
+ ticket)
+
+
def suite():
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(RelationManagementModuleTestCase, 'test'))
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/web_ui.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/web_ui.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/web_ui.py Sun Jul 28 17:22:23 2013
@@ -1,183 +1,172 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-r"""Ticket relations for Apache(TM) Bloodhound
-
-Ticket relations user interface.
-"""
-
-import re
-import pkg_resources
-
-from trac.core import Component, implements, TracError
-from trac.resource import get_resource_url, ResourceNotFound, Resource
-from trac.ticket.model import Ticket
-from trac.util.translation import _
-from trac.web import IRequestHandler
-from trac.web.chrome import ITemplateProvider, add_warning
-
-from bhrelations.api import RelationsSystem, ResourceIdSerializer, \
- TicketRelationsSpecifics, UnknownRelationType
-from bhrelations.model import Relation
-from bhrelations.validation import ValidationError
-
-from multiproduct.model import Product
-from multiproduct.env import ProductEnvironment
-
-class RelationManagementModule(Component):
- implements(IRequestHandler, ITemplateProvider)
-
- # IRequestHandler methods
- def match_request(self, req):
- match = re.match(r'/ticket/([0-9]+)/relations/*$', req.path_info)
- if not match:
- return False
-
- req.args['id'] = match.group(1)
- return True
-
- def process_request(self, req):
- tid = req.args.get('id')
- if not tid:
- raise TracError(_('No ticket id provided.'))
-
- try:
- ticket = Ticket(self.env, tid)
- except ValueError:
- raise TracError(_('Invalid ticket id.'))
-
- req.perm.require('TICKET_VIEW')
- relsys = RelationsSystem(self.env)
-
- data = {
- 'relation': {},
- }
- if req.method == 'POST':
- # for modifying the relations TICKET_MODIFY is required for
- # both the source and the destination tickets
- req.perm.require('TICKET_MODIFY')
-
- if 'remove' in req.args:
- rellist = req.args.get('sel')
- if rellist:
- if isinstance(rellist, basestring):
- rellist = [rellist, ]
- self.remove_relations(req, rellist)
- elif 'add' in req.args:
- relation = dict(
- destination=req.args.get('dest_tid', ''),
- type=req.args.get('reltype', ''),
- comment=req.args.get('comment', ''),
- )
- try:
- dest_ticket = self.find_ticket(relation['destination'])
- req.perm.require('TICKET_MODIFY',
- Resource(dest_ticket.id))
- relsys.add(ticket, dest_ticket,
- relation['type'],
- relation['comment'],
- req.authname)
- except NoSuchTicketError:
- data['error'] = _('Invalid ticket id.')
- except UnknownRelationType:
- data['error'] = _('Unknown relation type.')
- except ValidationError as ex:
- data['error'] = ex.message
- if 'error' in data:
- data['relation'] = relation
-
- else:
- raise TracError(_('Invalid operation.'))
-
- data.update({
- 'ticket': ticket,
- 'reltypes': relsys.get_relation_types(),
- 'relations': self.get_ticket_relations(ticket),
- })
- return 'manage.html', data, None
-
- # ITemplateProvider methods
- def get_htdocs_dirs(self):
- resource_filename = pkg_resources.resource_filename
- return [('relations', resource_filename('bhrelations', 'htdocs')), ]
-
- def get_templates_dirs(self):
- resource_filename = pkg_resources.resource_filename
- return [resource_filename('bhrelations', 'templates'), ]
-
- # utility functions
- def get_ticket_relations(self, ticket):
- grouped_relations = {}
- relsys = RelationsSystem(self.env)
- reltypes = relsys.get_relation_types()
- trs = TicketRelationsSpecifics(self.env)
- for r in relsys.get_relations(ticket):
- r['desthref'] = get_resource_url(self.env, r['destination'],
- self.env.href)
- r['destticket'] = trs._create_ticket_by_full_id(r['destination'])
- grouped_relations.setdefault(reltypes[r['type']], []).append(r)
- return grouped_relations
-
- def find_ticket(self, ticket_spec):
- ticket = None
- m = re.match(r'#?(?P<tid>\d+)', ticket_spec)
- if m:
- tid = m.group('tid')
- try:
- ticket = Ticket(self.env, tid)
- except ResourceNotFound:
- # ticket not found in current product, try all other products
- 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)
- try:
- ticket = Ticket(penv, tid)
- except ResourceNotFound:
- pass
- else:
- break
-
- # ticket still not found, use fallback for <prefix>:ticket:<id> syntax
- if ticket is None:
- trs = TicketRelationsSpecifics(self.env)
- try:
- resource = ResourceIdSerializer.get_resource_by_id(tid)
- ticket = trs._create_ticket_by_full_id(resource)
- except:
- raise NoSuchTicketError
- return ticket
-
- def remove_relations(self, req, rellist):
- relsys = RelationsSystem(self.env)
- for relid in rellist:
- relation = Relation.load_by_relation_id(self.env, relid)
- resource = ResourceIdSerializer.get_resource_by_id(
- relation.destination)
- if 'TICKET_MODIFY' in req.perm(resource):
- relsys.delete(relid)
- else:
- add_warning(req,
- _('Not enough permissions to remove relation "%s"' % relid))
-
-
-class NoSuchTicketError(ValueError):
- pass
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+r"""Ticket relations for Apache(TM) Bloodhound
+
+Ticket relations user interface.
+"""
+
+import re
+
+from trac.core import Component, implements, TracError
+from trac.resource import get_resource_url, Resource
+from trac.ticket.model import Ticket
+from trac.util.translation import _
+from trac.web import IRequestHandler, IRequestFilter
+from trac.web.chrome import ITemplateProvider, add_warning
+
+from bhrelations.api import RelationsSystem, ResourceIdSerializer, \
+ TicketRelationsSpecifics, UnknownRelationType, NoSuchTicketError
+from bhrelations.model import Relation
+from bhrelations.validation import ValidationError
+
+
+class RelationManagementModule(Component):
+ implements(IRequestFilter, IRequestHandler, ITemplateProvider)
+
+ # IRequestHandler methods
+ def match_request(self, req):
+ match = re.match(r'/ticket/([0-9]+)/relations/*$', req.path_info)
+ if not match:
+ return False
+
+ req.args['id'] = match.group(1)
+ return True
+
+ def process_request(self, req):
+ tid = req.args.get('id')
+ if not tid:
+ raise TracError(_('No ticket id provided.'))
+
+ try:
+ ticket = Ticket(self.env, tid)
+ except ValueError:
+ raise TracError(_('Invalid ticket id.'))
+
+ req.perm.require('TICKET_VIEW')
+ relsys = RelationsSystem(self.env)
+
+ data = {
+ 'relation': {},
+ }
+ if req.method == 'POST':
+ # for modifying the relations TICKET_MODIFY is required for
+ # both the source and the destination tickets
+ req.perm.require('TICKET_MODIFY')
+
+ if 'remove' in req.args:
+ rellist = req.args.get('sel')
+ if rellist:
+ if isinstance(rellist, basestring):
+ rellist = [rellist, ]
+ self.remove_relations(req, rellist)
+ elif 'add' in req.args:
+ relation = dict(
+ destination=req.args.get('dest_tid', ''),
+ type=req.args.get('reltype', ''),
+ comment=req.args.get('comment', ''),
+ )
+ try:
+ trs = TicketRelationsSpecifics(self.env)
+ dest_ticket = trs.find_ticket(relation['destination'])
+ except NoSuchTicketError:
+ data['error'] = _('Invalid ticket ID.')
+ else:
+ req.perm.require('TICKET_MODIFY', Resource(dest_ticket.id))
+
+ try:
+ relsys.add(ticket, dest_ticket,
+ relation['type'],
+ relation['comment'],
+ req.authname)
+ except NoSuchTicketError:
+ data['error'] = _('Invalid ticket ID.')
+ except UnknownRelationType:
+ data['error'] = _('Unknown relation type.')
+ except ValidationError as ex:
+ data['error'] = ex.message
+
+ if 'error' in data:
+ data['relation'] = relation
+ else:
+ raise TracError(_('Invalid operation.'))
+
+ data.update({
+ 'ticket': ticket,
+ 'reltypes': relsys.get_relation_types(),
+ 'relations': self.get_ticket_relations(ticket),
+ })
+ return 'manage.html', data, None
+
+ # ITemplateProvider methods
+ def get_htdocs_dirs(self):
+ return []
+
+ def get_templates_dirs(self):
+ from pkg_resources import resource_filename
+ return [resource_filename('bhrelations', 'templates')]
+
+ # IRequestFilter methods
+ def pre_process_request(self, req, handler):
+ return handler
+
+ def post_process_request(self, req, template, data, content_type):
+ if req.path_info.startswith('/ticket/'):
+ ticket = data['ticket']
+ rls = RelationsSystem(self.env)
+ try:
+ resid = ResourceIdSerializer.get_resource_id_from_instance(
+ self.env, ticket)
+ except ValueError:
+ resid = None
+
+ if rls.duplicate_relation_type and resid is not None:
+ duplicate_relations = \
+ rls._select_relations(resid, rls.duplicate_relation_type)
+ if duplicate_relations:
+ data['ticket_duplicate_of'] = \
+ duplicate_relations[0].destination
+ return template, data, content_type
+
+ # utility functions
+ def get_ticket_relations(self, ticket):
+ grouped_relations = {}
+ relsys = RelationsSystem(self.env)
+ reltypes = relsys.get_relation_types()
+ trs = TicketRelationsSpecifics(self.env)
+ for r in relsys.get_relations(ticket):
+ r['desthref'] = get_resource_url(self.env, r['destination'],
+ self.env.href)
+ r['destticket'] = trs._create_ticket_by_full_id(r['destination'])
+ grouped_relations.setdefault(reltypes[r['type']], []).append(r)
+ return grouped_relations
+
+ def remove_relations(self, req, rellist):
+ relsys = RelationsSystem(self.env)
+ for relid in rellist:
+ relation = Relation.load_by_relation_id(self.env, relid)
+ resource = ResourceIdSerializer.get_resource_by_id(
+ relation.destination)
+ if 'TICKET_MODIFY' in req.perm(resource):
+ relsys.delete(relid)
+ else:
+ add_warning(req,
+ _('Not enough permissions to remove relation "%s"' % relid))
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/relations.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/relations.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/relations.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/relations.py Sun Jul 28 17:22:23 2013
@@ -1,75 +1,75 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-
-r"""Project dashboard for Apache(TM) Bloodhound
-
-Widgets displaying ticket relations.
-"""
-
-from trac.util.translation import _
-from trac.ticket.model import Ticket
-
-from bhdashboard.util import WidgetBase, check_widget_name, pretty_wrapper
-from bhrelations.web_ui import RelationManagementModule
-
-__metaclass__ = type
-
-
-class TicketRelationsWidget(WidgetBase):
- """Display ticket relations.
- """
- def get_widget_params(self, name):
- """Return a dictionary containing arguments specification for
- the widget with specified name.
- """
- return {
- 'tid' : {
- 'desc' : """Source ticket id""",
- 'type' : int
- },
-
- 'max' : {
- 'desc' : """Limit the number of relations displayed""",
- 'type' : int
- },
- }
-
- get_widget_params = pretty_wrapper(get_widget_params, check_widget_name)
-
- def render_widget(self, name, context, options):
- """Gather list of relations and render data in compact view
- """
- req = context.req
- title = _('Related tickets')
- params = ('tid', 'max')
- tid, max_ = self.bind_params(name, options, *params)
-
- ticket = Ticket(self.env, tid)
- data = {
- 'ticket': ticket,
- 'relations': \
- RelationManagementModule(self.env).get_ticket_relations(ticket),
- }
- return 'widget_relations.html', \
- { 'title': title, 'data': data, }, context
-
- render_widget = pretty_wrapper(render_widget, check_widget_name)
-
+#!/usr/bin/env python
+# -*- coding: UTF-8 -*-
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+r"""Project dashboard for Apache(TM) Bloodhound
+
+Widgets displaying ticket relations.
+"""
+
+from trac.util.translation import _
+from trac.ticket.model import Ticket
+
+from bhdashboard.util import WidgetBase, check_widget_name, pretty_wrapper
+from bhrelations.web_ui import RelationManagementModule
+
+__metaclass__ = type
+
+
+class TicketRelationsWidget(WidgetBase):
+ """Display ticket relations.
+ """
+ def get_widget_params(self, name):
+ """Return a dictionary containing arguments specification for
+ the widget with specified name.
+ """
+ return {
+ 'tid' : {
+ 'desc' : """Source ticket id""",
+ 'type' : int
+ },
+
+ 'max' : {
+ 'desc' : """Limit the number of relations displayed""",
+ 'type' : int
+ },
+ }
+
+ get_widget_params = pretty_wrapper(get_widget_params, check_widget_name)
+
+ def render_widget(self, name, context, options):
+ """Gather list of relations and render data in compact view
+ """
+ req = context.req
+ title = _('Related tickets')
+ params = ('tid', 'max')
+ tid, max_ = self.bind_params(name, options, *params)
+
+ ticket = Ticket(self.env, tid)
+ data = {
+ 'ticket': ticket,
+ 'relations': \
+ RelationManagementModule(self.env).get_ticket_relations(ticket),
+ }
+ return 'widget_relations.html', \
+ {'title': title, 'data': data, }, context
+
+ render_widget = pretty_wrapper(render_widget, check_widget_name)
+
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.py Sun Jul 28 17:22:23 2013
@@ -17,7 +17,8 @@
# specific language governing permissions and limitations
# under the License.
-
+import sys
+from pkg_resources import parse_version
try:
from setuptools import setup
except ImportError:
@@ -32,6 +33,7 @@ versions = [
(0, 4, 0),
(0, 5, 0),
(0, 6, 0),
+ (0, 7, 0),
]
latest = '.'.join(str(x) for x in versions[-1])
@@ -71,13 +73,6 @@ cats = [
"Topic :: Software Development :: User Interfaces",
]
-# Be compatible with older versions of Python
-from sys import version
-if version < '2.2.3':
- from distutils.dist import DistributionMetadata
- DistributionMetadata.classifiers = None
- DistributionMetadata.download_url = None
-
# Add the change log to the package description.
chglog = None
try:
@@ -97,6 +92,8 @@ PKG_INFO = {'bhrelations': ('bhrelations
'htdocs/img/*.*', 'htdocs/js/*.js',
'templates/*', 'default-pages/*'],
),
+ 'bhrelations.widgets': (
+ 'bhrelations/widgets', ['templates/*.html']),
'bhrelations.tests': (
'bhrelations/tests', ['data/*.*']),
}
@@ -116,7 +113,7 @@ setup(
description=DESC.split('\n', 1)[0],
author = "Apache Bloodhound",
license = "Apache License v2",
- url = "http://incubator.apache.org/bloodhound/",
+ url = "https://bloodhound.apache.org/",
requires = ['trac'],
install_requires = [
'setuptools>=0.6b1',
@@ -132,6 +129,7 @@ setup(
entry_points = ENTRY_POINTS,
classifiers = cats,
long_description= DESC,
- test_suite='bhrelations.tests.test_suite'
+ test_suite='bhrelations.tests.test_suite',
+ tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else '']
)
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/__init__.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/__init__.py Sun Jul 28 17:22:23 2013
@@ -17,10 +17,10 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import sys
-if sys.version_info[:2] < (2, 7):
+
+try:
import unittest2 as unittest
-else:
+except ImportError:
import unittest
from bhsearch.tests import (whoosh_backend, index_with_whoosh, web_ui,
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/api.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/api.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/api.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/api.py Sun Jul 28 17:22:23 2013
@@ -17,13 +17,13 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import unittest
import shutil
from bhsearch.api import BloodhoundSearchApi, ASC, SortInstruction
from bhsearch.query_parser import DefaultQueryParser
-from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.search_resources.ticket_search import TicketSearchParticipant
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.whoosh_backend import WhooshBackend
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/base.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/base.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/base.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/base.py Sun Jul 28 17:22:23 2013
@@ -23,29 +23,26 @@ Test utils methods
"""
import contextlib
import shutil
-import sys
import tempfile
-if sys.version_info[:2] < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
-
-from bhsearch.web_ui import BloodhoundSearchModule
-from trac.ticket import Ticket, Milestone
from trac.test import EnvironmentStub, Mock, MockPerm
+from trac.ticket import Ticket, Milestone
from trac.web import Href, arg_list_to_args
from trac.wiki import WikiPage
+from bhsearch.tests import unittest
+from bhsearch.web_ui import BloodhoundSearchModule
+
BASE_PATH = "/main/"
+
class BaseBloodhoundSearchTest(unittest.TestCase):
def setUp(self, enabled=None, create_req=False, enable_security=False):
if not enabled:
enabled = ['trac.*', 'bhsearch.*']
if not enable_security:
- disabled = ['bhsearch.security.SecurityPreprocessor']
+ disabled = ['bhsearch.security.*']
else:
disabled = []
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/index_with_whoosh.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/index_with_whoosh.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/index_with_whoosh.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/index_with_whoosh.py Sun Jul 28 17:22:23 2013
@@ -18,14 +18,16 @@
# specific language governing permissions and limitations
# under the License.
-import unittest
import shutil
+
from bhsearch.api import BloodhoundSearchApi
from bhsearch.search_resources.milestone_search import MilestoneIndexer
-from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.search_resources.ticket_search import TicketIndexer
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.whoosh_backend import WhooshBackend
+
class IndexWhooshTestCase(BaseBloodhoundSearchTest):
def setUp(self):
super(IndexWhooshTestCase, self).setUp()
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_parser.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_parser.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_parser.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_parser.py Sun Jul 28 17:22:23 2013
@@ -18,10 +18,11 @@
# specific language governing permissions and limitations
# under the License.
-import unittest
-from bhsearch.tests.base import BaseBloodhoundSearchTest
-from bhsearch.query_parser import DefaultQueryParser
from trac.test import Mock
+
+from bhsearch.query_parser import DefaultQueryParser
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
from whoosh import query
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_suggestion.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_suggestion.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_suggestion.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/query_suggestion.py Sun Jul 28 17:22:23 2013
@@ -18,11 +18,10 @@
# specific language governing permissions and limitations
# under the License.
-import unittest
-from bhsearch.tests.base import BaseBloodhoundSearchTest
-
from bhsearch.api import BloodhoundSearchApi
from bhsearch.query_suggestion import SuggestionFields
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.web_ui import RequestParameters, RequestContext
from bhsearch.whoosh_backend import WhooshBackend
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/real_index_view.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/real_index_view.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/real_index_view.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/real_index_view.py Sun Jul 28 17:22:23 2013
@@ -17,16 +17,18 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import unittest
-from bhsearch.web_ui import RequestParameters
+
import os
-from bhsearch.tests.base import BaseBloodhoundSearchTest
-from bhsearch.whoosh_backend import WhooshBackend
from trac.test import EnvironmentStub, Mock, MockPerm
-from whoosh import query
from trac.web import Href, arg_list_to_args
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
+from bhsearch.web_ui import RequestParameters
+from bhsearch.whoosh_backend import WhooshBackend
+from whoosh import query
+
class RealIndexTestCase(BaseBloodhoundSearchTest):
"""
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/base.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/base.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/base.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/base.py Sun Jul 28 17:22:23 2013
@@ -18,17 +18,14 @@
# specific language governing permissions and limitations
# under the License.
-import sys
-if sys.version_info[:2] < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
+from trac.test import MockPerm
+from trac.web import Href
+from trac.wiki import format_to_html
from bhsearch.search_resources.base import SimpleSearchWikiSyntaxFormatter
+from bhsearch.tests import unittest
from bhsearch.tests.base import BaseBloodhoundSearchTest
-from trac.web import Href
-from trac.test import MockPerm
-from trac.wiki import format_to_html
+
class SimpleSearchWikiSyntaxFormatterTestCase(BaseBloodhoundSearchTest):
def setUp(self):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/changeset_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/changeset_search.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/changeset_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/changeset_search.py Sun Jul 28 17:22:23 2013
@@ -17,17 +17,18 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import unittest
+
+from trac.core import Component, implements
+from trac.versioncontrol import Changeset
+from trac.versioncontrol.api import (
+ IRepositoryConnector, Repository, RepositoryManager)
from bhsearch.api import BloodhoundSearchApi
from bhsearch.search_resources.changeset_search import (
ChangesetSearchParticipant)
+from bhsearch.tests import unittest
from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.whoosh_backend import WhooshBackend
-from trac.core import Component, implements
-from trac.versioncontrol.api import (IRepositoryConnector, RepositoryManager,
- Repository)
-from trac.versioncontrol import Changeset
class ChangesetIndexerEventsTestCase(BaseBloodhoundSearchTest):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/milestone_search.py Sun Jul 28 17:22:23 2013
@@ -17,16 +17,16 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import unittest
+
+from trac.ticket import Milestone
from bhsearch.api import BloodhoundSearchApi
from bhsearch.search_resources.milestone_search import (
MilestoneSearchParticipant)
+from bhsearch.tests import unittest
from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.whoosh_backend import WhooshBackend
-from trac.ticket import Milestone
-
class MilestoneIndexerEventsTestCase(BaseBloodhoundSearchTest):
DUMMY_MILESTONE_NAME = "dummyName"
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/ticket_search.py Sun Jul 28 17:22:23 2013
@@ -17,13 +17,15 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import unittest
+
+from trac.ticket.model import Component
+
from bhsearch.api import BloodhoundSearchApi
+from bhsearch.search_resources.ticket_search import TicketIndexer
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.whoosh_backend import WhooshBackend
-from bhsearch.tests.base import BaseBloodhoundSearchTest
-from bhsearch.search_resources.ticket_search import TicketIndexer
-from trac.ticket.model import Component
class TicketIndexerTestCase(BaseBloodhoundSearchTest):
def setUp(self):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/wiki_search.py Sun Jul 28 17:22:23 2013
@@ -18,16 +18,16 @@
# specific language governing permissions and limitations
# under the License.
import shutil
-import unittest
+
+from trac.wiki import WikiSystem, WikiPage
from bhsearch.api import BloodhoundSearchApi
from bhsearch.query_parser import DefaultQueryParser
-from bhsearch.tests.base import BaseBloodhoundSearchTest
-from bhsearch.whoosh_backend import WhooshBackend
from bhsearch.search_resources.wiki_search import (
WikiIndexer, WikiSearchParticipant)
-
-from trac.wiki import WikiSystem, WikiPage
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
+from bhsearch.whoosh_backend import WhooshBackend
class WikiIndexerSilenceOnExceptionTestCase(BaseBloodhoundSearchTest):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/security.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/security.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/security.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/security.py Sun Jul 28 17:22:23 2013
@@ -24,17 +24,16 @@ system backend.
"""
import contextlib
import os
-import unittest
from sqlite3 import OperationalError
-from trac.perm import (PermissionSystem, DefaultPermissionPolicy,
- PermissionCache)
+from trac.perm import (DefaultPermissionPolicy, PermissionCache,
+ PermissionSystem)
-from multiproduct.api import MultiProductSystem, ProductEnvironment
-
-from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.api import BloodhoundSearchApi
+from bhsearch.tests import unittest
+from bhsearch.tests.base import BaseBloodhoundSearchTest
from bhsearch.whoosh_backend import WhooshBackend
+from multiproduct.api import MultiProductSystem, ProductEnvironment
# TODO: Convince trac to register modules without these imports
from trac.wiki import web_ui
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/web_ui.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/web_ui.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/web_ui.py Sun Jul 28 17:22:23 2013
@@ -17,31 +17,28 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-import sys
-if sys.version_info[:2] < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
from urllib import urlencode, unquote, unquote_plus
+from trac.core import TracError
+from trac.search.web_ui import SearchModule as TracSearchModule
+from trac.test import Mock, MockPerm
+from trac.util import format_datetime
+from trac.util.datefmt import FixedOffset
+from trac.web import Href, RequestDone, arg_list_to_args, parse_arg_list
+
from bhsearch import web_ui
from bhsearch.api import ASC, DESC, SortInstruction
+from bhsearch.tests import unittest
from bhsearch.tests.base import BaseBloodhoundSearchTest
-from bhsearch.web_ui import RequestParameters, BloodhoundSearchModule
+from bhsearch.web_ui import BloodhoundSearchModule, RequestParameters
from bhsearch.whoosh_backend import WhooshBackend
-from trac.test import Mock, MockPerm
-from trac.core import TracError
-from trac.search.web_ui import SearchModule as TracSearchModule
-from trac.util.datefmt import FixedOffset
-from trac.util import format_datetime
-from trac.web import Href, arg_list_to_args, parse_arg_list, RequestDone
-
BASE_PATH = "/main/"
BHSEARCH_URL = BASE_PATH + "bhsearch"
DEFAULT_DOCS_PER_PAGE = 10
+
class WebUiTestCaseWithWhoosh(BaseBloodhoundSearchTest):
def setUp(self):
super(WebUiTestCaseWithWhoosh, self).setUp(
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/whoosh_backend.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/whoosh_backend.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/whoosh_backend.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/whoosh_backend.py Sun Jul 28 17:22:23 2013
@@ -20,23 +20,20 @@
from datetime import datetime
import os
import shutil
-import sys
import tempfile
-if sys.version_info[:2] < (2, 7):
- import unittest2 as unittest
-else:
- import unittest
+
+from trac.util.datefmt import FixedOffset, utc
from bhsearch.api import ASC, DESC, SCORE, SortInstruction
from bhsearch.query_parser import DefaultQueryParser
+from bhsearch.tests import unittest
from bhsearch.tests.base import BaseBloodhoundSearchTest
-from bhsearch.whoosh_backend import (WhooshBackend,
- WhooshEmptyFacetErrorWorkaround)
-from trac.util.datefmt import FixedOffset, utc
-from whoosh import index, sorting, query
-from whoosh.fields import Schema, ID, TEXT, KEYWORD
-from whoosh.qparser import MultifieldPlugin, QueryParser, WhitespacePlugin, \
- PhrasePlugin, MultifieldParser
+from bhsearch.whoosh_backend import WhooshBackend, \
+ WhooshEmptyFacetErrorWorkaround
+from whoosh import index, query, sorting
+from whoosh.fields import ID, KEYWORD, TEXT, Schema
+from whoosh.qparser import MultifieldParser, MultifieldPlugin, PhrasePlugin, \
+ QueryParser, WhitespacePlugin
class WhooshBackendTestCase(BaseBloodhoundSearchTest):
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/setup.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/setup.py?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/setup.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/setup.py Sun Jul 28 17:22:23 2013
@@ -18,6 +18,8 @@
# under the License.
+import sys
+from pkg_resources import parse_version
try:
from setuptools import setup
except ImportError:
@@ -32,6 +34,7 @@ versions = [
(0, 4, 0),
(0, 5, 0),
(0, 6, 0),
+ (0, 7, 0),
]
latest = '.'.join(str(x) for x in versions[-1])
@@ -71,13 +74,6 @@ cats = [
"Topic :: Software Development :: User Interfaces",
]
-# Be compatible with older versions of Python
-from sys import version
-if version < '2.2.3':
- from distutils.dist import DistributionMetadata
- DistributionMetadata.classifiers = None
- DistributionMetadata.download_url = None
-
# Add the change log to the package description.
chglog = None
try:
@@ -145,7 +141,7 @@ setup(
description=DESC.split('\n', 1)[0],
author = "Apache Bloodhound",
license = "Apache License v2",
- url = "http://incubator.apache.org/bloodhound/",
+ url = "https://bloodhound.apache.org/",
requires = ['trac'],
install_requires = [
'setuptools>=0.6b1',
@@ -163,5 +159,6 @@ setup(
classifiers = cats,
long_description= DESC,
test_suite='bhsearch.tests.test_suite',
+ tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else '']
)
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/bloodhound.css
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/bloodhound.css?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/bloodhound.css (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/bloodhound.css Sun Jul 28 17:22:23 2013
@@ -174,6 +174,11 @@ div.reports form {
text-align: right;
}
+#duplicate_id {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
#trac-ticket-title {
margin-bottom: 5px;
}
@@ -465,6 +470,12 @@ h1, h2, h3, h4 {
padding: 0.8em 0px;
}
+#edit, #text {
+ min-height: 10em;
+ padding: 0px;
+ resize: vertical;
+}
+
/* @end */
/* @group Search */
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/js/theme.js
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/js/theme.js?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/js/theme.js (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/htdocs/js/theme.js Sun Jul 28 17:22:23 2013
@@ -123,17 +123,17 @@ $( function () {
);
$('#qct-create').click(
function() {
- var base_url = $('#qct-create').attr('data-target');
- if (base_url === '/')
- base_url = '';
- $.post(base_url + '/qct', $('#qct-form').serialize(),
- function(ticket_id) {
- var href = base_url + '/ticket/' + ticket_id;
+ // data-target is the base url for the product in current scope
+ var product_base_url = $('#qct-create').attr('data-target');
+ if (product_base_url === '/')
+ product_base_url = '';
+ $.post(product_base_url + '/qct', $('#qct-form').serialize(),
+ function(ticket) {
qct_alert({
- ticket: ticket_id,
+ ticket: ticket.id,
msg: '<span class="alert alert-success">' +
'Has been created</span> ' +
- '<a href="' + href + '">View / Edit</a>'
+ '<a href="' + ticket.url + '">View / Edit</a>'
});
})
.error(function(jqXHR, textStatus, errorMsg) {
@@ -155,30 +155,29 @@ $( function () {
);
$('#qct-inline-create').click(function() {
- var base_url = $('#qct-inline-create').attr('data-target');
- if (base_url === '/')
- base_url = '';
-
- $.post(base_url + '/qct', $('#qct-inline-form').serialize(),
- function(ticket_id) {
- var href = base_url + '/ticket/' + ticket_id;
- var msg = 'Ticket #' + ticket_id + ' has been created. ';
- msg += '<a href="' + href + '">View / Edit</a>';
- $('#qct-inline-notice-success span').html(msg);
- $('#qct-inline-notice-success').show({'duration': 400});
- })
- .error(function(jqXHR, textStatus, errorMsg) {
- var msg;
- if (textStatus === 'timeout')
- msg = 'Request timed out';
- else if (textStatus === 'error')
- msg = 'Could not create ticket. Error : ' + errorMsg;
- else if (textStatus === 'abort')
- msg = 'Aborted request';
-
- $('#qct-inline-notice-error span').html(msg);
- $('#qct-inline-notice-error').show({'duration': 400});
- });
+ // data-target is the base url for the product in current scope
+ var product_base_url = $('#qct-inline-create').attr('data-target');
+ if (product_base_url === '/')
+ product_base_url = '';
+ $.post(product_base_url + '/qct', $('#qct-inline-form').serialize(),
+ function(ticket) {
+ var msg = 'Ticket #' + ticket.id + ' has been created. ';
+ msg += '<a href="' + ticket.url + '">View / Edit</a>';
+ $('#qct-inline-notice-success span').html(msg);
+ $('#qct-inline-notice-success').show({'duration': 400});
+ })
+ .error(function(jqXHR, textStatus, errorMsg) {
+ var msg;
+ if (textStatus === 'timeout')
+ msg = 'Request timed out';
+ else if (textStatus === 'error')
+ msg = 'Could not create ticket. Error : ' + errorMsg;
+ else if (textStatus === 'abort')
+ msg = 'Aborted request';
+
+ $('#qct-inline-notice-error span').html(msg);
+ $('#qct-inline-notice-error').show({'duration': 400});
+ });
qct_clearui();
qct_inline_close();
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_about.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_about.html?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_about.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_about.html Sun Jul 28 17:22:23 2013
@@ -39,7 +39,7 @@
<body>
<div id="content" class="about">
- <a href="http://incubator.apache.org/bloodhound/"
+ <a href="https://bloodhound.apache.org/"
style="border: none; float: right; margin-left: 2em">
<img style="display: block" src="${href.chrome('theme/img/bh_logo.png')}"
alt="${chrome.labels.application_full}: Integrated SCM & Project Management"/>
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_account_details.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_account_details.html?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_account_details.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_account_details.html Sun Jul 28 17:22:23 2013
@@ -29,6 +29,7 @@
<?python
if _dgettext:
dgettext = _dgettext ?>
+
<head>
<title>Account Details</title>
</head>
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_products.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_products.html?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_products.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_products.html Sun Jul 28 17:22:23 2013
@@ -142,8 +142,8 @@
</td>
<td class="owner">$prod.owner</td>
<td class="default">
- <input type="radio" name="default" value="$prod.name"
- checked="${prod.name==default or None}" />
+ <input type="radio" name="default" value="$prod.prefix"
+ checked="${prod.prefix==default or None}" />
</td>
</tr>
</tbody>
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_users.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_users.html?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_users.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_admin_users.html Sun Jul 28 17:22:23 2013
@@ -31,6 +31,11 @@
dgettext = _dgettext ?>
<head>
<title>Accounts</title>
+ <script type="text/javascript">
+ jQuery(document).ready(function($) {
+ $("#username").focus();
+ });
+ </script>
</head>
<body>
@@ -137,49 +142,21 @@
py:with="msglabel = 'Warning';
msgbody = _('This password store does not support listing users.')"/>
</div>
- <form py:otherwise="" method="post" py:strip="not delete_enabled">
- <div>
- <table id="accountlist"
- class="listing table table-striped table-condensed table-bordered" >
- <thead>
- <tr>
- <th py:if="delete_enabled" class="sel">
- <i class="icon-check"></i>
- </th>
- <th>Account</th><th>Name</th><th>Email</th><th>Last Login</th>
- </tr>
- </thead>
- <tbody>
- <tr py:for="acct in accounts">
- <td py:if="delete_enabled">
- <input type="checkbox" name="sel" value="${acct.username}" />
- </td>
- <td>
- <a href="${acct.review_url}">$acct.username</a>
- <!--! Additional account status icons -->
- <py:choose py:if="acct.locked">
- <img py:when="acct.release_hint" alt="Account locked"
- src="${href.chrome('/acct_mgr/time-locked.png')}"
- title="${acct.release_hint}" />
- <img py:otherwise="" alt="Permanently locked"
- src="${href.chrome('/acct_mgr/locked.png')}"
- title="${dgettext('acct_mgr', 'Permanently locked')}" />
- </py:choose>
- </td>
- <td>$acct.name</td>
- <td>$acct.email</td>
- <td>$acct.last_visit</td>
- </tr>
- </tbody>
- </table>
- </div>
- <div class="buttons">
- <input type="submit" name="reset" class="btn"
+ <form method="post" py:otherwise="" py:strip="not delete_enabled">
+ <div class="system-message"
+ py:if="deletion_error"><p>${deletion_error}</p></div>
+ <xi:include href="bh_user_table.html"/>
+ <div class="buttons control-group">
+ <input type="submit" class="btn" name="reset"
py:if="password_reset_enabled"
+ title="Send another random password"
value="${dgettext('acct_mgr', 'Reset passwords')}" />
- <input type="submit" name="remove" class="btn"
+ <input type="submit" class="btn" name="remove"
py:if="delete_enabled"
value="${dgettext('acct_mgr', 'Remove selected accounts')}" />
+ <input type="submit" class="btn" name="cleanup"
+ py:if="req.perm.has_permission('ACCTMGR_ADMIN')"
+ value="${dgettext('acct_mgr', 'Review account attributes')}" />
</div>
</form>
</py:choose>
Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_browser.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_browser.html?rev=1507818&r1=1507817&r2=1507818&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_browser.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_theme/bhtheme/templates/bh_browser.html Sun Jul 28 17:22:23 2013
@@ -255,9 +255,12 @@
</form>
</div>
- <div id="help" i18n:msg="" class="help-block pull-right">
- <span class="label label-info">Note</span> See <a href="${href.wiki('TracBrowser')}">TracBrowser</a>
- for help on using the repository browser.
+ <div id="help" class="span12" i18n:msg="">
+ <p class="help-block pull-right">
+ <span class="label label-info">Note</span> See
+ <a href="${href.wiki('TracBrowser')}">TracBrowser</a>
+ for help on using the repository browser.
+ </p>
</div>
</div>