]> git.openstreetmap.org Git - nominatim.git/blob - test/python/api/test_api_search.py
Merge pull request #3067 from lonvia/python-search-api
[nominatim.git] / test / python / api / test_api_search.py
1 # SPDX-License-Identifier: GPL-3.0-or-later
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2023 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Tests for search API calls.
9
10 These tests make sure that all Python code is correct and executable.
11 Functional tests can be found in the BDD test suite.
12 """
13 import json
14
15 import pytest
16
17 import sqlalchemy as sa
18
19 import nominatim.api as napi
20 import nominatim.api.logging as loglib
21
22 @pytest.fixture(autouse=True)
23 def setup_icu_tokenizer(apiobj):
24     """ Setup the propoerties needed for using the ICU tokenizer.
25     """
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/'; 'ä' > 'ä '"},
30                     ])
31
32
33 def test_search_no_content(apiobj, table_factory):
34     table_factory('word',
35                   definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB')
36
37     assert apiobj.api.search('foo') == []
38
39
40 def test_search_simple_word(apiobj, table_factory):
41     table_factory('word',
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)])
45
46     apiobj.add_placex(place_id=444, class_='place', type='village',
47                       centroid=(1.3, 0.7))
48     apiobj.add_search_name(444, names=[2, 55])
49
50     results = apiobj.api.search('TEST')
51
52     assert [r.place_id for r in results] == [444]
53
54
55 @pytest.mark.parametrize('logtype', ['text', 'html'])
56 def test_search_with_debug(apiobj, table_factory, logtype):
57     table_factory('word',
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)])
61
62     apiobj.add_placex(place_id=444, class_='place', type='village',
63                       centroid=(1.3, 0.7))
64     apiobj.add_search_name(444, names=[2, 55])
65
66     loglib.set_log_output(logtype)
67     results = apiobj.api.search('TEST')
68
69     assert loglib.get_and_disable()
70
71
72 def test_address_no_content(apiobj, table_factory):
73     table_factory('word',
74                   definition='word_id INT, word_token TEXT, type TEXT, word TEXT, info JSONB')
75
76     assert apiobj.api.search_address(amenity='hotel',
77                                      street='Main St 34',
78                                      city='Happyville',
79                                      county='Wideland',
80                                      state='Praerie',
81                                      postalcode='55648',
82                                      country='xx') == []
83
84
85 @pytest.mark.parametrize('atype,address,search', [('street', 26, 26),
86                                                   ('city', 16, 18),
87                                                   ('county', 12, 12),
88                                                   ('state', 8, 8)])
89 def test_address_simple_places(apiobj, table_factory, atype, address, search):
90     table_factory('word',
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)])
94
95     apiobj.add_placex(place_id=444,
96                       rank_address=address, rank_search=search,
97                       centroid=(1.3, 0.7))
98     apiobj.add_search_name(444, names=[2, 55], address_rank=address, search_rank=search)
99
100     results = apiobj.api.search_address(**{atype: 'TEST'})
101
102     assert [r.place_id for r in results] == [444]
103
104
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'})
111
112     assert len(apiobj.api.search_address(country='ro')) == 1
113
114
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')
118
119     assert apiobj.api.search_category([], near_query='Berlin') == []
120
121
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')
125
126     assert apiobj.api.search_category([('amenity', 'restaurant')]) == []
127
128
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')
132
133     apiobj.add_placex(place_id=444, class_='amenity', type='restaurant',
134                       centroid=(1.3, 0.7))
135     apiobj.add_search_name(444, names=[2, 55], address_rank=16, search_rank=18)
136
137     results = apiobj.api.search_category([('amenity', 'restaurant')],
138                                          near=(1.3, 0.701), near_radius=0.015)
139
140     assert [r.place_id for r in results] == [444]
141
142
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)])
148
149     apiobj.add_placex(place_id=444, class_='place', type='village',
150                       rank_address=16, rank_search=18,
151                       centroid=(1.3, 0.7))
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))
155
156     results = apiobj.api.search_category([('amenity', 'restaurant')],
157                                          near_query='TEST')
158
159     assert [r.place_id for r in results] == [95]