1# -*- coding: utf-8 -*-
2"""QGIS Unit tests for QgsServer WMS GetPrint legend.
3
4From build dir, run: ctest -R PyQgsServerWMSGetPrintLegend -V
5
6
7.. note:: This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12"""
13__author__ = 'Sebastien Peillet'
14__date__ = '30/06/2021'
15__copyright__ = 'Copyright 2021, The QGIS Project'
16
17import os
18import shutil
19
20# Needed on Qt 5 so that the serialization of XML is consistent among all executions
21os.environ['QT_HASH_SEED'] = '1'
22
23from qgis.testing import unittest
24from qgis.server import QgsBufferServerRequest, QgsBufferServerResponse
25from qgis.core import QgsProject
26from qgis.PyQt.QtCore import QTemporaryDir
27from qgis.PyQt.QtGui import QImage
28
29
30from test_qgsserver import QgsServerTestBase
31from utilities import unitTestDataPath
32
33
34class PyQgsServerWMSGetPrintLegend(QgsServerTestBase):
35    """Tests for issue GH #42036 QGIS Server GetPrint:
36    QGIS server print behaves inconsistently regarding legend content"""
37
38    def test_wms_getprint_legend(self):
39        """Test project has 2 layer: red and green and five templates:
40            red: follow map theme red
41            green: follow map theme green
42            blank: no map theme
43            full: follow map theme full with both layer
44            falsegreen : follow map theme falsegreen (visible layer : green but with blue style)
45        """
46
47        tmp_dir = QTemporaryDir()
48        shutil.copyfile(os.path.join(unitTestDataPath('qgis_server'), 'test_project_legend.qgs'), os.path.join(tmp_dir.path(), 'test_project_legend.qgs'))
49        shutil.copyfile(os.path.join(unitTestDataPath('qgis_server'), 'test_project_legend.gpkg'), os.path.join(tmp_dir.path(), 'test_project_legend.gpkg'))
50
51        project = QgsProject()
52        self.assertTrue(project.read(os.path.join(tmp_dir.path(), 'test_project_legend.qgs')))
53
54        params = {
55            "SERVICE": "WMS",
56            "VERSION": "1.3",
57            "REQUEST": "GetPrint",
58            "TEMPLATE": "blank",
59            "FORMAT": "png",
60            "LAYERS": "",
61            "map0:EXTENT": "778000,5600000,836000,5650000",
62            "map0:SCALE": "281285",
63            "map0:LAYERS": "red",
64            "CRS": "EPSG:3857",
65            "DPI": '72'
66        }
67
68        ######################################################
69        # Template legend tests
70        # Legend symbol are displayed at coordinates :
71        #   First item  : 600 x , 40 y
72        #   Second item : 600 x , 60 y
73
74        # blank template, no theme, no LAYERS, specified map0:LAYERS is red
75        response = QgsBufferServerResponse()
76        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
77        self.server.handleRequest(request, response, project)
78
79        image = QImage.fromData(response.body(), "PNG")
80        # Only the red layer is displayed, there is no second item
81        self._assertRed(image.pixelColor(600, 40))
82        self._assertWhite(image.pixelColor(600, 60))
83
84        # blank template, no LAYERS, specified map0:LAYERS is green
85        params["map0:LAYERS"] = "green"
86        response = QgsBufferServerResponse()
87        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
88        self.server.handleRequest(request, response, project)
89
90        image = QImage.fromData(response.body(), "PNG")
91        # Only the green layer is displayed, there is no second item
92        self._assertGreen(image.pixelColor(600, 40))
93        self._assertWhite(image.pixelColor(600, 60))
94
95        # blank template
96        params["map0:LAYERS"] = ""
97        response = QgsBufferServerResponse()
98        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
99        self.server.handleRequest(request, response, project)
100
101        image = QImage.fromData(response.body(), "PNG")
102        # Only the red layer is displayed, there is no second item
103        self._assertRed(image.pixelColor(600, 40))
104        self._assertGreen(image.pixelColor(600, 60))
105
106        # red template, red theme, specified map0:LAYERS is red
107        params["TEMPLATE"] = "red"
108        params["map0:LAYERS"] = "red"
109        response = QgsBufferServerResponse()
110        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
111        self.server.handleRequest(request, response, project)
112
113        image = QImage.fromData(response.body(), "PNG")
114        # Only the red layer is displayed, there is no second item
115        self._assertRed(image.pixelColor(600, 40))
116        self._assertWhite(image.pixelColor(600, 60))
117
118        # red template, red theme, specified map0:LAYERS is green
119        params["map0:LAYERS"] = "green"
120        response = QgsBufferServerResponse()
121        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
122        self.server.handleRequest(request, response, project)
123
124        image = QImage.fromData(response.body(), "PNG")
125        # Only the green layer is displayed, there is no second item
126        self._assertGreen(image.pixelColor(600, 40))
127        self._assertWhite(image.pixelColor(600, 60))
128
129        # red template, red theme, no map0:LAYERS
130        params["map0:LAYERS"] = ""
131        response = QgsBufferServerResponse()
132        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
133        self.server.handleRequest(request, response, project)
134
135        image = QImage.fromData(response.body(), "PNG")
136        # Only the red layer is displayed, there is no second item
137        self._assertRed(image.pixelColor(600, 40))
138        self._assertWhite(image.pixelColor(600, 60))
139
140        # green template, green theme, specified map0:LAYERS is red
141        params["TEMPLATE"] = "green"
142        params["map0:LAYERS"] = "red"
143        response = QgsBufferServerResponse()
144        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
145        self.server.handleRequest(request, response, project)
146
147        image = QImage.fromData(response.body(), "PNG")
148        # Only the red layer is displayed, there is no second item
149        self._assertRed(image.pixelColor(600, 40))
150        self._assertWhite(image.pixelColor(600, 60))
151
152        # green template, green theme, specified map0:LAYERS is green
153        params["map0:LAYERS"] = "green"
154        response = QgsBufferServerResponse()
155        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
156        self.server.handleRequest(request, response, project)
157
158        image = QImage.fromData(response.body(), "PNG")
159        # Only the green layer is displayed, there is no second item
160        self._assertGreen(image.pixelColor(600, 40))
161        self._assertWhite(image.pixelColor(600, 60))
162
163        # green template, green theme, no map0:LAYERS
164        params["map0:LAYERS"] = ""
165        response = QgsBufferServerResponse()
166        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
167        self.server.handleRequest(request, response, project)
168
169        image = QImage.fromData(response.body(), "PNG")
170        # Only the green layer is displayed, there is no second item
171        self._assertGreen(image.pixelColor(600, 40))
172        self._assertWhite(image.pixelColor(600, 60))
173
174        # full template, full theme, specified map0:LAYERS is red
175        params["TEMPLATE"] = "full"
176        params["map0:LAYERS"] = "red"
177        response = QgsBufferServerResponse()
178        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
179        self.server.handleRequest(request, response, project)
180
181        image = QImage.fromData(response.body(), "PNG")
182        # Only the red layer is displayed, there is no second item
183        self._assertRed(image.pixelColor(600, 40))
184        self._assertWhite(image.pixelColor(600, 60))
185
186        # full template, full theme, specified map0:LAYERS is green
187        params["map0:LAYERS"] = "green"
188        response = QgsBufferServerResponse()
189        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
190        self.server.handleRequest(request, response, project)
191
192        image = QImage.fromData(response.body(), "PNG")
193        # Only the green layer is displayed, there is no second item
194        self._assertGreen(image.pixelColor(600, 40))
195        self._assertWhite(image.pixelColor(600, 60))
196
197        # full template, full theme, no map0:LAYERS
198        params["map0:LAYERS"] = ""
199        response = QgsBufferServerResponse()
200        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
201        self.server.handleRequest(request, response, project)
202
203        image = QImage.fromData(response.body(), "PNG")
204        # Both red and green layers are displayed
205        self._assertRed(image.pixelColor(600, 40))
206        self._assertGreen(image.pixelColor(600, 60))
207
208        # falsegreen template, falsegreen theme (green layer is blue), specified map0:LAYERS is red
209        params["TEMPLATE"] = "falsegreen"
210        params["map0:LAYERS"] = "red"
211        response = QgsBufferServerResponse()
212        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
213        self.server.handleRequest(request, response, project)
214
215        image = QImage.fromData(response.body(), "PNG")
216        # Only the red layer is displayed, there is no second item
217        self._assertRed(image.pixelColor(600, 40))
218        self._assertWhite(image.pixelColor(600, 60))
219
220        # full template, full theme, specified map0:LAYERS is green
221        params["map0:LAYERS"] = "green"
222        response = QgsBufferServerResponse()
223        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
224        self.server.handleRequest(request, response, project)
225
226        image = QImage.fromData(response.body(), "PNG")
227        # Only the green layer (in blue) is displayed, there is no second item
228        self._assertBlue(image.pixelColor(600, 40))
229        self._assertWhite(image.pixelColor(600, 60))
230
231        # full template, full theme, no map0:LAYERS
232        params["map0:LAYERS"] = ""
233        response = QgsBufferServerResponse()
234        request = QgsBufferServerRequest('?' + '&'.join(["%s=%s" % i for i in params.items()]))
235        self.server.handleRequest(request, response, project)
236
237        image = QImage.fromData(response.body(), "PNG")
238        # Only the green layer (in blue) is displayed, there is no second item
239        self._assertBlue(image.pixelColor(600, 40))
240        self._assertWhite(image.pixelColor(600, 60))
241
242
243if __name__ == '__main__':
244    unittest.main()
245