/**************************************************************************** ** ** Copyright (C) 2014 basysKom GmbH, info@basyskom.com, author Lutz Schönemann ** Contact: http://www.qt.io/licensing/ ** ** 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 The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/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. ** ** As a special exception, The Qt Company gives you certain additional ** rights. These rights are described in The Qt Company 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" } property var lastFactoryObj property var createdFactoryObjects: [] QtObject { id: myFactory function cleanup() { while (createdFactoryObjects.length) { var obj = createdFactoryObjects.shift(); if (obj) { obj.destroy(); } } } function create(id) { lastFactoryObj = component.createObject(myFactory, {objectName: id}); createdFactoryObjects.push(lastFactoryObj); return lastFactoryObj; } 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(); lastFactoryObj = undefined; createdFactoryObjects = []; // 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 = lastFactoryObj; 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 = lastFactoryObj; 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 = lastFactoryObj; 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 = lastFactoryObj; 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"]); } }