From 49ae0206f4e3373edd76568b4f9fe5d8f8bdae64 Mon Sep 17 00:00:00 2001 From: Alessandro Pasotti Date: Thu, 29 Sep 2016 11:47:32 +0200 Subject: [PATCH] [Server 3.0] Tests reliability + new auth test - Local server searches for a free port before binding - Server tests now ignore attributes order - Updated reference docs - Renamed projects ("+" -> "_") - Added a smoke test for auth manager and WMS/WFS providers --- tests/src/python/CMakeLists.txt | 1 + tests/src/python/qgis_wrapped_server.py | 46 ++- tests/src/python/test_authmanager_endpoint.py | 180 +++++++++ tests/src/python/test_offline_editing_wfs.py | 7 +- tests/src/python/test_qgsserver.py | 57 ++- tests/src/python/test_qgsserver_wfst.py | 7 +- .../testdata/qgis_server/getcapabilities.txt | 16 +- .../qgis_server/getcapabilities_inspire.txt | 16 +- .../qgis_server/getprojectsettings.txt | 21 +- .../{test+project.qgs => test_project.qgs} | 350 ++++++++++-------- ...t_inspire.qgs => test_project_inspire.qgs} | 0 ...t+project_wfs.qgs => test_project_wfs.qgs} | 0 12 files changed, 495 insertions(+), 206 deletions(-) create mode 100644 tests/src/python/test_authmanager_endpoint.py rename tests/testdata/qgis_server/{test+project.qgs => test_project.qgs} (68%) rename tests/testdata/qgis_server/{test+project_inspire.qgs => test_project_inspire.qgs} (100%) rename tests/testdata/qgis_server/{test+project_wfs.qgs => test_project_wfs.qgs} (100%) diff --git a/tests/src/python/CMakeLists.txt b/tests/src/python/CMakeLists.txt index 646ac90c48d..d268f8c072e 100644 --- a/tests/src/python/CMakeLists.txt +++ b/tests/src/python/CMakeLists.txt @@ -150,4 +150,5 @@ IF (WITH_SERVER) ADD_PYTHON_TEST(PyQgsServerAccessControl test_qgsserver_accesscontrol.py) ADD_PYTHON_TEST(PyQgsServerWFST test_qgsserver_wfst.py) ADD_PYTHON_TEST(PyQgsOfflineEditingWFS test_offline_editing_wfs.py) + ADD_PYTHON_TEST(PyQgsAuthManagerEnpointTest test_authmanager_endpoint.py) ENDIF (WITH_SERVER) diff --git a/tests/src/python/qgis_wrapped_server.py b/tests/src/python/qgis_wrapped_server.py index 04328c00860..4d033d0f1a6 100644 --- a/tests/src/python/qgis_wrapped_server.py +++ b/tests/src/python/qgis_wrapped_server.py @@ -5,6 +5,13 @@ QGIS Server HTTP wrapper This script launches a QGIS Server listening on port 8081 or on the port specified on the environment variable QGIS_SERVER_DEFAULT_PORT +For testing purposes, HTTP Basic can be enabled by setting the following +environment variables: + + * QGIS_SERVER_HTTP_BASIC_AUTH (default not set, set to anything to enable) + * QGIS_SERVER_USERNAME (default ="username") + * QGIS_SERVER_PASSWORD (default ="password") + .. note:: This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -22,6 +29,8 @@ __revision__ = '$Format:%H$' import os +import sys +import signal import urllib.parse from http.server import BaseHTTPRequestHandler, HTTPServer from qgis.core import QgsApplication @@ -36,11 +45,35 @@ qgs_app = QgsApplication([], False) qgs_server = QgsServer() +if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None: + from qgis.server import QgsServerFilter + import base64 + + class HTTPBasicFilter(QgsServerFilter): + + def responseComplete(self): + request = self.serverInterface().requestHandler() + if self.serverInterface().getEnv('HTTP_AUTHORIZATION'): + username, password = base64.b64decode(self.serverInterface().getEnv('HTTP_AUTHORIZATION')[6:]).split(b':') + if (username.decode('utf-8') == os.environ.get('QGIS_SERVER_USERNAME', 'username') + and password.decode('utf-8') == os.environ.get('QGIS_SERVER_PASSWORD', 'password')): + return + # No auth ... + request.clearHeaders() + request.setHeader('Status', '401 Authorization required') + request.setHeader('WWW-Authenticate', 'Basic realm="QGIS Server"') + request.clearBody() + request.appendBody(b'

