]> git.openstreetmap.org Git - nominatim.git/blob - test/python/tokenizer/sanitizers/test_delete_names.py
prepare release 5.3.2.post7
[nominatim.git] / test / python / tokenizer / sanitizers / test_delete_names.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) 2026 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Tests for the sanitizer that deletes names.
9 """
10 import pytest
11
12 from nominatim_db.data.place_info import PlaceInfo
13 from nominatim_db.tokenizer.place_sanitizer import PlaceSanitizer
14
15
16 class TestWithDefault:
17
18     @pytest.fixture(autouse=True)
19     def setup_country(self, def_config):
20         self.config = def_config
21
22     def run_sanitizer_on(self, type, **kwargs):
23
24         place = PlaceInfo({type: {k.replace('_', ':'): v for k, v in kwargs.items()},
25                           'country_code': 'de', 'rank_address': 30})
26
27         sanitizer_args = {'step': 'delete-names'}
28
29         PlaceSanitizer([sanitizer_args], self.config).process_names(place)
30
31         return {'name': sorted([(p.name, p.kind, p.suffix or '')
32                                 for p in place.searchable_names]),
33                 'address': sorted([(p.name, p.kind, p.suffix or '')
34                                    for p in place.searchable_address])}
35
36     def test_on_name(self):
37         res = self.run_sanitizer_on('name', name='foo', ref='bar', ref_abc='baz')
38
39         assert res.get('name') == []
40
41     def test_on_address(self):
42         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')
43
44         assert res.get('address') == [('bar', 'ref', ''), ('baz', 'ref', 'abc'),
45                                       ('foo', 'name', '')]
46
47
48 class TestTypeField:
49
50     @pytest.fixture(autouse=True)
51     def setup_country(self, def_config):
52         self.config = def_config
53
54     def run_sanitizer_on(self, type, **kwargs):
55
56         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
57                            'country_code': 'de', 'rank_address': 30})
58
59         sanitizer_args = {'step': 'delete-names',
60                           'type': type}
61
62         PlaceSanitizer([sanitizer_args], self.config).process_names(place)
63
64         return sorted([(p.name, p.kind, p.suffix or '') for p in place.searchable_names])
65
66     def test_name_type(self):
67         res = self.run_sanitizer_on('name', name='foo', ref='bar', ref_abc='baz')
68
69         assert res == []
70
71     def test_address_type(self):
72         res = self.run_sanitizer_on('address', name='foo', ref='bar', ref_abc='baz')
73
74         assert res == [('bar', 'ref', ''), ('baz', 'ref', 'abc'),
75                        ('foo', 'name', '')]
76
77
78 class TestFilterKind:
79
80     @pytest.fixture(autouse=True)
81     def setup_country(self, def_config):
82         self.config = def_config
83
84     def run_sanitizer_on(self, filt, **kwargs):
85
86         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
87                            'country_code': 'de', 'rank_address': 30})
88
89         sanitizer_args = {'step': 'delete-names',
90                           'filter-kind': filt}
91
92         PlaceSanitizer([sanitizer_args], self.config).process_names(place)
93
94         return sorted([(p.name, p.kind, p.suffix or '') for p in place.searchable_names])
95
96     def test_single_exact_name(self):
97         res = self.run_sanitizer_on(['name'], ref='foo', name='foo',
98                                     name_abc='bar', ref_abc='bar')
99
100         assert res == [('bar', 'ref', 'abc'), ('foo', 'ref', '')]
101
102     def test_single_pattern(self):
103         res = self.run_sanitizer_on(['.*name'],
104                                     name_fr='foo', ref_fr='foo', namexx_fr='bar',
105                                     shortname_fr='bar', name='bar')
106
107         assert res == [('bar', 'namexx', 'fr'), ('foo', 'ref', 'fr')]
108
109     def test_multiple_patterns(self):
110         res = self.run_sanitizer_on(['.*name', 'ref'],
111                                     name_fr='foo', ref_fr='foo', oldref_fr='foo',
112                                     namexx_fr='bar', shortname_fr='baz', name='baz')
113
114         assert res == [('bar', 'namexx', 'fr'), ('foo', 'oldref', 'fr')]
115
116
117 class TestRankAddress:
118
119     @pytest.fixture(autouse=True)
120     def setup_country(self, def_config):
121         self.config = def_config
122
123     def run_sanitizer_on(self, rank_addr, **kwargs):
124
125         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
126                            'country_code': 'de', 'rank_address': 30})
127
128         sanitizer_args = {'step': 'delete-names',
129                           'filter-rank': rank_addr}
130
131         PlaceSanitizer([sanitizer_args], self.config).process_names(place)
132
133         return sorted([(p.name, p.kind, p.suffix or '') for p in place.searchable_names])
134
135     def test_single_rank(self):
136         res = self.run_sanitizer_on('30', name='foo', ref='bar')
137
138         assert res == []
139
140     def test_single_rank_fail(self):
141         res = self.run_sanitizer_on('28', name='foo', ref='bar')
142
143         assert res == [('bar', 'ref', ''), ('foo', 'name', '')]
144
145     def test_ranged_rank_pass(self):
146         res = self.run_sanitizer_on('26-30', name='foo', ref='bar')
147
148         assert res == []
149
150     def test_ranged_rank_fail(self):
151         res = self.run_sanitizer_on('26-29', name='foo', ref='bar')
152
153         assert res == [('bar', 'ref', ''), ('foo', 'name', '')]
154
155     def test_mixed_rank_pass(self):
156         res = self.run_sanitizer_on(['4', '20-28', '30', '10-12'], name='foo', ref='bar')
157
158         assert res == []
159
160     def test_mixed_rank_fail(self):
161         res = self.run_sanitizer_on(['4-8', '10', '26-29', '18'], name='foo', ref='bar')
162
163         assert res == [('bar', 'ref', ''), ('foo', 'name', '')]
164
165
166 class TestSuffix:
167
168     @pytest.fixture(autouse=True)
169     def setup_country(self, def_config):
170         self.config = def_config
171
172     def run_sanitizer_on(self, suffix, **kwargs):
173
174         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
175                            'country_code': 'de', 'rank_address': 30})
176
177         sanitizer_args = {'step': 'delete-names',
178                           'filter-suffix': suffix}
179
180         PlaceSanitizer([sanitizer_args], self.config).process_names(place)
181
182         return sorted([(p.name, p.kind, p.suffix or '') for p in place.searchable_names])
183
184     def test_single_suffix(self):
185         res = self.run_sanitizer_on('abc', name='foo', name_abc='foo',
186                                     name_pqr='bar', ref='bar', ref_abc='baz')
187
188         assert res == [('bar', 'name', 'pqr'), ('bar', 'ref', ''), ('foo', 'name', '')]
189
190     def test_multiple_suffix(self):
191         res = self.run_sanitizer_on(['abc.*', 'pqr'], name='foo', name_abcxx='foo',
192                                     ref_pqr='bar', name_pqrxx='baz')
193
194         assert res == [('baz', 'name', 'pqrxx'), ('foo', 'name', '')]
195
196
197 class TestCountryCodes:
198
199     @pytest.fixture(autouse=True)
200     def setup_country(self, def_config):
201         self.config = def_config
202
203     def run_sanitizer_on(self, country_code, **kwargs):
204
205         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
206                            'country_code': 'de', 'rank_address': 30})
207
208         sanitizer_args = {'step': 'delete-names',
209                           'filter-country': country_code}
210
211         PlaceSanitizer([sanitizer_args], self.config).process_names(place)
212
213         return sorted([(p.name, p.kind) for p in place.searchable_names])
214
215     def test_single_country_code_pass(self):
216         res = self.run_sanitizer_on('de', name='foo', ref='bar')
217
218         assert res == []
219
220     def test_single_country_code_fail(self):
221         res = self.run_sanitizer_on('in', name='foo', ref='bar')
222
223         assert res == [('bar', 'ref'), ('foo', 'name')]
224
225     def test_empty_country_code_list(self):
226         res = self.run_sanitizer_on([], name='foo', ref='bar')
227
228         assert res == [('bar', 'ref'), ('foo', 'name')]
229
230     def test_multiple_country_code_pass(self):
231         res = self.run_sanitizer_on(['in', 'de', 'fr'], name='foo', ref='bar')
232
233         assert res == []
234
235     def test_multiple_country_code_fail(self):
236         res = self.run_sanitizer_on(['in', 'au', 'fr'], name='foo', ref='bar')
237
238         assert res == [('bar', 'ref'), ('foo', 'name')]
239
240
241 class TestAllParameters:
242
243     @pytest.fixture(autouse=True)
244     def setup_country(self, def_config):
245         self.config = def_config
246
247     def run_sanitizer_on(self, country_code, rank_addr, suffix, **kwargs):
248
249         place = PlaceInfo({'name': {k.replace('_', ':'): v for k, v in kwargs.items()},
250                            'country_code': 'de', 'rank_address': 30})
251
252         sanitizer_args = {
253                         'step': 'delete-names',
254                         'type': 'name',
255                         'filter-kind': ['name', 'ref'],
256                         'filter-country': country_code,
257                         'filter-rank': rank_addr,
258                         'filter-suffix': suffix,
259                         'filter-name': r'[\s\S]*',
260                     }
261
262         PlaceSanitizer([sanitizer_args], self.config).process_names(place)
263
264         return sorted([(p.name, p.kind, p.suffix or '') for p in place.searchable_names])
265
266     def test_string_arguments_pass(self):
267         res = self.run_sanitizer_on('de', '25-30', r'[\s\S]*',
268                                     name='foo', ref='foo', name_abc='bar', ref_abc='baz')
269
270         assert res == []
271
272     def test_string_arguments_fail(self):
273         res = self.run_sanitizer_on('in', '25-30', r'[\s\S]*',
274                                     name='foo', ref='foo', name_abc='bar', ref_abc='baz')
275
276         assert res == [('bar', 'name', 'abc'), ('baz', 'ref', 'abc'),
277                        ('foo', 'name', ''), ('foo', 'ref', '')]
278
279     def test_list_arguments_pass(self):
280         res = self.run_sanitizer_on(['de', 'in'], ['20-28', '30'], [r'abc.*', r'[\s\S]*'],
281                                     name='foo', ref='foo', name_abcxx='bar', ref_pqr='baz')
282
283         assert res == []
284
285     def test_list_arguments_fail(self):
286         res = self.run_sanitizer_on(['de', 'in'], ['14', '20-29'], [r'abc.*', r'pqr'],
287                                     name='foo', ref_abc='foo', name_abcxx='bar', ref_pqr='baz')
288
289         assert res == [('bar', 'name', 'abcxx'), ('baz', 'ref', 'pqr'),
290                        ('foo', 'name', ''), ('foo', 'ref', 'abc')]
291
292     def test_mix_arguments_pass(self):
293         res = self.run_sanitizer_on('de', ['10', '20-28', '30'], r'[\s\S]*',
294                                     name_abc='foo', ref_abc='foo', name_abcxx='bar', ref_pqr='baz')
295
296         assert res == []
297
298     def test_mix_arguments_fail(self):
299         res = self.run_sanitizer_on(['de', 'in'], ['10', '20-28', '30'], r'abc.*',
300                                     name='foo', ref='foo', name_pqr='bar', ref_pqr='baz')
301
302         assert res == [('bar', 'name', 'pqr'), ('baz', 'ref', 'pqr'),
303                        ('foo', 'name', ''), ('foo', 'ref', '')]