summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorBernd Lamecker <bernd.lamecker@basyskom.com>2014-08-12 16:46:59 +0200
committerMilian Wolff <milian.wolff@kdab.com>2014-12-19 11:39:52 +0100
commit3ed29bca08dec484003cf573dd428b73627ffa81 (patch)
tree8e688a00c409cbd4a37412342faa2185b7b3869d /tests
parent9fdce8e443030ab99d31e42fffc977cf284c36c4 (diff)
downloadqtwebchannel-3ed29bca08dec484003cf573dd428b73627ffa81.tar.gz
Do not broadcast signals or property changes of wrapped qobjects
Signals and property changes caused by dynamically created qobjects (qobjects returned from a method call at runtime) should not be broadcasted to any client but only sent to clients which know these qobjects. Also added testcases for the changes. Change-Id: I9aacfa9e7e9df9314b44c6ba8e7339a2069e3c37 Reviewed-by: Milian Wolff <milian.wolff@kdab.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qml/Client.qml9
-rw-r--r--tests/auto/qml/qml.pro5
-rw-r--r--tests/auto/qml/tst_webchannel.qml2
-rw-r--r--tests/auto/qml/tst_webchannelseparation.qml356
4 files changed, 368 insertions, 4 deletions
diff --git a/tests/auto/qml/Client.qml b/tests/auto/qml/Client.qml
index 6e12993..c18644f 100644
--- a/tests/auto/qml/Client.qml
+++ b/tests/auto/qml/Client.qml
@@ -98,7 +98,12 @@ Item {
for (var i = 0; i < 10 && !root[from].length; ++i)
wait(10);
- return root[from].shift();
+
+ var msg = root[from].shift();
+ if (debug) {
+ console.log((root.objectName ? "(" + root.objectName + ")" : ""), "Shifting Message " + from + ":" + JSON.stringify(msg));
+ }
+ return msg;
}
function awaitMessage(from)
@@ -114,7 +119,7 @@ Item {
function await(type, from, skip) {
var msg;
do {
- msg = awaitMessage();
+ msg = awaitMessage(from);
verify(msg);
} while (skip && (msg.type === JSClient.QWebChannelMessageTypes.idle));
if (type !== null) {
diff --git a/tests/auto/qml/qml.pro b/tests/auto/qml/qml.pro
index 89c5f56..5dbac40 100644
--- a/tests/auto/qml/qml.pro
+++ b/tests/auto/qml/qml.pro
@@ -22,6 +22,9 @@ OTHER_FILES += \
tst_webchannel.qml \
tst_metaobjectpublisher.qml \
tst_bench.qml \
- tst_multiclient.qml \
+ tst_multiclient.qml
TESTDATA = data/*
+
+DISTFILES += \
+ tst_webchannelseparation.qml
diff --git a/tests/auto/qml/tst_webchannel.qml b/tests/auto/qml/tst_webchannel.qml
index f304197..8f40cf5 100644
--- a/tests/auto/qml/tst_webchannel.qml
+++ b/tests/auto/qml/tst_webchannel.qml
@@ -139,7 +139,6 @@ TestCase {
compare(myObj.myProperty, 3);
client.awaitIdle(); // init
- client.awaitIdle(); // property update
// change property, should be propagated to HTML client and a message be send there
myObj.myProperty = 2;
@@ -332,6 +331,7 @@ TestCase {
compare(channel.objects[testObjId].myProperty, 42);
channel.objects[testObjId].deleteLater();
+ client.awaitIdle();
msg = client.awaitMessage();
compare(msg.type, JSClient.QWebChannelMessageTypes.invokeMethod);
}
diff --git a/tests/auto/qml/tst_webchannelseparation.qml b/tests/auto/qml/tst_webchannelseparation.qml
new file mode 100644
index 0000000..289f8b2
--- /dev/null
+++ b/tests/auto/qml/tst_webchannelseparation.qml
@@ -0,0 +1,356 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 basysKom GmbH, info@basyskom.com, author Lutz Schönemann <lutz.schoenemann@basyskom.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.0
+import QtTest 1.0
+
+import QtWebChannel 1.0
+import QtWebChannel.Tests 1.0
+import "qrc:///qtwebchannel/qwebchannel.js" as JSClient
+
+TestCase {
+ name: "WebChannelSeparation"
+
+ Client {
+ id: client1
+ objectName: "client1"
+ }
+ Client {
+ id: client2
+ objectName: "client2"
+ }
+
+ property var lastMethodArg
+
+ QtObject {
+ id: myObj
+ property int myProperty: 1
+
+ signal mySignal(var arg)
+
+ function myMethod(arg)
+ {
+ lastMethodArg = arg;
+ }
+
+ WebChannel.id: "myObj"
+ }
+ QtObject {
+ id: myOtherObj
+ property var foo: 1
+ property var bar: 1
+ WebChannel.id: "myOtherObj"
+ }
+ QtObject {
+ id: myObj2
+ function myMethod()
+ {
+ // return a javascript object which is handled as an Object, but not a QObject
+ return { "obj1": { "name": "n1", "value": 1 }, "obj2" : {"name": "n2", "value": 2} };
+ }
+
+ WebChannel.id: "myObj2"
+ }
+
+ QtObject {
+ id: myObj3
+
+ // always returns the same object
+ function getObject()
+ {
+ return myObj;
+ }
+ WebChannel.id: "myObj3"
+ }
+ QtObject {
+ id: myFactory
+ property var lastObj
+ property var createdObjects: []
+
+ function cleanup()
+ {
+ while (createdObjects.length) {
+ var obj = createdObjects.shift();
+ if (obj) {
+ obj.destroy();
+ }
+ }
+ }
+
+ function create(id)
+ {
+ lastObj = component.createObject(myFactory, {objectName: id});
+ createdObjects.push(lastObj);
+ return lastObj;
+ }
+ WebChannel.id: "myFactory"
+ }
+
+ Component {
+ id: component
+ QtObject {
+ property var myProperty : 0
+ function myMethod(arg)
+ {
+ lastMethodArg = arg;
+ }
+ signal mySignal(var arg1, var arg2)
+ }
+ }
+
+ TestWebChannel {
+ id: webChannel
+ transports: [client1.serverTransport, client2.serverTransport]
+ registeredObjects: [myObj, myOtherObj, myObj2, myObj3, myFactory]
+ }
+
+ function init()
+ {
+ myObj.myProperty = 1
+ client1.cleanup();
+ client2.cleanup();
+ }
+
+ function cleanup()
+ {
+ client1.debug = false;
+ client2.debug = false;
+ // delete all created objects
+ myFactory.cleanup();
+ myFactory.lastObj = undefined;
+ // reschedule current task to end of event loop
+ wait(1);
+ }
+
+ function test_signalSeparation()
+ {
+ var testObj1;
+ var testObj1Id;
+ var testObj2;
+ var testObj2Id;
+
+ var channel1 = client1.createChannel(function (channel1) {
+ channel1.objects.myFactory.create("testObj1", function (obj1) {
+ testObj1 = myFactory.lastObj;
+ testObj1Id = obj1.__id__;
+
+ obj1.mySignal.connect(function (arg1_1, arg1_2) {
+ console.debug("client 1 received signal 'mySignal' " + arg1_1);
+ });
+
+ // create second channel after factory has created first
+ // object to make sure that a dynamically created object
+ // exists but does not get exposed to new channels
+ createSecondChannel();
+ });
+ });
+
+ var channel2;
+ function createSecondChannel()
+ {
+ // dismiss all messges received before channel creation
+ client2.cleanup();
+
+ channel2 = client2.createChannel(function (channel2) {
+ channel2.objects.myFactory.create("testObj2", function (obj2) {
+ testObj2 = myFactory.lastObj;
+ testObj2Id = obj2.__id__;
+ obj2.mySignal.connect(function (arg2_1, arg2_2) {
+ console.debug("client 2 received signal 'mySignal'");
+ });
+ });
+ });
+ }
+
+ client1.awaitInit();
+ client1.skipToMessage(JSClient.QWebChannelMessageTypes.idle);
+
+ client2.awaitInit();
+ client2.skipToMessage(JSClient.QWebChannelMessageTypes.idle);
+
+ // dismiss server messages
+ client1.serverMessages = [];
+ client2.serverMessages = [];
+
+ // now everything is set-up
+ // and we can kick off a signal
+ testObj1.mySignal("foo", "bar");
+
+ var msg1 = client1.awaitSignal();
+ compare(msg1.signal, 6);
+
+ // look if there is a signal send to client2, which should not happen
+ var msg2 = client2.skipToMessage(1, "server", 10);
+ console.log("client2 received a signal. let's check that it does not come from testObj1");
+ if (msg2 !== false) {
+ verify(msg2.object !== testObj1Id);
+ }
+ }
+
+ function test_separationForSameObject()
+ {
+ var testObj1;
+ var testObj2;
+ var receivedSignal1 = false;
+ var receivedSignal2 = false;
+
+ var channel2;
+ var channel1 = client1.createChannel(function (channel1) {
+ channel1.objects.myObj3.getObject(function (obj) {
+ testObj1 = obj;
+
+ testObj1.mySignal.connect(function() {
+ receivedSignal1 = true;
+ });
+
+ // create second channel after factory has created first
+ // object to make sure that a dynamically created object
+ // exists but does not get exposed to new channels
+ createSecondChannel();
+ });
+ });
+
+ function createSecondChannel()
+ {
+ // dismiss all messges received before channel creation
+ client2.cleanup();
+
+ channel2 = client2.createChannel(function (channel2) {
+ verify(channel2.objects.myObj2)
+ channel2.objects.myObj3.getObject(function (obj) {
+ testObj2 = obj;
+ testObj2.mySignal.connect(function() {
+ receivedSignal2 = true;
+ });
+
+ });
+ });
+ }
+
+ client1.awaitInit();
+ client1.skipToMessage(JSClient.QWebChannelMessageTypes.idle);
+
+ client2.awaitInit();
+ client2.skipToMessage(JSClient.QWebChannelMessageTypes.idle);
+
+ // trigger signal, signal should be received by both channels
+ myObj.mySignal("foo", "bar");
+
+ verify(receivedSignal1, "Channel 1 missed signal")
+ verify(receivedSignal2, "Channel 2 missed signal")
+ }
+
+ function test_propertyUpdateSeparation()
+ {
+ var testObj1;
+ var testObj1Id;
+ var testObj2;
+ var testObj2Id;
+
+ var channel1 = client1.createChannel(function (channel1) {
+ channel1.objects.myFactory.create("testObj1", function (obj1) {
+ testObj1 = myFactory.lastObj;
+ testObj1Id = obj1.__id__;
+
+ obj1.myPropertyChanged.connect(function (arg1_1) {
+ console.debug("client 1 received property update 'myProperty' " + obj1.myProperty);
+ });
+
+ // create second channel after factory has created first
+ // object to make sure that a dynamically created object
+ // exists but does not get exposed to new channels
+ createSecondChannel();
+ });
+ });
+
+ var channel2;
+ function createSecondChannel()
+ {
+ // dismiss all messges received before channel creation
+ client2.cleanup();
+
+ channel2 = client2.createChannel(function (channel2) {
+ channel2.objects.myFactory.create("testObj2", function (obj2) {
+ testObj2 = myFactory.lastObj;
+ testObj2Id = obj2.__id__;
+ obj2.myPropertyChanged.connect(function (arg1_1) {
+ console.debug("client 2 received property update 'myProperty' " + obj2.myProperty);
+ });
+ });
+ });
+ }
+
+ client1.awaitInit();
+ client1.skipToMessage(JSClient.QWebChannelMessageTypes.idle);
+
+ client2.awaitInit();
+ client2.skipToMessage(JSClient.QWebChannelMessageTypes.idle);
+
+ // dismiss server messages
+ client1.serverMessages = [];
+ client2.serverMessages = [];
+
+ // now everything is set-up
+ // and we can kick off a property change
+ testObj1.myProperty = 5;
+
+ var msg1 = client1.awaitPropertyUpdate();
+ compare(msg1.type, JSClient.QWebChannelMessageTypes.propertyUpdate);
+
+ //look if there is a propertyUpdate sent to client2, which should not happen
+ var msg2 = client2.skipToMessage(2, "server", 10);
+ console.log("client2 received a propertyUpdate. let's check that it does not come from testObj1");
+ if (msg2 !== false) {
+ verify(msg2.object !== testObj1Id);
+ }
+ }
+
+ function test_returnNonQObject()
+ {
+ var retObj;
+
+ var channel = client1.createChannel(function (channel) {
+ channel.objects.myObj2.myMethod(function(result) {
+ retObj = result;
+ });
+ });
+
+ client1.awaitInit();
+
+ var msg1 = client1.awaitMessage();
+ compare(msg1.type, JSClient.QWebChannelMessageTypes.invokeMethod); // create
+
+ msg1 = client1.awaitIdle();
+ verify(retObj["obj1"]["name"]);
+ }
+}
+