diff --git a/storybook/pages/AccountSelectorPage.qml b/storybook/pages/AccountSelectorPage.qml index 1174bff22d1..f8a3898a126 100644 --- a/storybook/pages/AccountSelectorPage.qml +++ b/storybook/pages/AccountSelectorPage.qml @@ -2,8 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import Models - import SortFilterProxyModel import shared.controls @@ -14,6 +12,9 @@ import AppLayouts.Wallet.adaptors import utils +import Models +import Mocks + SplitView { id: root @@ -23,9 +24,9 @@ SplitView { id: d readonly property var flatNetworks: NetworksModel.flatNetworks - readonly property var assetsStore: WalletAssetsStore { + readonly property var assetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore - walletTokensStore: TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} } readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {} diff --git a/storybook/pages/ActivityFilterMenuPage.qml b/storybook/pages/ActivityFilterMenuPage.qml index 045c7e946b6..818743eacf6 100644 --- a/storybook/pages/ActivityFilterMenuPage.qml +++ b/storybook/pages/ActivityFilterMenuPage.qml @@ -15,14 +15,14 @@ import StatusQ.Popups import SortFilterProxyModel -import Storybook - -import Models - import utils import shared.controls +import Storybook +import Models +import Mocks + SplitView { id: root @@ -75,7 +75,7 @@ SplitView { } } - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { } } ActivityFiltersStore { diff --git a/storybook/pages/AssetsDetailViewPage.qml b/storybook/pages/AssetsDetailViewPage.qml index 4132a4efbd0..906d95bf7f1 100644 --- a/storybook/pages/AssetsDetailViewPage.qml +++ b/storybook/pages/AssetsDetailViewPage.qml @@ -9,6 +9,7 @@ import shared.stores as SharedStores import utils import Models +import Mocks Item { id: root @@ -17,7 +18,7 @@ Item { AssetsDetailView { anchors.fill: parent - tokensStore: WalletStores.TokensStore {} + tokensStore: TokensStoreMock {} currencyStore: SharedStores.CurrenciesStore {} networkConnectionStore: SharedStores.NetworkConnectionStore {} diff --git a/storybook/pages/BrowserLayoutPage.qml b/storybook/pages/BrowserLayoutPage.qml index 84ee2d18769..d943a4143c7 100644 --- a/storybook/pages/BrowserLayoutPage.qml +++ b/storybook/pages/BrowserLayoutPage.qml @@ -7,9 +7,6 @@ import QtQml import StatusQ import StatusQ.Core.Utils as SQUtils -import Models -import Storybook - import utils import AppLayouts.Browser @@ -18,6 +15,10 @@ import AppLayouts.Wallet.stores import shared.stores as SharedStores import shared.stores.send +import Storybook +import Models +import Mocks + Item { id: root @@ -29,7 +30,7 @@ Item { Layout.fillWidth: true Layout.fillHeight: true userUID: "0xdeadbeef" - transactionStore: TransactionStore {} + transactionStore: TransactionStoreMock {} thirdpartyServicesEnabled: true connectorController: null platformOS: ctrlPlatformOS.currentValue diff --git a/storybook/pages/BuyCryptoModalPage.qml b/storybook/pages/BuyCryptoModalPage.qml index 43fd943e9bb..4be590b4491 100644 --- a/storybook/pages/BuyCryptoModalPage.qml +++ b/storybook/pages/BuyCryptoModalPage.qml @@ -2,9 +2,6 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts -import Storybook -import Models - import StatusQ import StatusQ.Core.Backpressure @@ -14,6 +11,10 @@ import AppLayouts.Wallet.adaptors import shared.stores +import Storybook +import Models +import Mocks + SplitView { id: root @@ -51,9 +52,9 @@ SplitView { } readonly property var currencyStore: CurrenciesStore {} - readonly property var assetsStore: WalletAssetsStore { + readonly property var assetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore - walletTokensStore: TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} } readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {} diff --git a/storybook/pages/CommunitiesViewPage.qml b/storybook/pages/CommunitiesViewPage.qml index 79bacfc3db4..51ab42e93fe 100644 --- a/storybook/pages/CommunitiesViewPage.qml +++ b/storybook/pages/CommunitiesViewPage.qml @@ -10,9 +10,11 @@ import AppLayouts.Profile.stores import mainui import utils +import shared.stores as SharedStores + import Storybook import Models -import shared.stores as SharedStores +import Mocks SplitView { id: root @@ -21,7 +23,7 @@ SplitView { orientation: Qt.Vertical - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { } readonly property var currencyStore: SharedStores.CurrenciesStore {} diff --git a/storybook/pages/CommunityMembershipSetupDialogPage.qml b/storybook/pages/CommunityMembershipSetupDialogPage.qml index 77000e44cf2..2ba2e0670fb 100644 --- a/storybook/pages/CommunityMembershipSetupDialogPage.qml +++ b/storybook/pages/CommunityMembershipSetupDialogPage.qml @@ -3,14 +3,15 @@ import QtQuick.Controls import QtQuick.Layouts import QtQml -import Storybook -import Models - import shared.popups import utils import AppLayouts.Wallet.stores +import Storybook +import Models +import Mocks + SplitView { SplitView { id: root @@ -20,7 +21,7 @@ SplitView { Logs { id: logs } - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { } function openDialog() { diff --git a/storybook/pages/ManageAssetsPanelPage.qml b/storybook/pages/ManageAssetsPanelPage.qml index 13dc38f7f4e..1007b7e9938 100644 --- a/storybook/pages/ManageAssetsPanelPage.qml +++ b/storybook/pages/ManageAssetsPanelPage.qml @@ -9,12 +9,13 @@ import StatusQ.Models import utils -import Storybook -import Models - import AppLayouts.Wallet.panels import AppLayouts.Wallet.stores +import Storybook +import Models +import Mocks + SplitView { id: root @@ -22,7 +23,7 @@ SplitView { orientation: Qt.Horizontal - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { } ManageAssetsPanel { diff --git a/storybook/pages/ManageHiddenPanelPage.qml b/storybook/pages/ManageHiddenPanelPage.qml index babc4e2778f..fbaa6a6c815 100644 --- a/storybook/pages/ManageHiddenPanelPage.qml +++ b/storybook/pages/ManageHiddenPanelPage.qml @@ -12,10 +12,11 @@ import AppLayouts.Wallet.stores import utils +import QtModelsToolkit + import Storybook import Models - -import QtModelsToolkit +import Mocks SplitView { id: root @@ -24,7 +25,7 @@ SplitView { orientation: Qt.Horizontal - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { } ManageCollectiblesModel { diff --git a/storybook/pages/ProfileShowcaseAssetsPanelPage.qml b/storybook/pages/ProfileShowcaseAssetsPanelPage.qml index baf762b2ab7..2f7b6ddefb2 100644 --- a/storybook/pages/ProfileShowcaseAssetsPanelPage.qml +++ b/storybook/pages/ProfileShowcaseAssetsPanelPage.qml @@ -14,10 +14,11 @@ import shared.stores import utils +import AppLayouts.Wallet.stores + import Storybook import Models - -import AppLayouts.Wallet.stores +import Mocks SplitView { id: root @@ -26,7 +27,7 @@ SplitView { orientation: Qt.Vertical - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { } SortFilterProxyModel { diff --git a/storybook/pages/SendModalPage.qml b/storybook/pages/SendModalPage.qml index 6b3b84d37b8..ce508148d0c 100644 --- a/storybook/pages/SendModalPage.qml +++ b/storybook/pages/SendModalPage.qml @@ -7,8 +7,6 @@ import StatusQ.Core import StatusQ.Core.Utils import StatusQ.Controls -import Storybook -import Models import utils import shared.popups.send @@ -18,12 +16,16 @@ import shared.stores.send import SortFilterProxyModel import AppLayouts.Wallet.stores +import Storybook +import Models +import Mocks + SplitView { id: root orientation: Qt.Horizontal - property WalletAssetsStore walletAssetStore: WalletAssetsStore { + property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { property var groupedAccountAssetsModel: ListModel { @@ -88,7 +90,7 @@ SplitView { } } - TransactionStore { + TransactionStoreMock { id: txStore property bool areTestNetworksEnabled: true @@ -96,9 +98,31 @@ SplitView { function resetData() {} walletAssetStore: root.walletAssetStore - tokensStore.showCommunityAssetsInSend: showCommunityAssetsCheckBox.checked - tokensStore.displayAssetsBelowBalance: balanceThresholdCheckbox.checked - tokensStore.getDisplayAssetsBelowBalanceThresholdDisplayAmount: () => Number(balanceThresholdValue.text) + Component.onCompleted: { + if (tokensStore) { + tokensStore.showCommunityAssetsInSend = showCommunityAssetsCheckBox.checked + tokensStore.displayAssetsBelowBalance = balanceThresholdCheckbox.checked + tokensStore._displayAssetsBelowBalanceThresholdDisplayAmountFunc = () => Number(balanceThresholdValue.text) + } + } + } + + Connections { + target: showCommunityAssetsCheckBox + function onCheckedChanged() { + if (txStore.tokensStore) { + txStore.tokensStore.showCommunityAssetsInSend = showCommunityAssetsCheckBox.checked + } + } + } + + Connections { + target: balanceThresholdCheckbox + function onCheckedChanged() { + if (txStore.tokensStore) { + txStore.tokensStore.displayAssetsBelowBalance = balanceThresholdCheckbox.checked + } + } } NetworksStore { diff --git a/storybook/pages/SharedAddressesAccountSelectorPage.qml b/storybook/pages/SharedAddressesAccountSelectorPage.qml index 8ac0a46c585..43b473100d9 100644 --- a/storybook/pages/SharedAddressesAccountSelectorPage.qml +++ b/storybook/pages/SharedAddressesAccountSelectorPage.qml @@ -1,12 +1,12 @@ import QtQuick import QtQuick.Controls -import Storybook -import Models - import AppLayouts.Wallet.stores import AppLayouts.Communities.panels +import Storybook +import Models +import Mocks SplitView { id: root @@ -16,7 +16,7 @@ SplitView { Logs { id: logs } - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { } WalletAccountsModel { diff --git a/storybook/pages/SimpleSendModalPage.qml b/storybook/pages/SimpleSendModalPage.qml index bdbd8c923e2..61873d37fca 100644 --- a/storybook/pages/SimpleSendModalPage.qml +++ b/storybook/pages/SimpleSendModalPage.qml @@ -11,15 +11,16 @@ import StatusQ.Core.Utils import StatusQ.Core.Theme import StatusQ.Core.Backpressure -import Models -import Storybook - import AppLayouts.Wallet.popups.simpleSend import AppLayouts.Wallet.stores import AppLayouts.Wallet.adaptors import utils +import Storybook +import Models +import Mocks + SplitView { id: root @@ -33,10 +34,10 @@ SplitView { filters: ValueFilter { roleName: "isTest"; value: testNetworksCheckbox.checked } } - readonly property WalletAssetsStore walletAssetStore: WalletAssetsStore { - walletTokensStore: TokensStore { + readonly property WalletAssetsStoreMock walletAssetStore: WalletAssetsStoreMock { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel{} - getDisplayAssetsBelowBalanceThresholdDisplayAmount: () => 0 + _displayAssetsBelowBalanceThresholdDisplayAmountFunc: () => 0 } } diff --git a/storybook/pages/SwapInputPanelPage.qml b/storybook/pages/SwapInputPanelPage.qml index 81640922b1e..9dad091366a 100644 --- a/storybook/pages/SwapInputPanelPage.qml +++ b/storybook/pages/SwapInputPanelPage.qml @@ -16,11 +16,12 @@ import AppLayouts.Wallet.controls import AppLayouts.Wallet.popups.swap -import Models -import Storybook - import SortFilterProxyModel +import Storybook +import Models +import Mocks + SplitView { id: root @@ -73,9 +74,9 @@ SplitView { networksStore: NetworksStore { readonly property var activeNetworks: NetworksModel.flatNetworks } - walletAssetsStore: WalletAssetsStore { + walletAssetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore - walletTokensStore: TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} } readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {} diff --git a/storybook/pages/SwapModalPage.qml b/storybook/pages/SwapModalPage.qml index eb8320ab2d5..a2841c188bb 100644 --- a/storybook/pages/SwapModalPage.qml +++ b/storybook/pages/SwapModalPage.qml @@ -11,8 +11,6 @@ import StatusQ.Core.Backpressure import StatusQ.Core.Utils import utils -import Storybook -import Models import mainui import AppLayouts.Wallet.popups.swap @@ -20,6 +18,10 @@ import AppLayouts.Wallet.stores import AppLayouts.stores as AppLayoutStores import shared.stores as SharedStores +import Storybook +import Models +import Mocks + SplitView { id: root @@ -115,16 +117,16 @@ SplitView { signalName: "authenticateAndTransferSignal" } - TokensStore { + TokensStoreMock { id: tokensStore tokenGroupsModel: TokenGroupsModel {} - getDisplayAssetsBelowBalanceThresholdDisplayAmount: () => 0 + _displayAssetsBelowBalanceThresholdDisplayAmountFunc: () => 0 } SwapModalAdaptor { id: adaptor swapStore: dSwapStore - walletAssetsStore: WalletAssetsStore { + walletAssetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore walletTokensStore: tokensStore readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {} diff --git a/storybook/pages/WalletAccountsSelectorAdaptorPage.qml b/storybook/pages/WalletAccountsSelectorAdaptorPage.qml index 858edebeda9..a120b293e27 100644 --- a/storybook/pages/WalletAccountsSelectorAdaptorPage.qml +++ b/storybook/pages/WalletAccountsSelectorAdaptorPage.qml @@ -6,12 +6,13 @@ import SortFilterProxyModel import AppLayouts.Wallet.stores import AppLayouts.Wallet.adaptors -import Storybook -import Models - import shared.stores import utils +import Storybook +import Models +import Mocks + Item { id: root @@ -98,9 +99,9 @@ Item { QtObject { id: d - readonly property var assetsStore: WalletAssetsStore { + readonly property var assetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore - walletTokensStore: TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} } readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {} diff --git a/storybook/qmlTests/tests/tst_BuyCryptoModal.qml b/storybook/qmlTests/tests/tst_BuyCryptoModal.qml index 92f33509573..cbbca81f894 100644 --- a/storybook/qmlTests/tests/tst_BuyCryptoModal.qml +++ b/storybook/qmlTests/tests/tst_BuyCryptoModal.qml @@ -9,7 +9,6 @@ import StatusQ.Core.Utils import StatusQ.Core.Theme import StatusQ.Core.Backpressure -import Models import utils import AppLayouts.Wallet.popups.buy @@ -17,6 +16,9 @@ import AppLayouts.Wallet.stores import shared.stores +import Models +import Mocks + Item { id: root width: 600 @@ -90,9 +92,9 @@ Item { value: true } } - readonly property var assetsStore: WalletAssetsStore { + readonly property var assetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore - walletTokensStore: TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} } } diff --git a/storybook/qmlTests/tests/tst_DAppsWorkflow.qml b/storybook/qmlTests/tests/tst_DAppsWorkflow.qml index 119e33c89f9..dde1cf7f822 100644 --- a/storybook/qmlTests/tests/tst_DAppsWorkflow.qml +++ b/storybook/qmlTests/tests/tst_DAppsWorkflow.qml @@ -3,14 +3,10 @@ import QtQuick import QtTest import "helpers/wallet_connect.js" as Testing -import Models - import StatusQ.Core.Utils import QtQuick.Controls -import Storybook - import AppLayouts.Wallet.services.dapps import AppLayouts.Wallet.services.dapps.types import AppLayouts.Profile.stores @@ -22,6 +18,10 @@ import shared.stores import utils +import Storybook +import Models +import Mocks + Item { id: root @@ -311,9 +311,9 @@ Item { } } - WalletStore.WalletAssetsStore { + WalletAssetsStoreMock { id: assetsStoreMock - walletTokensStore: WalletStore.TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} } } @@ -581,7 +581,7 @@ Item { session.params.request.expiryTimestamp = (Date.now() - 10000) / 1000 verify(session.params.request.expiryTimestamp < Date.now() / 1000, "expected expiryTimestamp to be in the past") - + mockActiveSession(handler.accountsModel, handler.networksModel, sdk, topic) sdk.sessionRequestEvent(session) diff --git a/storybook/qmlTests/tests/tst_SwapInputPanel.qml b/storybook/qmlTests/tests/tst_SwapInputPanel.qml index e1e34347620..92ff20df810 100644 --- a/storybook/qmlTests/tests/tst_SwapInputPanel.qml +++ b/storybook/qmlTests/tests/tst_SwapInputPanel.qml @@ -14,11 +14,12 @@ import AppLayouts.Wallet import shared.stores -import Models -import Storybook - import QtModelsToolkit +import Storybook +import Models +import Mocks + Item { id: root width: 1200 @@ -35,8 +36,8 @@ Item { swapStore: SwapStore { readonly property var accounts: WalletAccountsModel {} } - walletAssetsStore: WalletAssetsStore { - walletTokensStore: TokensStore { + walletAssetsStore: WalletAssetsStoreMock { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} tokenGroupsForChainModel: TokenGroupsModel { skipInitialLoad: true diff --git a/storybook/qmlTests/tests/tst_SwapModal.qml b/storybook/qmlTests/tests/tst_SwapModal.qml index 14cd9ff65f4..b5695b555a4 100644 --- a/storybook/qmlTests/tests/tst_SwapModal.qml +++ b/storybook/qmlTests/tests/tst_SwapModal.qml @@ -1,4 +1,4 @@ -import QtQuick +import QtQuick import QtTest import StatusQ.Core @@ -8,9 +8,6 @@ import StatusQ.Controls import QtQuick.Controls -import Models -import Storybook - import utils import shared.stores import AppLayouts.Wallet.popups.swap @@ -18,6 +15,10 @@ import AppLayouts.Wallet.stores import AppLayouts.Wallet import AppLayouts.Wallet.adaptors +import Storybook +import Models +import Mocks + Item { id: root width: 800 @@ -50,9 +51,9 @@ Item { readonly property SwapModalAdaptor swapAdaptor: SwapModalAdaptor { currencyStore: CurrenciesStore {} - walletAssetsStore: WalletAssetsStore { + walletAssetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore - walletTokensStore: TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} tokenGroupsForChainModel: TokenGroupsModel { skipInitialLoad: true @@ -61,7 +62,7 @@ Item { skipInitialLoad: true tokenGroupsForChainModel: thisWalletAssetStore.walletTokensStore.tokenGroupsForChainModel } - getDisplayAssetsBelowBalanceThresholdDisplayAmount: () => 0 + _displayAssetsBelowBalanceThresholdDisplayAmountFunc: () => 0 } readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {} } diff --git a/storybook/qmlTests/tests/tst_TokenSelectorViewAdaptor.qml b/storybook/qmlTests/tests/tst_TokenSelectorViewAdaptor.qml index cc80dc07d96..f1d7ea32cac 100644 --- a/storybook/qmlTests/tests/tst_TokenSelectorViewAdaptor.qml +++ b/storybook/qmlTests/tests/tst_TokenSelectorViewAdaptor.qml @@ -1,7 +1,6 @@ import QtQuick import QtTest -import Models import utils import StatusQ @@ -13,6 +12,9 @@ import AppLayouts.Wallet.adaptors import QtModelsToolkit import SortFilterProxyModel +import Models +import Mocks + Item { id: root width: 600 @@ -25,8 +27,8 @@ Item { id: d readonly property var flatNetworks: NetworksModel.flatNetworks - readonly property var assetsStore: WalletAssetsStore { - walletTokensStore: TokensStore { + readonly property var assetsStore: WalletAssetsStoreMock { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} tokenGroupsForChainModel: TokenGroupsModel { skipInitialLoad: true diff --git a/storybook/qmlTests/tests/tst_WalletAccountsSelectorAdaptor.qml b/storybook/qmlTests/tests/tst_WalletAccountsSelectorAdaptor.qml index adaf1690c5d..9e54e9bd43b 100644 --- a/storybook/qmlTests/tests/tst_WalletAccountsSelectorAdaptor.qml +++ b/storybook/qmlTests/tests/tst_WalletAccountsSelectorAdaptor.qml @@ -7,14 +7,15 @@ import StatusQ.Core.Utils import AppLayouts.Wallet.stores import AppLayouts.Wallet.adaptors -import Models - import shared.stores import utils import QtModelsToolkit import SortFilterProxyModel +import Models +import Mocks + Item { id: root width: 600 @@ -107,9 +108,9 @@ Item { id: d readonly property var flatNetworks: NetworksModel.flatNetworks - readonly property var assetsStore: WalletAssetsStore { + readonly property var assetsStore: WalletAssetsStoreMock { id: thisWalletAssetStore - walletTokensStore: TokensStore { + walletTokensStore: TokensStoreMock { tokenGroupsModel: TokenGroupsModel {} } } diff --git a/storybook/src/Mocks/TokensStoreMock.qml b/storybook/src/Mocks/TokensStoreMock.qml new file mode 100644 index 00000000000..8632489baf5 --- /dev/null +++ b/storybook/src/Mocks/TokensStoreMock.qml @@ -0,0 +1,80 @@ +import QtQuick + +import StatusQ.Core.Utils + +import QtModelsToolkit + +import AppLayouts.Wallet.stores + +TokensStore { + id: root + + property var tokenGroupsModel + property var tokenGroupsForChainModel + property var searchResultModel + property bool showCommunityAssetsInSend + property bool displayAssetsBelowBalance + property var _displayAssetsBelowBalanceThresholdDisplayAmountFunc: function() { return 0 } + property double tokenListUpdatedAt + + function getDisplayAssetsBelowBalanceThresholdDisplayAmount() { + return _displayAssetsBelowBalanceThresholdDisplayAmountFunc() + } + + function buildGroupsForChain(chainId) { + if (!root.tokenGroupsModel || chainId <= 0) { + console.warn("buildGroupsForChain: invalid parameters", chainId) + return + } + + if (!root.tokenGroupsForChainModel) { + console.warn("buildGroupsForChain: tokenGroupsForChainModel is not set") + return + } + + root.tokenGroupsForChainModel.clear() + + for (let i = 0; i < root.tokenGroupsModel.ModelCount.count; i++) { + const group = ModelUtils.get(root.tokenGroupsModel, i) + + if (!group.tokens || group.tokens.ModelCount.count === 0) { + continue + } + + const tokensListModel = Qt.createQmlObject('import QtQuick; ListModel {}', root) + for (let j = 0; j < group.tokens.ModelCount.count; j++) { + const token = ModelUtils.get(group.tokens, j) + if (token.chainId === chainId) { + tokensListModel.append({ + key: token.key, + groupKey: token.groupKey, + crossChainId: token.crossChainId, + chainId: token.chainId, + address: token.address, + name: token.name, + symbol: token.symbol, + decimals: token.decimals, + image: token.image, + customToken: token.customToken, + communityId: token.communityId + }) + } + } + + if (tokensListModel.count > 0) { + root.tokenGroupsForChainModel.append({ + key: group.key, + symbol: group.symbol, + name: group.name, + decimals: group.decimals, + logoUri: group.logoUri, + tokens: tokensListModel, + communityId: group.communityId || "", + marketDetails: group.marketDetails || {}, + detailsLoading: group.detailsLoading || false, + marketDetailsLoading: group.marketDetailsLoading || false + }) + } + } + } +} diff --git a/storybook/src/Mocks/TransactionStoreMock.qml b/storybook/src/Mocks/TransactionStoreMock.qml new file mode 100644 index 00000000000..5d3822f8cf4 --- /dev/null +++ b/storybook/src/Mocks/TransactionStoreMock.qml @@ -0,0 +1,193 @@ +import QtQuick + +import utils +import StatusQ +import StatusQ.Core.Utils as SQUtils +import shared.stores +import shared.stores.send +import SortFilterProxyModel + +import AppLayouts.Wallet.stores + +import Models +import Mocks + +TransactionStore { + id: root + + readonly property CurrenciesStore currencyStore: CurrenciesStore {} + + readonly property var tokensStore: TokensStoreMock {} + + readonly property var accounts: WalletSendAccountsModel { + Component.onCompleted: selectedSenderAccountAddress = accounts.get(0).address + } + + property WalletAssetsStore walletAssetStore + + property QtObject tmpActivityController0: QtObject { + property ListModel model: ListModel{} + } + property QtObject tmpActivityController1: QtObject { + property ListModel model: ListModel{} + } + + property var flatNetworksModel: NetworksModel.flatNetworks + property var fromNetworksRouteModel: NetworksModel.sendFromNetworks + property var toNetworksRouteModel: NetworksModel.sendToNetworks + property string selectedSenderAccountAddress + + readonly property QtObject walletSectionSendInst: QtObject { + signal transactionSent(var chainId, var txHash, var uuid, var error) + signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription) + } + readonly property QtObject mainModuleInst: QtObject { + signal resolvedENS(var resolvedPubKey, var resolvedAddress, var uuid) + } + + property string selectedAssetKey + property bool showUnPreferredChains: false + property int sendType: Constants.SendType.Transfer + property string selectedRecipient + + readonly property var savedAddressesModel: ListModel { + Component.onCompleted: { + for (let i = 0; i < 10; i++) + append({ + name: "some saved addr name " + i, + ens: [], + address: "0x2B748A02e06B159C7C3E98F5064577B96E55A7b4", + }) + append({ + name: "some saved ENS name ", + ens: ["me@status.eth"], + address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc4", + }) + } + } + + function splitAndFormatAddressPrefix(textAddress, updateInStore) { + return { + formattedText: textAddress, + address: textAddress + } + } + + function resolveENS(value: string) { + if (!!value && value.endsWith(".eth")) + root.mainModuleInst.resolvedENS("", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc4", "") // return some valid address + else + root.mainModuleInst.resolvedENS("", "", "") // invalid + } + + function getAsset(assetsList, symbol) { + const idx = SQUtils.ModelUtils.indexOf(assetsList, "symbol", symbol) + if (idx < 0) { + return {} + } + return SQUtils.ModelUtils.get(assetsList, idx) + } + + readonly property string currentCurrency: "USD" + + function getAllNetworksSupportedString() { + return "OPT" + } + + function prepareTransactionsForAddress(address) { + console.log("prepareTransactionsForAddress:", address) + } + + function getTransactions() { + return transactions + } + + readonly property var transactions_: ListModel { + id: transactions + + Component.onCompleted: { + for (let i = 0; i < 10; i++) + append({ + to: "to", + loadingTransaction: false, + value: { + displayDecimals: true, + stripTrailingZeroes: true, + amount: 3.234 + }, + timestamp: new Date() + }) + } + } + + function setSenderAccount(address) { + for (let i = 0; i < accounts.count; i++) { + const acc = accounts.get(i) + if (acc.address === address && acc.canSend) { + selectedSenderAccountAddress = acc.address + break + } + } + } + + function setSendType(sendType) { + root.sendType = sendType + } + + function setSelectedRecipient(recipientAddress) { + root.selectedRecipient = recipientAddress + } + + function setSelectedAssetKey(assetsKey) { + root.selectedAssetKey = assetsKey + } + + function getWei2Eth(wei, decimals) { + return wei/(10**decimals) + } + + function updateRoutePreferredChains(chainIds) { + root.toNetworksRouteModel.updateRoutePreferredChains(chainIds) + } + + function toggleShowUnPreferredChains() { + root.showUnPreferredChains = !root.showUnPreferredChains + } + + function setAllNetworksAsRoutePreferredChains() { + } + + function setRouteEnabledChain(chainId) { + } + + function setSelectedTokenIsOwnerToken(isOwnerToken) { + } + + function setSelectedTokenName(tokenName) { + } + + property string amountToSend + property bool suggestedRoutesCalled: false + function suggestedRoutes(amount) { + root.amountToSend = amount + root.suggestedRoutesCalled = true + } + + function resetStoredProperties() { + root.amountToSend = "" + root.sendType = Constants.SendType.Transfer + root.selectedRecipient = "" + root.selectedAssetKey = "" + root.showUnPreferredChains = false + root.fromNetworksRouteModel.reset() + root.toNetworksRouteModel.reset() + } + + function getNetworkName(chainId) { + return SQUtils.ModelUtils.getByKey(flatNetworksModel, "chainId", chainId, "chainName") + } + + function formatCurrencyAmountFromBigInt(balance, symbol, decimals, options = null) { + return currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options) + } +} diff --git a/storybook/src/Mocks/WalletAssetsStoreMock.qml b/storybook/src/Mocks/WalletAssetsStoreMock.qml new file mode 100644 index 00000000000..ee23061db32 --- /dev/null +++ b/storybook/src/Mocks/WalletAssetsStoreMock.qml @@ -0,0 +1,113 @@ +import QtQuick + +import StatusQ +import StatusQ.Models +import StatusQ.Core.Utils as SQUtils + +import utils + +import QtModelsToolkit +import SortFilterProxyModel + +import AppLayouts.Wallet.stores + +import Storybook +import Models +import Mocks + +WalletAssetsStore { + id: root + + property var walletTokensStore: TokensStoreMock {} + + property var baseGroupedAccountAssetModel: BaseGroupedAccountsAssetsModel {} + + readonly property var assetsController: QtObject { + property int revision + function filterAcceptsSymbol(symbol) { + return true + } + } + + readonly property var communityModel: ListModel { + Component.onCompleted: append([ + { + id: "ddls", + name: "Doodles", + image: ModelsData.collectibles.doodles, + description: "" + }, + { + id: "sox", + name: "Socks", + image: ModelsData.icons.socks, + description: "" + }, + { + id: "ast", + name: "Astafarians", + image: ModelsData.icons.dribble, + description: "" + } + ]) + } + + readonly property var _renamedCommunitiesModel: RolesRenamingModel { + sourceModel: communityModel + mapping: [ + RoleRename { + from: "id" + to: "communityId" + }, + RoleRename { + from: "name" + to: "communityName" + }, + RoleRename { + from: "image" + to: "communityImage" + }, + RoleRename { + from: "description" + to: "communityDescription" + } + ] + } + + property LeftJoinModel _tokenGroupsModelWithCommunityInfo: LeftJoinModel { + leftModel: walletTokensStore.tokenGroupsModel + rightModel: _renamedCommunitiesModel + joinRole: "communityId" + } + + // This is the joined model that exposes all roles (matching production) + property LeftJoinModel groupedAccountAssetsModel: LeftJoinModel { + objectName: "groupedAccountAssetsModel" + leftModel: baseGroupedAccountAssetModel + rightModel: _tokenGroupsModelWithCommunityInfo + joinRole: "key" + } + + readonly property SortFilterProxyModel bridgeableGroupedAccountAssetsModel: SortFilterProxyModel { + objectName: "bridgeableGroupedAccountAssetsModel" + sourceModel: root.groupedAccountAssetsModel + + filters: [ + FastExpressionFilter { + function isBSC(chainId) { + return chainId === Constants.chains.binanceSmartChainMainnetChainId || + chainId === Constants.chains.binanceSmartChainTestnetChainId + } + + // this function returns true if the token group item contains at least one token which can be bridged via Hop + function supportedByHopBridge(tokens) { + return false + } + expression: { + return supportedByHopBridge(model.tokens) + } + expectedRoles: ["tokens"] + } + ] + } +} diff --git a/storybook/src/Mocks/qmldir b/storybook/src/Mocks/qmldir new file mode 100644 index 00000000000..3024327f7d0 --- /dev/null +++ b/storybook/src/Mocks/qmldir @@ -0,0 +1,3 @@ +TokensStoreMock 1.0 TokensStoreMock.qml +WalletAssetsStoreMock 1.0 WalletAssetsStoreMock.qml +TransactionStoreMock 1.0 TransactionStoreMock.qml diff --git a/storybook/stubs/AppLayouts/Wallet/stores/TokensStore.qml b/storybook/stubs/AppLayouts/Wallet/stores/TokensStore.qml index 96ab267bf02..4611af3533e 100644 --- a/storybook/stubs/AppLayouts/Wallet/stores/TokensStore.qml +++ b/storybook/stubs/AppLayouts/Wallet/stores/TokensStore.qml @@ -1,74 +1,3 @@ import QtQuick -import StatusQ.Core.Utils - -import QtModelsToolkit - -QtObject { - id: root - - property var tokenGroupsModel - property var tokenGroupsForChainModel - property var searchResultModel - property bool showCommunityAssetsInSend - property bool displayAssetsBelowBalance - property var getDisplayAssetsBelowBalanceThresholdDisplayAmount - property double tokenListUpdatedAt - - function buildGroupsForChain(chainId) { - if (!root.tokenGroupsModel || chainId <= 0) { - console.warn("buildGroupsForChain: invalid parameters", chainId) - return - } - - if (!root.tokenGroupsForChainModel) { - console.warn("buildGroupsForChain: tokenGroupsForChainModel is not set") - return - } - - root.tokenGroupsForChainModel.clear() - - for (let i = 0; i < root.tokenGroupsModel.ModelCount.count; i++) { - const group = ModelUtils.get(root.tokenGroupsModel, i) - - if (!group.tokens || group.tokens.ModelCount.count === 0) { - continue - } - - const tokensListModel = Qt.createQmlObject('import QtQuick; ListModel {}', root) - for (let j = 0; j < group.tokens.ModelCount.count; j++) { - const token = ModelUtils.get(group.tokens, j) - if (token.chainId === chainId) { - tokensListModel.append({ - key: token.key, - groupKey: token.groupKey, - crossChainId: token.crossChainId, - chainId: token.chainId, - address: token.address, - name: token.name, - symbol: token.symbol, - decimals: token.decimals, - image: token.image, - customToken: token.customToken, - communityId: token.communityId - }) - } - } - - if (tokensListModel.count > 0) { - root.tokenGroupsForChainModel.append({ - key: group.key, - symbol: group.symbol, - name: group.name, - decimals: group.decimals, - logoUri: group.logoUri, - tokens: tokensListModel, - communityId: group.communityId || "", - marketDetails: group.marketDetails || {}, - detailsLoading: group.detailsLoading || false, - marketDetailsLoading: group.marketDetailsLoading || false - }) - } - } - } -} +QtObject {} diff --git a/storybook/stubs/AppLayouts/Wallet/stores/WalletAssetsStore.qml b/storybook/stubs/AppLayouts/Wallet/stores/WalletAssetsStore.qml index fddd95b113c..4611af3533e 100644 --- a/storybook/stubs/AppLayouts/Wallet/stores/WalletAssetsStore.qml +++ b/storybook/stubs/AppLayouts/Wallet/stores/WalletAssetsStore.qml @@ -1,110 +1,3 @@ import QtQuick -import Storybook -import Models - -import StatusQ -import StatusQ.Models -import StatusQ.Core.Utils as SQUtils - -import utils - -import QtModelsToolkit -import SortFilterProxyModel - -QtObject { - id: root - - property TokensStore walletTokensStore: TokensStore {} - - property var baseGroupedAccountAssetModel: BaseGroupedAccountsAssetsModel {} - - readonly property var assetsController: QtObject { - property int revision - function filterAcceptsSymbol(symbol) { - return true - } - } - - readonly property var communityModel: ListModel { - Component.onCompleted: append([ - { - id: "ddls", - name: "Doodles", - image: ModelsData.collectibles.doodles, - description: "" - }, - { - id: "sox", - name: "Socks", - image: ModelsData.icons.socks, - description: "" - }, - { - id: "ast", - name: "Astafarians", - image: ModelsData.icons.dribble, - description: "" - } - ]) - } - - readonly property var _renamedCommunitiesModel: RolesRenamingModel { - sourceModel: communityModel - mapping: [ - RoleRename { - from: "id" - to: "communityId" - }, - RoleRename { - from: "name" - to: "communityName" - }, - RoleRename { - from: "image" - to: "communityImage" - }, - RoleRename { - from: "description" - to: "communityDescription" - } - ] - } - - property LeftJoinModel _tokenGroupsModelWithCommunityInfo: LeftJoinModel { - leftModel: walletTokensStore.tokenGroupsModel - rightModel: _renamedCommunitiesModel - joinRole: "communityId" - } - - // This is the joined model that exposes all roles (matching production) - property LeftJoinModel groupedAccountAssetsModel: LeftJoinModel { - objectName: "groupedAccountAssetsModel" - leftModel: baseGroupedAccountAssetModel - rightModel: _tokenGroupsModelWithCommunityInfo - joinRole: "key" - } - - readonly property SortFilterProxyModel bridgeableGroupedAccountAssetsModel: SortFilterProxyModel { - objectName: "bridgeableGroupedAccountAssetsModel" - sourceModel: root.groupedAccountAssetsModel - - filters: [ - FastExpressionFilter { - function isBSC(chainId) { - return chainId === Constants.chains.binanceSmartChainMainnetChainId || - chainId === Constants.chains.binanceSmartChainTestnetChainId - } - - // this function returns true if the token group item contains at least one token which can be bridged via Hop - function supportedByHopBridge(tokens) { - return false - } - expression: { - return supportedByHopBridge(model.tokens) - } - expectedRoles: ["tokens"] - } - ] - } -} +QtObject {} diff --git a/storybook/stubs/shared/stores/send/TransactionStore.qml b/storybook/stubs/shared/stores/send/TransactionStore.qml index d531d7b2123..4611af3533e 100644 --- a/storybook/stubs/shared/stores/send/TransactionStore.qml +++ b/storybook/stubs/shared/stores/send/TransactionStore.qml @@ -1,200 +1,3 @@ import QtQuick -import Models -import utils -import StatusQ -import StatusQ.Core.Utils as SQUtils -import shared.stores -import SortFilterProxyModel - -import AppLayouts.Wallet.stores - -// TODO: This store, as all other stores should be empty QtObject {}. -// All mocking should be done in place in Storybook pages and unit tests. -// If it's necessary to share mocks between tests/pages, such mock can be -// created by deriving from empty stub and putting in mocks dir. -// Stores itself should be simple, thin layers over functionality exposed from -// the backend. No additional logic should there. Data transformation logic -// should be delegated to adaptors, stateles helpers to proper utility singletons. -// -// PLEASE DO NOT ADD ANY NEW CONTENT HERE - -QtObject { - id: root - - readonly property CurrenciesStore currencyStore: CurrenciesStore {} - - readonly property TokensStore tokensStore: TokensStore {} - - readonly property var accounts: WalletSendAccountsModel { - Component.onCompleted: selectedSenderAccountAddress = accounts.get(0).address - } - - property WalletAssetsStore walletAssetStore - - property QtObject tmpActivityController0: QtObject { - property ListModel model: ListModel{} - } - property QtObject tmpActivityController1: QtObject { - property ListModel model: ListModel{} - } - - property var flatNetworksModel: NetworksModel.flatNetworks - property var fromNetworksRouteModel: NetworksModel.sendFromNetworks - property var toNetworksRouteModel: NetworksModel.sendToNetworks - property string selectedSenderAccountAddress - - readonly property QtObject walletSectionSendInst: QtObject { - signal transactionSent(var chainId, var txHash, var uuid, var error) - signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription) - } - readonly property QtObject mainModuleInst: QtObject { - signal resolvedENS(var resolvedPubKey, var resolvedAddress, var uuid) - } - - property string selectedAssetKey - property bool showUnPreferredChains: false - property int sendType: Constants.SendType.Transfer - property string selectedRecipient - - readonly property var savedAddressesModel: ListModel { - Component.onCompleted: { - for (let i = 0; i < 10; i++) - append({ - name: "some saved addr name " + i, - ens: [], - address: "0x2B748A02e06B159C7C3E98F5064577B96E55A7b4", - }) - append({ - name: "some saved ENS name ", - ens: ["me@status.eth"], - address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc4", - }) - } - } - - function splitAndFormatAddressPrefix(textAddress, updateInStore) { - return { - formattedText: textAddress, - address: textAddress - } - } - - function resolveENS(value: string) { - if (!!value && value.endsWith(".eth")) - root.mainModuleInst.resolvedENS("", "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc4", "") // return some valid address - else - root.mainModuleInst.resolvedENS("", "", "") // invalid - } - - function getAsset(assetsList, symbol) { - const idx = SQUtils.ModelUtils.indexOf(assetsList, "symbol", symbol) - if (idx < 0) { - return {} - } - return SQUtils.ModelUtils.get(assetsList, idx) - } - - readonly property string currentCurrency: "USD" - - function getAllNetworksSupportedString() { - return "OPT" - } - - function prepareTransactionsForAddress(address) { - console.log("prepareTransactionsForAddress:", address) - } - - function getTransactions() { - return transactions - } - - readonly property var transactions_: ListModel { - id: transactions - - Component.onCompleted: { - for (let i = 0; i < 10; i++) - append({ - to: "to", - loadingTransaction: false, - value: { - displayDecimals: true, - stripTrailingZeroes: true, - amount: 3.234 - }, - timestamp: new Date() - }) - } - } - - function setSenderAccount(address) { - for (let i = 0; i < accounts.count; i++) { - const acc = accounts.get(i) - if (acc.address === address && acc.canSend) { - selectedSenderAccountAddress = acc.address - break - } - } - } - - function setSendType(sendType) { - root.sendType = sendType - } - - function setSelectedRecipient(recipientAddress) { - root.selectedRecipient = recipientAddress - } - - function setSelectedAssetKey(assetsKey) { - root.selectedAssetKey = assetsKey - } - - function getWei2Eth(wei, decimals) { - return wei/(10**decimals) - } - - function updateRoutePreferredChains(chainIds) { - root.toNetworksRouteModel.updateRoutePreferredChains(chainIds) - } - - function toggleShowUnPreferredChains() { - root.showUnPreferredChains = !root.showUnPreferredChains - } - - function setAllNetworksAsRoutePreferredChains() { - } - - function setRouteEnabledChain(chainId) { - } - - function setSelectedTokenIsOwnerToken(isOwnerToken) { - } - - function setSelectedTokenName(tokenName) { - } - - property string amountToSend - property bool suggestedRoutesCalled: false - function suggestedRoutes(amount) { - root.amountToSend = amount - root.suggestedRoutesCalled = true - } - - function resetStoredProperties() { - root.amountToSend = "" - root.sendType = Constants.SendType.Transfer - root.selectedRecipient = "" - root.selectedAssetKey = "" - root.showUnPreferredChains = false - root.fromNetworksRouteModel.reset() - root.toNetworksRouteModel.reset() - } - - function getNetworkName(chainId) { - return SQUtils.ModelUtils.getByKey(flatNetworksModel, "chainId", chainId, "chainName") - } - - function formatCurrencyAmountFromBigInt(balance, symbol, decimals, options = null) { - return currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options) - } -} +QtObject {} diff --git a/ui/app/AppLayouts/Chat/popups/PaymentRequestModal.qml b/ui/app/AppLayouts/Chat/popups/PaymentRequestModal.qml index 4f095fd73fe..17ca3e53f4c 100644 --- a/ui/app/AppLayouts/Chat/popups/PaymentRequestModal.qml +++ b/ui/app/AppLayouts/Chat/popups/PaymentRequestModal.qml @@ -46,11 +46,8 @@ StatusDialog { property int selectedNetworkChainId: Constants.chains.mainnetChainId property string selectedAccountAddress property string selectedTokenGroupKey: defaultTokenGroupKey - readonly property string selectedTokenKey: { - // selected token key is automatically evaluated based on the selected group key and selected chain - const token = SQUtils.ModelUtils.getByKey(d.selectedHolding.item.tokens, "chainId", root.selectedNetworkChainId) - return token.key - } + // selected token key is automatically evaluated based on the selected group key and selected chain + readonly property string selectedTokenKey: SQUtils.ModelUtils.getByKey(d.selectedHolding.item.tokens, "chainId", root.selectedNetworkChainId, "key") readonly property string symbol: d.selectedHolding.item.symbol diff --git a/ui/app/AppLayouts/Wallet/panels/SearchableAssetsPanel.qml b/ui/app/AppLayouts/Wallet/panels/SearchableAssetsPanel.qml index e80877e7f69..afce0aea650 100644 --- a/ui/app/AppLayouts/Wallet/panels/SearchableAssetsPanel.qml +++ b/ui/app/AppLayouts/Wallet/panels/SearchableAssetsPanel.qml @@ -21,6 +21,25 @@ import SortFilterProxyModel Control { id: root + /** + Expected model structure: + + key [string] - refers to token group key + name [string] - name + symbol [string] - symbol + decimals [int] - decimals + logoUri [string] - icon + currencyBalanceAsString [string] - formatted balance + sectionName (optional) [string] - text to be rendered as a section + balances [model] - contains a single entry for (token, accountAddress) pair + account [string] - wallet account address + groupKey [string] - group key that the token belongs to (cross chain id or token key if cross chain id is empty) + tokenKey [string] - token unique key (chain - address) + chainId [int] - token's chain id + tokenAddress [string] - token's address (contract) + balance [string] - raw balance that the `account` has for token with `tokenKey` + balanceAsString [string] - display value for balance that the `account` has for token with `tokenKey` + **/ property var model property string highlightedKey property string nonInteractiveKey diff --git a/ui/imports/shared/popups/send/SendModal.qml b/ui/imports/shared/popups/send/SendModal.qml index aeeeffa901a..b5759bd1e5a 100644 --- a/ui/imports/shared/popups/send/SendModal.qml +++ b/ui/imports/shared/popups/send/SendModal.qml @@ -167,7 +167,7 @@ StatusDialog { return } - let entry = SQUtils.ModelUtils.getByKey( + const entry = SQUtils.ModelUtils.getByKey( assetsAdaptor.outputAssetsModel, "key", d.selectedHolding.key) if(!entry){