Revision control
++ // Copyright (C) 2016 basysKom GmbH, info@basyskom.com, author Lutz Schönemann <lutz.schoenemann@basyskom.com>
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
++ import QtQuick
++ import QtTest
++
++ import QtWebChannel
++ import QtWebChannel.Tests
++ 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, 5);
++
++ // 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"]);
++ }
++ }
++