]> git.openstreetmap.org Git - nominatim.git/blobdiff - test/bdd/steps/http_responses.py
bdd: fully check correctness of geojson and geocodejson
[nominatim.git] / test / bdd / steps / http_responses.py
index b493f013293fbaf749fc7b9d0b95ba92ee12fbfb..aee0d7f069b62950292aab92cf6c983077b658a6 100644 (file)
@@ -7,12 +7,11 @@
 """
 Classes wrapping HTTP responses from the Nominatim API.
 """
-from collections import OrderedDict
 import re
 import json
 import xml.etree.ElementTree as ET
 
-from check_functions import Almost
+from check_functions import Almost, check_for_attributes
 
 OSM_TYPE = {'N' : 'node', 'W' : 'way', 'R' : 'relation',
             'n' : 'node', 'w' : 'way', 'r' : 'relation',
@@ -70,22 +69,54 @@ class GenericResponse:
         else:
             code = m.group(2)
             self.header['json_func'] = m.group(1)
-        self.result = json.JSONDecoder(object_pairs_hook=OrderedDict).decode(code)
-        if isinstance(self.result, OrderedDict):
+        self.result = json.JSONDecoder().decode(code)
+        if isinstance(self.result, dict):
             if 'error' in self.result:
                 self.result = []
             else:
                 self.result = [self.result]
 
+
     def _parse_geojson(self):
         self._parse_json()
         if self.result:
-            self.result = list(map(_geojson_result_to_json_result, self.result[0]['features']))
+            geojson = self.result[0]
+            # check for valid geojson
+            check_for_attributes(geojson, 'type,features')
+            assert geojson['type'] == 'FeatureCollection'
+            assert isinstance(geojson['features'], list)
+
+            self.result = []
+            for result in geojson['features']:
+                check_for_attributes(result, 'type,properties,geometry')
+                assert result['type'] == 'Feature'
+                new = result['properties']
+                check_for_attributes(new, 'geojson', 'absent')
+                new['geojson'] = result['geometry']
+                if 'bbox' in result:
+                    check_for_attributes(new, 'boundingbox', 'absent')
+                    # bbox is  minlon, minlat, maxlon, maxlat
+                    # boundingbox is minlat, maxlat, minlon, maxlon
+                    new['boundingbox'] = [result['bbox'][1],
+                                          result['bbox'][3],
+                                          result['bbox'][0],
+                                          result['bbox'][2]]
+                for k, v in geojson.items():
+                    if k not in ('type', 'features'):
+                        check_for_attributes(new, '__' + k, 'absent')
+                        new['__' + k] = v
+                self.result.append(new)
+
 
     def _parse_geocodejson(self):
         self._parse_geojson()
-        if self.result is not None:
-            self.result = [r['geocoding'] for r in self.result]
+        if self.result:
+            for r in self.result:
+                assert set(r.keys()) == {'geocoding', 'geojson', '__geocoding'}, \
+                       f"Unexpected keys in result: {r.keys()}"
+                check_for_attributes(r['geocoding'], 'geojson', 'absent')
+                r |= r.pop('geocoding')
+
 
     def assert_field(self, idx, field, value):
         """ Check that result row `idx` has a field `field` with value `value`.
@@ -102,7 +133,7 @@ class GenericResponse:
         elif value.startswith("^"):
             assert re.fullmatch(value, self.result[idx][field]), \
                    BadRowValueAssert(self, idx, field, value)
-        elif isinstance(self.result[idx][field], OrderedDict):
+        elif isinstance(self.result[idx][field], dict):
             assert self.result[idx][field] == eval('{' + value + '}'), \
                    BadRowValueAssert(self, idx, field, value)
         else:
@@ -115,7 +146,7 @@ class GenericResponse:
 
         field = self.result[idx]
         for p in path:
-            assert isinstance(field, OrderedDict)
+            assert isinstance(field, dict)
             assert p in field
             field = field[p]
 
@@ -123,7 +154,7 @@ class GenericResponse:
             assert Almost(value) == float(field)
         elif value.startswith("^"):
             assert re.fullmatch(value, field)
-        elif isinstance(field, OrderedDict):
+        elif isinstance(field, dict):
             assert field, eval('{' + value + '}')
         else:
             assert str(field) == str(value)