Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #8223 from signedav/json_tests
QgsServer Tests for JSON fields
  • Loading branch information
m-kuhn committed Oct 25, 2018
2 parents b0104a2 + 0a2689d commit dc334ac
Show file tree
Hide file tree
Showing 6 changed files with 395 additions and 13 deletions.
9 changes: 6 additions & 3 deletions tests/src/python/test_qgsserver_wms.py
Expand Up @@ -48,15 +48,18 @@ class TestQgsServerWMSTestBase(QgsServerTestBase):
# Set to True to re-generate reference files for this class
regenerate_reference = False

def wms_request_compare(self, request, extra=None, reference_file=None, project='test_project.qgs', version='1.3.0'):
def wms_request(self, request, extra=None, project='test_project.qgs', version='1.3.0'):
project = self.testdata_path + project
assert os.path.exists(project), "Project file not found: " + project

query_string = 'https://www.qgis.org/?MAP=%s&SERVICE=WMS&VERSION=%s&REQUEST=%s' % (urllib.parse.quote(project), version, request)
if extra is not None:
query_string += extra
header, body = self._execute_request(query_string)
response = header + body
return (header, body, query_string)

def wms_request_compare(self, request, extra=None, reference_file=None, project='test_project.qgs', version='1.3.0'):
response_header, response_body, query_string = self.wms_request(request, extra, project, version)
response = response_header + response_body
reference_path = self.testdata_path + (request.lower() if not reference_file else reference_file) + '.txt'
self.store_reference(reference_path, response)
f = open(reference_path, 'rb')
Expand Down
119 changes: 109 additions & 10 deletions tests/src/python/test_qgsserver_wms_getfeatureinfo.py
Expand Up @@ -18,14 +18,18 @@

import os

# Needed on Qt 5 so that the serialization of XML is consistent among all executions
# Needed on Qt 5 so that the serialization of XML is consistent among all
# executions
os.environ['QT_HASH_SEED'] = '1'

import re
import urllib.request
import urllib.parse
import urllib.error

import xml.etree.ElementTree as ET
import json

from qgis.testing import unittest
from qgis.PyQt.QtCore import QSize

Expand Down Expand Up @@ -194,7 +198,8 @@ def testGetFeatureInfo(self):
'wms_getfeatureinfo_notvisible',
'test_project_scalevisibility.qgs')

# Test GetFeatureInfo resolves "value map" widget values but also Server usage of qgs and gpkg file
# Test GetFeatureInfo resolves "value map" widget values but also
# Server usage of qgs and gpkg file
mypath = self.testdata_path + "test_project_values.qgz"
self.wms_request_compare('GetFeatureInfo',
'&layers=layer0&styles=&' +
Expand Down Expand Up @@ -240,7 +245,8 @@ def testGetFeatureInfoValueRelationArray(self):
'wms_getfeatureinfo-values3-text-xml',
'test_project_values.qgz')

# TODO make GetFeatureInfo show what's in the display expression and enable test
# TODO make GetFeatureInfo show what's in the display expression and
# enable test
@unittest.expectedFailure
def testGetFeatureInfoRelationReference(self):
"""Test GetFeatureInfo solves "relation reference" widget "display expression" values"""
Expand All @@ -267,7 +273,8 @@ def testGetFeatureInfoFilterGPKG(self):
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
urllib.parse.quote(':"NAME" = \'two\''),
'wms_getfeatureinfo_filter_gpkg',
'test_project.qgz')

Expand All @@ -281,7 +288,8 @@ def testGetFeatureInfoFilter(self):
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
urllib.parse.quote(':"NAME" = \'two\''),
'wms_getfeatureinfo_filter')

# Test a filter with NO condition results
Expand All @@ -290,7 +298,9 @@ def testGetFeatureInfoFilter(self):
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' AND "utf8nameè" = \'no-results\''),
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
urllib.parse.quote(
':"NAME" = \'two\' AND "utf8nameè" = \'no-results\''),
'wms_getfeatureinfo_filter_no_results')

# Test a filter with OR condition results
Expand All @@ -299,7 +309,9 @@ def testGetFeatureInfoFilter(self):
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "NAME" = \'three\''),
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
urllib.parse.quote(
':"NAME" = \'two\' OR "NAME" = \'three\''),
'wms_getfeatureinfo_filter_or')

# Test a filter with OR condition and UTF results
Expand All @@ -310,16 +322,20 @@ def testGetFeatureInfoFilter(self):
'INFO_FORMAT=text%2Fxml&' +
'width=600&height=400&srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\' OR "utf8nameè" = \'three èé↓\''),
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
urllib.parse.quote(
':"NAME" = \'two\' OR "utf8nameè" = \'three èé↓\''),
'wms_getfeatureinfo_filter_or_utf8')

# Regression #18292 Server GetFeatureInfo FILTER search fails when WIDTH, HEIGHT are not specified
# Regression #18292 Server GetFeatureInfo FILTER search fails when
# WIDTH, HEIGHT are not specified
self.wms_request_compare('GetFeatureInfo',
'&layers=testlayer%20%C3%A8%C3%A9&' +
'INFO_FORMAT=text%2Fxml&' +
'srs=EPSG%3A3857&' +
'query_layers=testlayer%20%C3%A8%C3%A9&' +
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib.parse.quote(':"NAME" = \'two\''),
'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
urllib.parse.quote(':"NAME" = \'two\''),
'wms_getfeatureinfo_filter_no_width')

