1 # SPDX-License-Identifier: GPL-2.0-only
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 formatting results for the V1 API.
15 import nominatim.api.v1 as api_impl
16 import nominatim.api as napi
17 from nominatim.version import NOMINATIM_VERSION
19 STATUS_FORMATS = {'text', 'json'}
23 def test_status_format_list():
24 assert set(api_impl.list_formats(napi.StatusResult)) == STATUS_FORMATS
27 @pytest.mark.parametrize('fmt', list(STATUS_FORMATS))
28 def test_status_supported(fmt):
29 assert api_impl.supports_format(napi.StatusResult, fmt)
32 def test_status_unsupported():
33 assert not api_impl.supports_format(napi.StatusResult, 'gagaga')
36 def test_status_format_text():
37 assert api_impl.format_result(napi.StatusResult(0, 'message here'), 'text', {}) == 'OK'
40 def test_status_format_text():
41 assert api_impl.format_result(napi.StatusResult(500, 'message here'), 'text', {}) == 'ERROR: message here'
44 def test_status_format_json_minimal():
45 status = napi.StatusResult(700, 'Bad format.')
47 result = api_impl.format_result(status, 'json', {})
49 assert result == '{"status":700,"message":"Bad format.","software_version":"%s"}' % (NOMINATIM_VERSION, )
52 def test_status_format_json_full():
53 status = napi.StatusResult(0, 'OK')
54 status.data_updated = dt.datetime(2010, 2, 7, 20, 20, 3, 0, tzinfo=dt.timezone.utc)
55 status.database_version = '5.6'
57 result = api_impl.format_result(status, 'json', {})
59 assert result == '{"status":0,"message":"OK","data_updated":"2010-02-07T20:20:03+00:00","software_version":"%s","database_version":"5.6"}' % (NOMINATIM_VERSION, )
64 def test_search_details_minimal():
65 search = napi.DetailedResult(napi.SourceTable.PLACEX,
69 result = api_impl.format_result(search, 'json', {})
71 assert json.loads(result) == \
76 'calculated_importance': pytest.approx(0.0000001),
80 'centroid': {'type': 'Point', 'coordinates': [1.0, 2.0]},
81 'geometry': {'type': 'Point', 'coordinates': [1.0, 2.0]},
85 def test_search_details_full():
86 import_date = dt.datetime(2010, 2, 7, 20, 20, 3, 0, tzinfo=dt.timezone.utc)
87 search = napi.DetailedResult(
88 source_table=napi.SourceTable.PLACEX,
89 category=('amenity', 'bank'),
90 centroid=napi.Point(56.947, -87.44),
93 linked_place_id=55693,
94 osm_object=('W', 442100),
96 names={'name': 'Bank', 'name:fr': 'Banque'},
97 address={'city': 'Niento', 'housenumber': ' 3'},
98 extratags={'atm': 'yes'},
106 indexed_date = import_date
109 result = api_impl.format_result(search, 'json', {})
111 assert json.loads(result) == \
113 'parent_place_id': 114,
116 'category': 'amenity',
120 'names': {'name': 'Bank', 'name:fr': 'Banque'},
121 'addresstags': {'city': 'Niento', 'housenumber': ' 3'},
123 'calculated_postcode': '556 X23',
124 'country_code': 'll',
125 'indexed_date': '2010-02-07T20:20:03+00:00',
126 'importance': pytest.approx(0.0443),
127 'calculated_importance': pytest.approx(0.0443),
128 'extratags': {'atm': 'yes'},
129 'calculated_wikipedia': 'en:Bank',
133 'centroid': {'type': 'Point', 'coordinates': [56.947, -87.44]},
134 'geometry': {'type': 'Point', 'coordinates': [56.947, -87.44]},
138 @pytest.mark.parametrize('gtype,isarea', [('ST_Point', False),
139 ('ST_LineString', False),
140 ('ST_Polygon', True),
141 ('ST_MultiPolygon', True)])
142 def test_search_details_no_geometry(gtype, isarea):
143 search = napi.DetailedResult(napi.SourceTable.PLACEX,
145 napi.Point(1.0, 2.0),
146 geometry={'type': gtype})
148 result = api_impl.format_result(search, 'json', {})
149 js = json.loads(result)
151 assert js['geometry'] == {'type': 'Point', 'coordinates': [1.0, 2.0]}
152 assert js['isarea'] == isarea
155 def test_search_details_with_geometry():
156 search = napi.DetailedResult(napi.SourceTable.PLACEX,
158 napi.Point(1.0, 2.0),
159 geometry={'geojson': '{"type":"Point","coordinates":[56.947,-87.44]}'})
161 result = api_impl.format_result(search, 'json', {})
162 js = json.loads(result)
164 assert js['geometry'] == {'type': 'Point', 'coordinates': [56.947, -87.44]}
165 assert js['isarea'] == False
168 def test_search_details_with_address_minimal():
169 search = napi.DetailedResult(napi.SourceTable.PLACEX,
171 napi.Point(1.0, 2.0),
173 napi.AddressLine(place_id=None,
175 category=('bnd', 'note'),
185 result = api_impl.format_result(search, 'json', {})
186 js = json.loads(result)
188 assert js['address'] == [{'localname': '',
196 def test_search_details_with_address_full():
197 search = napi.DetailedResult(napi.SourceTable.PLACEX,
199 napi.Point(1.0, 2.0),
201 napi.AddressLine(place_id=3498,
202 osm_object=('R', 442),
203 category=('bnd', 'note'),
204 names={'name': 'Trespass'},
205 extratags={'access': 'no',
206 'place_type': 'spec'},
214 result = api_impl.format_result(search, 'json', {})
215 js = json.loads(result)
217 assert js['address'] == [{'localname': 'Trespass',
221 'place_type': 'spec',