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/02/27 03:14:38 UTC

svn commit: r1572404 [6/8] - in /bloodhound/branches/bep_0007_embeddable_objects: ./ bloodhound_dashboard/ bloodhound_dashboard/bhdashboard/ bloodhound_dashboard/bhdashboard/default-pages/ bloodhound_dashboard/bhdashboard/layouts/ bloodhound_dashboard/...

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -18,7 +17,6 @@
 #  specific language governing permissions and limitations
 #  under the License.
 from datetime import datetime
-from _sqlite3 import IntegrityError
 import unittest
 from bhrelations.api import TicketRelationsSpecifics
 from bhrelations.tests.mocks import TestRelationChangingListener
@@ -98,7 +96,10 @@ class ApiTestCase(BaseRelationsTestCase)
         with self.env.db_transaction as db:
             db(sql, ["1", "2", "dependson"])
             self.assertRaises(
-                IntegrityError, db, sql, ["1", "2", "dependson"])
+                self.env.db_exc.IntegrityError,
+                db,
+                sql,
+                ["1", "2", "dependson"])
 
     def test_can_add_one_way_relations(self):
         #arrange
@@ -447,17 +448,20 @@ class ApiTestCase(BaseRelationsTestCase)
             self.fail("Could not add valid relation.")
 
     def test_cannot_close_ticket_with_open_children(self):
-        t1 = self._insert_and_load_ticket("1", status='closed')
-        t2 = self._insert_and_load_ticket("2", status='closed')
-        t3 = self._insert_and_load_ticket("3")
+        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")
 
+        # A warning is be returned for each open ticket
         self.req.args["action"] = 'resolve'
-        warnings = TicketRelationsSpecifics(self.env).validate_ticket(
-            self.req, t1)
-        #assert
-        self.assertEqual(1, len(list(warnings)))
+        warnings = \
+            TicketRelationsSpecifics(self.env).validate_ticket(self.req, t1)
+
+        self.assertEqual(2, len(list(warnings)))
 
     def test_duplicate_can_only_reference_older_ticket(self):
         t1 = self._insert_and_load_ticket("1")
@@ -496,6 +500,42 @@ class ApiTestCase(BaseRelationsTestCase)
         self.relations_system.add(t1, t2, "refersto")
         self.relations_system.add(t2, t1, "refersto")
 
+    def test_can_find_ticket_by_id_from_same_env(self):
+        """ Can find ticket given #id"""
+        product2 = "tp2"
+        self._load_product_from_data(self.global_env, product2)
+        p2_env = ProductEnvironment(self.global_env, product2)
+        t1 = self._insert_and_load_ticket_with_env(p2_env, "T1")
+        trs = TicketRelationsSpecifics(p2_env)
+
+        ticket = trs.find_ticket("#%d" % t1.id)
+
+        self.assertEqual(ticket.id, 1)
+
+    def test_can_find_ticket_by_id_from_different_env(self):
+        """ Can find ticket from different env given #id"""
+        product2 = "tp2"
+        self._load_product_from_data(self.global_env, product2)
+        p2_env = ProductEnvironment(self.global_env, product2)
+        t1 = self._insert_and_load_ticket_with_env(p2_env, "T1")
+        trs = TicketRelationsSpecifics(self.env)
+
+        ticket = trs.find_ticket("#%d" % t1.id)
+
+        self.assertEqual(ticket.id, 1)
+
+    def test_can_find_ticket_by_product_and_id(self):
+        """ Can find ticket given #prefix-id"""
+        product2 = "tp2"
+        self._load_product_from_data(self.global_env, product2)
+        p2_env = ProductEnvironment(self.global_env, product2)
+        t1 = self._insert_and_load_ticket_with_env(p2_env, "T1")
+        trs = TicketRelationsSpecifics(self.env)
+
+        ticket = trs.find_ticket("#%s-%d" % (product2, t1.id))
+
+        self.assertEqual(ticket.id, 1)
+
 
 class RelationChangingListenerTestCase(BaseRelationsTestCase):
     def test_can_sent_adding_event(self):

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,3 +1,5 @@
+# -*- 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
@@ -15,7 +17,6 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-from _sqlite3 import OperationalError
 from tests.env import MultiproductTestCase
 from multiproduct.env import ProductEnvironment
 from bhrelations.api import RelationsSystem, EnvironmentSetup, \
