def setUp(self): self.env = EnvironmentStub() self.search_module = SearchModule(self.env) pages_dir = pkg_resources.resource_filename('trac.wiki', 'default-pages') for page_name in ('WikiStart', 'TracModWSGI'): page = os.path.join(pages_dir, page_name) WikiAdmin(self.env).import_page(page, page_name)
def get_search_results(self, req, query, filters): #return if search all is not active if 'searchall' not in filters: return if not req.perm.has_permission( 'SEARCHALL_VIEW') and not req.perm.has_permission( 'TRAC_ADMIN'): return # remove 'searchall' from filters subfilters = [] for filter in filters: if not filter == 'searchall': subfilters.append(filter) # don't do anything if we have no filters if not subfilters: return projects = self.get_project_list(req) for project, project_path, project_url, env in projects: results = [] env_search = SearchModule(env) #available_filters = [] #for source in env_search.search_sources: # available_filters += source.get_search_filters(req) #subfilters = [x[0] for x in available_filters if x[0] != 'searchall'] self.env.log.debug("Searching project %s" % project) self.env.log.debug("Searching for %s" % query[0]) self.env.log.debug("Searching with filters %s" % subfilters) #Update request data orig_href = req.href req.href = Href(project_url) for source in env_search.search_sources: for filter in subfilters: try: results += list( source.get_search_results(req, query, [filter])) except Exception, ex: results += [ (req.href('search', **req.args), "<strong>ERROR</strong> in search filter <em>%s</em>" % filter, to_datetime(None), "none", "Exception: %s" % to_unicode(ex)), ] req.href = orig_href for result in results: yield (result[0], Markup('%s<br/> %s' % (env.project_name, result[1])))\ + result[2:]
class SearchModuleTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.search_module = SearchModule(self.env) def tearDown(self): self.env.reset_db() def _insert_ticket(self, **kw): """Helper for inserting a ticket into the database""" ticket = Ticket(self.env) for k, v in kw.items(): ticket[k] = v return ticket.insert() def test_process_request_page_in_range(self): for _ in range(0, 21): self._insert_ticket(summary="Trac") req = MockRequest(self.env, args={ 'page': '3', 'q': 'Trac', 'ticket': 'on' }) data = self.search_module.process_request(req)[1] self.assertEqual([], req.chrome['warnings']) self.assertEqual(2, data['results'].page) def test_process_request_page_out_of_range(self): """Out of range value for page defaults to page 1.""" for _ in range(0, 20): self._insert_ticket(summary="Trac") req = MockRequest(self.env, args={ 'page': '3', 'q': 'Trac', 'ticket': 'on' }) data = self.search_module.process_request(req)[1] self.assertIn("Page 3 is out of range.", req.chrome['warnings']) self.assertEqual(0, data['results'].page)
def get_search_filters(self, req): if not req.perm.has_permission( 'SEARCHALL_VIEW') and not req.perm.has_permission( 'TRAC_ADMIN'): return if hasattr(req, 'is_searchall_recursive'): return req.is_searchall_recursive = True #Check what filters are available in current project existing_filters = [] env_search = SearchModule(self.env) for source in env_search.search_sources: if source == self: continue existing_filters += source.get_search_filters(req) #Now get the filters available in other projects projects = self.get_project_list(req) for project, project_path, project_url, env in projects: env_search = SearchModule(env) available_filters = [] for source in env_search.search_sources: available_filters += source.get_search_filters(req) for filter in available_filters: if filter in existing_filters: continue existing_filters.append(filter) self.env.log.debug("Yielding %s from project %s", filter, project) yield filter yield ('searchall', 'All projects', 0)
def references_search(self, req, q, filters=[]): """ Returns list of possible references objects for given search parameters.""" if not q or not filters: return [] query = SearchModule(self.env)._get_search_terms(q) all_types = [ticket.name for ticket in Type.select(self.env)] used_types = [t for t in all_types if filters] if used_types: filters.append('ticket') filtered_res =[] for source in self.search_sources: for href, title, date, author, excerpt in source.get_search_results(req, query, filters): self.env.log.debug('references_search-res=%s' % ((href, title, date, author, excerpt),)) path = href.split('/') res = { 'href': href, 'date': date, 'author': author, 'excerpt': excerpt, 'title' : title, 'type': path[-2], 'id': path[-1] } if(res['type']=='ticket'): #hack to avoid database access self.env.log.debug('references_search-ticket=%s' % res) match = re.match('<span .+?>(.*?)</span>:(.+?):(.*)', str(title)) if match: ticket_type = match.group(2).strip() self.env.log.debug('references_search-ticket-type=%s' % ticket_type) if ticket_type not in filters: continue res.update( { 'title' :to_unicode(match.group(3)), 'idx': '%02d' % all_types.index(ticket_type), 'subtype' : ticket_type } ) else: res['title'] = to_unicode('wiki: %s' % res['title'].split(':',2)[0]) res['idx']=99 filtered_res.append(res) filtered_res.sort(key= lambda x: '%s %s' % (x['idx'], x['title'])) return filtered_res
def performSearch(self, req, query, filters=None): """ Perform a search using the given filters. Defaults to all if not provided. Results are returned as a list of tuples in the form (href, title, date, author, excerpt).""" query = SearchModule(self.env)._get_search_terms(query) filters_provided = filters is not None chosen_filters = set(filters or []) available_filters = [] for source in self.search_sources: available_filters += source.get_search_filters(req) filters = [f[0] for f in available_filters if f[0] in chosen_filters] if not filters: if filters_provided: return [] filters = [f[0] for f in available_filters] self.env.log.debug("Searching with %s", filters) results = [] for source in self.search_sources: for result in source.get_search_results(req, query, filters) or []: results.append(['/'.join(req.base_url.split('/')[0:3]) + result[0]] + list(result[1:])) return results
def setUp(self): self.env = EnvironmentStub() self.search_module = SearchModule(self.env)
class SearchModuleTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.search_module = SearchModule(self.env) pages_dir = pkg_resources.resource_filename('trac.wiki', 'default-pages') for page_name in ('WikiStart', 'TracModWSGI'): page = os.path.join(pages_dir, page_name) WikiAdmin(self.env).import_page(page, page_name) def tearDown(self): self.env.reset_db() def _insert_ticket(self, **kw): """Helper for inserting a ticket into the database""" ticket = Ticket(self.env) for k, v in kw.items(): ticket[k] = v return ticket.insert() def test_process_request_page_in_range(self): for _ in range(0, 21): self._insert_ticket(summary="Trac") req = MockRequest(self.env, args={ 'page': '3', 'q': 'Trac', 'ticket': 'on' }) data = self.search_module.process_request(req)[1] self.assertEqual([], req.chrome['warnings']) self.assertEqual(2, data['results'].page) def test_process_request_page_out_of_range(self): """Out of range value for page defaults to page 1.""" for _ in range(0, 20): self._insert_ticket(summary="Trac") req = MockRequest(self.env, args={ 'page': '3', 'q': 'Trac', 'ticket': 'on' }) data = self.search_module.process_request(req)[1] self.assertIn("Page 3 is out of range.", req.chrome['warnings']) self.assertEqual(0, data['results'].page) def test_camelcase_quickjump(self): """CamelCase word does quick-jump.""" req = MockRequest(self.env, args={'q': 'WikiStart'}) self.assertRaises(RequestDone, self.search_module.process_request, req) self.assertEqual('http://example.org/trac.cgi/wiki/WikiStart', req.headers_sent['Location']) self.assertIn("You arrived here through", req.chrome['notices'][0]) self.assertIn( '<a href="/trac.cgi/search?' 'q=WikiStart&noquickjump=1">here</a>', req.chrome['notices'][0]) def test_non_camelcase_no_quickjump(self): """Non-CamelCase word does not quick-jump.""" req = MockRequest(self.env, args={'q': 'TracModWSGI'}) data = self.search_module.process_request(req)[1] results = list(data['results']) self.assertIsNone(data['quickjump']) self.assertEqual('TracModWSGI', data['query']) self.assertEqual(1, len(results)) self.assertEqual('/trac.cgi/wiki/TracModWSGI', results[0]['href']) self.assertEqual([], req.chrome['notices'])
class SearchModuleTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.search_module = SearchModule(self.env) def tearDown(self): self.env.reset_db() def _create_request(self, authname='anonymous', **kwargs): kw = { 'path_info': '/', 'perm': MockPerm(), 'args': _RequestArgs(), 'href': self.env.href, 'abs_href': self.env.abs_href, 'tz': utc, 'locale': None, 'lc_time': locale_en, 'session': {}, 'authname': authname, 'chrome': { 'notices': [], 'warnings': [] }, 'method': None, 'get_header': lambda v: None, 'is_xhr': False, 'form_token': None } if 'args' in kwargs: kw['args'].update(kwargs.pop('args')) kw.update(kwargs) def redirect(url, permanent=False): raise RequestDone return Mock(add_redirect_listener=lambda x: [].append(x), redirect=redirect, **kw) def _insert_ticket(self, **kw): """Helper for inserting a ticket into the database""" ticket = Ticket(self.env) for k, v in kw.items(): ticket[k] = v return ticket.insert() def test_process_request_page_in_range(self): for _ in range(0, 21): self._insert_ticket(summary="Trac") req = self._create_request(args={ 'page': '3', 'q': 'Trac', 'ticket': 'on' }) data = self.search_module.process_request(req)[1] self.assertEqual([], req.chrome['warnings']) self.assertEqual(2, data['results'].page) def test_process_request_page_out_of_range(self): """Out of range value for page defaults to page 1.""" for _ in range(0, 20): self._insert_ticket(summary="Trac") req = self._create_request(args={ 'page': '3', 'q': 'Trac', 'ticket': 'on' }) data = self.search_module.process_request(req)[1] self.assertIn("Page 3 is out of range.", req.chrome['warnings']) self.assertEqual(0, data['results'].page)
class SearchModuleTestCase(unittest.TestCase): def setUp(self): self.env = EnvironmentStub() self.search_module = SearchModule(self.env) self.chrome = Chrome(self.env) pages_dir = pkg_resources.resource_filename('trac.wiki', 'default-pages') for page_name in ('WikiStart', 'TracModWSGI'): page = os.path.join(pages_dir, page_name) WikiAdmin(self.env).import_page(page, page_name) def tearDown(self): self.env.reset_db() def _insert_ticket(self, **kw): """Helper for inserting a ticket into the database""" return insert_ticket(self.env, **kw) def _process_request(self, req): self.assertEqual(True, self.search_module.match_request(req)) return self.search_module.process_request(req) def _render_template(self, req, template, data): rendered = self.chrome.render_template(req, template, data, {'iterable': False, 'fragment': False}) return rendered.decode('utf-8') def test_process_request_page_in_range(self): for _ in range(21): self._insert_ticket(summary="Trac") req = MockRequest(self.env, path_info='/search', args={'page': '3', 'q': 'Trac', 'ticket': 'on'}) data = self._process_request(req)[1] self.assertEqual([], req.chrome['warnings']) self.assertEqual(2, data['results'].page) def test_process_request_page_out_of_range(self): """Out of range value for page defaults to page 1.""" for _ in range(20): self._insert_ticket(summary="Trac") req = MockRequest(self.env, path_info='/search', args={'page': '3', 'q': 'Trac', 'ticket': 'on'}) data = self._process_request(req)[1] self.assertIn("Page 3 is out of range.", req.chrome['warnings']) self.assertEqual(0, data['results'].page) def test_camelcase_quickjump(self): """CamelCase word does quick-jump.""" req = MockRequest(self.env, path_info='/search', args={'q': 'WikiStart'}) self.assertRaises(RequestDone, self._process_request, req) self.assertEqual('http://example.org/trac.cgi/wiki/WikiStart', req.headers_sent['Location']) self.assertIn("You arrived here through", req.chrome['notices'][0]) self.assertIn('<a href="/trac.cgi/search?' 'q=WikiStart&noquickjump=1">here</a>', req.chrome['notices'][0]) def test_non_camelcase_no_quickjump(self): """Non-CamelCase word does not quick-jump.""" req = MockRequest(self.env, path_info='/search', args={'q': 'TracModWSGI'}) data = self._process_request(req)[1] results = list(data['results']) self.assertIsNone(data['quickjump']) self.assertEqual('TracModWSGI', data['query']) self.assertEqual(1, len(results)) self.assertEqual('/trac.cgi/wiki/TracModWSGI', results[0]['href']) self.assertEqual([], req.chrome['notices']) def test_rendering_noquickjump_unicode_error(self): """Test for regression of https://trac.edgewall.org/ticket/13212 """ def do_render(query): req = MockRequest(self.env, path_info='/search', args={'q': query, 'noquickjump': '1'}) template, data = self._process_request(req) return self._render_template(req, template, data) self.assertIn('<a href="/trac.cgi/query?id=1-2">Quickjump to <em>' 'ticket:1,\u200b2</em></a>', do_render('ticket:1,2')) self.assertIn('<a href="mailto:[email protected]">Quickjump to <em>' '<span class="icon">\u200b</span>[email protected]' '</em></a>', do_render('*****@*****.**'))