Exemple #1
0
 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)
Exemple #2
0
    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:]
Exemple #3
0
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)
Exemple #4
0
    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)
Exemple #5
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
Exemple #6
0
    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
Exemple #7
0
 def setUp(self):
     self.env = EnvironmentStub()
     self.search_module = SearchModule(self.env)
Exemple #8
0
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&amp;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'])
Exemple #9
0
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)
Exemple #10
0
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&amp;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('*****@*****.**'))