@@ -86,7 +87,7 @@ class BaseRelationsTestCase(Multiproduct
         environment_setup = EnvironmentSetup(self.env)
         try:
             environment_setup.upgrade_environment(self.env.db_transaction)
-        except OperationalError:
+        except self.env.db_exc.OperationalError:
             # table remains but database version is deleted
             pass
 

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/validation.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/validation.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/validation.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/validation.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -27,10 +26,10 @@ Ticket relations user interface.
 import re
 
 from trac.core import Component, implements, TracError
-from trac.resource import get_resource_url, Resource
+from trac.resource import get_resource_url, Resource, \
+                          get_resource_shortname, get_resource_summary
 from trac.ticket.model import Ticket
 from trac.util import exception_to_unicode, to_unicode
-from trac.util.translation import _
 from trac.web import IRequestHandler, IRequestFilter
 from trac.web.chrome import ITemplateProvider, add_warning
 
@@ -38,6 +37,7 @@ from bhrelations.api import RelationsSys
     TicketRelationsSpecifics, UnknownRelationType, NoSuchTicketError
 from bhrelations.model import Relation
 from bhrelations.validation import ValidationError
+from bhrelations.utils.translation import _
 
 
 class RelationManagementModule(Component):
@@ -104,18 +104,18 @@ class RelationManagementModule(Component
                         data['error'] = _('Unknown relation type.')
                     except ValidationError as ex:
                         data['error'] = ex.message
-
-                # Notify
-                try:
-                    self.notify_relation_changed(dbrel)
-                except Exception, e:
-                    self.log.error("Failure sending notification on"
-                                   "creation of relation: %s",
-                                   exception_to_unicode(e))
-                    add_warning(req, _("The relation has been added, but an "
-                                       "error occurred while sending"
-                                       "notifications: " "%(message)s",
-                                       message=to_unicode(e)))
+                    else:
+                        # Notify
+                        try:
+                            self.notify_relation_changed(dbrel)
+                        except Exception, e:
+                            self.log.error("Failure sending notification on"
+                                           "creation of relation: %s",
+                                           exception_to_unicode(e))
+                            add_warning(req, _("The relation has been added, but an "
+                                               "error occurred while sending"
+                                               "notifications: " "%(message)s",
+                                               message=to_unicode(e)))
 
                 if 'error' in data:
                     data['relation'] = relation
@@ -127,6 +127,8 @@ class RelationManagementModule(Component
             'reltypes': sorted(relsys.get_relation_types().iteritems(),
                 key=lambda x: x[0]),
             'relations': self.get_ticket_relations(ticket),
+            'get_resource_shortname': get_resource_shortname,
+            'get_resource_summary': get_resource_summary,
         })
         return 'relations_manage.html', data, None
 

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/__init__.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/bhrelations/widgets/__init__.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -24,11 +23,13 @@ r"""Project dashboard for Apache(TM) Blo
 Widgets displaying ticket relations.
 """
 
-from trac.util.translation import _
+from trac.resource import get_resource_shortname, get_resource_summary
 from trac.ticket.model import Ticket
 
-from bhdashboard.util import WidgetBase, check_widget_name, pretty_wrapper
+from bhdashboard.util import pretty_wrapper
+from bhdashboard.util.widgets import WidgetBase, check_widget_name
 from bhrelations.web_ui import RelationManagementModule
+from bhrelations.utils.translation import _
 
 __metaclass__ = type
 
@@ -67,9 +68,10 @@ class TicketRelationsWidget(WidgetBase):
             'ticket': ticket,
             'relations': \
                 RelationManagementModule(self.env).get_ticket_relations(ticket),
+            'get_resource_shortname': get_resource_shortname,
+            'get_resource_summary': get_resource_summary,
         }
         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.cfg
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.cfg?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.cfg (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.cfg Thu Feb 27 02:14:33 2014
@@ -23,3 +23,24 @@ tag_svn_revision = true
 [sdist]
 formats = gztar,bztar,ztar,tar,zip
 
+[extract_messages]
+add_comments = TRANSLATOR:
+copyright_holder = Apache Software Foundation
+msgid_bugs_address = dev@bloodhound.apache.org
+output_file = bhrelations/locale/messages.pot
+keywords = _ ngettext:1,2 N_ tag_ tagn_:1,2 Option:4 BoolOption:4 IntOption:4 ListOption:6 OrderedExtensionsOption:6 PathOption:4
+no-wrap = true
+
+[init_catalog]
+input_file = bhrelations/locale/messages.pot
+output_dir = bhrelations/locale
+domain = bhrelations
+
+[compile_catalog]
+directory = bhrelations/locale
+domain = bhrelations
+
+[update_catalog]
+input_file = bhrelations/locale/messages.pot
+output_dir = bhrelations/locale
+domain = bhrelations

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=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_relations/setup.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,5 @@
 #!/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
@@ -91,12 +92,15 @@ PKG_INFO = {'bhrelations': ('bhrelations
                               '../NOTICE', '../README', '../TESTING_README',
                               'htdocs/*.*', 'htdocs/css/*.css',
                               'htdocs/img/*.*', 'htdocs/js/*.js',
-                              'templates/*', 'default-pages/*'],
+                              'templates/*', 'default-pages/*',
+                              'locale/*/LC_MESSAGES/*.mo'],
                           ),
             'bhrelations.widgets': (
                 'bhrelations/widgets', ['templates/*.html']),
             'bhrelations.tests': (
                 'bhrelations/tests', ['data/*.*']),
+            'bhrelations.utils': (
+                'bhrelations/utils', []),
             }
 
 ENTRY_POINTS = {
@@ -108,6 +112,26 @@ ENTRY_POINTS = {
         'bhrelations.widgets.ticketrelations = bhrelations.widgets.relations',
     ],
 }
+
+extra = {}
+try:
+    from trac.util.dist import get_l10n_js_cmdclass
+    cmdclass = get_l10n_js_cmdclass()
+    if cmdclass:
+        extra['cmdclass'] = cmdclass
+        extractors = [
+            ('**.py',                'trac.dist:extract_python', None),
+            ('**/templates/**.html', 'genshi', None),
+            ('**/templates/**.txt',  'genshi', {
+                'template_class': 'genshi.template:TextTemplate'
+            }),
+        ]
+        extra['message_extractors'] = {
+            'bhrelations': extractors,
+        }
+except ImportError:
+    pass
+
 setup(
     name=DIST_NM,
     version=latest,
@@ -131,6 +155,6 @@ setup(
     classifiers = cats,
     long_description= DESC,
     test_suite='bhrelations.tests.test_suite',
-    tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else '']
+    tests_require=['unittest2' if parse_version(sys.version) < parse_version('2.7') else ''],
+    **extra
     )
-

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/__init__.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/__init__.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/admin.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/admin.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/admin.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/admin.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -36,4 +35,3 @@ class BloodhoundSearchAdmin(Component):
         yield ('bhsearch optimize', '',
             'Optimize Bloodhound search index',
             None, BloodhoundSearchApi(self.env).optimize)
