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 @pytest.fixture(autouse=True)
23 def setup_icu_tokenizer(apiobj):
24 """ Setup the propoerties needed for using the ICU tokenizer.
26 apiobj.add_data('properties',
27 [{'property': 'tokenizer', 'value': 'icu'},
28 {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
29 {'property': 'tokenizer_import_transliteration', 'value': "'1' > '/1/'; 'ä' > 'ä '"},
33 def test_search_no_content(apiobj, table_factory):
35 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB')
37 assert apiobj.api.search('foo') == []
40 def test_search_simple_word(apiobj, table_factory):
42 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB',
43 content=[(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 results = apiobj.api.search('TEST')
52 assert [r.place_id for r in results] == [444]
55 @pytest.mark.parametrize('logtype', ['text', 'html'])
56 def test_search_with_debug(apiobj, table_factory, logtype):
58 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB',
59 content=[(55, 'test', 'W', 'test', None),
60 (2, 'test', 'w', 'test', None)])
62 apiobj.add_placex(place_id=444, class_='place', type='village',
64 apiobj.add_search_name(444, names=[2, 55])
66 loglib.set_log_output(logtype)
67 results = apiobj.api.search('TEST')
69 assert loglib.get_and_disable()
72 def test_address_no_content(apiobj, table_factory):
74 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB')
76 assert apiobj.api.search_address(amenity='hotel',
85 @pytest.mark.parametrize('atype,address,search', [('street', 26, 26),
89 def test_address_simple_places(apiobj, table_factory, atype, address, search):
91 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB',
92 content=[(55, 'test', 'W', 'test', None),
93 (2, 'test', 'w', 'test', None)])
95 apiobj.add_placex(place_id=444,
96 rank_address=address, rank_search=search,
98 apiobj.add_search_name(444, names=[2, 55], address_rank=address, search_rank=search)
100 results = apiobj.api.search_address(**{atype: 'TEST'})
102 assert [r.place_id for r in results] == [444]
105 def test_address_country(apiobj, table_factory):
106 table_factory('word',
107 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB',
108 content=[(None, 'ro', 'C', 'ro', None)])
109 apiobj.add_country('ro', 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
110 apiobj.add_country_name('ro', {'name': 'România'})
112 assert len(apiobj.api.search_address(country='ro')) == 1
115 def test_category_no_categories(apiobj, table_factory):
116 table_factory('word',
117 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB')
119 assert apiobj.api.search_category([], near_query='Berlin') == []
122 def test_category_no_content(apiobj, table_factory):
123 table_factory('word',
124 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB')
126 assert apiobj.api.search_category([('amenity', 'restaurant')]) == []
129 def test_category_simple_restaurant(apiobj, table_factory):
130 table_factory('word',
131 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB')
133 apiobj.add_placex(place_id=444, class_='amenity', type='restaurant',
135 apiobj.add_search_name(444, names=[2, 55], address_rank=16, search_rank=18)
137 results = apiobj.api.search_category([('amenity', 'restaurant')],
138 near=(1.3, 0.701), near_radius=0.015)
140 assert [r.place_id for r in results] == [444]
143 def test_category_with_search_phrase(apiobj, table_factory):
144 table_factory('word',
145 definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB',
146 content=[(55, 'test', 'W', 'test', None),
147 (2, 'test', 'w', 'test', None)])
149 apiobj.add_placex(place_id=444, class_='place', type='village',
150 rank_address=16, rank_search=18,
152 apiobj.add_search_name(444, names=[2, 55], address_rank=16, search_rank=18)
153 apiobj.add_placex(place_id=95, class_='amenity', type='restaurant',
154 centroid=(1.3, 0.7003))
156 results = apiobj.api.search_category([('amenity', 'restaurant')],
159 assert [r.place_id for r in results] == [95]