Example #1
0
 def setUp(self):
     super(TicketIndexerTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.ticket_indexer = TicketIndexer(self.env)
     self.search_api = BloodhoundSearchApi(self.env)
     self.env.config.set('bhsearch', 'silence_on_error', "False")
class ChangesetIndexerEventsTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(ChangesetIndexerEventsTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.repository_manager = RepositoryManager(self.env)
        self.inject_dummy_repository()

    def test_can_index_added_changeset(self):
        rev = self.insert_changeset("Changed document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Changed document 1.", doc["message"])

    def test_can_index_modified_changeset(self):
        rev = self.insert_changeset("Changed document 1.")
        self.modify_changeset(rev, "Added document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Added document 1.", doc["message"])

    def insert_changeset(self, message, author=None, date=None, revision=None):
        rev = self.repository.add_changeset(revision, message, author, date)
        self.repository_manager.notify("changeset_added", 'dummy', [rev])
        return rev

    def modify_changeset(self, rev, message=None, author=None, date=None):
        changeset = self.repository.get_changeset(rev)
        if message is not None:
            changeset.message = message
        if author is not None:
            changeset.author = author
        if date is not None:
            changeset.date = date
        self.repository_manager.notify("changeset_modified", "dummy", [rev])

    def inject_dummy_repository(self):
        # pylint: disable=protected-access,attribute-defined-outside-init
        self.repository = DummyRepositry()
        self.repository_connector = DummyRepositoryConnector(self.env)
        self.repository_connector.repository = self.repository
        self.repository_manager._all_repositories = {
            'dummy': dict(dir='dirname', type='dummy')
        }
        self.repository_manager._connectors = {
            'dummy': (self.repository_connector, 100)
        }
Example #3
0
 def get_admin_commands(self):
     yield ('bhsearch rebuild', '',
         'Rebuild Bloodhound Search index',
         None, BloodhoundSearchApi(self.env).rebuild_index)
     yield ('bhsearch optimize', '',
         'Optimize Bloodhound search index',
         None, BloodhoundSearchApi(self.env).optimize)
 def setUp(self):
     super(ChangesetIndexerEventsTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
     self.repository_manager = RepositoryManager(self.env)
     self.inject_dummy_repository()
Example #5
0
 def setUp(self):
     super(WikiIndexerEventsTestCase, self).setUp()
     self.wiki_system = WikiSystem(self.env)
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
     self.wiki_participant = WikiSearchParticipant(self.env)
     self.query_parser = DefaultQueryParser(self.env)
Example #6
0
class ChangesetIndexerEventsTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(ChangesetIndexerEventsTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.repository_manager = RepositoryManager(self.env)
        self.inject_dummy_repository()

    def test_can_index_added_changeset(self):
        rev = self.insert_changeset("Changed document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Changed document 1.", doc["message"])

    def test_can_index_modified_changeset(self):
        rev = self.insert_changeset("Changed document 1.")
        self.modify_changeset(rev, "Added document 1.")

        results = self.search_api.query("*:*")

        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual('%s/dummy' % rev, doc["id"])
        self.assertEqual('dummy', doc["repository"])
        self.assertEqual('1', doc["revision"])
        self.assertEqual("Added document 1.", doc["message"])

    def insert_changeset(self, message, author=None, date=None, revision=None):
        rev = self.repository.add_changeset(revision, message, author, date)
        self.repository_manager.notify("changeset_added", 'dummy', [rev])
        return rev

    def modify_changeset(self, rev, message=None, author=None, date=None):
        changeset = self.repository.get_changeset(rev)
        if message is not None:
            changeset.message = message
        if author is not None:
            changeset.author = author
        if date is not None:
            changeset.date = date
        self.repository_manager.notify("changeset_modified", "dummy", [rev])

    def inject_dummy_repository(self):
        # pylint: disable=protected-access,attribute-defined-outside-init
        self.repository = DummyRepositry()
        self.repository_connector = DummyRepositoryConnector(self.env)
        self.repository_connector.repository = self.repository
        self.repository_manager._all_repositories = {
            'dummy': dict(dir='dirname', type='dummy')}
        self.repository_manager._connectors = {
            'dummy': (self.repository_connector, 100)}
 def milestone_deleted(self, milestone):
     try:
         search_api = BloodhoundSearchApi(self.env)
         search_api.delete_doc(MILESTONE_TYPE, milestone.name)
     except Exception, e:
         if self.silence_on_error:
             self.log.error("Error occurs during milestone indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #8
0
 def ticket_deleted(self, ticket):
     """Called when a ticket is deleted."""
     try:
         search_api = BloodhoundSearchApi(self.env)
         search_api.delete_doc(TICKET_TYPE, ticket.id)
     except Exception, e:
         if self.silence_on_error:
             self.log.error("Error occurs during deleting ticket. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #9
0
 def _index_milestone(self, milestone):
     try:
         doc = self.build_doc(milestone)
         search_api = BloodhoundSearchApi(self.env)
         search_api.add_doc(doc)
     except Exception, e:
         if self.silence_on_error:
             self.log.error("Error occurs during wiki indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #10
0
 def wiki_page_deleted(self, page):
     """Called when a ticket is deleted."""
     try:
         search_api = BloodhoundSearchApi(self.env)
         search_api.delete_doc(
             get_product(self.env).prefix, WIKI_TYPE, page.name)
     except Exception, e:
         if self.silence_on_error.lower() == "true":
             self.log.error("Error occurs during wiki indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #11
0
 def _ticket_deleted(self, ticket):
     """Called when a ticket is deleted."""
     try:
         search_api = BloodhoundSearchApi(self.env)
         search_api.delete_doc(ticket.product, TICKET_TYPE, ticket.id)
     except Exception, e:
         if self.silence_on_error:
             self.log.error(
                 "Error occurs during deleting ticket. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #12
0
 def resource_deleted(self, resource, context):
     # pylint: disable=unused-argument
     try:
         search_api = BloodhoundSearchApi(self.env)
         search_api.delete_doc(
             get_product(self.env).prefix, MILESTONE_TYPE, resource.name)
     except Exception, e:
         if self.silence_on_error:
             self.log.error("Error occurs during milestone indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #13
0
 def _index_changeset(self, changeset):
     try:
         doc = self.build_doc(changeset)
         search_api = BloodhoundSearchApi(self.env)
         search_api.add_doc(doc)
     except Exception, e:
         if self.silence_on_error:
             self.log.error(
                 "Error occurs during changeset indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #14
0
 def _index_ticket(self, ticket, search_api=None, operation_context=None):
     try:
         if not search_api:
             search_api = BloodhoundSearchApi(self.env)
         doc = self.build_doc(ticket)
         search_api.add_doc(doc, operation_context)
     except Exception, e:
         if self.silence_on_error:
             self.log.error("Error occurs during ticket indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #15
0
 def resource_deleted(self, resource, context):
     # pylint: disable=unused-argument
     try:
         search_api = BloodhoundSearchApi(self.env)
         search_api.delete_doc(
             get_product(self.env).prefix, MILESTONE_TYPE, resource.name)
     except Exception, e:
         if self.silence_on_error:
             self.log.error(
                 "Error occurs during milestone indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #16
0
 def _index_ticket(self, ticket, search_api=None, operation_context=None):
     try:
         if not search_api:
             search_api = BloodhoundSearchApi(self.env)
         doc = self.build_doc(ticket)
         search_api.add_doc(doc, operation_context)
     except Exception, e:
         if self.silence_on_error:
             self.log.error(
                 "Error occurs during ticket indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #17
0
 def wiki_page_renamed(self, page, old_name):
     """Called when a page has been renamed."""
     try:
         doc = self.build_doc(page)
         search_api = BloodhoundSearchApi(self.env)
         search_api.change_doc_id(doc, old_name)
     except Exception, e:
         if self.silence_on_error:
             self.log.error("Error occurs during renaming wiki from %s \
                 to %s. The error will not be propagated. Exception: %s",
             old_name, page.name, e)
         else:
             raise
Example #18
0
 def wiki_page_deleted(self, page):
     """Called when a ticket is deleted."""
     try:
         search_api = BloodhoundSearchApi(self.env)
         search_api.delete_doc(
             get_product(self.env).prefix, WIKI_TYPE, page.name)
     except Exception, e:
         if self.silence_on_error.lower() == "true":
             self.log.error(
                 "Error occurs during wiki indexing. \
                 The error will not be propagated. Exception: %s", e)
         else:
             raise
Example #19
0
 def wiki_page_renamed(self, page, old_name):
     """Called when a page has been renamed."""
     try:
         doc = self.build_doc(page)
         search_api = BloodhoundSearchApi(self.env)
         search_api.change_doc_id(doc, old_name)
     except Exception, e:
         if self.silence_on_error:
             self.log.error(
                 "Error occurs during renaming wiki from %s \
                 to %s. The error will not be propagated. Exception: %s",
                 old_name, page.name, e)
         else:
             raise
Example #20
0
 def _rename_milestone(self, milestone, old_name):
     try:
         doc = self.build_doc(milestone)
         search_api = BloodhoundSearchApi(self.env)
         with search_api.start_operation() as operation_context:
             search_api.change_doc_id(doc, old_name, operation_context)
             TicketIndexer(self.env).reindex_tickets(
                 search_api, operation_context, milestone=milestone.name)
     except Exception, e:
         if self.silence_on_error:
             self.log.error("Error occurs during renaming milestone from \
              %s to %s. The error will not be propagated. Exception: %s",
             old_name, milestone.name, e)
         else:
             raise
Example #21
0
 def _index_wiki(self, page):
     try:
         doc = self.build_doc(page)
         search_api = BloodhoundSearchApi(self.env)
         search_api.add_doc(doc)
     except Exception, e:
         page_name = None
         if page is not None:
             page_name = page.name
         if self.silence_on_error:
             self.log.error("Error occurs during wiki indexing: %s. \
                 The error will not be propagated. Exception: %s",
                 page_name, e)
         else:
             raise
Example #22
0
 def setUp(self):
     super(TicketIndexerTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.ticket_indexer = TicketIndexer(self.env)
     self.search_api = BloodhoundSearchApi(self.env)
     self.env.config.set('bhsearch', 'silence_on_error', "False")
Example #23
0
 def setUp(self):
     super(ChangesetIndexerEventsTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
     self.repository_manager = RepositoryManager(self.env)
     self.inject_dummy_repository()
Example #24
0
 def _rename_milestone(self, milestone, old_name):
     try:
         doc = self.build_doc(milestone)
         search_api = BloodhoundSearchApi(self.env)
         with search_api.start_operation() as operation_context:
             search_api.change_doc_id(doc, old_name, operation_context)
             TicketIndexer(self.env).reindex_tickets(
                 search_api, operation_context, milestone=milestone.name)
     except Exception, e:
         if self.silence_on_error:
             self.log.error(
                 "Error occurs during renaming milestone from \
              %s to %s. The error will not be propagated. Exception: %s",
                 old_name, milestone.name, e)
         else:
             raise
Example #25
0
 def _index_wiki(self, page):
     try:
         doc = self.build_doc(page)
         search_api = BloodhoundSearchApi(self.env)
         search_api.add_doc(doc)
     except Exception, e:
         page_name = None
         if page is not None:
             page_name = page.name
         if self.silence_on_error:
             self.log.error(
                 "Error occurs during wiki indexing: %s. \
                 The error will not be propagated. Exception: %s",
                 page_name, e)
         else:
             raise
Example #26
0
 def _component_changed(self, component, old_values):
     if "name" in old_values:
         old_name = old_values["name"]
         try:
             search_api = BloodhoundSearchApi(self.env)
             with search_api.start_operation() as operation_context:
                 TicketIndexer(self.env).reindex_tickets(
                     search_api,
                     operation_context,
                     component=component.name)
         except Exception, e:
             if self.silence_on_error:
                 self.log.error("Error occurs during renaming Component \
                 from %s to %s. The error will not be propagated. \
                 Exception: %s",
                 old_name, component.name, e)
             else:
                 raise
Example #27
0
 def _component_changed(self, component, old_values):
     if "name" in old_values:
         old_name = old_values["name"]
         try:
             search_api = BloodhoundSearchApi(self.env)
             with search_api.start_operation() as operation_context:
                 TicketIndexer(self.env).reindex_tickets(
                     search_api,
                     operation_context,
                     component=component.name)
         except Exception, e:
             if self.silence_on_error:
                 self.log.error(
                     "Error occurs during renaming Component \
                 from %s to %s. The error will not be propagated. \
                 Exception: %s", old_name, component.name, e)
             else:
                 raise
Example #28
0
class QuerySuggestionTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(QuerySuggestionTestCase, self).setUp(create_req=True)
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()

        self.search_api = BloodhoundSearchApi(self.env)

    def test_fills_suggestion_field(self):
        self.insert_ticket("test")
        self.insert_milestone("test")
        self.insert_wiki("name", "test")

        results = self.search_api.query("%s:test" % SuggestionFields.BASKET)

        self.assertEqual(results.hits, 3)

    def test_provides_suggestions(self):
        self.insert_ticket("test")
        self.req.args[RequestParameters.QUERY] = "tesk"

        data = self.process_request()

        self.assertIn(RequestContext.DATA_QUERY_SUGGESTION, data)
        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertEqual(suggestion['query'], 'test')
        self.assertIn('q=test', suggestion['href'])

    def test_provides_suggestions_for_multi_term_queries(self):
        self.insert_ticket("another test")
        self.req.args[RequestParameters.QUERY] = "another tesk"

        data = self.process_request()

        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertEqual(suggestion['query'], 'another test')

    def test_provides_suggestions_for_queries_with_unknown_words(self):
        self.insert_ticket("test")
        self.req.args[RequestParameters.QUERY] = "another tesk"

        data = self.process_request()

        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertEqual(suggestion['query'], 'another test')

    def test_suggestion_href_contains_used_filters(self):
        self.insert_ticket("test")
        self.req.args[RequestParameters.QUERY] = "tesk"
        self.req.args[RequestParameters.FILTER_QUERY] = ['filter']

        data = self.process_request()

        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertIn('fq=filter', suggestion['href'])
class QuerySuggestionTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(QuerySuggestionTestCase, self).setUp(create_req=True)
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()

        self.search_api = BloodhoundSearchApi(self.env)

    def test_fills_suggestion_field(self):
        self.insert_ticket("test")
        self.insert_milestone("test")
        self.insert_wiki("name", "test")

        results = self.search_api.query("%s:test" % SuggestionFields.BASKET)

        self.assertEqual(results.hits, 3)

    def test_provides_suggestions(self):
        self.insert_ticket("test")
        self.req.args[RequestParameters.QUERY] = "tesk"

        data = self.process_request()

        self.assertIn(RequestContext.DATA_QUERY_SUGGESTION, data)
        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertEqual(suggestion['query'], 'test')
        self.assertIn('q=test', suggestion['href'])

    def test_provides_suggestions_for_multi_term_queries(self):
        self.insert_ticket("another test")
        self.req.args[RequestParameters.QUERY] = "another tesk"

        data = self.process_request()

        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertEqual(suggestion['query'], 'another test')

    def test_provides_suggestions_for_queries_with_unknown_words(self):
        self.insert_ticket("test")
        self.req.args[RequestParameters.QUERY] = "another tesk"

        data = self.process_request()

        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertEqual(suggestion['query'], 'another test')

    def test_suggestion_href_contains_used_filters(self):
        self.insert_ticket("test")
        self.req.args[RequestParameters.QUERY] = "tesk"
        self.req.args[RequestParameters.FILTER_QUERY] = ['filter']

        data = self.process_request()

        suggestion = data[RequestContext.DATA_QUERY_SUGGESTION]
        self.assertIn('fq=filter', suggestion['href'])
Example #30
0
    def setUp(self, enabled=[]):
        super(SecurityTest, self).setUp(
            enabled=enabled +
            ['trac.*', 'trac.wiki.*', 'bhsearch.*', 'multiproduct.*'],
            create_req=True,
            enable_security=True,
        )
        self.env.parent = None
        self.product_envs = []
        self.req.perm = PermissionCache(self.env, 'x')

        self._setup_multiproduct()
        self._disable_trac_caches()
        self._create_whoosh_index()

        self.search_api = BloodhoundSearchApi(self.env)
        self._add_products('p1', 'p2')
Example #31
0
    def process_request(self, req):
        req.perm.assert_permission(SEARCH_PERMISSION)

        if self._is_opensearch_request(req):
            return ('opensearch.xml', {},
                    'application/opensearchdescription+xml')

        request_context = RequestContext(
            self.env,
            req,
            self.search_participants,
            self.default_view,
            self.all_grid_fields,
            self.default_facets,
            self.global_quicksearch,
            self.query_suggestions_enabled,
        )

        if request_context.requires_redirect:
            req.redirect(request_context.parameters.create_href(), True)

        # compatibility with legacy search
        req.search_query = request_context.parameters.query

        query_result = BloodhoundSearchApi(self.env).query(
            request_context.parameters.query,
            pagenum=request_context.page,
            pagelen=request_context.pagelen,
            sort=request_context.sort,
            fields=request_context.fields,
            facets=request_context.facets,
            filter=request_context.query_filter,
            highlight=True,
            context=request_context,
        )

        request_context.process_results(query_result)
        return self._return_data(req, request_context.data)
Example #32
0
class SearchIntegrationTestCase(BaseRelationsTestCase):

    def setUp(self):
        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)
        BaseRelationsTestCase.tearDown(self)

    def test_relations_are_indexed_on_creation(self):
        t1 = self._insert_and_load_ticket("Foo")
        t2 = self._insert_and_load_ticket("Bar")

        self.add_relation(t1, DEPENDENCY_OF, t2)

        result = self.search_api.query('%s:#2' % DEPENDENCY_OF)
        self.assertEqual(result.hits, 1)

    def test_relations_are_indexed_on_deletion(self):
        t1 = self._insert_and_load_ticket("Foo")
        t2 = self._insert_and_load_ticket("Bar")

        self.add_relation(t1, DEPENDENCY_OF, t2)
        relations = self.get_relations(t1)
        self.relations_system.delete(relations[0]["relation_id"])

        result = self.search_api.query('%s:#2' % DEPENDENCY_OF)
        self.assertEqual(result.hits, 0)

    def test_different_types_of_queries(self):
        t1 = self._insert_and_load_ticket("Foo")
        t2 = self._insert_and_load_ticket("Bar")

        self.add_relation(t1, DEPENDENCY_OF, t2)

        self.assertEqual(self.search_api.query('%s:#2'
                                               % DEPENDENCY_OF).hits, 1)
        self.assertEqual(self.search_api.query('%s:#tp1-2'
                                               % DEPENDENCY_OF).hits, 1)
Example #33
0
class SearchIntegrationTestCase(BaseRelationsTestCase):
    def setUp(self):
        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)
        BaseRelationsTestCase.tearDown(self)

    def test_relations_are_indexed_on_creation(self):
        t1 = self._insert_and_load_ticket("Foo")
        t2 = self._insert_and_load_ticket("Bar")

        self.add_relation(t1, DEPENDENCY_OF, t2)

        result = self.search_api.query('%s:#2' % DEPENDENCY_OF)
        self.assertEqual(result.hits, 1)

    def test_relations_are_indexed_on_deletion(self):
        t1 = self._insert_and_load_ticket("Foo")
        t2 = self._insert_and_load_ticket("Bar")

        self.add_relation(t1, DEPENDENCY_OF, t2)
        relations = self.get_relations(t1)
        self.relations_system.delete(relations[0]["relation_id"])

        result = self.search_api.query('%s:#2' % DEPENDENCY_OF)
        self.assertEqual(result.hits, 0)

    def test_different_types_of_queries(self):
        t1 = self._insert_and_load_ticket("Foo")
        t2 = self._insert_and_load_ticket("Bar")

        self.add_relation(t1, DEPENDENCY_OF, t2)

        self.assertEqual(
            self.search_api.query('%s:#2' % DEPENDENCY_OF).hits, 1)
        self.assertEqual(
            self.search_api.query('%s:#tp1-2' % DEPENDENCY_OF).hits, 1)
Example #34
0
 def setUp(self):
     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)
Example #35
0
class ApiQueryWithWhooshTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(ApiQueryWithWhooshTestCase, self).setUp(create_req=True)
        WhooshBackend(self.env).recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.ticket_participant = TicketSearchParticipant(self.env)
        self.query_parser = DefaultQueryParser(self.env)

    def tearDown(self):
        shutil.rmtree(self.env.path)
        self.env.reset_db()

    def test_can_search_free_description(self):
        #arrange
        self.insert_ticket("dummy summary", description="aaa keyword bla")
        #act
        results = self.search_api.query("keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_query_free_summary(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        #act
        results = self.search_api.query("keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_query_strict_summary(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        self.insert_ticket("summary2", description = "bla keyword")
        #act
        results = self.search_api.query("summary:keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_that_summary_hit_is_higher_than_description(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        self.insert_ticket("summary2", description = "bla keyword")
        #act
        results = self.search_api.query("keyword")
        self.print_result(results)
        #assert
        self.assertEqual(2, results.hits)
        docs = results.docs
        self.assertEqual("summary1 keyword", docs[0]["summary"])
        self.assertEqual("summary2", docs[1]["summary"])

    def test_other_conditions_applied(self):
        #arrange
        self.insert_ticket("summary1 keyword", status="closed")
        self.insert_ticket("summary2", description = "bla keyword")
        self.insert_ticket("summary3", status="closed")
        #act
        results = self.search_api.query("keyword status:closed")
        self.print_result(results)
        #assert
        self.assertEqual(1, results.hits)
        docs = results.docs
        self.assertEqual("summary1 keyword", docs[0]["summary"])

    def test_that_filter_queries_applied(self):
        #arrange
        self.insert_ticket("t1", status="closed", component = "c1")
        self.insert_ticket("t2", status="closed", component = "c1")
        self.insert_ticket("t3", status="closed",
            component = "NotInFilterCriteria")
        #act
        results = self.search_api.query(
            "*",
            filter= ['status:"closed"', 'component:"c1"'],
            sort= [SortInstruction("id", ASC)]
        )
        self.print_result(results)
        #assert
        self.assertEqual(2, results.hits)
        docs = results.docs
        self.assertEqual("t1", docs[0]["summary"])
        self.assertEqual("t2", docs[1]["summary"])

    def test_that_upgrading_environment_adds_documents_to_index(self):
        self.insert_ticket("t1")
        self.insert_ticket("t2")

        self.search_api.upgrade_environment(self.env.db_transaction)

        results = self.search_api.query("type:ticket")

        self.assertEqual(2, results.hits)

    def test_can_index_wiki_with_same_id_from_different_products(self):
        with self.product('p1'):
            self.insert_wiki('title', 'content')
        with self.product('p2'):
            self.insert_wiki('title', 'content 2')

        results = self.search_api.query("type:wiki")

        self.assertEqual(results.hits, 2)

    def test_upgrade_index_with_no_product(self):
        """See #773"""

        class NoProductIndexer(BaseIndexer):
            implements(IIndexParticipant)

            def get_entries_for_index(self):
                yield {
                    IndexFields.TYPE: 'noproduct',
                    IndexFields.ID: '1'
                }

        self.search_api.rebuild_index()

        self.unregister(NoProductIndexer)

    @staticmethod
    def unregister(component):
        ComponentMeta._components.remove(component)
        for interface in component.__dict__.get('_implements', ()):
            ComponentMeta._registry.get(interface).remove(component)
Example #36
0
class TicketIndexerTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(TicketIndexerTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.ticket_indexer = TicketIndexer(self.env)
        self.search_api = BloodhoundSearchApi(self.env)
        self.env.config.set('bhsearch', 'silence_on_error', "False")

    def tearDown(self):
        pass

    def test_does_not_raise_exception_by_default(self):
        self.env.config.set('bhsearch', 'silence_on_error', "True")
        self.ticket_indexer.resource_created(None, None)

    def test_raise_exception_if_configured(self):
        self.env.config.set('bhsearch', 'silence_on_error', "False")
        self.assertRaises(
            Exception,
            self.ticket_indexer.resource_created,
            None)

    def test_can_strip_wiki_syntax(self):
        #act
        self.insert_ticket("T1", description=" = Header")
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)
        self.assertEqual("Header", results.docs[0]["content"])

    def test_that_tickets_updated_after_component_renaming(self):
        #arrange
        INITIAL_COMPONENT = "initial_name"
        RENAMED_COMPONENT = "renamed_name"
        component = self._insert_component(INITIAL_COMPONENT)
        self.insert_ticket("T1", component=INITIAL_COMPONENT)
        self.insert_ticket("T2", component=INITIAL_COMPONENT)
        #act
        component.name = RENAMED_COMPONENT
        component.update()
        #arrange
        results = self.search_api.query("*")
        self.print_result(results)
        for doc in results.docs:
            self.assertEqual(RENAMED_COMPONENT, doc["component"])

    def test_that_ticket_updated_after_changing(self):
        #arrange
        ticket = self.insert_ticket("T1", description="some text")
        #act
        CHANGED_SUMMARY = "T1 changed"
        ticket["summary"] = CHANGED_SUMMARY
        ticket.save_changes()
        #arrange
        results = self.search_api.query("*")
        self.print_result(results)
        self.assertEqual(CHANGED_SUMMARY, results.docs[0]["summary"])

    def test_fills_product_field_if_product_is_set(self):
        with self.product('p'):
            self.insert_ticket("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.docs[0]["product"], 'p')

    def test_can_work_if_env_does_not_have_product(self):
        if 'product' in self.env:
            del self.env["product"]

        self.insert_ticket("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.hits, 1)
        self.assertNotIn("product", results.docs[0])

    def _insert_component(self, name):
        component = Component(self.env)
        component.name = name
        component.insert()
        return component
Example #37
0
    def setUp(self):
        super(QuerySuggestionTestCase, self).setUp(create_req=True)
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()

        self.search_api = BloodhoundSearchApi(self.env)
Example #38
0
class IndexWhooshTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(IndexWhooshTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)

    def tearDown(self):
        shutil.rmtree(self.env.path)
        self.env.reset_db()

    def test_can_index_ticket(self):
        ticket = self.create_dummy_ticket()
        TicketIndexer(self.env).resource_created(ticket, None)

        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_that_ticket_indexed_when_inserted_in_db(self):
        ticket = self.create_dummy_ticket()
        ticket.insert()
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_reindex_twice(self):
        self.insert_ticket("t1")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #just to test that index was re-created
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.assertEqual(1, results.hits)

    def test_can_reindex_tickets(self):
        self.insert_ticket("t1")
        self.insert_ticket("t2")
        self.insert_ticket("t3")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(3, results.hits)

    def test_can_reindex_wiki(self):
        self.insert_wiki("page1", "some text")
        self.insert_wiki("page2", "some text")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(2, results.hits)

    def test_can_reindex_mixed_types(self):
        self.insert_wiki("page1", "some text")
        self.insert_ticket("t1")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(2, results.hits)

    def test_can_reindex_milestones(self):
        MilestoneIndexer(self.env)
        self.insert_milestone("M1")
        self.insert_milestone("M2")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(2, results.hits)
Example #39
0
class ApiQueryWithWhooshTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(ApiQueryWithWhooshTestCase, self).setUp(create_req=True)
        WhooshBackend(self.env).recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.ticket_participant = TicketSearchParticipant(self.env)
        self.query_parser = DefaultQueryParser(self.env)

    def tearDown(self):
        shutil.rmtree(self.env.path)
        self.env.reset_db()

    def test_can_search_free_description(self):
        #arrange
        self.insert_ticket("dummy summary", description="aaa keyword bla")
        #act
        results = self.search_api.query("keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_query_free_summary(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        #act
        results = self.search_api.query("keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_query_strict_summary(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        self.insert_ticket("summary2", description="bla keyword")
        #act
        results = self.search_api.query("summary:keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_that_summary_hit_is_higher_than_description(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        self.insert_ticket("summary2", description="bla keyword")
        #act
        results = self.search_api.query("keyword")
        self.print_result(results)
        #assert
        self.assertEqual(2, results.hits)
        docs = results.docs
        self.assertEqual("summary1 keyword", docs[0]["summary"])
        self.assertEqual("summary2", docs[1]["summary"])

    def test_other_conditions_applied(self):
        #arrange
        self.insert_ticket("summary1 keyword", status="closed")
        self.insert_ticket("summary2", description="bla keyword")
        self.insert_ticket("summary3", status="closed")
        #act
        results = self.search_api.query("keyword status:closed")
        self.print_result(results)
        #assert
        self.assertEqual(1, results.hits)
        docs = results.docs
        self.assertEqual("summary1 keyword", docs[0]["summary"])

    def test_that_filter_queries_applied(self):
        #arrange
        self.insert_ticket("t1", status="closed", component="c1")
        self.insert_ticket("t2", status="closed", component="c1")
        self.insert_ticket("t3",
                           status="closed",
                           component="NotInFilterCriteria")
        #act
        results = self.search_api.query(
            "*",
            filter=['status:"closed"', 'component:"c1"'],
            sort=[SortInstruction("id", ASC)])
        self.print_result(results)
        #assert
        self.assertEqual(2, results.hits)
        docs = results.docs
        self.assertEqual("t1", docs[0]["summary"])
        self.assertEqual("t2", docs[1]["summary"])

    def test_that_upgrading_environment_adds_documents_to_index(self):
        self.insert_ticket("t1")
        self.insert_ticket("t2")

        self.search_api.upgrade_environment(self.env.db_transaction)

        results = self.search_api.query("type:ticket")

        self.assertEqual(2, results.hits)

    def test_can_index_wiki_with_same_id_from_different_products(self):
        with self.product('p1'):
            self.insert_wiki('title', 'content')
        with self.product('p2'):
            self.insert_wiki('title', 'content 2')

        results = self.search_api.query("type:wiki")

        self.assertEqual(results.hits, 2)
Example #40
0
 def setUp(self):
     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)
Example #41
0
class TicketIndexerTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(TicketIndexerTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.ticket_indexer = TicketIndexer(self.env)
        self.search_api = BloodhoundSearchApi(self.env)
        self.env.config.set('bhsearch', 'silence_on_error', "False")

    def tearDown(self):
        pass

    def test_does_not_raise_exception_by_default(self):
        self.env.config.set('bhsearch', 'silence_on_error', "True")
        self.ticket_indexer.resource_created(None, None)

    def test_raise_exception_if_configured(self):
        self.env.config.set('bhsearch', 'silence_on_error', "False")
        self.assertRaises(Exception, self.ticket_indexer.resource_created,
                          None)

    def test_can_strip_wiki_syntax(self):
        #act
        self.insert_ticket("T1", description=" = Header")
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)
        self.assertEqual("Header", results.docs[0]["content"])

    def test_that_tickets_updated_after_component_renaming(self):
        #arrange
        INITIAL_COMPONENT = "initial_name"
        RENAMED_COMPONENT = "renamed_name"
        component = self._insert_component(INITIAL_COMPONENT)
        self.insert_ticket("T1", component=INITIAL_COMPONENT)
        self.insert_ticket("T2", component=INITIAL_COMPONENT)
        #act
        component.name = RENAMED_COMPONENT
        component.update()
        #arrange
        results = self.search_api.query("*")
        self.print_result(results)
        for doc in results.docs:
            self.assertEqual(RENAMED_COMPONENT, doc["component"])

    def test_that_ticket_updated_after_changing(self):
        #arrange
        ticket = self.insert_ticket("T1", description="some text")
        #act
        CHANGED_SUMMARY = "T1 changed"
        ticket["summary"] = CHANGED_SUMMARY
        ticket.save_changes()
        #arrange
        results = self.search_api.query("*")
        self.print_result(results)
        self.assertEqual(CHANGED_SUMMARY, results.docs[0]["summary"])

    def test_fills_product_field_if_product_is_set(self):
        with self.product('p'):
            self.insert_ticket("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.docs[0]["product"], 'p')

    def test_can_work_if_env_does_not_have_product(self):
        if 'product' in self.env:
            del self.env["product"]

        self.insert_ticket("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.hits, 1)
        self.assertNotIn("product", results.docs[0])

    def _insert_component(self, name):
        component = Component(self.env)
        component.name = name
        component.insert()
        return component
Example #42
0
 def setUp(self):
     super(ApiQueryWithWhooshTestCase, self).setUp(create_req=True)
     WhooshBackend(self.env).recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
     self.ticket_participant = TicketSearchParticipant(self.env)
     self.query_parser = DefaultQueryParser(self.env)
Example #43
0
class WikiIndexerEventsTestCase(BaseBloodhoundSearchTest):
    DUMMY_PAGE_NAME = "dummyName"

    def setUp(self):
        super(WikiIndexerEventsTestCase, self).setUp()
        self.wiki_system = WikiSystem(self.env)
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.wiki_participant = WikiSearchParticipant(self.env)
        self.query_parser = DefaultQueryParser(self.env)

    def tearDown(self):
        shutil.rmtree(self.env.path)
        self.env.reset_db()

    def test_can_add_new_wiki_page_to_index(self):
        #arrange
        self.insert_wiki(self.DUMMY_PAGE_NAME, "dummy text")
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_PAGE_NAME, doc["id"])
        self.assertEqual("dummy text", doc["content"])
        self.assertEqual("wiki", doc["type"])

    def test_can_delete_wiki_page_from_index(self):
        #arrange
        self.insert_wiki(self.DUMMY_PAGE_NAME)
        WikiPage(self.env, self.DUMMY_PAGE_NAME).delete()
        #act
        results = self.search_api.query("*.*")
        #assert
        self.print_result(results)
        self.assertEqual(0, results.hits)

    def test_can_index_changed_event(self):
        #arrange
        self.insert_wiki(self.DUMMY_PAGE_NAME, "Text to be changed")
        page = WikiPage(self.env, self.DUMMY_PAGE_NAME)
        page.text = "changed text with keyword"
        page.save("anAuthor", "some comment", "::1")
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual("changed text with keyword", doc["content"])

    def test_can_index_renamed_event(self):
        #arrange
        self.insert_wiki(self.DUMMY_PAGE_NAME)
        page = WikiPage(self.env, self.DUMMY_PAGE_NAME)
        page.rename("NewPageName")
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        self.assertEqual("NewPageName", results.docs[0]["id"])

    def test_can_index_version_deleted_event(self):
        #arrange
        self.insert_wiki(self.DUMMY_PAGE_NAME, "version1")
        page = WikiPage(self.env, self.DUMMY_PAGE_NAME)
        page.text = "version 2"
        page.save("anAuthor", "some comment", "::1")
        page.delete(version=2)
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        self.assertEqual("version1", results.docs[0]["content"])

    def test_can_strip_wiki_formatting(self):
        #arrange
        self.insert_wiki(self.DUMMY_PAGE_NAME, " = Header")
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        self.assertEqual("Header", results.docs[0]["content"])

    def test_fills_product_field_if_product_is_set(self):
        with self.product('p'):
            self.insert_wiki(self.DUMMY_PAGE_NAME, "content")

        results = self.search_api.query("*")
        self.assertEqual(results.docs[0]["product"], 'p')

    def test_can_work_if_env_does_not_have_product(self):
        if 'product' in self.env:
            del self.env["product"]

        self.insert_wiki(self.DUMMY_PAGE_NAME, "content")

        results = self.search_api.query("*")
        self.assertEqual(results.hits, 1)
        self.assertNotIn("product", results.docs[0])
class MilestoneIndexerEventsTestCase(BaseBloodhoundSearchTest):
    DUMMY_MILESTONE_NAME = "dummyName"

    def setUp(self):
        super(MilestoneIndexerEventsTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)

    def test_can_index_created_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME, "dummy text")
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertEqual("dummy text", doc["content"])
        self.assertEqual("milestone", doc["type"])
        self.assertNotIn("due", doc )

    def test_can_index_minimal_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME)
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertNotIn("content", doc)


    def test_can_index_renamed_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME, "dummy text")
        self.change_milestone(
            self.DUMMY_MILESTONE_NAME,
            name="updated name",
            description="updated description",
        )
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual("updated name", doc["id"])
        self.assertEqual("updated description", doc["content"])

    def test_can_index_changed_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME, "dummy text")
        self.change_milestone(
            self.DUMMY_MILESTONE_NAME,
            description="updated description",
        )
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertEqual("updated description", doc["content"])

    def test_can_index_delete(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME)
        results = self.search_api.query("*")
        self.assertEqual(1, results.hits)
        #act
        Milestone(self.env, self.DUMMY_MILESTONE_NAME).delete()
        #assert
        results = self.search_api.query("*")
        self.print_result(results)
        self.assertEqual(0, results.hits)

    def test_can_reindex_minimal_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME)
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertEqual("milestone", doc["type"])

    def test_that_tickets_updated_after_milestone_renaming(self):
        #asser
        INITIAL_MILESTONE = "initial_milestone"
        RENAMED_MILESTONE = "renamed_name"
        milestone = self.insert_milestone(INITIAL_MILESTONE)
        self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
        self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
        #act
        milestone.name = RENAMED_MILESTONE
        milestone.update()
        #assert
        results = self.search_api.query("type:ticket")
        self.print_result(results)
        self.assertEqual(2, results.hits)
        self.assertEqual(RENAMED_MILESTONE, results.docs[0]["milestone"])
        self.assertEqual(RENAMED_MILESTONE, results.docs[1]["milestone"])

    def test_that_tickets_updated_after_milestone_delete_no_retarget(self):
        #asser
        INITIAL_MILESTONE = "initial_milestone"
        milestone = self.insert_milestone(INITIAL_MILESTONE)
        self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
        self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
        #act
        milestone.delete()
        #assert
        results = self.search_api.query("type:ticket")
        self.print_result(results)
        self.assertEqual(2, results.hits)
        self.assertNotIn("milestone", results.docs[0])
        self.assertNotIn("milestone", results.docs[1])

    def test_that_tickets_updated_after_milestone_delete_with_retarget(self):
        #asser
        INITIAL_MILESTONE = "initial_milestone"
        RETARGET_MILESTONE = "retarget_milestone"
        milestone = self.insert_milestone(INITIAL_MILESTONE)
        self.insert_milestone(RETARGET_MILESTONE)
        self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
        self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
        #act
        milestone.delete(retarget_to=RETARGET_MILESTONE)
        #assert
        results = self.search_api.query("type:ticket")
        self.print_result(results)
        self.assertEqual(2, results.hits)
        self.assertEqual(RETARGET_MILESTONE, results.docs[0]["milestone"])
        self.assertEqual(RETARGET_MILESTONE, results.docs[1]["milestone"])

    def test_fills_product_field_if_product_is_set(self):
        with self.product('p'):
            self.insert_milestone("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.docs[0]["product"], 'p')

    def test_can_work_if_env_does_not_have_product(self):
        if 'product' in self.env:
            del self.env["product"]

        self.insert_milestone("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.hits, 1)
        self.assertNotIn("product", results.docs[0])
Example #45
0
class ApiQueryWithWhooshTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(ApiQueryWithWhooshTestCase, self).setUp(create_req=True)
        WhooshBackend(self.env).recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)
        self.ticket_participant = TicketSearchParticipant(self.env)
        self.query_parser = DefaultQueryParser(self.env)

    def tearDown(self):
        shutil.rmtree(self.env.path)
        self.env.reset_db()

    def test_can_search_free_description(self):
        #arrange
        self.insert_ticket("dummy summary", description="aaa keyword bla")
        #act
        results = self.search_api.query("keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_query_free_summary(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        #act
        results = self.search_api.query("keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_query_strict_summary(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        self.insert_ticket("summary2", description = "bla keyword")
        #act
        results = self.search_api.query("summary:keyword")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_that_summary_hit_is_higher_than_description(self):
        #arrange
        self.insert_ticket("summary1 keyword")
        self.insert_ticket("summary2", description = "bla keyword")
        #act
        results = self.search_api.query("keyword")
        self.print_result(results)
        #assert
        self.assertEqual(2, results.hits)
        docs = results.docs
        self.assertEqual("summary1 keyword", docs[0]["summary"])
        self.assertEqual("summary2", docs[1]["summary"])

    def test_other_conditions_applied(self):
        #arrange
        self.insert_ticket("summary1 keyword", status="closed")
        self.insert_ticket("summary2", description = "bla keyword")
        self.insert_ticket("summary3", status="closed")
        #act
        results = self.search_api.query("keyword status:closed")
        self.print_result(results)
        #assert
        self.assertEqual(1, results.hits)
        docs = results.docs
        self.assertEqual("summary1 keyword", docs[0]["summary"])

    def test_that_filter_queries_applied(self):
        #arrange
        self.insert_ticket("t1", status="closed", component = "c1")
        self.insert_ticket("t2", status="closed", component = "c1")
        self.insert_ticket("t3", status="closed",
            component = "NotInFilterCriteria")
        #act
        results = self.search_api.query(
            "*",
            filter= ['status:"closed"', 'component:"c1"'],
            sort= [SortInstruction("id", ASC)]
        )
        self.print_result(results)
        #assert
        self.assertEqual(2, results.hits)
        docs = results.docs
        self.assertEqual("t1", docs[0]["summary"])
        self.assertEqual("t2", docs[1]["summary"])

    def test_that_upgrading_environment_adds_documents_to_index(self):
        self.insert_ticket("t1")
        self.insert_ticket("t2")

        self.search_api.upgrade_environment(self.env.db_transaction)

        results = self.search_api.query("type:ticket")

        self.assertEqual(2, results.hits)

    def test_can_index_wiki_with_same_id_from_different_products(self):
        with self.product('p1'):
            self.insert_wiki('title', 'content')
        with self.product('p2'):
            self.insert_wiki('title', 'content 2')

        results = self.search_api.query("type:wiki")

        self.assertEqual(results.hits, 2)
Example #46
0
 def setUp(self):
     super(ApiQueryWithWhooshTestCase, self).setUp(create_req=True)
     WhooshBackend(self.env).recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
     self.ticket_participant = TicketSearchParticipant(self.env)
     self.query_parser = DefaultQueryParser(self.env)
Example #47
0
class IndexWhooshTestCase(BaseBloodhoundSearchTest):
    def setUp(self):
        super(IndexWhooshTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)

    def tearDown(self):
        shutil.rmtree(self.env.path)
        self.env.reset_db()

    def test_can_index_ticket(self):
        ticket = self.create_dummy_ticket()
        TicketIndexer(self.env).resource_created(ticket, None)

        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_that_ticket_indexed_when_inserted_in_db(self):
        ticket = self.create_dummy_ticket()
        ticket.insert()
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)

    def test_can_reindex_twice(self):
        self.insert_ticket("t1")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
         #just to test that index was re-created
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.assertEqual(1, results.hits)

    def test_can_reindex_tickets(self):
        self.insert_ticket("t1")
        self.insert_ticket("t2")
        self.insert_ticket("t3")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(3, results.hits)

    def test_can_reindex_wiki(self):
        self.insert_wiki("page1", "some text")
        self.insert_wiki("page2", "some text")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(2, results.hits)

    def test_can_reindex_mixed_types(self):
        self.insert_wiki("page1", "some text")
        self.insert_ticket("t1")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(2, results.hits)

    def test_can_reindex_milestones(self):
        MilestoneIndexer(self.env)
        self.insert_milestone("M1")
        self.insert_milestone("M2")
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(2, results.hits)
    def setUp(self):
        super(QuerySuggestionTestCase, self).setUp(create_req=True)
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()

        self.search_api = BloodhoundSearchApi(self.env)
class MilestoneIndexerEventsTestCase(BaseBloodhoundSearchTest):
    DUMMY_MILESTONE_NAME = "dummyName"

    def setUp(self):
        super(MilestoneIndexerEventsTestCase, self).setUp()
        self.whoosh_backend = WhooshBackend(self.env)
        self.whoosh_backend.recreate_index()
        self.search_api = BloodhoundSearchApi(self.env)

    def test_can_index_created_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME, "dummy text")
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertEqual("dummy text", doc["content"])
        self.assertEqual("milestone", doc["type"])
        self.assertNotIn("due", doc)

    def test_can_index_minimal_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME)
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertNotIn("content", doc)

    def test_can_index_renamed_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME, "dummy text")
        self.change_milestone(
            self.DUMMY_MILESTONE_NAME,
            name="updated name",
            description="updated description",
        )
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual("updated name", doc["id"])
        self.assertEqual("updated description", doc["content"])

    def test_can_index_changed_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME, "dummy text")
        self.change_milestone(
            self.DUMMY_MILESTONE_NAME,
            description="updated description",
        )
        #act
        results = self.search_api.query("*:*")
        #assert
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertEqual("updated description", doc["content"])

    def test_can_index_delete(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME)
        results = self.search_api.query("*")
        self.assertEqual(1, results.hits)
        #act
        Milestone(self.env, self.DUMMY_MILESTONE_NAME).delete()
        #assert
        results = self.search_api.query("*")
        self.print_result(results)
        self.assertEqual(0, results.hits)

    def test_can_reindex_minimal_milestone(self):
        #arrange
        self.insert_milestone(self.DUMMY_MILESTONE_NAME)
        self.whoosh_backend.recreate_index()
        #act
        self.search_api.rebuild_index()
        #assert
        results = self.search_api.query("*:*")
        self.print_result(results)
        self.assertEqual(1, results.hits)
        doc = results.docs[0]
        self.assertEqual(self.DUMMY_MILESTONE_NAME, doc["id"])
        self.assertEqual("milestone", doc["type"])

    def test_that_tickets_updated_after_milestone_renaming(self):
        #asser
        INITIAL_MILESTONE = "initial_milestone"
        RENAMED_MILESTONE = "renamed_name"
        milestone = self.insert_milestone(INITIAL_MILESTONE)
        self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
        self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
        #act
        milestone.name = RENAMED_MILESTONE
        milestone.update()
        #assert
        results = self.search_api.query("type:ticket")
        self.print_result(results)
        self.assertEqual(2, results.hits)
        self.assertEqual(RENAMED_MILESTONE, results.docs[0]["milestone"])
        self.assertEqual(RENAMED_MILESTONE, results.docs[1]["milestone"])

    def test_that_tickets_updated_after_milestone_delete_no_retarget(self):
        #asser
        INITIAL_MILESTONE = "initial_milestone"
        milestone = self.insert_milestone(INITIAL_MILESTONE)
        self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
        self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
        #act
        milestone.delete()
        #assert
        results = self.search_api.query("type:ticket")
        self.print_result(results)
        self.assertEqual(2, results.hits)
        self.assertNotIn("milestone", results.docs[0])
        self.assertNotIn("milestone", results.docs[1])

    def test_that_tickets_updated_after_milestone_delete_with_retarget(self):
        #asser
        INITIAL_MILESTONE = "initial_milestone"
        RETARGET_MILESTONE = "retarget_milestone"
        milestone = self.insert_milestone(INITIAL_MILESTONE)
        self.insert_milestone(RETARGET_MILESTONE)
        self.insert_ticket("T1", milestone=INITIAL_MILESTONE)
        self.insert_ticket("T2", milestone=INITIAL_MILESTONE)
        #act
        milestone.delete(retarget_to=RETARGET_MILESTONE)
        #assert
        results = self.search_api.query("type:ticket")
        self.print_result(results)
        self.assertEqual(2, results.hits)
        self.assertEqual(RETARGET_MILESTONE, results.docs[0]["milestone"])
        self.assertEqual(RETARGET_MILESTONE, results.docs[1]["milestone"])

    def test_fills_product_field_if_product_is_set(self):
        with self.product('p'):
            self.insert_milestone("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.docs[0]["product"], 'p')

    def test_can_work_if_env_does_not_have_product(self):
        if 'product' in self.env:
            del self.env["product"]

        self.insert_milestone("T1")

        results = self.search_api.query("*")
        self.assertEqual(results.hits, 1)
        self.assertNotIn("product", results.docs[0])
 def setUp(self):
     super(MilestoneIndexerEventsTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)
 def setUp(self):
     super(MilestoneIndexerEventsTestCase, self).setUp()
     self.whoosh_backend = WhooshBackend(self.env)
     self.whoosh_backend.recreate_index()
     self.search_api = BloodhoundSearchApi(self.env)