-

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/api.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/api.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/api.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/api.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -25,6 +24,7 @@ from trac.core import (Interface, Compon
 from trac.env import IEnvironmentSetupParticipant
 from multiproduct.api import ISupportMultiProductEnvironment
 from multiproduct.core import MultiProductExtensionPoint
+from bhsearch.utils.translation import _, add_domain
 
 ASC = "asc"
 DESC = "desc"
@@ -238,19 +238,25 @@ class BloodhoundSearchApi(Component):
     """
     implements(IEnvironmentSetupParticipant, ISupportMultiProductEnvironment)
 
+    def __init__(self, *args, **kwargs):
+        import pkg_resources
+        locale_dir = pkg_resources.resource_filename(__name__, 'locale')
+        add_domain(self.env.path, locale_dir)
+        super(BloodhoundSearchApi, self).__init__(*args, **kwargs)
+
     backend = ExtensionOption('bhsearch', 'search_backend',
         ISearchBackend, 'WhooshBackend',
         'Name of the component implementing Bloodhound Search backend \
-        interface: ISearchBackend.')
+        interface: ISearchBackend.', doc_domain='bhsearch')
 
     parser = ExtensionOption('bhsearch', 'query_parser',
         IQueryParser, 'DefaultQueryParser',
         'Name of the component implementing Bloodhound Search query \
-        parser.')
+        parser.', doc_domain='bhsearch')
 
     index_pre_processors = OrderedExtensionsOption(
         'bhsearch', 'index_preprocessors', IDocIndexPreprocessor,
-        ['SecurityPreprocessor'],
+        ['SecurityPreprocessor'], include_missing=True,
     )
     result_post_processors = ExtensionPoint(IResultPostprocessor)
     query_processors = ExtensionPoint(IQueryPreprocessor)

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_parser.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_parser.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_parser.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_parser.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_suggestion.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_suggestion.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_suggestion.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/query_suggestion.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/__init__.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/__init__.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/base.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/base.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/base.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/base.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -30,12 +29,13 @@ class BaseIndexer(Component):
     This is base class for Bloodhound Search indexers of specific resource
     """
     silence_on_error = BoolOption('bhsearch', 'silence_on_error', "True",
-        """If true, do not throw an exception during indexing a resource""")
+        """If true, do not throw an exception during indexing a resource""",
+                                  doc_domain='bhsearch')
 
     wiki_formatter = ExtensionOption('bhsearch', 'wiki_syntax_formatter',
         ISearchWikiSyntaxFormatter, 'SimpleSearchWikiSyntaxFormatter',
         'Name of the component implementing wiki syntax to text formatter \
-        interface: ISearchWikiSyntaxFormatter.')
+        interface: ISearchWikiSyntaxFormatter.', doc_domain='bhsearch')
 
 
 class BaseSearchParticipant(Component):
