18
18
19
19
import os
20
20
21
- # Needed on Qt 5 so that the serialization of XML is consistent among all executions
21
+ # Needed on Qt 5 so that the serialization of XML is consistent among all
22
+ # executions
22
23
os .environ ['QT_HASH_SEED' ] = '1'
23
24
24
25
import re
25
26
import urllib .request
26
27
import urllib .parse
27
28
import urllib .error
28
29
30
+ import xml .etree .ElementTree as ET
31
+ import json
32
+
29
33
from qgis .testing import unittest
30
34
from qgis .PyQt .QtCore import QSize
31
35
@@ -194,7 +198,8 @@ def testGetFeatureInfo(self):
194
198
'wms_getfeatureinfo_notvisible' ,
195
199
'test_project_scalevisibility.qgs' )
196
200
197
- # Test GetFeatureInfo resolves "value map" widget values but also Server usage of qgs and gpkg file
201
+ # Test GetFeatureInfo resolves "value map" widget values but also
202
+ # Server usage of qgs and gpkg file
198
203
mypath = self .testdata_path + "test_project_values.qgz"
199
204
self .wms_request_compare ('GetFeatureInfo' ,
200
205
'&layers=layer0&styles=&' +
@@ -240,7 +245,8 @@ def testGetFeatureInfoValueRelationArray(self):
240
245
'wms_getfeatureinfo-values3-text-xml' ,
241
246
'test_project_values.qgz' )
242
247
243
- # TODO make GetFeatureInfo show what's in the display expression and enable test
248
+ # TODO make GetFeatureInfo show what's in the display expression and
249
+ # enable test
244
250
@unittest .expectedFailure
245
251
def testGetFeatureInfoRelationReference (self ):
246
252
"""Test GetFeatureInfo solves "relation reference" widget "display expression" values"""
@@ -267,7 +273,8 @@ def testGetFeatureInfoFilterGPKG(self):
267
273
'INFO_FORMAT=text%2Fxml&' +
268
274
'width=600&height=400&srs=EPSG%3A3857&' +
269
275
'query_layers=testlayer%20%C3%A8%C3%A9&' +
270
- 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib .parse .quote (':"NAME" = \' two\' ' ),
276
+ 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
277
+ urllib .parse .quote (':"NAME" = \' two\' ' ),
271
278
'wms_getfeatureinfo_filter_gpkg' ,
272
279
'test_project.qgz' )
273
280
@@ -281,7 +288,8 @@ def testGetFeatureInfoFilter(self):
281
288
'INFO_FORMAT=text%2Fxml&' +
282
289
'width=600&height=400&srs=EPSG%3A3857&' +
283
290
'query_layers=testlayer%20%C3%A8%C3%A9&' +
284
- 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib .parse .quote (':"NAME" = \' two\' ' ),
291
+ 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
292
+ urllib .parse .quote (':"NAME" = \' two\' ' ),
285
293
'wms_getfeatureinfo_filter' )
286
294
287
295
# Test a filter with NO condition results
@@ -290,7 +298,9 @@ def testGetFeatureInfoFilter(self):
290
298
'INFO_FORMAT=text%2Fxml&' +
291
299
'width=600&height=400&srs=EPSG%3A3857&' +
292
300
'query_layers=testlayer%20%C3%A8%C3%A9&' +
293
- 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib .parse .quote (':"NAME" = \' two\' AND "utf8nameè" = \' no-results\' ' ),
301
+ 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
302
+ urllib .parse .quote (
303
+ ':"NAME" = \' two\' AND "utf8nameè" = \' no-results\' ' ),
294
304
'wms_getfeatureinfo_filter_no_results' )
295
305
296
306
# Test a filter with OR condition results
@@ -299,7 +309,9 @@ def testGetFeatureInfoFilter(self):
299
309
'INFO_FORMAT=text%2Fxml&' +
300
310
'width=600&height=400&srs=EPSG%3A3857&' +
301
311
'query_layers=testlayer%20%C3%A8%C3%A9&' +
302
- 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib .parse .quote (':"NAME" = \' two\' OR "NAME" = \' three\' ' ),
312
+ 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
313
+ urllib .parse .quote (
314
+ ':"NAME" = \' two\' OR "NAME" = \' three\' ' ),
303
315
'wms_getfeatureinfo_filter_or' )
304
316
305
317
# Test a filter with OR condition and UTF results
@@ -310,16 +322,20 @@ def testGetFeatureInfoFilter(self):
310
322
'INFO_FORMAT=text%2Fxml&' +
311
323
'width=600&height=400&srs=EPSG%3A3857&' +
312
324
'query_layers=testlayer%20%C3%A8%C3%A9&' +
313
- 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib .parse .quote (':"NAME" = \' two\' OR "utf8nameè" = \' three èé↓\' ' ),
325
+ 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
326
+ urllib .parse .quote (
327
+ ':"NAME" = \' two\' OR "utf8nameè" = \' three èé↓\' ' ),
314
328
'wms_getfeatureinfo_filter_or_utf8' )
315
329
316
- # Regression #18292 Server GetFeatureInfo FILTER search fails when WIDTH, HEIGHT are not specified
330
+ # Regression #18292 Server GetFeatureInfo FILTER search fails when
331
+ # WIDTH, HEIGHT are not specified
317
332
self .wms_request_compare ('GetFeatureInfo' ,
318
333
'&layers=testlayer%20%C3%A8%C3%A9&' +
319
334
'INFO_FORMAT=text%2Fxml&' +
320
335
'srs=EPSG%3A3857&' +
321
336
'query_layers=testlayer%20%C3%A8%C3%A9&' +
322
- 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' + urllib .parse .quote (':"NAME" = \' two\' ' ),
337
+ 'FEATURE_COUNT=10&FILTER=testlayer%20%C3%A8%C3%A9' +
338
+ urllib .parse .quote (':"NAME" = \' two\' ' ),
323
339
'wms_getfeatureinfo_filter_no_width' )
324
340
325
341
def testGetFeatureInfoTolerance (self ):
@@ -407,6 +423,89 @@ def testGetFeatureInfoTolerance(self):
407
423
'wms_getfeatureinfo_polygon_tolerance_20_text_xml' ,
408
424
'test_project_values.qgz' )
409
425
426
+ def testGetFeatureInfoPostgresTypes (self ):
427
+ # compare json list output with file
428
+ self .wms_request_compare ('GetFeatureInfo' ,
429
+ '&layers=json' +
430
+ '&info_format=text%2Fxml' +
431
+ '&srs=EPSG%3A3857' +
432
+ '&QUERY_LAYERS=json' +
433
+ '&FILTER=json' +
434
+ urllib .parse .quote (':"pk" = 1' ),
435
+ 'get_postgres_types_json_list' ,
436
+ 'test_project_postgres_types.qgs' )
437
+
438
+ # compare dict output with file
439
+ self .wms_request_compare ('GetFeatureInfo' ,
440
+ '&layers=json' +
441
+ '&info_format=text%2Fxml' +
442
+ '&srs=EPSG%3A3857' +
443
+ '&QUERY_LAYERS=json' +
444
+ '&FILTER=json' +
445
+ urllib .parse .quote (':"pk" = 2' ),
446
+ 'get_postgres_types_json_dict' ,
447
+ 'test_project_postgres_types.qgs' )
448
+
449
+ # compare decoded json field list
450
+ response_header , response_body , query_string = self .wms_request ('GetFeatureInfo' ,
451
+ '&layers=json' +
452
+ '&info_format=text%2Fxml' +
453
+ '&srs=EPSG%3A3857' +
454
+ '&QUERY_LAYERS=json' +
455
+ '&FILTER=json' +
456
+ urllib .parse .quote (
457
+ ':"pk" = 1' ),
458
+ 'test_project_postgres_types.qgs' )
459
+ root = ET .fromstring (response_body )
460
+ for attribute in root .iter ('Attribute' ):
461
+ if attribute .get ('name' ) == 'jvalue' :
462
+ self .assertIsInstance (json .loads (attribute .get ('value' )), list )
463
+ self .assertEqual (json .loads (attribute .get ('value' )), [1 , 2 , 3 ])
464
+ self .assertEqual (
465
+ json .loads (
466
+ attribute .get ('value' )), [
467
+ 1.0 , 2.0 , 3.0 ])
468
+ if attribute .get ('name' ) == 'jbvalue' :
469
+ self .assertIsInstance (json .loads (attribute .get ('value' )), list )
470
+ self .assertEqual (json .loads (attribute .get ('value' )), [4 , 5 , 6 ])
471
+ self .assertEqual (
472
+ json .loads (
473
+ attribute .get ('value' )), [
474
+ 4.0 , 5.0 , 6.0 ])
475
+
476
+ # compare decoded json field dict
477
+ response_header , response_body , query_string = self .wms_request ('GetFeatureInfo' ,
478
+ '&layers=json' +
479
+ '&info_format=text%2Fxml' +
480
+ '&srs=EPSG%3A3857' +
481
+ '&QUERY_LAYERS=json' +
482
+ '&FILTER=json' +
483
+ urllib .parse .quote (
484
+ ':"pk" = 2' ),
485
+ 'test_project_postgres_types.qgs' )
486
+ root = ET .fromstring (response_body )
487
+ for attribute in root .iter ('Attribute' ):
488
+ if attribute .get ('name' ) == 'jvalue' :
489
+ self .assertIsInstance (json .loads (attribute .get ('value' )), dict )
490
+ self .assertEqual (
491
+ json .loads (
492
+ attribute .get ('value' )), {
493
+ 'a' : 1 , 'b' : 2 })
494
+ self .assertEqual (
495
+ json .loads (
496
+ attribute .get ('value' )), {
497
+ 'a' : 1.0 , 'b' : 2.0 })
498
+ if attribute .get ('name' ) == 'jbvalue' :
499
+ self .assertIsInstance (json .loads (attribute .get ('value' )), dict )
500
+ self .assertEqual (
501
+ json .loads (
502
+ attribute .get ('value' )), {
503
+ 'c' : 4 , 'd' : 5 })
504
+ self .assertEqual (
505
+ json .loads (
506
+ attribute .get ('value' )), {
507
+ 'c' : 4.0 , 'd' : 5.0 })
508
+
410
509
411
510
if __name__ == '__main__' :
412
511
unittest .main ()
0 commit comments