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
  • Loading branch information
nyalldawson committed Mar 28, 2018
1 parent 5d4e1bb commit 77941442c7e19e3db34be5b5abc63fea76748bd1
@@ -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 );
@@ -152,6 +152,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 7794144

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