From 705d595bdb14195b8bcace86b23c02acec05d182 Mon Sep 17 00:00:00 2001 From: Alex Jbanca Date: Thu, 24 Oct 2024 11:57:59 +0300 Subject: [PATCH] fix(WC): Adding tests for ChainsAvailabilityWatchdog and ChainsSupervisorPlugin + move other tests from the wrong folder --- .../tests/tst_ChainsAvailabilityWatchdog.qml | 132 +++++++++ .../tests/tst_ChainsSupervisorPlugin.qml | 252 ++++++++++++++++++ .../tst_SessionRequestWithAuth.qml | 0 .../{ => tests}/tst_SiweLifeCycle.qml | 0 .../{ => tests}/tst_SiweRequestPlugin.qml | 0 5 files changed, 384 insertions(+) create mode 100644 storybook/qmlTests/tests/tst_ChainsAvailabilityWatchdog.qml create mode 100644 storybook/qmlTests/tests/tst_ChainsSupervisorPlugin.qml rename storybook/qmlTests/{ => tests}/tst_SessionRequestWithAuth.qml (100%) rename storybook/qmlTests/{ => tests}/tst_SiweLifeCycle.qml (100%) rename storybook/qmlTests/{ => tests}/tst_SiweRequestPlugin.qml (100%) diff --git a/storybook/qmlTests/tests/tst_ChainsAvailabilityWatchdog.qml b/storybook/qmlTests/tests/tst_ChainsAvailabilityWatchdog.qml new file mode 100644 index 0000000000..cf0b7b0a24 --- /dev/null +++ b/storybook/qmlTests/tests/tst_ChainsAvailabilityWatchdog.qml @@ -0,0 +1,132 @@ +import QtQuick 2.15 + +import QtTest 1.15 + +import AppLayouts.Wallet.helpers 1.0 + +Item { + id: root + + width: 600 + height: 400 + + Component { + id: chainsAvailabilityWatchdogComponent + ChainsAvailabilityWatchdog { + id: chainsAvailabilityWatchdog + readonly property SignalSpy chainOnlineChangedSpy: SignalSpy { target: chainsAvailabilityWatchdog; signalName: "chainOnlineChanged" } + networksModel: ListModel { + ListElement { + chainId: 1 + isOnline: true + } + ListElement { + chainId: 2 + isOnline: true + } + } + } + } + + TestCase { + id: chainsAvailabilityWatchdogTest + name: "ChainsAvailabilityWatchdog" + + property ChainsAvailabilityWatchdog componentUnderTest: null + + function init() { + componentUnderTest = chainsAvailabilityWatchdogComponent.createObject(root) + componentUnderTest.chainOnlineChangedSpy.clear() + } + + function test_initAllOnline() { + tryVerify(() => componentUnderTest.allOnline) + tryVerify(() => !componentUnderTest.allOffline) + } + + function test_chainOnlineChanged() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + + tryVerify(() => !componentUnderTest.allOnline) + tryVerify(() => !componentUnderTest.allOffline) + compare(componentUnderTest.chainOnlineChangedSpy.count, 1) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][0], 1) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][1], false) + } + + function test_allOffline() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + tryVerify(() => !componentUnderTest.allOnline) + tryVerify(() => componentUnderTest.allOffline) + + compare(componentUnderTest.chainOnlineChangedSpy.count, 2) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][0], 1) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][1], false) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[1][0], 2) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[1][1], false) + } + + function test_emptyModel() { + componentUnderTest.networksModel.clear() + + tryVerify(() => !componentUnderTest.allOnline) + tryVerify(() => componentUnderTest.allOffline) + } + + function test_modelChanges() { + tryVerify(() => componentUnderTest.allOnline) + tryVerify(() => !componentUnderTest.allOffline) + + componentUnderTest.networksModel.append({ chainId: 3, isOnline: false }) + + compare(componentUnderTest.allOnline, false) + compare(componentUnderTest.allOffline, false) + compare(componentUnderTest.chainOnlineChangedSpy.count, 1) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][0], 3) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][1], false) + } + + function test_modelChanges2() { + tryVerify(() => componentUnderTest.allOnline) + tryVerify(() => !componentUnderTest.allOffline) + + componentUnderTest.networksModel.append({ chainId: 3, isOnline: true }) + + compare(componentUnderTest.allOnline, true) + compare(componentUnderTest.allOffline, false) + compare(componentUnderTest.chainOnlineChangedSpy.count, 1) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][0], 3) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][1], true) + } + + function test_modelChangesWhileOffline() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + tryVerify(() => !componentUnderTest.allOnline) + tryVerify(() => componentUnderTest.allOffline) + + componentUnderTest.networksModel.append({ chainId: 3, isOnline: false }) + + compare(componentUnderTest.allOnline, false) + compare(componentUnderTest.allOffline, true) + compare(componentUnderTest.chainOnlineChangedSpy.count, 3) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][0], 1) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[0][1], false) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[1][0], 2) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[1][1], false) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[2][0], 3) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[2][1], false) + + componentUnderTest.networksModel.setProperty(2, "isOnline", true) + + tryVerify(() => !componentUnderTest.allOnline) + tryVerify(() => !componentUnderTest.allOffline) + compare(componentUnderTest.chainOnlineChangedSpy.count, 4) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[3][0], 3) + compare(componentUnderTest.chainOnlineChangedSpy.signalArguments[3][1], true) + } + } +} \ No newline at end of file diff --git a/storybook/qmlTests/tests/tst_ChainsSupervisorPlugin.qml b/storybook/qmlTests/tests/tst_ChainsSupervisorPlugin.qml new file mode 100644 index 0000000000..fe8e0f55e1 --- /dev/null +++ b/storybook/qmlTests/tests/tst_ChainsSupervisorPlugin.qml @@ -0,0 +1,252 @@ +import QtQuick 2.15 + +import QtTest 1.15 + +import AppLayouts.Wallet.services.dapps 1.0 +import AppLayouts.Wallet.services.dapps.plugins 1.0 + +Item { + id: root + + width: 600 + height: 400 + + Component { + id: chainsSupervisorPluginComponent + ChainsSupervisorPlugin { + id: chainsSupervisorPlugin + networksModel: ListModel { + ListElement { + chainId: 1 + isOnline: true + } + ListElement { + chainId: 2 + isOnline: true + } + } + sdk: WalletConnectSDKBase { + property bool sdkReady: true + projectId: "projectId" + + property var getActiveSessionsCallbacks: [] + getActiveSessions: function(callback) { + getActiveSessionsCallbacks.push({callback}) + } + + property var emitSessionEventCalls: [] + emitSessionEvent: function(topic, event, chainId) { + emitSessionEventCalls.push({topic, event, chainId}) + } + + pair: function() { + verify(false, "pair should not be called") + } + + buildApprovedNamespaces: function(id, params, supportedNamespaces) { + verify(false, "buildApprovedNamespaces should not be called") + } + + approveSession: function(sessionProposalJson, approvedNamespaces) { + verif(false, "approveSession should not be called") + } + + acceptSessionRequest: function(topic, id, signature) { + verify(false, "acceptSessionRequest should not be called") + } + + rejectSessionRequest: function(topic, id, error) { + verify(false, "rejectSessionRequest should not be called") + } + + populateAuthPayload: function(id, authPayload, chains, methods) { + verify(false, "populateAuthPayload should not be called") + } + + formatAuthMessage: function(id, request, iss) { + verify(false, "formatAuthMessage should not be called") + } + + buildAuthObject: function(id, authPayload, signature, iss) { + verify(false, "buildAuthObject should not be called") + } + + acceptSessionAuthenticate: function(id, auths) { + verify(false, "acceptSessionAuthenticate should not be called") + } + } + } + } + + function getConfiguredSession(requiredEvents, requiredChains, requiredAccounts) { + return { + topic: "topic", + namespaces: { + eip155: { + events: requiredEvents, + chains: requiredChains, + accounts: requiredAccounts + } + } + } + } + + TestCase { + id: chainsSupervisorPluginTest + name: "ChainsSupervisorPlugin" + + property ChainsSupervisorPlugin componentUnderTest: null + + function init() { + componentUnderTest = chainsSupervisorPluginComponent.createObject(root) + tryVerify(() => componentUnderTest.anyChainAvailable) + componentUnderTest.sdk.getActiveSessionsCallbacks = [] + componentUnderTest.sdk.emitSessionEventCalls = [] + } + + function test_allChainsDisabled() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + tryVerify(() => !componentUnderTest.anyChainAvailable) + } + + function test_disconnectEventAllValid() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + // 2 chains negociated. 2 accounts + // Expected two disconnect events + const validSession = getConfiguredSession(["disconnect"], ["eip155:1", "eip155:2"], ["eip155:1:0x1234", "eip155:2:0x1234"]) + + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 2) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].topic, validSession.topic) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].event.name, "disconnect") + compare(componentUnderTest.sdk.emitSessionEventCalls[0].chainId, "eip155:1") + compare(componentUnderTest.sdk.emitSessionEventCalls[1].topic, validSession.topic) + compare(componentUnderTest.sdk.emitSessionEventCalls[1].event.name, "disconnect") + compare(componentUnderTest.sdk.emitSessionEventCalls[1].chainId, "eip155:2") + } + + function test_disconnectEventSingleChainAccount() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + // 2 chains negociated. Account on a single chain + // Expected a single disconnect event + const validSession = getConfiguredSession(["disconnect"], ["eip155:1", "eip155:2"], ["eip155:1:0x1234"]) + + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 1) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].topic, validSession.topic) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].event.name, "disconnect") + compare(componentUnderTest.sdk.emitSessionEventCalls[0].chainId, "eip155:1") + } + + function test_disconnectEventNoAccount() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + // 2 chains negociated. No account + // Expected no disconnect event + const validSession = getConfiguredSession(["disconnect"], ["eip155:1", "eip155:2"], []) + + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 0) + } + + function test_disconnectEventOneChainTwoAccounts() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + // 1 chain negociated. 2 accounts on a single chain + // Expected a single disconnect event + const validSession = getConfiguredSession(["disconnect"], ["eip155:1"], ["eip155:1:0x1234", "eip155:1:0x5678"]) + + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 1) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].topic, validSession.topic) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].event.name, "disconnect") + compare(componentUnderTest.sdk.emitSessionEventCalls[0].chainId, "eip155:1") + } + + function test_disconnectEventNoChains() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + // No chain negociated. 2 accounts + // Expected no disconnect event + const validSession = getConfiguredSession(["disconnect"], [], ["eip155:1:0x1234", "eip155:2:0x1234"]) + + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 0) + } + + function test_disconnectEventNoChainNoAccount() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + // No chain negociated. No account + // Expected no disconnect event + const validSession = getConfiguredSession(["disconnect"], [], []) + + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 0) + } + + function test_disconnectEventNoEventNegociated() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + // 2 chains negociated. 2 accounts + // Missing `disconnect` - Expected no disconnect event + const validSession = getConfiguredSession([], ["eip155:1", "eip155:2"], ["eip155:1:0x1234", "eip155:2:0x1234"]) + + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 0) + } + + function test_chainBackOnline() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + componentUnderTest.sdk.getActiveSessionsCallbacks = [] + + const validSession = getConfiguredSession(["connect"], ["eip155:1"], ["eip155:1:0x1234"]) + componentUnderTest.networksModel.setProperty(0, "isOnline", true) + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + + compare(componentUnderTest.sdk.emitSessionEventCalls.length, 1) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].topic, validSession.topic) + compare(componentUnderTest.sdk.emitSessionEventCalls[0].event.name, "connect") + compare(componentUnderTest.sdk.emitSessionEventCalls[0].chainId, "eip155:1") + } + + function test_spammingOnlineState() { + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", false) + const validSession = getConfiguredSession(["connect"], ["eip155:1", "eip155:2"], ["eip155:1:0x1234", "eip155:2:0x1234"]) + componentUnderTest.sdk.getActiveSessionsCallbacks[0].callback([validSession]) + componentUnderTest.sdk.getActiveSessionsCallbacks = [] + + componentUnderTest.networksModel.setProperty(0, "isOnline", false) + componentUnderTest.networksModel.setProperty(1, "isOnline", true) + componentUnderTest.sdk.getActiveSessionsCallbacks = [] + + for (let i = 0; i < 10; i++) { + componentUnderTest.networksModel.setProperty(0, "isOnline", i % 2 === 0) + } + + compare(componentUnderTest.sdk.getActiveSessionsCallbacks.length, 1) + } + } +} \ No newline at end of file diff --git a/storybook/qmlTests/tst_SessionRequestWithAuth.qml b/storybook/qmlTests/tests/tst_SessionRequestWithAuth.qml similarity index 100% rename from storybook/qmlTests/tst_SessionRequestWithAuth.qml rename to storybook/qmlTests/tests/tst_SessionRequestWithAuth.qml diff --git a/storybook/qmlTests/tst_SiweLifeCycle.qml b/storybook/qmlTests/tests/tst_SiweLifeCycle.qml similarity index 100% rename from storybook/qmlTests/tst_SiweLifeCycle.qml rename to storybook/qmlTests/tests/tst_SiweLifeCycle.qml diff --git a/storybook/qmlTests/tst_SiweRequestPlugin.qml b/storybook/qmlTests/tests/tst_SiweRequestPlugin.qml similarity index 100% rename from storybook/qmlTests/tst_SiweRequestPlugin.qml rename to storybook/qmlTests/tests/tst_SiweRequestPlugin.qml