def testGetFeatureInfoTolerance(self):
Expand Down Expand Up @@ -407,6 +423,89 @@ def testGetFeatureInfoTolerance(self):
'wms_getfeatureinfo_polygon_tolerance_20_text_xml',
'test_project_values.qgz')

def testGetFeatureInfoPostgresTypes(self):
# compare json list output with file
self.wms_request_compare('GetFeatureInfo',
'&layers=json' +
'&info_format=text%2Fxml' +
'&srs=EPSG%3A3857' +
'&QUERY_LAYERS=json' +
'&FILTER=json' +
urllib.parse.quote(':"pk" = 1'),
'get_postgres_types_json_list',
'test_project_postgres_types.qgs')

# compare dict output with file
self.wms_request_compare('GetFeatureInfo',
'&layers=json' +
'&info_format=text%2Fxml' +
'&srs=EPSG%3A3857' +
'&QUERY_LAYERS=json' +
'&FILTER=json' +
urllib.parse.quote(':"pk" = 2'),
'get_postgres_types_json_dict',
'test_project_postgres_types.qgs')

# compare decoded json field list
response_header, response_body, query_string = self.wms_request('GetFeatureInfo',
'&layers=json' +
'&info_format=text%2Fxml' +
'&srs=EPSG%3A3857' +
'&QUERY_LAYERS=json' +
'&FILTER=json' +
urllib.parse.quote(
':"pk" = 1'),
'test_project_postgres_types.qgs')
root = ET.fromstring(response_body)
for attribute in root.iter('Attribute'):
if attribute.get('name') == 'jvalue':
self.assertIsInstance(json.loads(attribute.get('value')), list)
self.assertEqual(json.loads(attribute.get('value')), [1, 2, 3])
self.assertEqual(
json.loads(
attribute.get('value')), [
1.0, 2.0, 3.0])
if attribute.get('name') == 'jbvalue':
self.assertIsInstance(json.loads(attribute.get('value')), list)
self.assertEqual(json.loads(attribute.get('value')), [4, 5, 6])
self.assertEqual(
json.loads(
attribute.get('value')), [
4.0, 5.0, 6.0])

# compare decoded json field dict
response_header, response_body, query_string = self.wms_request('GetFeatureInfo',
'&layers=json' +
'&info_format=text%2Fxml' +
'&srs=EPSG%3A3857' +
'&QUERY_LAYERS=json' +
'&FILTER=json' +
urllib.parse.quote(
':"pk" = 2'),
'test_project_postgres_types.qgs')
root = ET.fromstring(response_body)
for attribute in root.iter('Attribute'):
if attribute.get('name') == 'jvalue':
self.assertIsInstance(json.loads(attribute.get('value')), dict)
self.assertEqual(
json.loads(
attribute.get('value')), {
'a': 1, 'b': 2})
self.assertEqual(
json.loads(
attribute.get('value')), {
'a': 1.0, 'b': 2.0})
if attribute.get('name') == 'jbvalue':
self.assertIsInstance(json.loads(attribute.get('value')), dict)
self.assertEqual(
json.loads(
attribute.get('value')), {
'c': 4, 'd': 5})
self.assertEqual(
json.loads(
attribute.get('value')), {
'c': 4.0, 'd': 5.0})


if __name__ == '__main__':
unittest.main()
Binary file modified tests/testdata/qgis_server/db.gpkg
Binary file not shown.
13 changes: 13 additions & 0 deletions tests/testdata/qgis_server/get_postgres_types_json_dict.txt
@@ -0,0 +1,13 @@
*****
Content-Type: text/xml; charset=utf-8

<GetFeatureInfoResponse>
<BoundingBox maxy="0" maxx="0" miny="0" CRS="EPSG:3857" minx="0"/>
<Layer name="json">
<Feature id="2">
<Attribute value="2" name="pk"/>
<Attribute value="{&#xa; &quot;a&quot;: 1,&#xa; &quot;b&quot;: 2&#xa;}&#xa;" name="jvalue"/>
<Attribute value="{&#xa; &quot;c&quot;: 4,&#xa; &quot;d&quot;: 5&#xa;}&#xa;" name="jbvalue"/>
</Feature>
</Layer>
</GetFeatureInfoResponse>
13 changes: 13 additions & 0 deletions tests/testdata/qgis_server/get_postgres_types_json_list.txt
@@ -0,0 +1,13 @@
*****
Content-Type: text/xml; charset=utf-8

<GetFeatureInfoResponse>
<BoundingBox maxy="0" maxx="0" miny="0" CRS="EPSG:3857" minx="0"/>
<Layer name="json">
<Feature id="1">
<Attribute value="1" name="pk"/>
<Attribute value="[&#xa; 1,&#xa; 2,&#xa; 3&#xa;]&#xa;" name="jvalue"/>
<Attribute value="[&#xa; 4,&#xa; 5,&#xa; 6&#xa;]&#xa;" name="jbvalue"/>
</Feature>
</Layer>
</GetFeatureInfoResponse>

0 comments on commit dc334ac

Please sign in to comment.