Skip to content
Permalink
Browse files

When a remote SVG is requested but fails, use the missing SVG icon

as an indicator for users that something went wrong

This was previously only used for replies with incorrect mime
types or authentication errors, but it meant that an incorrect
SVG url would silently result in no symbols rendered.

Also add unit tests for fetching remote svg images

(cherry-picked from 7794144)
  • Loading branch information
nyalldawson committed Apr 2, 2018
1 parent 16fa1b9 commit 97b0ae62e04cc29a390d78d2645884f10698ae7e
@@ -433,10 +433,9 @@ QByteArray QgsSvgCache::getImageData( const QString &path ) const

if ( reply->error() != QNetworkReply::NoError )
{
QgsMessageLog::logMessage( tr( "SVG request failed [error: %1 - url: %2]" ).arg( reply->errorString(), reply->url().toString() ), tr( "SVG" ) );

QgsMessageLog::logMessage( tr( "SVG request failed [error: %1 - url: %2]" ).arg( reply->errorString(), path ), tr( "SVG" ) );
reply->deleteLater();
return QByteArray();
return mMissingSvg;
}

QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
@@ -149,6 +149,7 @@ ADD_PYTHON_TEST(PyQgsReport test_qgsreport.py)
ADD_PYTHON_TEST(PyQgsRulebasedRenderer test_qgsrulebasedrenderer.py)
ADD_PYTHON_TEST(PyQgsSingleSymbolRenderer test_qgssinglesymbolrenderer.py)
ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py)
ADD_PYTHON_TEST(PyQgsSvgCache test_qgssvgcache.py)
ADD_PYTHON_TEST(PyQgsSymbolButton test_qgssymbolbutton.py)
ADD_PYTHON_TEST(PyQgsTabfileProvider test_provider_tabfile.py)
ADD_PYTHON_TEST(PyQgsTabWidget test_qgstabwidget.py)
@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsSvgCache.
.. 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.
"""
__author__ = '(C) 2018 by Nyall Dawson'
__date__ = '29/03/2018'
__copyright__ = 'Copyright 2018, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'

import qgis # NOQA

import os
import socketserver
import threading
import http.server
from qgis.PyQt.QtCore import QDir
from qgis.PyQt.QtGui import QColor

from qgis.core import (QgsSvgCache, QgsRenderChecker, QgsApplication)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath

start_app()
TEST_DATA_DIR = unitTestDataPath()


class TestQgsSvgCache(unittest.TestCase):

@classmethod
def setUpClass(cls):
# Bring up a simple HTTP server, for remote SVG tests
os.chdir(unitTestDataPath() + '')
handler = http.server.SimpleHTTPRequestHandler

cls.httpd = socketserver.TCPServer(('localhost', 0), handler)
cls.port = cls.httpd.server_address[1]

cls.httpd_thread = threading.Thread(target=cls.httpd.serve_forever)
cls.httpd_thread.setDaemon(True)
cls.httpd_thread.start()

def setUp(self):
self.report = "<h1>Python QgsSvgCache Tests</h1>\n"

def tearDown(self):
report_file_path = "%s/qgistest.html" % QDir.tempPath()
with open(report_file_path, 'a') as report_file:
report_file.write(self.report)

def testRemoteSVG(self):
"""Test fetching remote svg."""
url = 'http://localhost:{}/qgis_local_server/sample_svg.svg'.format(str(TestQgsSvgCache.port))
image, in_cache = QgsApplication.svgCache().svgAsImage(url, 100, fill=QColor(0, 0, 0), stroke=QColor(0, 0, 0), strokeWidth=0.1, widthScaleFactor=1)
self.assertTrue(self.imageCheck('Remote SVG', 'remote_svg', image))

def testRemoteSvgAsText(self):
"""Test fetching remote svg with text mime format - e.g. github raw svgs"""
url = 'http://localhost:{}/qgis_local_server/svg_as_text.txt'.format(str(TestQgsSvgCache.port))
image, in_cache = QgsApplication.svgCache().svgAsImage(url, 100, fill=QColor(0, 0, 0), stroke=QColor(0, 0, 0), strokeWidth=0.1, widthScaleFactor=1)
self.assertTrue(self.imageCheck('Remote SVG as Text', 'remote_svg', image))

def testRemoteSvgBadMime(self):
"""Test fetching remote svg with bad mime type"""
url = 'http://localhost:{}/qgis_local_server/logo.png'.format(str(TestQgsSvgCache.port))
image, in_cache = QgsApplication.svgCache().svgAsImage(url, 100, fill=QColor(0, 0, 0), stroke=QColor(0, 0, 0), strokeWidth=0.1, widthScaleFactor=1)
self.assertTrue(self.imageCheck('Remote SVG bad MIME type', 'bad_svg', image))

def testRemoteSvgMissing(self):
"""Test fetching remote svg with bad url"""
url = 'http://localhost:{}/qgis_local_server/xxx.svg'.format(str(TestQgsSvgCache.port)) # oooo naughty
image, in_cache = QgsApplication.svgCache().svgAsImage(url, 100, fill=QColor(0, 0, 0), stroke=QColor(0, 0, 0), strokeWidth=0.1, widthScaleFactor=1)
self.assertTrue(self.imageCheck('Remote SVG missing', 'bad_svg', image))

def imageCheck(self, name, reference_image, image):
self.report += "<h2>Render {}</h2>\n".format(name)
temp_dir = QDir.tempPath() + '/'
file_name = temp_dir + 'svg_' + name + ".png"
image.save(file_name, "PNG")
checker = QgsRenderChecker()
checker.setControlPathPrefix("svg_cache")
checker.setControlName("expected_" + reference_image)
checker.setRenderedImage(file_name)
checker.setColorTolerance(2)
result = checker.compareImages(name, 20)
self.report += checker.report()
print((self.report))
return result

if __name__ == '__main__':
unittest.main()
Binary file not shown.
Binary file not shown.

0 comments on commit 97b0ae6

Please sign in to comment.
You can’t perform that action at this time.