mirror of https://github.com/searxng/searxng.git
Merge 3d139086c1
into b07c0ae39f
This commit is contained in:
commit
b1a2b685af
|
@ -135,14 +135,38 @@ def _terms_query(query):
|
||||||
|
|
||||||
|
|
||||||
def _custom_query(query):
|
def _custom_query(query):
|
||||||
key, value = query.split(':')
|
key = value = None
|
||||||
custom_query = custom_query_json
|
if any(placeholder in custom_query_json for placeholder in ["{{KEY}}", "{{VALUE}}", "{{VALUES}}"]):
|
||||||
|
try:
|
||||||
|
key, value = query.split(':', maxsplit=1)
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError('query format must be "key:value"') from e
|
||||||
|
if not key:
|
||||||
|
raise ValueError('empty key from "key:value" query')
|
||||||
|
try:
|
||||||
|
custom_query = loads(custom_query_json)
|
||||||
|
except Exception as e:
|
||||||
|
raise ValueError('invalid custom_query string') from e
|
||||||
|
return _custom_query_r(query, key, value, custom_query)
|
||||||
|
|
||||||
|
|
||||||
|
def _custom_query_r(query, key, value, custom_query):
|
||||||
|
new_query = {}
|
||||||
for query_key, query_value in custom_query.items():
|
for query_key, query_value in custom_query.items():
|
||||||
if query_key == '{{KEY}}':
|
if query_key == '{{KEY}}':
|
||||||
custom_query[key] = custom_query.pop(query_key)
|
query_key = key
|
||||||
if query_value == '{{VALUE}}':
|
|
||||||
custom_query[query_key] = value
|
if isinstance(query_value, dict):
|
||||||
return custom_query
|
query_value = _custom_query_r(query, key, value, query_value)
|
||||||
|
elif query_value == '{{VALUE}}':
|
||||||
|
query_value = value
|
||||||
|
elif query_value == '{{VALUES}}':
|
||||||
|
query_value = value.split(',')
|
||||||
|
elif query_value == '{{QUERY}}':
|
||||||
|
query_value = query
|
||||||
|
|
||||||
|
new_query[query_key] = query_value
|
||||||
|
return new_query
|
||||||
|
|
||||||
|
|
||||||
def response(resp):
|
def response(resp):
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
# pylint: disable=missing-module-docstring
|
||||||
|
|
||||||
|
'''
|
||||||
|
searx is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
searx 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 Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with searx. If not, see < http://www.gnu.org/licenses/ >.
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
from json import loads
|
||||||
|
from searx.engines import elasticsearch as elasticsearch_engine
|
||||||
|
from tests import SearxTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestElasticsearchEngine(SearxTestCase): # pylint: disable=missing-class-docstring
|
||||||
|
default_params = {"headers": {}}
|
||||||
|
|
||||||
|
def test_url_settings(self):
|
||||||
|
elasticsearch_engine.base_url = 'http://es:12345'
|
||||||
|
elasticsearch_engine.index = 'index'
|
||||||
|
params = elasticsearch_engine.request("city:berlin", self.default_params)
|
||||||
|
self.assertEqual(params["url"], "http://es:12345/index/_search")
|
||||||
|
|
||||||
|
def test_basic_queries(self):
|
||||||
|
queries = [
|
||||||
|
['match', 'field:stuff', '{"query": {"match": {"field": {"query": "stuff"}}}}'],
|
||||||
|
['simple_query_string', 'stuff', '{"query": {"simple_query_string": {"query": "stuff"}}}'],
|
||||||
|
['term', 'field:stuff', '{"query": {"term": {"field": "stuff"}}}'],
|
||||||
|
['terms', 'field:stuff1,stuff2', '{"query": {"terms": {"field": ["stuff1", "stuff2"]}}}'],
|
||||||
|
]
|
||||||
|
|
||||||
|
for query in queries:
|
||||||
|
elasticsearch_engine.query_type = query[0]
|
||||||
|
params = elasticsearch_engine.request(query[1], self.default_params)
|
||||||
|
self.assertEqual(loads(params["data"]), loads(query[2]))
|
||||||
|
|
||||||
|
def test_basic_failures(self):
|
||||||
|
queries = [
|
||||||
|
['match', 'stuff', 'query format must be "key:value'],
|
||||||
|
['term', 'stuff', 'query format must be key:value'],
|
||||||
|
['terms', 'stuff', 'query format must be key:value1,value2'],
|
||||||
|
]
|
||||||
|
|
||||||
|
for query in queries:
|
||||||
|
elasticsearch_engine.query_type = query[0]
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
elasticsearch_engine.request(query[1], self.default_params)
|
||||||
|
self.assertIn(query[2], str(context.exception))
|
||||||
|
|
||||||
|
def test_custom_queries(self):
|
||||||
|
queries = [
|
||||||
|
[
|
||||||
|
'field:stuff',
|
||||||
|
'{"query": {"match": {"{{KEY}}": {"query": "{{VALUE}}"}}}}',
|
||||||
|
'{"query": {"match": {"field": {"query": "stuff"}}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'stuff',
|
||||||
|
'{"query": {"simple_query_string": {"query": "{{QUERY}}"}}}',
|
||||||
|
'{"query": {"simple_query_string": {"query": "stuff"}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'space stuff',
|
||||||
|
'{"query": {"simple_query_string": {"query": "{{QUERY}}"}}}',
|
||||||
|
'{"query": {"simple_query_string": {"query": "space stuff"}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'"space stuff"',
|
||||||
|
'{"query": {"simple_query_string": {"query": "{{QUERY}}"}}}',
|
||||||
|
'{"query": {"simple_query_string": {"query": "\\\"space stuff\\\""}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"embedded'apostrophe",
|
||||||
|
'{"query": {"simple_query_string": {"query": "{{QUERY}}"}}}',
|
||||||
|
'{"query": {"simple_query_string": {"query": "embedded\'apostrophe"}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'more:stuff',
|
||||||
|
'{"query": {"simple_query_string": {"query": "{{QUERY}}"}}}',
|
||||||
|
'{"query": {"simple_query_string": {"query": "more:stuff"}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field:stuff',
|
||||||
|
'{"query": {"term": {"{{KEY}}": "{{VALUE}}"}}}',
|
||||||
|
'{"query": {"term": {"field": "stuff"}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field:more:stuff',
|
||||||
|
'{"query": {"match": {"{{KEY}}": {"query": "{{VALUE}}"}}}}',
|
||||||
|
'{"query": {"match": {"field": {"query": "more:stuff"}}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field:stuff1,stuff2',
|
||||||
|
'{"query": {"terms": {"{{KEY}}": "{{VALUES}}"}}}',
|
||||||
|
'{"query": {"terms": {"field": ["stuff1", "stuff2"]}}}',
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'field:stuff1',
|
||||||
|
'{"query": {"terms": {"{{KEY}}": "{{VALUES}}"}}}',
|
||||||
|
'{"query": {"terms": {"field": ["stuff1"]}}}',
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
elasticsearch_engine.query_type = 'custom'
|
||||||
|
for query in queries:
|
||||||
|
elasticsearch_engine.custom_query_json = query[1]
|
||||||
|
params = elasticsearch_engine.request(query[0], self.default_params)
|
||||||
|
self.assertEqual(loads(params["data"]), loads(query[2]))
|
||||||
|
|
||||||
|
def test_custom_failures(self):
|
||||||
|
queries = [
|
||||||
|
['stuff', '{"query": {"match": {"{{KEY}}": {"query": "{{VALUE}}"}}}}', 'query format must be "key:value"'],
|
||||||
|
['stuff', '{"query": {"terms": {"{{KEY}}": "{{VALUES}}"}}}', 'query format must be "key:value"'],
|
||||||
|
['stuff', '{"query": {"simple_query_string": {"query": {{QUERY}}}}}', 'invalid custom_query string'],
|
||||||
|
['stuff', '"query": {"simple_query_string": {"query": "{{QUERY}}"}}}', 'invalid custom_query string'],
|
||||||
|
]
|
||||||
|
|
||||||
|
elasticsearch_engine.query_type = 'custom'
|
||||||
|
for query in queries:
|
||||||
|
elasticsearch_engine.custom_query_json = query[1]
|
||||||
|
with self.assertRaises(ValueError) as context:
|
||||||
|
elasticsearch_engine.request(query[0], self.default_params)
|
||||||
|
self.assertIn(query[2], str(context.exception))
|
||||||
|
|
||||||
|
|
||||||
|
# vi:sw=4
|
Loading…
Reference in New Issue