Skip to content

Commit 3c71405

Browse files
elpasonyalldawson
authored andcommittedDec 7, 2021
Tests for form submit actions
1 parent c62a255 commit 3c71405

File tree

4 files changed

+112
-0
lines changed

4 files changed

+112
-0
lines changed
 

‎src/core/qgsaction.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ void QgsAction::run( const QgsExpressionContext &expressionContext ) const
100100
url.setQuery( QString( ) );
101101

102102
QNetworkRequest req { url };
103+
104+
// Specific code for testing, produces an invalid POST but we can still listen to
105+
// signals and examine the request
106+
if ( url.toString().contains( QLatin1String( "fake_qgis_http_endpoint" ) ) )
107+
{
108+
req.setUrl( QStringLiteral( "file://%1" ).arg( url.path() ) );
109+
}
110+
103111
QNetworkReply *reply = nullptr;
104112

105113
if ( mType != QgsAction::SubmitUrlMultipart )

‎tests/src/core/testqgsexpression.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,6 +1984,7 @@ class TestQgsExpression: public QObject
19841984
// Form encoding tests
19851985
QTest::newRow( "url_encode" ) << QStringLiteral( "url_encode(map())" ).arg( testDataDir ) << false << QVariant( "" );
19861986
QTest::newRow( "url_encode" ) << QStringLiteral( "url_encode(map('a b', 'a b', 'c &% d', 'c &% d'))" ).arg( testDataDir ) << false << QVariant( "a%20b=a%20b&c%20%26%25%20d=c%20%26%25%20d" );
1987+
QTest::newRow( "url_encode" ) << QStringLiteral( "url_encode(map('a&+b', 'a and plus b', 'a=b', 'a equals b'))" ).arg( testDataDir ) << false << QVariant( "a%26+b=a%20and%20plus%20b&a%3Db=a%20equals%20b" );
19871988
}
19881989

19891990
void run_evaluation_test( QgsExpression &exp, bool evalError, QVariant &expected )

‎tests/src/python/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ADD_PYTHON_TEST(PyCoreAdditions test_core_additions.py)
1313
ADD_PYTHON_TEST(PyPythonRepr test_python_repr.py)
1414
ADD_PYTHON_TEST(PyPythonUtils test_python_utils.py)
1515
ADD_PYTHON_TEST(PyQgsActionManager test_qgsactionmanager.py)
16+
ADD_PYTHON_TEST(PyQgsAction test_qgsaction.py)
1617
ADD_PYTHON_TEST(PyQgsAFSProvider test_provider_afs.py)
1718
ADD_PYTHON_TEST(PyQgsAggregateMappingWidget test_qgsaggregatemappingwidget.py)
1819
ADD_PYTHON_TEST(PyQgsAlignmentComboBox test_qgsalignmentcombobox.py)

‎tests/src/python/test_qgsaction.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# -*- coding: utf-8 -*-
2+
"""QGIS Unit tests for QgsAction.
3+
4+
From build dir, run: ctest -R PyQgsAction -V
5+
6+
.. note:: This program is free software; you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation; either version 2 of the License, or
9+
(at your option) any later version.
10+
"""
11+
__author__ = 'Alessandro Pasotti'
12+
__date__ = '24/11/2021'
13+
__copyright__ = 'Copyright 2021, The QGIS Project'
14+
15+
import qgis # NOQA switch sip api
16+
17+
from qgis.core import (
18+
QgsExpressionContext,
19+
QgsAction,
20+
QgsNetworkAccessManager,
21+
QgsNetworkRequestParameters,
22+
QgsApplication,
23+
)
24+
25+
from qgis.PyQt.QtCore import QTemporaryDir
26+
27+
from qgis.testing import start_app, unittest
28+
29+
import os
30+
import re
31+
import time
32+
import platform
33+
from functools import partial
34+
35+
start_app()
36+
37+
38+
class TestQgsAction(unittest.TestCase):
39+
40+
def setUp(self):
41+
self.body = None
42+
43+
def _req_logger(self, params):
44+
self.body = bytes(params.content())
45+
46+
def test_post_urlencoded_action(self):
47+
"""Test form www urlencoded"""
48+
49+
def _req_logger(self, params):
50+
self.body = bytes(params.content())
51+
52+
QgsNetworkAccessManager.instance().requestAboutToBeCreated[QgsNetworkRequestParameters].connect(partial(_req_logger, self))
53+
54+
temp_dir = QTemporaryDir()
55+
temp_path = temp_dir.path()
56+
temp_file = os.path.join(temp_path, 'urlencoded.txt')
57+
58+
action = QgsAction(QgsAction.SubmitUrlEncoded, 'url_encoded', "http://fake_qgis_http_endpoint" + temp_file + r"?[% url_encode(map('a&+b', 'a and plus b', 'a=b', 'a equals b')) %]")
59+
ctx = QgsExpressionContext()
60+
action.run(ctx)
61+
62+
while not self.body:
63+
QgsApplication.instance().processEvents()
64+
65+
self.assertEqual(self.body, br"a%26%2Bb=a%20and%20plus%20b&a%3Db=a%20equals%20b")
66+
67+
def test_post_multipart_action(self):
68+
"""Test multipart"""
69+
70+
self.body = None
71+
72+
def _req_logger(self, params):
73+
self.body = bytes(params.content())
74+
75+
QgsNetworkAccessManager.instance().requestAboutToBeCreated[QgsNetworkRequestParameters].connect(partial(_req_logger, self))
76+
77+
temp_dir = QTemporaryDir()
78+
temp_path = temp_dir.path()
79+
temp_file = os.path.join(temp_path, 'multipart.txt')
80+
81+
action = QgsAction(QgsAction.SubmitUrlMultipart, 'url_encoded', "http://fake_qgis_http_endpoint" + temp_file + r"?[% url_encode(map('a&+b', 'a and plus b', 'a=b', 'a equals b')) %]")
82+
ctx = QgsExpressionContext()
83+
action.run(ctx)
84+
85+
while not self.body:
86+
QgsApplication.instance().processEvents()
87+
88+
self.assertEqual(re.sub(r'\.oOo\.[^\r]*', '.oOo.UUID', self.body.decode('utf8')), '\r\n'.join([
89+
'--boundary_.oOo.UUID',
90+
'Content-Disposition: form-data; name="a&+b"',
91+
'',
92+
'a and plus b',
93+
'--boundary_.oOo.UUID',
94+
'Content-Disposition: form-data; name="a=b"',
95+
'',
96+
'a equals b',
97+
'--boundary_.oOo.UUID',
98+
'']))
99+
100+
101+
if __name__ == '__main__':
102+
unittest.main()

0 commit comments

Comments
 (0)
Please sign in to comment.