1 # SPDX-License-Identifier: GPL-3.0-or-later
3 # This file is part of Nominatim. (https://nominatim.org)
5 # Copyright (C) 2023 by the Nominatim developer community.
6 # For a full list of authors see the git log.
8 Tests for search API calls.
10 These tests make sure that all Python code is correct and executable.
11 Functional tests can be found in the BDD test suite.
17 import sqlalchemy as sa
19 import nominatim.api as napi
20 import nominatim.api.logging as loglib
22 API_OPTIONS = {'search'}
24 @pytest.fixture(autouse=True)
25 def setup_icu_tokenizer(apiobj):
26 """ Setup the properties needed for using the ICU tokenizer.
28 apiobj.add_data('properties',
29 [{'property': 'tokenizer', 'value': 'icu'},
30 {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
31 {'property': 'tokenizer_import_transliteration', 'value': "'1' > '/1/'; 'ä' > 'ä '"},
35 def test_search_no_content(apiobj, frontend):
36 apiobj.add_word_table([])
38 api = frontend(apiobj, options=API_OPTIONS)
39 assert api.search('foo') == []
42 def test_search_simple_word(apiobj, frontend):
43 apiobj.add_word_table([(55, 'test', 'W', 'test', None),
44 (2, 'test', 'w', 'test', None)])
46 apiobj.add_placex(place_id=444, class_='place', type='village',
48 apiobj.add_search_name(444, names=[2, 55])
50 api = frontend(apiobj, options=API_OPTIONS)
51 results = api.search('TEST')
53 assert [r.place_id for r in results] == [444]
56 @pytest.mark.parametrize('logtype', ['text', 'html'])
57 def test_search_with_debug(apiobj, frontend, logtype):
58 apiobj.add_word_table([(55, 'test', 'W', 'test', None),
59 (2, 'test', 'w', 'test', None)])
61 apiobj.add_placex(place_id=444, class_='place', type='village',
63 apiobj.add_search_name(444, names=[2, 55])
65 api = frontend(apiobj, options=API_OPTIONS)
66 loglib.set_log_output(logtype)
67 results = api.search('TEST')
69 assert loglib.get_and_disable()
72 def test_address_no_content(apiobj, frontend):
73 apiobj.add_word_table([])
75 api = frontend(apiobj, options=API_OPTIONS)
76 assert api.search_address(amenity='hotel',
85 @pytest.mark.parametrize('atype,address,search', [('street', 26, 26),
89 def test_address_simple_places(apiobj, frontend, atype, address, search):
90 apiobj.add_word_table([(55, 'test', 'W', 'test', None),
91 (2, 'test', 'w', 'test', None)])
93 apiobj.add_placex(place_id=444,
94 rank_address=address, rank_search=search,
96 apiobj.add_search_name(444, names=[2, 55], address_rank=address, search_rank=search)
98 api = frontend(apiobj, options=API_OPTIONS)
99 results = api.search_address(**{atype: 'TEST'})
101 assert [r.place_id for r in results] == [444]
104 def test_address_country(apiobj, frontend):
105 apiobj.add_word_table([(None, 'ro', 'C', 'ro', None)])
106 apiobj.add_country('ro', 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
107 apiobj.add_country_name('ro', {'name': 'România'})
109 api = frontend(apiobj, options=API_OPTIONS)
110 assert len(api.search_address(country='ro')) == 1
113 def test_category_no_categories(apiobj, frontend):
114 apiobj.add_word_table([])
116 api = frontend(apiobj, options=API_OPTIONS)
117 assert api.search_category([], near_query='Berlin') == []
120 def test_category_no_content(apiobj, frontend):
121 apiobj.add_word_table([])
123 api = frontend(apiobj, options=API_OPTIONS)
124 assert api.search_category([('amenity', 'restaurant')]) == []
127 def test_category_simple_restaurant(apiobj, frontend):
128 apiobj.add_word_table([])
130 apiobj.add_placex(place_id=444, class_='amenity', type='restaurant',
132 apiobj.add_search_name(444, names=[2, 55], address_rank=16, search_rank=18)
134 api = frontend(apiobj, options=API_OPTIONS)
135 results = api.search_category([('amenity', 'restaurant')],
136 near=(1.3, 0.701), near_radius=0.015)
138 assert [r.place_id for r in results] == [444]
141 def test_category_with_search_phrase(apiobj, frontend):
142 apiobj.add_word_table([(55, 'test', 'W', 'test', None),
143 (2, 'test', 'w', 'test', None)])
145 apiobj.add_placex(place_id=444, class_='place', type='village',
146 rank_address=16, rank_search=18,
148 apiobj.add_search_name(444, names=[2, 55], address_rank=16, search_rank=18)
149 apiobj.add_placex(place_id=95, class_='amenity', type='restaurant',
150 centroid=(1.3, 0.7003))
152 api = frontend(apiobj, options=API_OPTIONS)
153 results = api.search_category([('amenity', 'restaurant')], near_query='TEST')
155 assert [r.place_id for r in results] == [95]