Authorization required

') + + filter = HTTPBasicFilter(qgs_server.serverInterface()) + qgs_server.serverInterface().registerFilter(filter) + + class Handler(BaseHTTPRequestHandler): def do_GET(self): # CGI vars: - for k, v in list(self.headers.items()): + for k, v in self.headers.items(): qgs_server.putenv('HTTP_%s' % k.replace(' ', '-').replace('-', '_').replace(' ', '-').upper(), v) qgs_server.putenv('SERVER_PORT', str(self.server.server_port)) qgs_server.putenv('SERVER_NAME', self.server.server_name) @@ -52,7 +85,7 @@ class Handler(BaseHTTPRequestHandler): self.send_response(int(headers_dict['Status'].split(' ')[0])) except: self.send_response(200) - for k, v in list(headers_dict.items()): + for k, v in headers_dict.items(): self.send_header(k, v) self.end_headers() self.wfile.write(body) @@ -71,5 +104,12 @@ if __name__ == '__main__': server = HTTPServer(('localhost', QGIS_SERVER_DEFAULT_PORT), Handler) print('Starting server on localhost:%s, use to stop' % QGIS_SERVER_DEFAULT_PORT) + + def signal_handler(signal, frame): + global qgs_app + print("\nExiting QGIS...") + qgs_app.exitQgis() + sys.exit(0) + + signal.signal(signal.SIGINT, signal_handler) server.serve_forever() - qgs_app.exitQgis() diff --git a/tests/src/python/test_authmanager_endpoint.py b/tests/src/python/test_authmanager_endpoint.py new file mode 100644 index 00000000000..50d712b6773 --- /dev/null +++ b/tests/src/python/test_authmanager_endpoint.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- +""" +Tests for auth manager WMS/WFS using QGIS Server through HTTP Basic +enabled qgis_wrapped_server.py. + +This is an integration test for QGIS Desktop Auth Manager WFS and WMS provider +and QGIS Server WFS/WMS that check if QGIS can use a stored auth manager auth +configuration to access an HTTP Basic protected endpoint. + + +From build dir, run: ctest -R PyQgsAuthManagerEnpointTest -V + +.. note:: This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. +""" +import os +import sys +import subprocess +import tempfile +import random +import string +import urllib + +__author__ = 'Alessandro Pasotti' +__date__ = '18/09/2016' +__copyright__ = 'Copyright 2016, The QGIS Project' +# This will get replaced with a git SHA1 when you do a git archive +__revision__ = '$Format:%H$' + +from time import sleep +from urllib.parse import quote +from shutil import rmtree + +from utilities import unitTestDataPath +from qgis.core import ( + QgsAuthManager, + QgsAuthMethodConfig, + QgsVectorLayer, + QgsRasterLayer, +) +from qgis.testing import ( + start_app, + unittest, +) + +try: + QGIS_SERVER_AUTHMANAGER_DEFAULT_PORT = os.environ['QGIS_SERVER_AUTHMANAGER_DEFAULT_PORT'] +except: + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 0)) + QGIS_SERVER_AUTHMANAGER_DEFAULT_PORT = s.getsockname()[1] + s.close() + +QGIS_AUTH_DB_DIR_PATH = tempfile.mkdtemp() + +os.environ['QGIS_AUTH_DB_DIR_PATH'] = QGIS_AUTH_DB_DIR_PATH + +qgis_app = start_app() + + +class TestAuthManager(unittest.TestCase): + + @classmethod + def setUpClass(cls): + """Run before all tests: + Creates an auth configuration""" + cls.port = QGIS_SERVER_AUTHMANAGER_DEFAULT_PORT + # Clean env just to be sure + env_vars = ['QUERY_STRING', 'QGIS_PROJECT_FILE'] + for ev in env_vars: + try: + del os.environ[ev] + except KeyError: + pass + cls.testdata_path = unitTestDataPath('qgis_server') + '/' + cls.project_path = quote(cls.testdata_path + "test_project.qgs") + # Enable auth + #os.environ['QGIS_AUTH_PASSWORD_FILE'] = QGIS_AUTH_PASSWORD_FILE + authm = QgsAuthManager.instance() + assert (authm.setMasterPassword('masterpassword', True)) + cls.auth_config = QgsAuthMethodConfig('Basic') + cls.auth_config.setName('test_auth_config') + cls.username = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6)) + cls.password = cls.username[::-1] # reversed + cls.auth_config.setConfig('username', cls.username) + cls.auth_config.setConfig('password', cls.password) + assert (authm.storeAuthenticationConfig(cls.auth_config)[0]) + + os.environ['QGIS_SERVER_HTTP_BASIC_AUTH'] = '1' + os.environ['QGIS_SERVER_USERNAME'] = cls.username + os.environ['QGIS_SERVER_PASSWORD'] = cls.password + os.environ['QGIS_SERVER_DEFAULT_PORT'] = str(cls.port) + server_path = os.path.dirname(os.path.realpath(__file__)) + \ + '/qgis_wrapped_server.py' + cls.server = subprocess.Popen([sys.executable, server_path], + env=os.environ) + sleep(2) + + @classmethod + def tearDownClass(cls): + """Run after all tests""" + cls.server.terminate() + rmtree(QGIS_AUTH_DB_DIR_PATH) + del cls.server + + def setUp(self): + """Run before each test.""" + pass + + def tearDown(self): + """Run after each test.""" + pass + + @classmethod + def _getWFSLayer(cls, type_name, layer_name=None, authcfg=None): + """ + WFS layer factory + """ + if layer_name is None: + layer_name = 'wfs_' + type_name + parms = { + 'srsname': 'EPSG:4326', + 'typename': type_name, + 'url': 'http://127.0.0.1:%s/?map=%s' % (cls.port, cls.project_path), + 'version': 'auto', + 'table': '', + } + if authcfg is not None: + parms.update({'authcfg': authcfg}) + uri = ' '.join([("%s='%s'" % (k, v)) for k, v in list(parms.items())]) + wfs_layer = QgsVectorLayer(uri, layer_name, 'WFS') + return wfs_layer + + @classmethod + def _getWMSLayer(cls, layers, layer_name=None, authcfg=None): + """ + WMS layer factory + """ + if layer_name is None: + layer_name = 'wms_' + layers.replace(',', '') + parms = { + 'crs': 'EPSG:4326', + 'url': 'http://127.0.0.1:%s/?map=%s' % (cls.port, cls.project_path), + 'format': 'image/png', + # This is needed because of a really wierd implementation in QGIS Server, that + # replaces _ in the the real layer name with spaces + 'layers': urllib.parse.quote(layers).replace('_', ' '), + 'styles': '', + #'sql': '', + } + if authcfg is not None: + parms.update({'authcfg': authcfg}) + uri = '&'.join([("%s=%s" % (k, v.replace('=', '%3D'))) for k, v in list(parms.items())]) + wms_layer = QgsRasterLayer(uri, layer_name, 'wms') + return wms_layer + + def testValidAuthAccess(self): + """ + Access the HTTP Basic protected layer with valid credentials + """ + wfs_layer = self._getWFSLayer('testlayer_èé', authcfg=self.auth_config.id()) + self.assertTrue(wfs_layer.isValid()) + wms_layer = self._getWMSLayer('testlayer_èé', authcfg=self.auth_config.id()) + self.assertTrue(wms_layer.isValid()) + + def testInvalidAuthAccess(self): + """ + Access the HTTP Basic protected layer with no credentials + """ + wfs_layer = self._getWFSLayer('testlayer_èé') + self.assertFalse(wfs_layer.isValid()) + wms_layer = self._getWMSLayer('testlayer_èé') + self.assertFalse(wms_layer.isValid()) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/src/python/test_offline_editing_wfs.py b/tests/src/python/test_offline_editing_wfs.py index 62c2072bb0f..3477581a77d 100644 --- a/tests/src/python/test_offline_editing_wfs.py +++ b/tests/src/python/test_offline_editing_wfs.py @@ -45,10 +45,15 @@ from qgis.testing import ( from offlineditingtestbase import OfflineTestBase + try: QGIS_SERVER_WFST_DEFAULT_PORT = os.environ['QGIS_SERVER_WFST_DEFAULT_PORT'] except: - QGIS_SERVER_WFST_DEFAULT_PORT = 8081 + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 0)) + QGIS_SERVER_WFST_DEFAULT_PORT = s.getsockname()[1] + s.close() qgis_app = start_app() diff --git a/tests/src/python/test_qgsserver.py b/tests/src/python/test_qgsserver.py index bff4426d912..460859d2ee8 100644 --- a/tests/src/python/test_qgsserver.py +++ b/tests/src/python/test_qgsserver.py @@ -30,11 +30,37 @@ import osgeo.gdal # Also strip all multi-attribute tags (Qt5 attr order is random) # FIXME: this is a temporary workaround to make the test pass, a more # robust implementation must check for attributes too -RE_STRIP_UNCHECKABLE = b']*>|]*>|]*>|]*>|MAP=[^"]+|Content-Length: \d+|]*>|]*>|]*>|]*>|]*>|]*>|]*>|]*>' +#RE_STRIP_UNCHECKABLE = b']*>|]*>|]*>|]*>|MAP=[^"]+|Content-Length: \d+|]*>|]*>|]*>|]*>|]*>|]*>|]*>|]*>' +RE_STRIP_UNCHECKABLE = b'MAP=[^"]+|Content-Length: \d+' +RE_ATTRIBUTES = b'[^>\s]+=[^>\s]+' class TestQgsServer(unittest.TestCase): + def assertXMLEqual(self, response, expected, msg=''): + """Compare XML line by line and sorted attributes""" + response_lines = response.splitlines() + expected_lines = expected.splitlines() + line_no = 1 + for expected_line in expected_lines: + expected_line = expected_line.strip() + response_line = response_lines[line_no - 1].strip() + # Compare tag + try: + self.assertEqual(re.findall(b'<([^>\s]+)[ >]', expected_line)[0], + re.findall(b'<([^>\s]+)[ >]', response_line)[0], msg=msg + "\nTag mismatch on line %s: %s != %s" % (line_no, expected_line, response_line)) + except IndexError: + self.assertEqual(expected_line, response_line, msg=msg + "\nTag line mismatch %s: %s != %s" % (line_no, expected_line, response_line)) + #print("---->%s\t%s == %s" % (line_no, expected_line, response_line)) + # Compare attributes + if re.match(RE_ATTRIBUTES, expected_line): # has attrs + expected_attrs = re.findall(RE_ATTRIBUTES, expected_line) + expected_attrs.sort() + response_attrs = re.findall(RE_ATTRIBUTES, response_line) + response_attrs.sort() + self.assertEqual(expected_attrs, response_attrs, msg=msg + "\nXML attributes differ at line {0}: {1} != {2}".format(line_no, expected_attrs, response_attrs)) + line_no += 1 + @classmethod def setUpClass(cls): cls.app = QgsApplication([], False) @@ -170,7 +196,7 @@ class TestQgsServer(unittest.TestCase): # WMS tests def wms_request_compare(self, request, extra=None, reference_file=None): - project = self.testdata_path + "test+project.qgs" + project = self.testdata_path + "test_project.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = 'MAP=%s&SERVICE=WMS&VERSION=1.3&REQUEST=%s' % (urllib.parse.quote(project), request) @@ -202,7 +228,7 @@ class TestQgsServer(unittest.TestCase): if int(osgeo.gdal.VersionInfo()[:1]) < 2: expected = expected.replace(b'typeName="Integer64" precision="0" length="10" editType="TextEdit" type="qlonglong"', b'typeName="Integer" precision="0" length="10" editType="TextEdit" type="int"') - self.assertEqual(response, expected, msg="request %s failed.\n Query: %s\n Expected:\n%s\n\n Response:\n%s" % (query_string, request, expected.decode('utf-8'), response.decode('utf-8'))) + self.assertXMLEqual(response, expected, msg="request %s failed.\n Query: %s\n Expected:\n%s\n\n Response:\n%s" % (query_string, request, expected.decode('utf-8'), response.decode('utf-8'))) def test_project_wms(self): """Test some WMS request""" @@ -239,7 +265,7 @@ class TestQgsServer(unittest.TestCase): def wms_inspire_request_compare(self, request): """WMS INSPIRE tests""" - project = self.testdata_path + "test+project_inspire.qgs" + project = self.testdata_path + "test_project_inspire.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = 'MAP=%s&SERVICE=WMS&VERSION=1.3.0&REQUEST=%s' % (urllib.parse.quote(project), request) @@ -259,7 +285,7 @@ class TestQgsServer(unittest.TestCase): """ response = re.sub(RE_STRIP_UNCHECKABLE, b'', response) expected = re.sub(RE_STRIP_UNCHECKABLE, b'', expected) - self.assertEqual(response, expected, msg="request %s failed.\n Query: %s\n Expected:\n%s\n\n Response:\n%s" % (query_string, request, expected.decode('utf-8'), response.decode('utf-8'))) + self.assertXMLEqual(response, expected, msg="request %s failed.\n Query: %s\n Expected:\n%s\n\n Response:\n%s" % (query_string, request, expected.decode('utf-8'), response.decode('utf-8'))) def test_project_wms_inspire(self): """Test some WMS request""" @@ -268,7 +294,7 @@ class TestQgsServer(unittest.TestCase): # WFS tests def wfs_request_compare(self, request): - project = self.testdata_path + "test+project_wfs.qgs" + project = self.testdata_path + "test_project_wfs.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = 'MAP=%s&SERVICE=WFS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), request) @@ -294,7 +320,7 @@ class TestQgsServer(unittest.TestCase): if int(osgeo.gdal.VersionInfo()[:1]) < 2: expected = expected.replace(b'', b'') - self.assertEqual(response, expected, msg="request %s failed.\n Query: %s\n Expected:\n%s\n\n Response:\n%s" % (query_string, request, expected.decode('utf-8'), response.decode('utf-8'))) + self.assertXMLEqual(response, expected, msg="request %s failed.\n Query: %s\n Expected:\n%s\n\n Response:\n%s" % (query_string, request, expected.decode('utf-8'), response.decode('utf-8'))) def test_project_wfs(self): """Test some WFS request""" @@ -302,7 +328,7 @@ class TestQgsServer(unittest.TestCase): self.wfs_request_compare(request) def wfs_getfeature_compare(self, requestid, request): - project = self.testdata_path + "test+project_wfs.qgs" + project = self.testdata_path + "test_project_wfs.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = 'MAP=%s&SERVICE=WFS&VERSION=1.0.0&REQUEST=%s' % (urllib.parse.quote(project), request) @@ -333,8 +359,8 @@ class TestQgsServer(unittest.TestCase): """ response = re.sub(RE_STRIP_UNCHECKABLE, b'', response) expected = re.sub(RE_STRIP_UNCHECKABLE, b'', expected) - self.assertEqual(response, expected, msg="%s\n Expected:\n%s\n\n Response:\n%s" - % (error_msg_header, + self.assertXMLEqual(response, expected, msg="%s\n Expected:\n%s\n\n Response:\n%s" + % (error_msg_header, str(expected, errors='replace'), str(response, errors='replace'))) @@ -349,7 +375,7 @@ class TestQgsServer(unittest.TestCase): self.wfs_getfeature_compare(id, req) def wfs_getfeature_post_compare(self, requestid, request): - project = self.testdata_path + "test+project_wfs.qgs" + project = self.testdata_path + "test_project_wfs.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = 'MAP={}'.format(urllib.parse.quote(project)) @@ -365,7 +391,6 @@ class TestQgsServer(unittest.TestCase): header, body, ) - @unittest.skip def test_getfeature_post(self): template = """ @@ -392,20 +417,20 @@ class TestQgsServer(unittest.TestCase): for id, req in tests: self.wfs_getfeature_post_compare(id, req) - @unittest.skip def test_getLegendGraphics(self): """Test that does not return an exception but an image""" parms = { - 'MAP': self.testdata_path + "test%2Bproject.qgs", + 'MAP': self.testdata_path + "test_project.qgs", 'SERVICE': 'WMS', - 'VERSION': '1.0.0', + 'VERSION': '1.3.0', 'REQUEST': 'GetLegendGraphic', 'FORMAT': 'image/png', #'WIDTH': '20', # optional #'HEIGHT': '20', # optional - 'LAYER': 'testlayer+èé', + 'LAYER': 'testlayer%20èé', } qs = '&'.join(["%s=%s" % (k, v) for k, v in parms.items()]) + print(qs) h, r = self.server.handleRequest(qs) self.assertEqual(-1, h.find(b'Content-Type: text/xml; charset=utf-8'), "Header: %s\nResponse:\n%s" % (h, r)) self.assertNotEqual(-1, h.find(b'Content-Type: image/png'), "Header: %s\nResponse:\n%s" % (h, r)) diff --git a/tests/src/python/test_qgsserver_wfst.py b/tests/src/python/test_qgsserver_wfst.py index 4997c3a9981..7462f828c49 100644 --- a/tests/src/python/test_qgsserver_wfst.py +++ b/tests/src/python/test_qgsserver_wfst.py @@ -1,3 +1,4 @@ + # -*- coding: utf-8 -*- """ Tests for WFS-T provider using QGIS Server through qgis_wrapped_server.py. @@ -58,7 +59,11 @@ from qgis.testing import ( try: QGIS_SERVER_WFST_DEFAULT_PORT = os.environ['QGIS_SERVER_WFST_DEFAULT_PORT'] except: - QGIS_SERVER_WFST_DEFAULT_PORT = 8081 + import socket + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.bind(("", 0)) + QGIS_SERVER_WFST_DEFAULT_PORT = s.getsockname()[1] + s.close() qgis_app = start_app() diff --git a/tests/testdata/qgis_server/getcapabilities.txt b/tests/testdata/qgis_server/getcapabilities.txt index e170cbda76c..94fdf5c247d 100644 --- a/tests/testdata/qgis_server/getcapabilities.txt +++ b/tests/testdata/qgis_server/getcapabilities.txt @@ -2,7 +2,7 @@ Content-Length: 5590 Content-Type: text/xml; charset=utf-8 - + WMS QGIS TestProject @@ -30,7 +30,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -45,7 +45,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -59,7 +59,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -70,7 +70,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -80,7 +80,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -90,7 +90,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -131,7 +131,7 @@ Content-Type: text/xml; charset=utf-8 default image/png - + diff --git a/tests/testdata/qgis_server/getcapabilities_inspire.txt b/tests/testdata/qgis_server/getcapabilities_inspire.txt index da2f31dbcc8..2186a71be3f 100644 --- a/tests/testdata/qgis_server/getcapabilities_inspire.txt +++ b/tests/testdata/qgis_server/getcapabilities_inspire.txt @@ -2,7 +2,7 @@ Content-Length: 7368 Content-Type: text/xml; charset=utf-8 - + WMS QGIS TestProject @@ -30,7 +30,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -45,7 +45,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -59,7 +59,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -70,7 +70,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -80,7 +80,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -90,7 +90,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -152,7 +152,7 @@ Content-Type: text/xml; charset=utf-8 default image/png - + diff --git a/tests/testdata/qgis_server/getprojectsettings.txt b/tests/testdata/qgis_server/getprojectsettings.txt index 6a018cfb84f..bc96a7b9f27 100644 --- a/tests/testdata/qgis_server/getprojectsettings.txt +++ b/tests/testdata/qgis_server/getprojectsettings.txt @@ -2,7 +2,7 @@ Content-Length: 6685 Content-Type: text/xml; charset=utf-8 - + WMS QGIS TestProject @@ -30,7 +30,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -45,7 +45,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -59,7 +59,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -70,7 +70,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -80,7 +80,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -90,7 +90,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -102,7 +102,7 @@ Content-Type: text/xml; charset=utf-8 - + @@ -112,6 +112,9 @@ Content-Type: text/xml; charset=utf-8 text/xml + + + QGIS Test Project QGIS Test Project @@ -145,7 +148,7 @@ Content-Type: text/xml; charset=utf-8 default image/png - + testlayer èé diff --git a/tests/testdata/qgis_server/test+project.qgs b/tests/testdata/qgis_server/test_project.qgs similarity index 68% rename from tests/testdata/qgis_server/test+project.qgs rename to tests/testdata/qgis_server/test_project.qgs index 896980a2787..5ef2de9216b 100644 --- a/tests/testdata/qgis_server/test+project.qgs +++ b/tests/testdata/qgis_server/test_project.qgs @@ -1,11 +1,11 @@ - + QGIS Test Project - + - + @@ -13,10 +13,10 @@ degrees - 8.20315414376310059 - 44.9012858326611024 - 8.204164917965862 - 44.90154911342418131 + 8.20202108826836884 + 44.9009031607650968 + 8.20606418507941449 + 44.90195628381741244 0 1 @@ -34,7 +34,7 @@ 0 - + @@ -43,14 +43,14 @@ - + - + testlayer20150528120452665 ./testlayer.shp A test vector layer @@ -72,70 +72,65 @@ ogr + "name" - - - - - - - - + + - - + + - - + + - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - + + - - - - + + + + @@ -286,51 +281,73 @@ 0 0 0 - - - - + name + + + + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + . - - - + + + - + . 0 - + . 0 generatedlayout @@ -339,106 +356,119 @@ - - "name" - - - - + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + meters + m2 + + + false + 8.20315414376310059 44.901236559338642 8.204164917965862 44.90159838674664172 - + + + + + true + 255 + + + None + elpaso@itopen.it + 90 + + 8 + + + QGIS TestProject + + + + testlayer20150528120452665 + + + testlayer20150528120452665 + + + testlayer20150528120452665 + + - - - - - 90 - Some UTF8 text èòù - true - - - - - - QGIS TestProject - - - 4 - - +proj=longlat +datum=WGS84 +no_defs - 1 - EPSG:4326 - 3452 - - - false - - false - - - - off - current_layer - - - 0 - - 2 - - + conditions unknown + true + + + 4 + + + + 2 + current_layer + + + + off + 0 + + + + + + Alessandro Pasotti QGIS dev team - - - - true - elpaso@itopen.it - - WGS84 - + + + + + false + + + + + + 2 true D - - - - - - Alessandro Pasotti - - false - - - - true - - 255 - - - - - 255 - 255 - 255 - 255 0 + 255 255 + 255 255 + 255 + 255 + + WGS84 + + Some UTF8 text èòù + + testlayer20150528120452665 + + + true + false diff --git a/tests/testdata/qgis_server/test+project_inspire.qgs b/tests/testdata/qgis_server/test_project_inspire.qgs similarity index 100% rename from tests/testdata/qgis_server/test+project_inspire.qgs rename to tests/testdata/qgis_server/test_project_inspire.qgs diff --git a/tests/testdata/qgis_server/test+project_wfs.qgs b/tests/testdata/qgis_server/test_project_wfs.qgs similarity index 100% rename from tests/testdata/qgis_server/test+project_wfs.qgs rename to tests/testdata/qgis_server/test_project_wfs.qgs