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) }
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()
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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'])
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')
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)
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)
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)
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)
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)
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
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 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)
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)
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
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)
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])
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)
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)