# HG changeset patch # User Marcin Lulek # Date 2019-03-29 11:51:50 # Node ID fd61cf07af5433ec6b797b7197e26acfe9f93b83 # Parent 909e77a99e669f370835fdd034f1c54ab653268e api: added tests for the search API diff --git a/rhodecode/api/tests/test_fts_search.py b/rhodecode/api/tests/test_fts_search.py new file mode 100644 --- /dev/null +++ b/rhodecode/api/tests/test_fts_search.py @@ -0,0 +1,93 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2010-2019 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + +import pytest +from rhodecode.tests import HG_REPO +from rhodecode.api.tests.utils import ( + build_data, api_call, assert_error, assert_ok) + + +@pytest.mark.usefixtures("testuser_api", "app") +class TestApiSearch(object): + + @pytest.mark.parametrize("query, expected_hits, expected_paths", [ + ('todo', 23, [ + 'vcs/backends/hg/inmemory.py', + 'vcs/tests/test_git.py']), + ('extension:rst installation', 6, [ + 'docs/index.rst', + 'docs/installation.rst']), + ('def repo', 87, [ + 'vcs/tests/test_git.py', + 'vcs/tests/test_changesets.py']), + ('repository:%s def test' % HG_REPO, 18, [ + 'vcs/tests/test_git.py', + 'vcs/tests/test_changesets.py']), + ('"def main"', 9, [ + 'vcs/__init__.py', + 'vcs/tests/__init__.py', + 'vcs/utils/progressbar.py']), + ('owner:test_admin', 358, [ + 'vcs/tests/base.py', + 'MANIFEST.in', + 'vcs/utils/termcolors.py', + 'docs/theme/ADC/static/documentation.png']), + ('owner:test_admin def main', 72, [ + 'vcs/__init__.py', + 'vcs/tests/test_utils_filesize.py', + 'vcs/tests/test_cli.py']), + ('owner:michaƂ test', 0, []), + ]) + def test_search_content_results(self, query, expected_hits, expected_paths): + id_, params = build_data( + self.apikey_regular, 'search', + search_query=query, + search_type='content') + + response = api_call(self.app, params) + json_response = response.json + + assert json_response['result']['item_count'] == expected_hits + paths = [x['f_path'] for x in json_response['result']['results']] + + for expected_path in expected_paths: + assert expected_path in paths + + @pytest.mark.parametrize("query, expected_hits, expected_paths", [ + ('readme.rst', 3, []), + ('test*', 75, []), + ('*model*', 1, []), + ('extension:rst', 48, []), + ('extension:rst api', 24, []), + ]) + def test_search_file_paths(self, query, expected_hits, expected_paths): + id_, params = build_data( + self.apikey_regular, 'search', + search_query=query, + search_type='path') + + response = api_call(self.app, params) + json_response = response.json + + assert json_response['result']['item_count'] == expected_hits + paths = [x['f_path'] for x in json_response['result']['results']] + + for expected_path in expected_paths: + assert expected_path in paths diff --git a/rhodecode/api/views/search_api.py b/rhodecode/api/views/search_api.py --- a/rhodecode/api/views/search_api.py +++ b/rhodecode/api/views/search_api.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright (C) 2011-2018 RhodeCode GmbH +# Copyright (C) 2011-2019 RhodeCode GmbH # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License, version 3 @@ -32,9 +32,11 @@ log = logging.getLogger(__name__) @jsonrpc_method() -def search(request, apiuser, search_query, search_type, page_limit=Optional(10), page=Optional(1), search_sort=Optional('newfirst'), repo_name=Optional(None), repo_group_name=Optional(None)): +def search(request, apiuser, search_query, search_type, page_limit=Optional(10), + page=Optional(1), search_sort=Optional('newfirst'), + repo_name=Optional(None), repo_group_name=Optional(None)): """ - Search + Fetch Full Text Search results using API. :param apiuser: This is filled automatically from the |authtoken|. :type apiuser: AuthUser @@ -59,14 +61,12 @@ def search(request, apiuser, search_quer :type repo_group_name: Optional(str) """ - searcher = searcher_from_config(request.registry.settings) data = {'execution_time': ''} repo_name = Optional.extract(repo_name) repo_group_name = Optional.extract(repo_group_name) schema = search_schema.SearchParamsSchema() - search_params = {} try: search_params = schema.deserialize( dict(search_query=search_query, @@ -86,6 +86,8 @@ def search(request, apiuser, search_quer page_limit = search_params['page_limit'] requested_page = search_params['requested_page'] + searcher = searcher_from_config(request.registry.settings) + try: search_result = searcher.search( search_query, search_type, apiuser, repo_name, repo_group_name, @@ -104,6 +106,7 @@ def search(request, apiuser, search_quer search_result['runtime']) else: node = schema['search_query'] - raise JSONRPCValidationError(colander_exc=validation_schema.Invalid(node, search_result['error'])) + raise JSONRPCValidationError( + colander_exc=validation_schema.Invalid(node, search_result['error'])) return data