@@ -84,5 +84,3 @@ class SimpleSearchWikiSyntaxFormatter(Co
         intermediate = self.REPLACE_CHARS.sub(" ", intermediate)
         result = self.WHITE_SPACE_RE.sub(" ", intermediate)
         return result.strip()
-
-

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/changeset_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/changeset_search.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/changeset_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/changeset_search.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -114,19 +113,21 @@ class ChangesetSearchParticipant(BaseSea
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default=",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/milestone_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/milestone_search.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/milestone_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/milestone_search.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -148,19 +147,21 @@ class MilestoneSearchParticipant(BaseSea
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default=",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/ticket_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/ticket_search.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/ticket_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/ticket_search.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -214,19 +213,21 @@ class TicketSearchParticipant(BaseSearch
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default = ",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):
@@ -250,4 +251,3 @@ class TicketSearchParticipant(BaseSearch
         id = tag.span('#', id, class_=css_class)
         summary = res['hilited_summary'] or res['summary']
         return tag('[', res['product'], '] ', id, ': ', summary, ' (%s)' % stat)
-

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/wiki_search.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/wiki_search.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/wiki_search.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/search_resources/wiki_search.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -140,19 +139,21 @@ class WikiSearchParticipant(BaseSearchPa
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join(default_facets),
-        doc="""Default facets applied to search view of specific resource""")
+        doc="""Default facets applied to search view of specific resource""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc = """If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     default_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default = ",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     #ISearchParticipant members
     def get_title(self):

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/security.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/security.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/security.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/security.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -54,8 +53,8 @@ class SecurityPreprocessor(Component):
 
     def update_security_filter(self, query_parameters, allowed=(), denied=()):
         security_filter = self.create_security_filter(query_parameters)
-        security_filter.allowed.extend(allowed)
-        security_filter.denied.extend(denied)
+        security_filter.add_allowed(allowed)
+        security_filter.add_denied(denied)
 
     def create_security_filter(self, query_parameters):
         security_filter = self.find_security_filter(query_parameters['filter'])
@@ -214,32 +213,22 @@ class AuthzSecurityPreprocessor(Security
 
 
 class SecurityFilter(query.AndNot):
-    def __init__(self, allowed=(), denied=()):
-        self.allowed = list(allowed)
-        self.denied = list(denied)
-        super(SecurityFilter, self).__init__(self.allowed, self.denied)
-
-    _subqueries = ()
-    @property
-    def subqueries(self):
-        self.finalize()
-        return self._subqueries
-
-    @subqueries.setter
-    def subqueries(self, value):
-        pass
-
-    def finalize(self):
-        self._subqueries = []
-        if self.allowed:
-            self.a = query.Or(self.allowed)
-        else:
-            self.a = query.NullQuery
-        if self.denied:
-            self.b = query.Or(self.denied)
-        else:
-            self.b = query.NullQuery
-        self._subqueries = (self.a, self.b)
+    def __init__(self):
+        super(SecurityFilter, self).__init__(query.NullQuery, query.NullQuery)
+
+    def add_allowed(self, allowed):
+        if self.a == query.NullQuery:
+            self.a = query.Or([])
+
+        self.a.subqueries.extend(allowed)
+        self.subqueries = (self.a, self.b)
+
+    def add_denied(self, denied):
+        if self.b == query.NullQuery:
+            self.b = query.Or([])
+
+        self.b.subqueries.extend(denied)
+        self.subqueries = (self.a, self.b)
 
     def __repr__(self):
         r = "%s(allow=%r, deny=%r)" % (self.__class__.__name__,

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch.html?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch.html Thu Feb 27 02:14:33 2014
@@ -1,7 +1,4 @@
-<!DOCTYPE html
-    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<!--
+<!--!
   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
@@ -20,9 +17,14 @@
   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:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhsearch"
       xmlns:xi="http://www.w3.org/2001/XInclude">
   <xi:include href="layout.html" />
 
@@ -198,4 +200,4 @@
 
     </div>
   </body>
-</html>
\ No newline at end of file
+</html>

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/templates/bhsearch_breadcrumbs.html Thu Feb 27 02:14:33 2014
@@ -1,7 +1,4 @@
-<!DOCTYPE html
-        PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<!--
+<!--!
   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
@@ -19,9 +16,14 @@
   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:py="http://genshi.edgewall.org/"
       xmlns:i18n="http://genshi.edgewall.org/i18n"
+      i18n:domain="bhsearch"
       xmlns:xi="http://www.w3.org/2001/XInclude">
 <a py:if="active_product or active_filter_queries or query" href="${href.bhsearch()}">Search</a>
 <py:if test='active_product'>

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -23,27 +22,22 @@ try:
 except ImportError:
     import unittest
 
-from bhsearch.tests import (whoosh_backend, index_with_whoosh, web_ui,
-                            api, query_parser, query_suggestion, security)
-from bhsearch.tests.search_resources import (ticket_search, wiki_search,
-                                             milestone_search, base,
-                                             changeset_search)
+from bhsearch.tests import (
+    api, index_with_whoosh, query_parser, query_suggestion,
+    search_resources, security, web_ui, whoosh_backend
+)
 
 
 def suite():
     test_suite = unittest.TestSuite()
-    test_suite.addTest(index_with_whoosh.suite())
-    test_suite.addTest(whoosh_backend.suite())
-    test_suite.addTest(web_ui.suite())
     test_suite.addTest(api.suite())
+    test_suite.addTest(index_with_whoosh.suite())
     test_suite.addTest(query_parser.suite())
     test_suite.addTest(query_suggestion.suite())
+    test_suite.addTest(search_resources.suite())
+    test_suite.addTest(web_ui.suite())
+    test_suite.addTest(whoosh_backend.suite())
     test_suite.addTest(security.suite())
-    test_suite.addTest(ticket_search.suite())
-    test_suite.addTest(wiki_search.suite())
-    test_suite.addTest(milestone_search.suite())
-    test_suite.addTest(changeset_search.suite())
-    test_suite.addTest(base.suite())
     return test_suite
 
 if __name__ == '__main__':

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -131,7 +130,7 @@ class BaseBloodhoundSearchTest(unittest.
         url, data, x = BloodhoundSearchModule(self.env).process_request(
             self.req)
         self.env.log.debug("Received url: %s data: %s", url, data)
-        if data.has_key("results"):
+        if 'results' in data:
             self.env.log.debug("results: %s", data["results"].__dict__)
         return data
 

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/__init__.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/__init__.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/__init__.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/tests/search_resources/__init__.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -18,3 +17,19 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
+from bhsearch.tests import unittest
+from bhsearch.tests.search_resources import base, changeset_search, \
+    milestone_search, ticket_search, wiki_search
+
+
+def suite():
+    suite = unittest.TestSuite()
+    suite.addTest(base.suite())
+    suite.addTest(changeset_search.suite())
+    suite.addTest(milestone_search.suite())
+    suite.addTest(ticket_search.suite())
+    suite.addTest(wiki_search.suite())
+    return suite
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='suite')

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -28,13 +27,13 @@ from bhsearch.tests.base import BaseBloo
 
 
 class SimpleSearchWikiSyntaxFormatterTestCase(BaseBloodhoundSearchTest):
+
     def setUp(self):
         super(SimpleSearchWikiSyntaxFormatterTestCase, self).setUp(
             create_req=True,
         )
         self.text_formatter = SimpleSearchWikiSyntaxFormatter(self.env)
 
-
     def test_can_format_header(self):
         wiki_content = """= Header #overview
         some text"""
@@ -64,7 +63,6 @@ class SimpleSearchWikiSyntaxFormatterTes
     def test_can_format_sample_wiki_link(self):
         self.assertEqual("WikiPage", self._call_format("WikiPage"))
 
-
     def test_can_format_makro(self):
         """
         Makro links must be formatted as text
@@ -80,7 +78,6 @@ class SimpleSearchWikiSyntaxFormatterTes
             self._call_format(
                 "**bold**, //italic//, **//WikiCreole style//**"))
 
-
     @unittest.skip("TODO")
     def test_can_format_non_wiki_camel_case(self):
         self.assertEqual("WikiPage", self._call_format("!WikiPage"))

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -110,6 +109,7 @@ class TicketIndexerTestCase(BaseBloodhou
         component.insert()
         return component
 
+
 def suite():
     return unittest.makeSuite(TicketIndexerTestCase, 'test')
 

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -24,11 +23,16 @@ system backend.
 """
 import contextlib
 import os
-from sqlite3 import OperationalError
-
-from trac.perm import (DefaultPermissionPolicy, PermissionCache,
-                       PermissionSystem)
+from bhsearch.security import SecurityFilter
 
+try:
+    import configobj
+except ImportError:
+    configobj = None
+
+from trac.perm import (
+    DefaultPermissionPolicy, PermissionCache, PermissionSystem
+)
 from bhsearch.api import BloodhoundSearchApi
 from bhsearch.tests import unittest
 from bhsearch.tests.base import BaseBloodhoundSearchTest
@@ -43,7 +47,8 @@ from bhsearch import security
 class SecurityTest(BaseBloodhoundSearchTest):
     def setUp(self, enabled=[]):
         super(SecurityTest, self).setUp(
-            enabled=enabled + ['trac.*', 'trac.wiki.*', 'bhsearch.*', 'multiproduct.*'],
+            enabled=enabled + ['trac.*', 'trac.wiki.*',
+                               'bhsearch.*', 'multiproduct.*'],
             create_req=True,
             enable_security=True,
         )
@@ -62,7 +67,7 @@ class SecurityTest(BaseBloodhoundSearchT
         try:
             MultiProductSystem(self.env)\
                 .upgrade_environment(self.env.db_transaction)
-        except OperationalError:
+        except self.env.db_exc.OperationalError:
             # table remains but content is deleted
             self._add_products('@')
         self.env.enable_multiproduct_schema()
@@ -102,7 +107,7 @@ class SecurityTest(BaseBloodhoundSearchT
             del PermissionSystem(env).store._all_permissions
 
 
-class MultiProductSecurityTestSuite(SecurityTest):
+class MultiProductSecurityTestCase(SecurityTest):
     def test_applies_security(self):
         self.insert_ticket('ticket 1')
 
@@ -114,38 +119,38 @@ class MultiProductSecurityTestSuite(Secu
             self.insert_ticket('ticket 3')
 
         results = self.search_api.query("type:wiki", context=self.context)
-        self.assertEqual(results.hits, 0)
+        self.assertEqual(0, results.hits)
 
         self._add_permission('x', 'WIKI_VIEW')
         results = self.search_api.query("type:wiki", context=self.context)
-        self.assertEqual(results.hits, 0)
+        self.assertEqual(0, results.hits)
 
         self._add_permission('x', 'WIKI_VIEW', 'p1')
         results = self.search_api.query("type:wiki", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
         self._add_permission('x', 'WIKI_VIEW', 'p2')
         results = self.search_api.query("type:wiki", context=self.context)
-        self.assertEqual(results.hits, 2)
+        self.assertEqual(2, results.hits)
 
         self._add_permission('x', 'TICKET_VIEW', 'p2')
         results = self.search_api.query("*", context=self.context)
-        self.assertEqual(results.hits, 3)
+        self.assertEqual(3, results.hits)
 
         self._add_permission('x', 'TICKET_VIEW', 'p1')
         results = self.search_api.query("*", context=self.context)
-        self.assertEqual(results.hits, 4)
+        self.assertEqual(4, results.hits)
 
         self._add_permission('x', 'TICKET_VIEW')
         results = self.search_api.query("*", context=self.context)
-        self.assertEqual(results.hits, 5)
+        self.assertEqual(5, results.hits)
 
     def test_admin_has_access(self):
         with self.product('p1'):
             self.insert_wiki('page 1', 'content')
         self._add_permission('x', 'TRAC_ADMIN')
         results = self.search_api.query("*", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
     def test_admin_granted_in_product_should_not_have_access(self):
         with self.product('p1'):
@@ -153,7 +158,7 @@ class MultiProductSecurityTestSuite(Secu
 
         self._add_permission('x', 'TRAC_ADMIN', 'p1')
         results = self.search_api.query("*", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
     def test_product_owner_has_access(self):
         self._add_products('p3', owner='x')
@@ -161,13 +166,13 @@ class MultiProductSecurityTestSuite(Secu
             self.insert_ticket("ticket")
 
         results = self.search_api.query("*", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
     def test_user_with_no_permissions(self):
         with self.product('p1'):
             self.insert_wiki('page 1', 'content')
         results = self.search_api.query("type:wiki", context=self.context)
-        self.assertEqual(results.hits, 0)
+        self.assertEqual(0, results.hits)
 
     def test_adding_security_filters_retains_existing_filters(self):
         with self.product('p1'):
@@ -184,14 +189,14 @@ class MultiProductSecurityTestSuite(Secu
             filter=["status:closed"],
             context=self.context
         )
-        self.assertEqual(results.hits, 2)
+        self.assertEqual(2, results.hits)
 
     def test_product_dropdown_with_no_permission(self):
         self._add_permission('x', 'SEARCH_VIEW')
         data = self.process_request()
 
         product_list = data['search_product_list']
-        self.assertEqual(len(product_list), 2)
+        self.assertEqual(2, len(product_list))
 
     def test_product_dropdown_with_trac_admin_permission(self):
         self._add_permission('x', 'SEARCH_VIEW')
@@ -199,7 +204,7 @@ class MultiProductSecurityTestSuite(Secu
         data = self.process_request()
 
         product_list = data['search_product_list']
-        self.assertEqual(len(product_list), 5)
+        self.assertEqual(5, len(product_list))
 
     def test_product_dropdown_with_product_view_permissions(self):
         self._add_permission('x', 'SEARCH_VIEW')
@@ -207,7 +212,7 @@ class MultiProductSecurityTestSuite(Secu
         data = self.process_request()
 
         product_list = data['search_product_list']
-        self.assertEqual(len(product_list), 3)
+        self.assertEqual(3, len(product_list))
 
     def test_check_permission_is_called_with_advanced_security(self):
         self.env.config.set('bhsearch', 'advanced_security', "True")
@@ -234,8 +239,8 @@ class MultiProductSecurityTestSuite(Secu
             context=self.context
         )
 
-        self.assertEqual(results.hits, 5)
-        self.assertEqual(len(calls), 5)
+        self.assertEqual(5, results.hits)
+        self.assertEqual(5, len(calls))
 
     def test_advanced_security_overrides_normal_permissions(self):
         self.env.config.set('bhsearch', 'advanced_security', "True")
@@ -245,14 +250,14 @@ class MultiProductSecurityTestSuite(Secu
         self._add_permission('x', 'TRAC_ADMIN')
 
         security.SecurityPreprocessor.check_permission = \
-            lambda x, doc, z: doc['product'] == 'p1'
+            lambda x, doc, z: doc.get('product', None) == 'p1'
 
         results = self.search_api.query(
             "*",
             context=self.context
         )
 
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
 
 class AuthzSecurityTestCase(SecurityTest):
@@ -266,22 +271,27 @@ class AuthzSecurityTestCase(SecurityTest
 
         # Create some dummy objects
         self.insert_ticket('ticket 1')
+        self.insert_ticket('ticket 2')
         self.insert_wiki('page 1', 'content')
         with self.product('p1'):
-            self.insert_ticket('ticket 2')
+            self.insert_ticket('ticket 1 in p1')
             self.insert_wiki('page 1', 'content')
 
+    def write_authz_config(self, content):
+        with open(self.authz_config, 'w') as authz_config:
+            authz_config.write(content)
+
     def test_authz_permissions(self):
         self._add_permission('x', 'WIKI_VIEW')
-        self.write_authz_config('\n'.join([
-            '[*]',
-            '* = TICKET_VIEW, !WIKI_VIEW',
-        ]))
+        self.write_authz_config("""
+            [*]
+            * = TICKET_VIEW, !WIKI_VIEW
+        """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 2)
+        self.assertEqual(3, results.hits)
         results = self.search_api.query("type:wiki", context=self.context)
-        self.assertEqual(results.hits, 0)
+        self.assertEqual(0, results.hits)
 
     def test_granular_permissions(self):
         self.write_authz_config("""
@@ -290,8 +300,8 @@ class AuthzSecurityTestCase(SecurityTest
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 1)
-        self.assertEqual(results.docs[0]['id'], u'1')
+        self.assertEqual(2, results.hits)
+        self.assertEqual(u'1', results.docs[0]['id'])
 
     def test_deny_overrides_default_permissions(self):
         self._add_permission('x', 'TICKET_VIEW')
@@ -301,9 +311,9 @@ class AuthzSecurityTestCase(SecurityTest
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 0)
+        self.assertEqual(0, results.hits)
 
-    def test_includes_wildcard_rows_for_registred_users(self):
+    def test_includes_wildcard_rows_for_registered_users(self):
         self.write_authz_config("""
             [*]
             * = TICKET_VIEW
@@ -312,11 +322,10 @@ class AuthzSecurityTestCase(SecurityTest
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 1)
-
+        self.assertEqual(1, results.hits)
 
     def test_includes_wildcard_rows_for_anonymous_users(self):
-        self.req.authname='anonymous'
+        self.req.authname = 'anonymous'
         self.write_authz_config("""
             [*]
             * = TICKET_VIEW
@@ -325,9 +334,9 @@ class AuthzSecurityTestCase(SecurityTest
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
-    def test_includes_authenticated_rows_for_registred_users(self):
+    def test_includes_authenticated_rows_for_registered_users(self):
         self.write_authz_config("""
             [*]
             * = TICKET_VIEW
@@ -336,9 +345,9 @@ class AuthzSecurityTestCase(SecurityTest
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
-    def test_includes_named_rows_for_registred_users(self):
+    def test_includes_named_rows_for_registered_users(self):
         self.write_authz_config("""
             [*]
             * = TICKET_VIEW
@@ -347,7 +356,7 @@ class AuthzSecurityTestCase(SecurityTest
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
     def test_includes_named_rows_for_anonymous_users(self):
         self.req.authname = 'anonymous'
@@ -359,30 +368,35 @@ class AuthzSecurityTestCase(SecurityTest
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
     def test_understands_groups(self):
         self.write_authz_config("""
             [groups]
             admins = x
-
             [*]
             @admins = TICKET_VIEW
-
             [ticket:1]
             * = !TRAC_ADMIN
         """)
 
         results = self.search_api.query("type:ticket", context=self.context)
-        self.assertEqual(results.hits, 1)
+        self.assertEqual(1, results.hits)
 
-    def write_authz_config(self, content):
-        with open(self.authz_config, 'w') as authz_config:
-            authz_config.write(content)
+
+class SecurityFilterTests(unittest.TestCase):
+    def test_hash(self):
+        sf = SecurityFilter()
+        hash(sf)
 
 
 def suite():
-    return unittest.makeSuite(MultiProductSecurityTestSuite, 'test')
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(MultiProductSecurityTestCase, 'test'))
+    if configobj:
+        suite.addTest(unittest.makeSuite(AuthzSecurityTestCase, 'test'))
+    suite.addTest(unittest.makeSuite(SecurityFilterTests, 'test'))
+    return suite
 
 if __name__ == '__main__':
-    unittest.main()
+    unittest.main(defaultTest="suite")

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -65,6 +64,12 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
             def href(self, *args):
                 return ('/main/products/%s/' % self.product) + '/'.join(args)
 
+            def abs_href(self, *args):
+                return 'http://example.org' + self.href(*args)
+
+            from multiproduct.env import ProductEnvironment
+            resolve_href = ProductEnvironment.resolve_href
+
         web_ui.ProductEnvironment = MockProductEnvironment
 
     def tearDown(self):
@@ -125,7 +130,7 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         result_datetime = result_items[0]["date"]
         self.env.log.debug(
             "Ticket time: %s, Formatted time: %s ,Returned time: %s",
-            ticket_time, expected_datetime,result_datetime)
+            ticket_time, expected_datetime, result_datetime)
         self.assertEqual(expected_datetime, result_datetime)
 
     def test_ticket_href(self):
@@ -149,7 +154,7 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         self._insert_tickets(DEFAULT_DOCS_PER_PAGE+1)
         self.req.args[RequestParameters.QUERY] = "*:*"
         data = self.process_request()
-        shown_pages =  data["results"].shown_pages
+        shown_pages = data["results"].shown_pages
         second_page_href = shown_pages[1]["href"]
         self.assertIn("page=2", second_page_href)
         self.assertIn("q=*%3A*", second_page_href)
@@ -270,13 +275,12 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         data = self.process_request()
         #assert
         page_href = data["page_href"]
-        self.assertIn(urlencode({'fq':'component:"c1"'}), page_href)
-        self.assertIn(urlencode({'fq':'status:"new"'}), page_href)
+        self.assertIn(urlencode({'fq': 'component:"c1"'}), page_href)
+        self.assertIn(urlencode({'fq': 'status:"new"'}), page_href)
 
         docs = data["results"].items
         self.assertEqual(2, len(docs))
 
-
     def test_can_handle_empty_facet_result(self):
         #arrange
         self.insert_ticket("T1", component="c1", status="new")
@@ -412,7 +416,6 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         self.assertEqual('T1 (new)', quick_jump_data["description"])
         self.assertEqual('/main/ticket/1', quick_jump_data["href"])
 
-
     def test_that_ticket_search_can_return_in_grid(self):
         #arrange
         self.env.config.set(
@@ -456,7 +459,6 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         self.assertNotIn("headers", data)
         self.assertNotIn("view", data)
 
-
     def test_can_returns_all_views(self):
         #arrange
         self.insert_ticket("T1", component="c1", status="new", milestone="A")
@@ -521,7 +523,6 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         #assert
         self.assertIn("title", data["results"].items[0])
 
-
     def test_that_grid_header_has_correct_sort_when_default_sorting(self):
         #arrange
         self.insert_ticket("T1", component="c1", status="new", milestone="A")
@@ -622,7 +623,7 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
         self.insert_ticket(term, id=id)
         self.insert_wiki(id, term)
 
-        self.req.args[RequestParameters.QUERY] =  term
+        self.req.args[RequestParameters.QUERY] = term
         data = self.process_request()
 
         for row in data["results"].items:
@@ -834,7 +835,7 @@ class WebUiTestCaseWithWhoosh(BaseBloodh
 
         return i
 
-    def _assertResourceType(self, type, label, active, href_contains = None):
+    def _assertResourceType(self, type, label, active, href_contains=None):
         self.assertEquals(label, type["label"])
         self.assertEquals(active, type["active"])
         if href_contains:
@@ -867,13 +868,13 @@ class RequestParametersTest(unittest.Tes
             None,
             self._evaluate_sort(" ,  , "))
         self.assertEqual(
-            [SortInstruction("f1", ASC),],
+            [SortInstruction("f1", ASC)],
             self._evaluate_sort(" f1 "))
         self.assertEqual(
-            [SortInstruction("f1", ASC),],
+            [SortInstruction("f1", ASC)],
             self._evaluate_sort(" f1 asc"))
         self.assertEqual(
-            [SortInstruction("f1", DESC),],
+            [SortInstruction("f1", DESC)],
             self._evaluate_sort("f1  desc"))
         self.assertEqual(
             [SortInstruction("f1", ASC), SortInstruction("f2", DESC)],

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=1572404&r1=1572403&r2=1572404&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 Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -28,8 +27,7 @@ from bhsearch.api import ASC, DESC, SCOR
 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 bhsearch.whoosh_backend import WhooshBackend
 from whoosh import index, query, sorting
 from whoosh.fields import ID, KEYWORD, TEXT, Schema
 from whoosh.qparser import MultifieldParser, MultifieldPlugin, PhrasePlugin, \
@@ -54,12 +52,12 @@ class WhooshBackendTestCase(BaseBloodhou
         self.assertEqual(2, result.hits)
         docs = result.docs
         self.assertEqual(
-            {'id': u'1', 'type': u'ticket', 'unique_id': u'empty:ticket:1',
-             'score': u'1'},
+            {'id': u'1', 'type': u'ticket', 'unique_id': u'ticket:1',
+             'score': 0},
             docs[0])
         self.assertEqual(
-            {'id': u'2', 'type': u'ticket', 'unique_id': u'empty:ticket:2',
-             'score': u'2'},
+            {'id': u'2', 'type': u'ticket', 'unique_id': u'ticket:2',
+             'score': 1},
             docs[1])
 
     def test_can_return_all_fields(self):
@@ -68,7 +66,7 @@ class WhooshBackendTestCase(BaseBloodhou
         self.print_result(result)
         docs = result.docs
         self.assertEqual(
-            {'id': u'1', 'type': u'ticket', 'unique_id': u'empty:ticket:1',
+            {'id': u'1', 'type': u'ticket', 'unique_id': u'ticket:1',
                 "score": 1.0},
             docs[0])
 
@@ -476,43 +474,6 @@ class WhooshFunctionalityTestCase(unitte
             {'status': {None: 1, 'New': 1}, 'type': {'type1': 1, 'type2': 1}},
             facets)
 
-    def test_out_of_range_on_empty_facets(self):
-        """
-        Whoosh raises exception IndexError: list index out of range
-        when search contains facets on field that is missing in at least one
-        document in the index. The error manifests only when index contains
-        more than one segment
-
-        The problem expected to be fixed in the next release.
-
-        For the time of being, whoosh-backend have to introduce workaround in
-        order to fix the problem. This unit-test is just a reminder to remove
-        workaround when the fixed version of Whoosh is applied.
-        """
-        schema = Schema(
-                unique_id=ID(stored=True, unique=True),
-                status=ID(stored=True),
-                )
-
-#        ix = RamStorage().create_index(schema)
-        ix = index.create_in(self.index_dir, schema=schema)
-        def insert_docs():
-            with ix.writer() as w:
-                for i in range(10):
-                    w.add_document(unique_id=unicode(i))
-
-        #the problem occurs only when index contains more than one segment
-        insert_docs()
-        insert_docs()
-
-        with ix.searcher() as s:
-            with self.assertRaises(IndexError):
-                s.search(
-                    query.Every(),
-                    groupedby=(u"status"),
-                    maptype=sorting.Count,
-                )
-
     def _load_facets(self, non_paged_results):
         facet_names = non_paged_results.facet_names()
         if not facet_names:
@@ -602,56 +563,10 @@ class WhooshFunctionalityTestCase(unitte
         self.assertEquals(len(r), 0)
 
 
-class WhooshEmptyFacetErrorWorkaroundTestCase(BaseBloodhoundSearchTest):
-    def setUp(self):
-        super(WhooshEmptyFacetErrorWorkaroundTestCase, self).setUp()
-        self.whoosh_backend = WhooshBackend(self.env)
-        self.whoosh_backend.recreate_index()
-        self.parser = DefaultQueryParser(self.env)
-        self.empty_facet_workaround = WhooshEmptyFacetErrorWorkaround(self.env)
-
-    def tearDown(self):
-        shutil.rmtree(self.env.path)
-        self.env.reset_db()
-
-    def test_set_should_not_be_empty_fields(self):
-        self.insert_ticket("test x")
-        result = self.whoosh_backend.query(query.Every())
-        self.print_result(result)
-        doc = result.docs[0]
-        null_marker = WhooshEmptyFacetErrorWorkaround.NULL_MARKER
-        self.assertEqual(null_marker, doc["component"])
-        self.assertEqual(null_marker, doc["status"])
-        self.assertEqual(null_marker, doc["milestone"])
-
-    def test_can_fix_query_filter(self):
-        parsed_filter = self.parser.parse_filters(
-            ["type:ticket", "NOT (milestone:*)"])
-        query_parameters = dict(filter=parsed_filter)
-        self.empty_facet_workaround.query_pre_process(
-            query_parameters)
-
-        result_filter = query_parameters["filter"]
-        self.assertEquals('(type:ticket AND milestone:empty)',
-            str(result_filter))
-
-    def test_does_interfere_query_filter_if_not_needed(self):
-        parsed_filter = self.parser.parse_filters(
-            ["type:ticket", "milestone:aaa"])
-        query_parameters = dict(filter=parsed_filter)
-        self.empty_facet_workaround.query_pre_process(
-            query_parameters)
-
-        result_filter = query_parameters["filter"]
-        self.assertEquals('(type:ticket AND milestone:aaa)',
-            str(result_filter))
-
 def suite():
     test_suite = unittest.TestSuite()
     test_suite.addTest(unittest.makeSuite(WhooshBackendTestCase, 'test'))
     test_suite.addTest(unittest.makeSuite(WhooshFunctionalityTestCase, 'test'))
-    test_suite.addTest(
-        unittest.makeSuite(WhooshEmptyFacetErrorWorkaroundTestCase, 'test'))
     return test_suite
 
 if __name__ == '__main__':

Modified: bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/web_ui.py
URL: http://svn.apache.org/viewvc/bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/web_ui.py?rev=1572404&r1=1572403&r2=1572404&view=diff
==============================================================================
--- bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/web_ui.py (original)
+++ bloodhound/branches/bep_0007_embeddable_objects/bloodhound_search/bhsearch/web_ui.py Thu Feb 27 02:14:33 2014
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: UTF-8 -*-
 
 #  Licensed to the Apache Software Foundation (ASF) under one
@@ -35,7 +34,6 @@ from trac.config import OrderedExtension
 from trac.util.presentation import Paginator
 from trac.util.datefmt import format_datetime, user_time
 from trac.web import IRequestHandler, IRequestFilter
-from trac.util.translation import _
 from trac.util.html import find_element
 from trac.web.chrome import (ITemplateProvider,
                              add_link, add_stylesheet, prevnext_nav,
@@ -43,6 +41,7 @@ from trac.web.chrome import (ITemplatePr
 from bhsearch.api import (BloodhoundSearchApi, ISearchParticipant, SCORE, ASC,
                           DESC, IndexFields, SortInstruction)
 from bhsearch.utils import get_global_env, using_multiproduct
+from bhsearch.utils.translation import _
 from trac.wiki.formatter import extract_link
 from multiproduct.env import ProductEnvironment
 from multiproduct.web_ui import ProductModule
@@ -245,7 +244,8 @@ class BloodhoundSearchModule(Component):
         'bhsearch',
         'search_participants',
         ISearchParticipant,
-        "TicketSearchParticipant, WikiSearchParticipant"
+        "TicketSearchParticipant, WikiSearchParticipant",
+        include_missing=True
     )
 
     prefix = "all"
@@ -262,44 +262,48 @@ class BloodhoundSearchModule(Component):
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_facets',
         default=",".join([IndexFields.PRODUCT, IndexFields.TYPE]),
-        doc="""Default facets applied to search view of all resources""")
+        doc="""Default facets applied to search view of all resources""",
+        doc_domain='bhsearch')
 
     default_view = Option(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_view',
         doc="""If true, show grid as default view for specific resource in
-            Bloodhound Search results""")
+            Bloodhound Search results""", doc_domain='bhsearch')
 
     all_grid_fields = ListOption(
         BHSEARCH_CONFIG_SECTION,
         prefix + '_default_grid_fields',
         default=",".join(default_grid_fields),
-        doc="""Default fields for grid view for specific resource""")
+        doc="""Default fields for grid view for specific resource""",
+        doc_domain='bhsearch')
 
     default_search = BoolOption(
         BHSEARCH_CONFIG_SECTION,
         'is_default',
         default=False,
-        doc="""Searching from quicksearch uses bhsearch.""")
+        doc="""Searching from quicksearch uses bhsearch.""",
+        doc_domain='bhsearch')
 
     redirect_enabled = BoolOption(
         BHSEARCH_CONFIG_SECTION,
         'enable_redirect',
         default=False,
-        doc="""Redirect links pointing to trac search to bhsearch""")
+        doc="""Redirect links pointing to trac search to bhsearch""",
+        doc_domain='bhsearch')
 
     global_quicksearch = BoolOption(
         BHSEARCH_CONFIG_SECTION,
         'global_quicksearch',
         default=True,
         doc="""Quicksearch searches all products, even when used
-            in product env.""")
+            in product env.""", doc_domain='bhsearch')
 
     query_suggestions_enabled = BoolOption(
         BHSEARCH_CONFIG_SECTION,
         'query_suggestions',
         default=True,
-        doc="""Display query suggestions."""
+        doc="""Display query suggestions.""", doc_domain='bhsearch'
     )
 
     # IPermissionRequestor methods
@@ -694,7 +698,8 @@ class RequestContext(object):
     def _process_doc(self, doc):
         ui_doc = dict(doc)
         if doc['product']:
-            product_href = ProductEnvironment(self.env, doc['product']).href
+            env = ProductEnvironment(self.env, doc['product'])
+            product_href = ProductEnvironment.resolve_href(env, self.env)
             # pylint: disable=too-many-function-args
             ui_doc["href"] = product_href(doc['type'], doc['id'])
         else: