diff options
author | Bernd Lamecker <bernd.lamecker@basyskom.com> | 2014-08-12 16:46:59 +0200 |
---|---|---|
committer | Milian Wolff <milian.wolff@kdab.com> | 2014-12-19 11:39:52 +0100 |
commit | 3ed29bca08dec484003cf573dd428b73627ffa81 (patch) | |
tree | 8e688a00c409cbd4a37412342faa2185b7b3869d /tests/auto/qml | |
parent | 9fdce8e443030ab99d31e42fffc977cf284c36c4 (diff) | |
download | qtwebchannel-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/auto/qml')
-rw-r--r-- | tests/auto/qml/Client.qml | 9 | ||||
-rw-r--r-- | tests/auto/qml/qml.pro | 5 | ||||
-rw-r--r-- | tests/auto/qml/tst_webchannel.qml | 2 | ||||
-rw-r--r-- | tests/auto/qml/tst_webchannelseparation.qml | 356 |
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"]); + } +} + |