1 # SPDX-License-Identifier: GPL-3.0-or-later
 
   3 # This file is part of Nominatim. (https://nominatim.org)
 
   5 # Copyright (C) 2025 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.
 
  15 import nominatim_api.logging as loglib
 
  17 API_OPTIONS = {'search'}
 
  20 @pytest.fixture(autouse=True)
 
  21 def setup_icu_tokenizer(apiobj):
 
  22     """ Setup the properties needed for using the ICU tokenizer.
 
  24     apiobj.add_data('properties',
 
  25                     [{'property': 'tokenizer', 'value': 'icu'},
 
  26                      {'property': 'tokenizer_import_normalisation', 'value': ':: lower();'},
 
  27                      {'property': 'tokenizer_import_transliteration',
 
  28                       'value': "'1' > '/1/'; 'ä' > 'ä '"},
 
  32 def test_search_no_content(apiobj, frontend):
 
  33     apiobj.add_word_table([])
 
  35     api = frontend(apiobj, options=API_OPTIONS)
 
  36     assert api.search('foo') == []
 
  39 def test_search_simple_word(apiobj, frontend):
 
  40     apiobj.add_word_table([(55, 'test', 'W', 'test', None),
 
  41                            (2, 'test', 'w', 'test', None)])
 
  43     apiobj.add_placex(place_id=444, class_='place', type='village',
 
  45     apiobj.add_search_name(444, names=[2, 55])
 
  47     api = frontend(apiobj, options=API_OPTIONS)
 
  48     results = api.search('TEST')
 
  50     assert [r.place_id for r in results] == [444]
 
  53 @pytest.mark.parametrize('logtype', ['text', 'html'])
 
  54 def test_search_with_debug(apiobj, frontend, logtype):
 
  55     apiobj.add_word_table([(55, 'test', 'W', 'test', None),
 
  56                            (2, 'test', 'w', 'test', None)])
 
  58     apiobj.add_placex(place_id=444, class_='place', type='village',
 
  60     apiobj.add_search_name(444, names=[2, 55])
 
  62     api = frontend(apiobj, options=API_OPTIONS)
 
  63     loglib.set_log_output(logtype)
 
  66     assert loglib.get_and_disable()
 
  69 def test_address_no_content(apiobj, frontend):
 
  70     apiobj.add_word_table([])
 
  72     api = frontend(apiobj, options=API_OPTIONS)
 
  73     assert api.search_address(amenity='hotel',
 
  82 @pytest.mark.parametrize('atype,address,search', [('street', 26, 26),
 
  86 def test_address_simple_places(apiobj, frontend, atype, address, search):
 
  87     apiobj.add_word_table([(55, 'test', 'W', 'test', None),
 
  88                            (2, 'test', 'w', 'test', None)])
 
  90     apiobj.add_placex(place_id=444,
 
  91                       rank_address=address, rank_search=search,
 
  93     apiobj.add_search_name(444, names=[2, 55], address_rank=address, search_rank=search)
 
  95     api = frontend(apiobj, options=API_OPTIONS)
 
  96     results = api.search_address(**{atype: 'TEST'})
 
  98     assert [r.place_id for r in results] == [444]
 
 101 def test_address_country(apiobj, frontend):
 
 102     apiobj.add_word_table([(None, 'ro', 'C', 'ro', None)])
 
 103     apiobj.add_country('ro', 'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))')
 
 104     apiobj.add_country_name('ro', {'name': 'România'})
 
 106     api = frontend(apiobj, options=API_OPTIONS)
 
 107     assert len(api.search_address(country='ro')) == 1
 
 110 def test_category_no_categories(apiobj, frontend):
 
 111     apiobj.add_word_table([])
 
 113     api = frontend(apiobj, options=API_OPTIONS)
 
 114     assert api.search_category([], near_query='Berlin') == []
 
 117 def test_category_no_content(apiobj, frontend):
 
 118     apiobj.add_word_table([])
 
 120     api = frontend(apiobj, options=API_OPTIONS)
 
 121     assert api.search_category([('amenity', 'restaurant')]) == []
 
 124 def test_category_simple_restaurant(apiobj, frontend):
 
 125     apiobj.add_word_table([])
 
 127     apiobj.add_placex(place_id=444, class_='amenity', type='restaurant',
 
 129     apiobj.add_search_name(444, names=[2, 55], address_rank=16, search_rank=18)
 
 131     api = frontend(apiobj, options=API_OPTIONS)
 
 132     results = api.search_category([('amenity', 'restaurant')],
 
 133                                   near=(1.3, 0.701), near_radius=0.015)
 
 135     assert [r.place_id for r in results] == [444]
 
 138 def test_category_with_search_phrase(apiobj, frontend):
 
 139     apiobj.add_word_table([(55, 'test', 'W', 'test', None),
 
 140                            (2, 'test', 'w', 'test', None)])
 
 142     apiobj.add_placex(place_id=444, class_='place', type='village',
 
 143                       rank_address=16, rank_search=18,
 
 145     apiobj.add_search_name(444, names=[2, 55], address_rank=16, search_rank=18)
 
 146     apiobj.add_placex(place_id=95, class_='amenity', type='restaurant',
 
 147                       centroid=(1.3, 0.7003))
 
 149     api = frontend(apiobj, options=API_OPTIONS)
 
 150     results = api.search_category([('amenity', 'restaurant')], near_query='TEST')
 
 152     assert [r.place_id for r in results] == [95]