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 test_does_not_automatically_create_index(self): whoosh_backend = WhooshBackend(self.env) self.assertIs(whoosh_backend.index, None) self.assertEqual(whoosh_backend.is_index_outdated(), True) whoosh_backend.recreate_index() self.assertEqual(whoosh_backend.is_index_outdated(), False) self.assertIsNot(whoosh_backend.index, None)
def test_detects_that_index_needs_upgrade(self): wrong_schema = Schema(content=TEXT()) index.create_in(self.index_dir, schema=wrong_schema) whoosh_backend = WhooshBackend(self.env) self.assertEqual(whoosh_backend.is_index_outdated(), True) whoosh_backend.recreate_index() self.assertEqual(whoosh_backend.is_index_outdated(), False)
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 RealIndexTestCase(BaseBloodhoundSearchTest): """ This test case is not supposed to be run from CI tool. The purpose of the class is to work with real Bloodhound Search Index and should be used for debugging purposes only """ def setUp(self): self.env = EnvironmentStub(enable=['bhsearch.*']) current_current_dir = os.getcwd() real_env_path = os.path.join( current_current_dir, "../../../installer/bloodhound/environments/main") self.env.path = real_env_path self.whoosh_backend = WhooshBackend(self.env) self.req = Mock( perm=MockPerm(), chrome={'logo': {}}, href=Href("/main"), args=arg_list_to_args([]), ) def test_read_all(self): result = self.whoosh_backend.query( query.Every() ) self.print_result(result) result = self.whoosh_backend.query( query.Every() ) self.print_result(result) self.assertLessEqual(1, result.hits) def test_read_with_type_facet(self): result = self.whoosh_backend.query( query.Every() ) self.print_result(result) result = self.whoosh_backend.query( query.Every(), facets=["type"] ) self.print_result(result) self.assertLessEqual(1, result.hits) def test_read_from_search_module(self): self.req.args[RequestParameters.QUERY] = "*" self.process_request()
def setUp(self): super(WebUiTestCaseWithWhoosh, self).setUp( create_req=True, ) self.req.redirect = self.redirect whoosh_backend = WhooshBackend(self.env) whoosh_backend.recreate_index() self.req.redirect = self.redirect self.redirect_url = None self.redirect_permanent = None self.old_product_environment = web_ui.ProductEnvironment self._inject_mocked_product_environment()
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 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 WhooshEmptyFacetErrorWorkaroundTestCase(BaseBloodhoundSearchTest): def setUp(self): super(WhooshEmptyFacetErrorWorkaroundTestCase, self).setUp() self.whoosh_backend = WhooshBackend(self.env) self.whoosh_backend.recreate_index() self.parser = DefaultQueryParser(self.env) self.empty_facet_workaround = WhooshEmptyFacetErrorWorkaround(self.env) def tearDown(self): shutil.rmtree(self.env.path) self.env.reset_db() def test_set_should_not_be_empty_fields(self): self.insert_ticket("test x") result = self.whoosh_backend.query(query.Every()) self.print_result(result) doc = result.docs[0] null_marker = WhooshEmptyFacetErrorWorkaround.NULL_MARKER self.assertEqual(null_marker, doc["component"]) self.assertEqual(null_marker, doc["status"]) self.assertEqual(null_marker, doc["milestone"]) def test_can_fix_query_filter(self): parsed_filter = self.parser.parse_filters( ["type:ticket", "NOT (milestone:*)"]) query_parameters = dict(filter=parsed_filter) self.empty_facet_workaround.query_pre_process( query_parameters) result_filter = query_parameters["filter"] self.assertEquals('(type:ticket AND milestone:empty)', str(result_filter)) def test_does_interfere_query_filter_if_not_needed(self): parsed_filter = self.parser.parse_filters( ["type:ticket", "milestone:aaa"]) query_parameters = dict(filter=parsed_filter) self.empty_facet_workaround.query_pre_process( query_parameters) result_filter = query_parameters["filter"] self.assertEquals('(type:ticket AND milestone:aaa)', str(result_filter))
def setUp(self): super(WebUiTestCaseWithWhoosh, self).setUp( create_req=True, ) self.req.redirect = self.redirect whoosh_backend = WhooshBackend(self.env) whoosh_backend.recreate_index() self.req = Mock( perm=MockPerm(), chrome={'logo': {}}, href=Href("/main"), base_path=BASE_PATH, args=arg_list_to_args([]), redirect=self.redirect ) self.redirect_url = None self.redirect_permanent = None
def setUp(self): self.env = EnvironmentStub(enable=['bhsearch.*']) current_current_dir = os.getcwd() real_env_path = os.path.join( current_current_dir, "../../../installer/bloodhound/environments/main") self.env.path = real_env_path self.whoosh_backend = WhooshBackend(self.env) self.req = Mock( perm=MockPerm(), chrome={'logo': {}}, href=Href("/main"), args=arg_list_to_args([]), )
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 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
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(IndexWhooshTestCase, self).setUp() self.whoosh_backend = WhooshBackend(self.env) self.whoosh_backend.recreate_index() self.search_api = BloodhoundSearchApi(self.env)
class WhooshBackendTestCase(BaseBloodhoundSearchTest): def setUp(self): super(WhooshBackendTestCase, self).setUp() self.whoosh_backend = WhooshBackend(self.env) self.whoosh_backend.recreate_index() self.parser = DefaultQueryParser(self.env) def test_can_retrieve_docs(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) self.whoosh_backend.add_doc(dict(id="2", type="ticket")) result = self.whoosh_backend.query( query.Every(), sort = [SortInstruction("id", ASC)], ) self.print_result(result) self.assertEqual(2, result.hits) docs = result.docs self.assertEqual( {'id': u'1', 'type': u'ticket', 'unique_id': u'empty:ticket:1', 'score': u'1'}, docs[0]) self.assertEqual( {'id': u'2', 'type': u'ticket', 'unique_id': u'empty:ticket:2', 'score': u'2'}, docs[1]) def test_can_return_all_fields(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) result = self.whoosh_backend.query(query.Every()) self.print_result(result) docs = result.docs self.assertEqual( {'id': u'1', 'type': u'ticket', 'unique_id': u'empty:ticket:1', "score": 1.0}, docs[0]) def test_can_select_fields(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) result = self.whoosh_backend.query(query.Every(), fields=("id", "type")) self.print_result(result) docs = result.docs self.assertEqual( {'id': '1', 'type': 'ticket'}, docs[0]) def test_can_survive_after_restart(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) whoosh_backend2 = WhooshBackend(self.env) whoosh_backend2.add_doc(dict(id="2", type="ticket")) result = whoosh_backend2.query(query.Every()) self.assertEqual(2, result.hits) def test_can_apply_multiple_sort_conditions_asc(self): self.whoosh_backend.add_doc(dict(id="2", type="ticket2")) self.whoosh_backend.add_doc(dict(id="3", type="ticket1")) self.whoosh_backend.add_doc(dict(id="4", type="ticket3")) self.whoosh_backend.add_doc(dict(id="1", type="ticket1")) result = self.whoosh_backend.query( query.Every(), sort = [SortInstruction("type", ASC), SortInstruction("id", ASC)], fields=("id", "type"), ) self.print_result(result) self.assertEqual([{'type': 'ticket1', 'id': '1'}, {'type': 'ticket1', 'id': '3'}, {'type': 'ticket2', 'id': '2'}, {'type': 'ticket3', 'id': '4'}], result.docs) def test_can_apply_multiple_sort_conditions_desc(self): self.whoosh_backend.add_doc(dict(id="2", type="ticket2")) self.whoosh_backend.add_doc(dict(id="3", type="ticket1")) self.whoosh_backend.add_doc(dict(id="4", type="ticket3")) self.whoosh_backend.add_doc(dict(id="1", type="ticket1")) result = self.whoosh_backend.query( query.Every(), sort = [SortInstruction("type", ASC), SortInstruction("id", DESC)], fields=("id", "type"), ) self.print_result(result) self.assertEqual([{'type': 'ticket1', 'id': '3'}, {'type': 'ticket1', 'id': '1'}, {'type': 'ticket2', 'id': '2'}, {'type': 'ticket3', 'id': '4'}], result.docs) def test_can_sort_by_score_and_date(self): the_first_date = datetime(2012, 12, 1) the_second_date = datetime(2012, 12, 2) the_third_date = datetime(2012, 12, 3) exact_match_string = "texttofind" not_exact_match_string = "texttofind bla" self.whoosh_backend.add_doc(dict( id="1", type="ticket", summary=not_exact_match_string, time=the_first_date, )) self.whoosh_backend.add_doc(dict( id="2", type="ticket", summary=exact_match_string, time=the_second_date, )) self.whoosh_backend.add_doc(dict( id="3", type="ticket", summary=not_exact_match_string, time=the_third_date, )) self.whoosh_backend.add_doc(dict( id="4", type="ticket", summary="some text out of search scope", time=the_third_date, )) parsed_query = self.parser.parse("summary:texttofind") result = self.whoosh_backend.query( parsed_query, sort = [ SortInstruction(SCORE, ASC), SortInstruction("time", DESC) ], ) self.print_result(result) self.assertEqual(3, result.hits) docs = result.docs #must be found first, because the highest score (of exact match) self.assertEqual("2", docs[0]["id"]) #must be found second, because the time order DESC self.assertEqual("3", docs[1]["id"]) #must be found third, because the time order DESC self.assertEqual("1", docs[2]["id"]) def test_can_do_facet_count(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket", product="A")) self.whoosh_backend.add_doc(dict(id="2", type="ticket", product="B")) self.whoosh_backend.add_doc(dict(id="3", type="wiki", product="A")) result = self.whoosh_backend.query( query.Every(), sort = [SortInstruction("type", ASC), SortInstruction("id", DESC)], fields=("id", "type"), facets= ("type", "product") ) self.print_result(result) self.assertEqual(3, result.hits) facets = result.facets self.assertEqual({"ticket":2, "wiki":1}, facets["type"]) self.assertEqual({"A":2, "B":1}, facets["product"]) def test_can_do_facet_if_filed_missing_TODO(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) self.whoosh_backend.add_doc(dict(id="2", type="ticket", status="New")) result = self.whoosh_backend.query( query.Every(), facets= ("type", "status") ) self.print_result(result) self.assertEqual(2, result.hits) facets = result.facets self.assertEqual({"ticket":2}, facets["type"]) self.assertEqual({None: 1, 'New': 1}, facets["status"]) def test_can_return_empty_result(self): result = self.whoosh_backend.query( query.Every(), sort = [SortInstruction("type", ASC), SortInstruction("id", DESC)], fields=("id", "type"), facets= ("type", "product") ) self.print_result(result) self.assertEqual(0, result.hits) def test_can_search_time_with_utc_tzinfo(self): time = datetime(2012, 12, 13, 11, 8, 34, 711957, tzinfo=FixedOffset(0, 'UTC')) self.whoosh_backend.add_doc(dict(id="1", type="ticket", time=time)) result = self.whoosh_backend.query(query.Every()) self.print_result(result) self.assertEqual(time, result.docs[0]["time"]) def test_can_search_time_without_tzinfo(self): time = datetime(2012, 12, 13, 11, 8, 34, 711957, tzinfo=None) self.whoosh_backend.add_doc(dict(id="1", type="ticket", time=time)) result = self.whoosh_backend.query(query.Every()) self.print_result(result) self.assertEqual(time.replace(tzinfo=utc), result.docs[0]["time"]) def test_can_search_time_with_non_utc_tzinfo(self): hours = 8 tz_diff = 1 time = datetime(2012, 12, 13, 11, hours, 34, 711957, tzinfo=FixedOffset(tz_diff, "just_one_timezone")) self.whoosh_backend.add_doc(dict(id="1", type="ticket", time=time)) result = self.whoosh_backend.query(query.Every()) self.print_result(result) self.assertEqual(datetime(2012, 12, 13, 11, hours-tz_diff, 34, 711957, tzinfo=utc), result.docs[0]["time"]) def test_can_apply_filter_and_facet(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) self.whoosh_backend.add_doc(dict(id="2", type="wiki" )) result = self.whoosh_backend.query( query.Every(), filter=query.Term("type", "ticket"), facets=["type"] ) self.print_result(result) self.assertEqual(1, result.hits) self.assertEqual("ticket", result.docs[0]["type"]) @unittest.skip("TODO clarify behavior on Whoosh mail list") def test_can_search_id_and_summary_TODO(self): #arrange self.insert_ticket("test x") self.insert_ticket("test 1") fieldboosts = dict( id = 1, summary = 1, ) mfp = MultifieldPlugin(list(fieldboosts.keys()),) pins = [WhitespacePlugin, PhrasePlugin, mfp] parser = QueryParser(None, WhooshBackend.SCHEMA, plugins=pins) parsed_query = parser.parse("1") result = self.whoosh_backend.query(parsed_query) self.print_result(result) self.assertEqual(2, result.hits) def test_no_index_error_when_counting_facet_on_missing_field(self): """ Whoosh 2.4.1 raises "IndexError: list index out of range" when search contains facets on field that is missing in at least one document in the index. The error manifests only when index contains more than one segment Introduced workaround should solve this problem. """ #add more tickets to make sure we have more than one segment in index count = 20 for i in range(count): self.insert_ticket("test %s" % (i)) result = self.whoosh_backend.query( query.Every(), facets=["milestone"] ) self.assertEquals(count, result.hits) def test_can_query_missing_field_and_type(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) self.whoosh_backend.add_doc(dict(id="2", type="ticket", milestone="A")) self.whoosh_backend.add_doc(dict(id="3", type="wiki")) filter = self.parser.parse_filters(["NOT (milestone:*)", "type:ticket"]) result = self.whoosh_backend.query( query.Every(), filter=filter, ) self.print_result(result) self.assertEqual(1, result.hits) self.assertEqual("1", result.docs[0]["id"]) def test_can_query_missing_field(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) self.whoosh_backend.add_doc(dict(id="2", type="ticket", milestone="A")) filter = self.parser.parse_filters(["NOT (milestone:*)"]) result = self.whoosh_backend.query( query.Every(), filter=filter, ) self.print_result(result) self.assertEqual(1, result.hits) self.assertEqual("1", result.docs[0]["id"]) @unittest.skip("TODO clarify behavior on Whoosh mail list") def test_can_query_missing_field_and_type_with_no_results(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) self.whoosh_backend.add_doc(dict(id="3", type="wiki")) filter = self.parser.parse_filters(["NOT (milestone:*)", "type:ticket"]) result = self.whoosh_backend.query( query.Every(), filter=filter, ) self.print_result(result) self.assertEqual(0, result.hits) def test_can_highlight_given_terms(self): term = 'search_term' text = "foo foo %s bar bar" % term self.whoosh_backend.add_doc(dict(id="1", type="ticket", content=text)) self.whoosh_backend.add_doc(dict(id="3", type="wiki", content=text)) search_query = self.parser.parse(term) result = self.whoosh_backend.query( search_query, highlight=True, highlight_fields=['content', 'summary'] ) self.print_result(result) self.assertEqual(len(result.highlighting), 2) for highlight in result.highlighting: self.assertIn(self._highlighted(term), highlight['content']) self.assertEquals("", highlight['summary']) def test_that_highlighting_escapes_html(self): term = 'search_term' text = "bla <a href=''>%s bar</a> bla" % term self.whoosh_backend.add_doc(dict(id="1", type="ticket", content=text)) search_query = self.parser.parse(term) result = self.whoosh_backend.query( search_query, highlight=True, highlight_fields=['content'] ) self.print_result(result) self.assertEqual(len(result.highlighting), 1) highlight = result.highlighting[0] self.assertEquals( "bla <a href=''><em>search_term</em> bar</a> bla", highlight['content']) def test_highlights_all_text_fields_by_default(self): term = 'search_term' text = "foo foo %s bar bar" % term self.whoosh_backend.add_doc(dict(id="1", type="ticket", content=text)) self.whoosh_backend.add_doc(dict(id="3", type="wiki", content=text)) search_query = self.parser.parse(term) result = self.whoosh_backend.query( search_query, highlight=True, ) self.print_result(result) self.assertEqual(len(result.highlighting), 2) for highlight in result.highlighting: self.assertIn('content', highlight) self.assertIn('summary', highlight) self.assertIn(self._highlighted(term), highlight['content']) def test_only_highlights_terms_in_fields_that_match_query(self): term = 'search_term' self.whoosh_backend.add_doc(dict(id=term, type="wiki", content=term)) self.whoosh_backend.add_doc(dict(id=term, type="ticket", summary=term)) search_query = self.parser.parse('id:%s' % term) result = self.whoosh_backend.query( search_query, highlight=True, highlight_fields=["id", "content", "summary"] ) self.print_result(result) self.assertEqual(len(result.highlighting), 2) for highlight in result.highlighting: self.assertIn(self._highlighted(term), highlight['id']) self.assertNotIn(self._highlighted(term), highlight['summary']) self.assertNotIn(self._highlighted(term), highlight['content']) def _highlighted(self, term): return '<em>%s</em>' % term
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])
def test_can_survive_after_restart(self): self.whoosh_backend.add_doc(dict(id="1", type="ticket")) whoosh_backend2 = WhooshBackend(self.env) whoosh_backend2.add_doc(dict(id="2", type="ticket")) result = whoosh_backend2.query(query.Every()) self.assertEqual(2, result.hits)
def setUp(self): super(WhooshEmptyFacetErrorWorkaroundTestCase, self).setUp() self.whoosh_backend = WhooshBackend(self.env) self.whoosh_backend.recreate_index() self.parser = DefaultQueryParser(self.env) self.empty_facet_workaround = WhooshEmptyFacetErrorWorkaround(self.env)
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 _create_whoosh_index(self): WhooshBackend(self.env).recreate_index()
def setUp(self): super(WhooshBackendTestCase, self).setUp() self.whoosh_backend = WhooshBackend(self.env) self.whoosh_backend.recreate_index() self.parser = DefaultQueryParser(self.env)
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 setUp(self): super(MilestoneIndexerEventsTestCase, self).setUp() self.whoosh_backend = WhooshBackend(self.env) self.whoosh_backend.recreate_index() self.search_api = BloodhoundSearchApi(self.env)
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