From 114abc7015e60527b3ae8892588c59766619b7b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= Date: Wed, 14 Aug 2024 15:04:28 +0200 Subject: [PATCH] chore(swap): port SwapInputPanel to AmountToSendNew - adjust the API calls - fixup the tests --- storybook/pages/SwapInputPanelPage.qml | 3 + storybook/pages/SwapModalPage.qml | 13 +- .../qmlTests/tests/tst_AmountToSendNew.qml | 34 ++++- .../qmlTests/tests/tst_SwapInputPanel.qml | 67 +++++----- storybook/qmlTests/tests/tst_SwapModal.qml | 117 +++++++++--------- .../Wallet/panels/SwapInputPanel.qml | 90 ++++++++------ .../Wallet/popups/swap/SwapModal.qml | 2 + ui/imports/shared/popups/send/SendModal.qml | 5 +- .../popups/send/views/AmountToSendNew.qml | 6 +- 9 files changed, 192 insertions(+), 145 deletions(-) diff --git a/storybook/pages/SwapInputPanelPage.qml b/storybook/pages/SwapInputPanelPage.qml index 553ecd1698..071bcc76b1 100644 --- a/storybook/pages/SwapInputPanelPage.qml +++ b/storybook/pages/SwapInputPanelPage.qml @@ -69,6 +69,9 @@ SplitView { readonly property var accounts: WalletAccountsModel {} readonly property var flatNetworks: NetworksModel.flatNetworks readonly property bool areTestNetworksEnabled: true + signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription) + signal transactionSent(var chainId, var txHash, var uuid, var error) + signal transactionSendingComplete(var txHash, var success) } walletAssetsStore: WalletAssetsStore { id: thisWalletAssetStore diff --git a/storybook/pages/SwapModalPage.qml b/storybook/pages/SwapModalPage.qml index 0ae59029c7..7939bb4bc4 100644 --- a/storybook/pages/SwapModalPage.qml +++ b/storybook/pages/SwapModalPage.qml @@ -130,7 +130,18 @@ SplitView { readonly property var baseGroupedAccountAssetModel: GroupedAccountsAssetsModel {} assetsWithFilteredBalances: thisWalletAssetStore.groupedAccountsAssetsModel } - currencyStore: CurrenciesStore {} + currencyStore: CurrenciesStore { + function formatBigNumber(number: string, symbol: string, noSymbolOption: bool) { + if (!number) + return "N/A" + if (!symbol) + symbol = root.currentCurrency + let options = {} + if (!!noSymbolOption) + options = {noSymbol: true} + return formatCurrencyAmount(parseFloat(number), symbol, options) + } + } swapFormData: SwapInputParamsForm { defaultToTokenKey: Constants.swap.testStatusTokenKey onSelectedAccountAddressChanged: { diff --git a/storybook/qmlTests/tests/tst_AmountToSendNew.qml b/storybook/qmlTests/tests/tst_AmountToSendNew.qml index cfbd5f2a9b..44a15c452c 100644 --- a/storybook/qmlTests/tests/tst_AmountToSendNew.qml +++ b/storybook/qmlTests/tests/tst_AmountToSendNew.qml @@ -3,6 +3,8 @@ import QtQuick.Controls 2.15 import QtTest 1.15 +import StatusQ 0.1 + import shared.popups.send.views 1.0 Item { @@ -16,6 +18,12 @@ Item { property AmountToSendNew amountToSend + SignalSpy { + id: amountChangedSpy + target: amountToSend + signalName: "amountChanged" + } + TestCase { name: "AmountToSendNew" when: windowShown @@ -30,6 +38,10 @@ Item { amountToSend = createTemporaryObject(componentUnderTest, root) } + function cleanup() { + amountChangedSpy.clear() + } + function test_empty() { compare(amountToSend.valid, false) compare(amountToSend.empty, true) @@ -179,9 +191,29 @@ Item { verify(!!textField) amountToSend.setValue("2.5") - tryCompare(amountToSend, "text", "2,5") tryCompare(textField, "text", "2,5") verify(amountToSend.valid) } + + function test_pasteChangesAmount() { + compare(amountToSend.valid, false) + compare(amountToSend.empty, true) + compare(amountToSend.amount, "0") + + QClipboardProxy.copyTextToClipboard("1.0005") + const textField = findChild(amountToSend, "amountToSend_textField") + verify(!!textField) + + verify(textField.canPaste) + mouseClick(textField) + keySequence(StandardKey.Paste) + compare(textField.text, "1.0005") + + compare(amountToSend.valid, true) + compare(amountToSend.empty, false) + compare(amountToSend.amount, "1000500000000000000") + + compare(amountChangedSpy.count, 1) + } } } diff --git a/storybook/qmlTests/tests/tst_SwapInputPanel.qml b/storybook/qmlTests/tests/tst_SwapInputPanel.qml index 71dc64cdf0..fefb49dd4a 100644 --- a/storybook/qmlTests/tests/tst_SwapInputPanel.qml +++ b/storybook/qmlTests/tests/tst_SwapInputPanel.qml @@ -165,7 +165,7 @@ Item { const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") verify(!!amountToSendInput) - tryCompare(amountToSendInput.input, "text", AmountsArithmetic.fromString(tokenAmount).toLocaleString(Qt.locale(), 'f', -128)) + tryCompare(amountToSendInput, "text", AmountsArithmetic.fromString(tokenAmount).toLocaleString(Qt.locale(), 'f', -128)) } function test_enterTokenAmountLocalizedNumber() { @@ -178,10 +178,10 @@ Item { verify(!!amountToSendInput) mouseClick(amountToSendInput) waitForRendering(amountToSendInput) - verify(amountToSendInput.input.input.edit.activeFocus) + verify(amountToSendInput.cursorVisible) - amountToSendInput.input.locale = Qt.locale("cs_CZ") - compare(amountToSendInput.input.locale.name, "cs_CZ") + amountToSendInput.locale = Qt.locale("cs_CZ") + compare(amountToSendInput.locale.name, "cs_CZ") // manually entering "1000000,00000042" meaning "1000000,00000042"; `,` being the decimal separator keyClick(Qt.Key_1) @@ -193,7 +193,7 @@ Item { keyClick(Qt.Key_4) keyClick(Qt.Key_2) - tryCompare(amountToSendInput.input, "text", "1000000,00000042") + tryCompare(amountToSendInput, "text", "1000000,00000042") tryCompare(controlUnderTest, "value", 1000000.00000042) verify(controlUnderTest.valueValid) } @@ -221,7 +221,7 @@ Item { verify(!!amountToSendInput) mouseClick(amountToSendInput) waitForRendering(amountToSendInput) - verify(amountToSendInput.input.input.edit.activeFocus) + verify(amountToSendInput.cursorVisible) keyClick(Qt.Key_1) keyClick(Qt.Key_Period) @@ -276,7 +276,7 @@ Item { // FIXME: This should be enabled after #15709 is resolved function test_clickingMaxButton() { - skip("maxTabButton is diabled") + skip("maxTabButton is disabled") controlUnderTest = createTemporaryObject(componentUnderTest, root, {tokenKey: "ETH"}) verify(!!controlUnderTest) waitForRendering(controlUnderTest) @@ -292,9 +292,9 @@ Item { const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") verify(!!amountToSendInput) waitForRendering(amountToSendInput) - const maxValue = amountToSendInput.maxInputBalance + const maxValue = maxTagButton.maxSafeValue - tryCompare(amountToSendInput.input, "text", maxValue.toLocaleString(Qt.locale(), 'f', -128)) + tryCompare(amountToSendInput, "text", maxValue.toLocaleString(Qt.locale(), 'f', -128)) tryCompare(controlUnderTest, "value", maxValue) verify(controlUnderTest.valueValid) } @@ -309,7 +309,7 @@ Item { const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") verify(!!amountToSendInput) - const amountInput = findChild(amountToSendInput, "amountInput") + const amountInput = findChild(amountToSendInput, "amountToSend_textField") verify(!!amountInput) verify(!amountInput.visible) @@ -357,7 +357,7 @@ Item { waitForRendering(controlUnderTest) verify(maxTagButton.visible) - // FIXME: maxTagButton should be enabled after #15709 is resolved + // FIXME: maxTagButton should be enabled after #15709 is resolved verify(!maxTagButton.enabled) verify(!maxTagButton.text.endsWith(modelItemToTest.symbol)) tryCompare(maxTagButton, "type", modelItemToTest.currentBalance === 0 ? StatusBaseButton.Type.Danger : StatusBaseButton.Type.Normal) @@ -367,15 +367,15 @@ Item { mouseClick(maxTagButton) waitForRendering(amountToSendInput) - tryCompare(amountToSendInput.input, "text", modelItemToTest.currentBalance === 0 ? "" : maxTagButton.maxSafeValueAsString) - compare(controlUnderTest.value, maxTagButton.maxSafeValue) + tryCompare(amountToSendInput, "text", modelItemToTest.currentBalance === 0 ? "" : maxTagButton.maxSafeValue.toString()) + tryCompare(controlUnderTest, "value", maxTagButton.maxSafeValue) verify(modelItemToTest.currentBalance === 0 ? !controlUnderTest.valueValid : controlUnderTest.valueValid) - const marketPrice = !!amountToSendInput.selectedHolding ? amountToSendInput.selectedHolding.marketDetails.currencyPrice.amount : 0 + const marketPrice = amountToSendInput.price compare(bottomItemText.text, d.adaptor.formatCurrencyAmount( maxTagButton.maxSafeValue * marketPrice, d.adaptor.currencyStore.currentCurrency)) } - amountToSendInput.input.input.edit.clear() + amountToSendInput.clear() } } @@ -383,9 +383,6 @@ Item { controlUnderTest = createTemporaryObject(componentUnderTest, root) verify(!!controlUnderTest) - controlUnderTest.mainInputLoading = true - controlUnderTest.bottomTextLoading = true - const maxTagButton = findChild(controlUnderTest, "maxTagButton") verify(!!maxTagButton) verify(!maxTagButton.visible) @@ -402,15 +399,15 @@ Item { const bottomItemText = findChild(amountToSendInput, "bottomItemText") verify(!!bottomItemText) + mouseClick(amountToSendInput) // enter 5.42 as entered amount keyClick(Qt.Key_5) keyClick(Qt.Key_Period) keyClick(Qt.Key_4) keyClick(Qt.Key_2) - let numberTested = LocaleUtils.numberFromLocaleString("5.42", amountToSendInput.input.locale) - - compare(amountToSendInput.input.text, "5.42") + let numberTested = 5.42 + tryCompare(amountToSendInput, "text", "5.42") for (let i= 0; i < d.tokenSelectorAdaptor.outputAssetsModel.count; i++) { let modelItemToTest = ModelUtils.get(d.tokenSelectorAdaptor.outputAssetsModel, i) @@ -425,13 +422,13 @@ Item { // check input value and state waitForItemPolished(controlUnderTest) - compare(amountToSendInput.input.text, "5.42") - const marketPrice = !!amountToSendInput.selectedHolding ? amountToSendInput.selectedHolding.marketDetails.currencyPrice.amount : 0 + compare(amountToSendInput.text, "5.42") + const marketPrice = amountToSendInput.price tryCompare(bottomItemText, "text", d.adaptor.formatCurrencyAmount( - numberTested * marketPrice, - d.adaptor.currencyStore.currentCurrency)) + numberTested * marketPrice, + d.adaptor.currencyStore.currentCurrency)) compare(controlUnderTest.value, numberTested) - compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.input.text, modelItemToTest.decimals).toString()) + compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.text, modelItemToTest.decimals).toString()) compare(controlUnderTest.valueValid, numberTested <= maxTagButton.maxSafeValue) compare(controlUnderTest.selectedHoldingId, modelItemToTest.tokensKey) compare(controlUnderTest.amountEnteredGreaterThanBalance, numberTested > maxTagButton.maxSafeValue) @@ -458,11 +455,11 @@ Item { const bottomItemText = findChild(amountToSendInput, "bottomItemText") verify(!!bottomItemText) - let numberTested = LocaleUtils.numberFromLocaleString(numberTestedString, amountToSendInput.input.locale) + let numberTested = LocaleUtils.numberFromLocaleString(numberTestedString, amountToSendInput.locale) - compare(amountToSendInput.input.text, numberTestedString) + compare(amountToSendInput.text, numberTestedString) compare(controlUnderTest.value, numberTested) - compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.input.text, modelItemToTest.decimals).toString()) + compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.text, modelItemToTest.decimals).toString()) compare(controlUnderTest.valueValid, true) compare(controlUnderTest.selectedHoldingId, tokenKeyToTest) compare(controlUnderTest.amountEnteredGreaterThanBalance, false) @@ -472,7 +469,7 @@ Item { controlUnderTest.tokenAmount = numberTestedString waitForItemPolished(controlUnderTest) - tryCompare(amountToSendInput.input, "text", numberTestedString) + tryCompare(amountToSendInput, "text", numberTestedString) tryCompare(controlUnderTest, "value", numberTested) compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(numberTested, modelItemToTest.decimals).toString()) compare(controlUnderTest.valueValid, false) @@ -496,20 +493,20 @@ Item { const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") verify(!!amountToSendInput) - let numberTested = LocaleUtils.numberFromLocaleString(numberTestedString, amountToSendInput.input.locale) + let numberTested = LocaleUtils.numberFromLocaleString(numberTestedString, amountToSendInput.locale) - compare(amountToSendInput.input.text, numberTestedString) + compare(amountToSendInput.text, numberTestedString) compare(controlUnderTest.value, numberTested) - compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.input.text, modelItemToTest.decimals).toString()) + compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.text, modelItemToTest.decimals).toString()) compare(controlUnderTest.valueValid, true) compare(controlUnderTest.selectedHoldingId, tokenKeyToTest) compare(controlUnderTest.amountEnteredGreaterThanBalance, false) d.tokenSelectorAdaptor.assetsModel.modelReset() - compare(amountToSendInput.input.text, numberTestedString) + compare(amountToSendInput.text, numberTestedString) compare(controlUnderTest.value, numberTested) - compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.input.text, modelItemToTest.decimals).toString()) + compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.text, modelItemToTest.decimals).toString()) compare(controlUnderTest.valueValid, true) compare(controlUnderTest.selectedHoldingId, tokenKeyToTest) compare(controlUnderTest.amountEnteredGreaterThanBalance, false) diff --git a/storybook/qmlTests/tests/tst_SwapModal.qml b/storybook/qmlTests/tests/tst_SwapModal.qml index 6fdfd4beb5..9eec289168 100644 --- a/storybook/qmlTests/tests/tst_SwapModal.qml +++ b/storybook/qmlTests/tests/tst_SwapModal.qml @@ -330,8 +330,7 @@ Item { verify(!!payPanel) const amountToSendInput = findChild(payPanel, "amountToSendInput") verify(!!amountToSendInput) - verify(amountToSendInput.input.input.edit.activeFocus) - verify(amountToSendInput.input.input.edit.cursorVisible) + verify(amountToSendInput.cursorVisible) for(let i =0; i< swapAdaptor.nonWatchAccounts.count; i++) { // launch account selection dropdown @@ -363,8 +362,7 @@ Item { verify(!!headerContentItemEmoji) compare(headerContentItemEmoji.asset.emoji, swapAdaptor.nonWatchAccounts.get(i).emoji) - verify(amountToSendInput.input.input.edit.activeFocus) - verify(amountToSendInput.input.input.edit.cursorVisible) + verify(amountToSendInput.cursorVisible) } closeAndVerfyModal() } @@ -377,8 +375,7 @@ Item { verify(!!payPanel) const amountToSendInput = findChild(payPanel, "amountToSendInput") verify(!!amountToSendInput) - verify(amountToSendInput.input.input.edit.activeFocus) - verify(amountToSendInput.input.input.edit.cursorVisible) + verify(amountToSendInput.cursorVisible) // get network comboBox const networkComboBox = findChild(controlUnderTest, "networkFilter") @@ -413,8 +410,7 @@ Item { verify(!!networkComboIcon) verify(networkComboIcon.asset.name.includes(root.swapAdaptor.filteredFlatNetworksModel.get(i).iconUrl)) - verify(amountToSendInput.input.input.edit.activeFocus) - verify(amountToSendInput.input.input.edit.cursorVisible) + verify(amountToSendInput.cursorVisible) } } networkComboBox.control.popup.close() @@ -817,9 +813,11 @@ Item { verify(!receivePanel.interactive) compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey) compare(receivePanel.value, root.swapStore.getWei2Eth(txHasRouteNoApproval.amountToReceive, root.swapAdaptor.toToken.decimals)) - compare(receivePanel.rawValue, SQUtils.AmountsArithmetic.fromNumber( - LocaleUtils.numberFromLocaleString(root.swapAdaptor.swapOutputData.toTokenAmount, Qt.locale()), - root.swapAdaptor.toToken.decimals).toString()) + compare(receivePanel.rawValue, + SQUtils.AmountsArithmetic.times( + SQUtils.AmountsArithmetic.fromString(root.swapAdaptor.swapOutputData.toTokenAmount), + SQUtils.AmountsArithmetic.fromNumber(1, root.swapAdaptor.toToken.decimals) + ).toFixed()) // edit some params to retry swap root.swapFormData.fromTokenAmount = "0.012" @@ -865,9 +863,11 @@ Item { verify(!receivePanel.interactive) compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey) compare(receivePanel.value, root.swapStore.getWei2Eth(txRoutes2.amountToReceive, root.swapAdaptor.toToken.decimals)) - compare(receivePanel.rawValue, SQUtils.AmountsArithmetic.fromNumber( - LocaleUtils.numberFromLocaleString(root.swapAdaptor.swapOutputData.toTokenAmount, Qt.locale()), - root.swapAdaptor.toToken.decimals).toString()) + compare(receivePanel.rawValue, + SQUtils.AmountsArithmetic.times( + SQUtils.AmountsArithmetic.fromString(root.swapAdaptor.swapOutputData.toTokenAmount), + SQUtils.AmountsArithmetic.fromNumber(1, root.swapAdaptor.toToken.decimals) + ).toFixed()) } function test_modal_pay_input_default() { @@ -887,14 +887,14 @@ Item { const tokenSelectorContentItemText = findChild(payPanel, "tokenSelectorContentItemText") verify(!!tokenSelectorContentItemText) - waitForRendering(payPanel) + waitForRendering(controlUnderTest.contentItem) // check default states for the from input selector compare(amountToSendInput.caption, qsTr("Pay")) verify(amountToSendInput.interactive) - compare(amountToSendInput.input.text, "") - verify(amountToSendInput.input.input.edit.cursorVisible) - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) + compare(amountToSendInput.text, "") + verify(amountToSendInput.cursorVisible) + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) compare(bottomItemText.text, root.swapAdaptor.currencyStore.formatCurrencyAmount(0, root.swapAdaptor.currencyStore.currentCurrency)) compare(holdingSelector.currentTokensKey, "") compare(tokenSelectorContentItemText.text, qsTr("Select asset")) @@ -941,9 +941,9 @@ Item { compare(amountToSendInput.caption, qsTr("Pay")) verify(amountToSendInput.interactive) - tryCompare(amountToSendInput.input.input, "text", valueToExchangeString) - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) - tryCompare(amountToSendInput.input.input.edit, "cursorVisible", true) + tryCompare(amountToSendInput, "text", valueToExchangeString) + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) + tryCompare(amountToSendInput, "cursorVisible", true) tryCompare(bottomItemText, "text", root.swapAdaptor.currencyStore.formatCurrencyAmount(valueToExchange * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency)) compare(holdingSelector.currentTokensKey, expectedToken.tokensKey) tryCompare(tokenSelectorContentItemText, "text", expectedToken.symbol) @@ -990,8 +990,8 @@ Item { compare(amountToSendInput.caption, qsTr("Pay")) verify(amountToSendInput.interactive) - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) - verify(amountToSendInput.input.input.edit.cursorVisible) + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) + verify(amountToSendInput.cursorVisible) compare(bottomItemText.text, root.swapAdaptor.currencyStore.formatCurrencyAmount(0, root.swapAdaptor.currencyStore.currentCurrency)) compare(holdingSelector.currentTokensKey, "") compare(tokenSelectorContentItemText.text, "Select asset") @@ -1039,9 +1039,9 @@ Item { compare(amountToSendInput.caption, qsTr("Pay")) verify(amountToSendInput.interactive) - compare(amountToSendInput.input.text, valueToExchangeString) - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) - tryCompare(amountToSendInput.input.input.edit, "cursorVisible", true) + compare(amountToSendInput.text, valueToExchangeString) + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) + tryCompare(amountToSendInput, "cursorVisible", true) tryCompare(bottomItemText, "text", root.swapAdaptor.currencyStore.formatCurrencyAmount(valueToExchange * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency)) compare(holdingSelector.currentTokensKey, expectedToken.tokensKey) compare(tokenSelectorContentItemText.text, expectedToken.symbol) @@ -1078,11 +1078,11 @@ Item { // check default states for the from input selector compare(amountToSendInput.caption, qsTr("Receive")) - compare(amountToSendInput.input.text, "") + compare(amountToSendInput.text, "") // TODO: this should be come interactive under https://github.com/status-im/status-desktop/issues/15095 verify(!amountToSendInput.interactive) - verify(!amountToSendInput.input.input.edit.cursorVisible) - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) + verify(!amountToSendInput.cursorVisible) + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) compare(bottomItemText.text, root.swapAdaptor.currencyStore.formatCurrencyAmount(0, root.swapAdaptor.currencyStore.currentCurrency)) compare(holdingSelector.currentTokensKey, "STT") compare(tokenSelectorContentItemText.text, "STT") @@ -1130,9 +1130,9 @@ Item { compare(amountToSendInput.caption, qsTr("Receive")) // TODO: this should be come interactive under https://github.com/status-im/status-desktop/issues/15095 verify(!amountToSendInput.interactive) - verify(!amountToSendInput.input.input.edit.cursorVisible) - compare(amountToSendInput.input.text, valueToReceive.toLocaleString(Qt.locale(), 'f', -128)) - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) + verify(!amountToSendInput.cursorVisible) + compare(amountToSendInput.text, valueToReceive.toLocaleString(Qt.locale(), 'f', -128)) + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) tryCompare(bottomItemText, "text", root.swapAdaptor.currencyStore.formatCurrencyAmount(valueToReceive * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency)) compare(holdingSelector.currentTokensKey, expectedToken.tokensKey) compare(tokenSelectorContentItemText.text, expectedToken.symbol) @@ -1179,7 +1179,7 @@ Item { // check states for the pay input selector verify(maxTagButton.visible) - // FIXME: maxTagButton should be enabled after #15709 is resolved + // FIXME: maxTagButton should be enabled after #15709 is resolved verify(!maxTagButton.enabled); let maxPossibleValue = WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol) let truncmaxPossibleValue = Math.trunc(maxPossibleValue*100)/100 @@ -1187,9 +1187,9 @@ Item { : root.swapAdaptor.currencyStore.formatCurrencyAmount(truncmaxPossibleValue, expectedToken.symbol, {noSymbol: true}))) waitForItemPolished(amountToSendInput) verify(amountToSendInput.interactive) - tryCompare(amountToSendInput.input.input.edit, "cursorVisible", true) - tryCompare(amountToSendInput.input, "text", valueToExchange.toLocaleString(Qt.locale(), 'f', -128)) - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) + tryCompare(amountToSendInput, "cursorVisible", true) + tryCompare(amountToSendInput, "text", valueToExchange.toLocaleString(Qt.locale(), 'f', -128)) + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) tryCompare(bottomItemText, "text", root.swapAdaptor.currencyStore.formatCurrencyAmount(valueToExchange * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency)) if (maxTagButton.enabled) { @@ -1198,8 +1198,8 @@ Item { waitForItemPolished(payPanel) verify(amountToSendInput.interactive) - verify(amountToSendInput.input.input.edit.cursorVisible) - tryCompare(amountToSendInput.input, "text", maxPossibleValue === 0 ? "" : maxPossibleValue.toLocaleString(Qt.locale(), 'f', -128)) + verify(amountToSendInput.cursorVisible) + tryCompare(amountToSendInput, "text", maxPossibleValue === 0 ? "" : maxPossibleValue.toLocaleString(Qt.locale(), 'f', -128)) tryCompare(bottomItemText, "text", root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency)) } closeAndVerfyModal() @@ -1239,9 +1239,9 @@ Item { compare(maxTagButton.text, qsTr("Max. %1").arg(maxPossibleValue === 0 ? "0" : root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue, expectedToken.symbol, {noSymbol: true}))) verify(amountToSendInput.interactive) - verify(amountToSendInput.input.input.edit.cursorVisible) - compare(amountToSendInput.input.text, "") - compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) + verify(amountToSendInput.cursorVisible) + compare(amountToSendInput.text, "") + compare(amountToSendInput.placeholderText, LocaleUtils.numberToLocaleString(0)) compare(bottomItemText.text, root.swapAdaptor.currencyStore.formatCurrencyAmount(0, root.swapAdaptor.currencyStore.currentCurrency)) // click on max button @@ -1251,8 +1251,8 @@ Item { formValuesChanged.wait() verify(amountToSendInput.interactive) - verify(amountToSendInput.input.input.edit.cursorVisible) - compare(amountToSendInput.input.text, maxPossibleValue > 0 ? maxPossibleValue.toLocaleString(Qt.locale(), 'f', -128) : "") + verify(amountToSendInput.cursorVisible) + compare(amountToSendInput.text, maxPossibleValue > 0 ? maxPossibleValue.toLocaleString(Qt.locale(), 'f', -128) : "") tryCompare(bottomItemText, "text", root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency)) closeAndVerfyModal() @@ -1407,7 +1407,7 @@ Item { // verify pay values compare(payPanel.tokenKey, data.fromToken) compare(payPanel.tokenAmount, data.fromTokenAmount) - verify(payAmountToSendInput.input.input.edit.cursorVisible) + verify(payAmountToSendInput.cursorVisible) compare(paytokenSelectorContentItemText.text, !!root.swapFormData.fromTokensKey ? root.swapFormData.fromTokensKey : qsTr("Select asset")) compare(!!data.fromToken , !!paytokenSelectorIcon) if(!!paytokenSelectorIcon) { @@ -1418,7 +1418,7 @@ Item { // verify receive values compare(receivePanel.tokenKey, data.toToken) compare(receivePanel.tokenAmount, data.toTokenAmount) - verify(!receiveAmountToSendInput.input.input.edit.cursorVisible) + verify(!receiveAmountToSendInput.cursorVisible) compare(receivetokenSelectorContentItemText.text, !!root.swapFormData.toTokenKey ? root.swapFormData.toTokenKey : qsTr("Select asset")) if(!!receivetokenSelectorIcon) { compare(receivetokenSelectorIcon.image.source, expectedToTokenIcon) @@ -1447,19 +1447,19 @@ Item { // verify pay values compare(payPanel.tokenKey, data.toToken) compare(payPanel.tokenAmount, data.toTokenAmount) - verify(payAmountToSendInput.input.input.edit.cursorVisible) + verify(payAmountToSendInput.cursorVisible) compare(paytokenSelectorContentItemText.text, !!data.toToken ? data.toToken : qsTr("Select asset")) if(!!paytokenSelectorIcon) { compare(paytokenSelectorIcon.image.source, expectedToTokenIcon) } verify(!!data.toToken ? maxTagButton.visible: !maxTagButton.visible) compare(maxTagButton.text, qsTr("Max. %1").arg(Qt.locale().zeroDigit)) - compare(maxTagButton.type, (payAmountToSendInput.input.valid || !payAmountToSendInput.input.text) && maxTagButton.value > 0 ? StatusBaseButton.Type.Normal : StatusBaseButton.Type.Danger) + compare(maxTagButton.type, (payAmountToSendInput.valid || !payAmountToSendInput.text) && maxTagButton.value > 0 ? StatusBaseButton.Type.Normal : StatusBaseButton.Type.Danger) // verify receive values compare(receivePanel.tokenKey, data.fromToken) compare(receivePanel.tokenAmount, data.fromTokenAmount) - verify(!receiveAmountToSendInput.input.input.edit.cursorVisible) + verify(!receiveAmountToSendInput.cursorVisible) compare(receivetokenSelectorContentItemText.text, !!data.fromToken ? data.fromToken : qsTr("Select asset")) if(!!receivetokenSelectorIcon) { compare(receivetokenSelectorIcon.image.source, expectedFromTokenIcon) @@ -1672,8 +1672,7 @@ Item { verify(!maxTagButton.visible) compare(payPanel.selectedHoldingId, "") verify(!payPanel.valueValid) - compare(payPanel.value, 0) - compare(payPanel.rawValue, "0") + tryCompare(payPanel, "rawValue", "0") verify(!errorTag.visible) compare(tokenSelectorContentItemText.text, qsTr("Select asset")) } else { @@ -1694,8 +1693,7 @@ Item { root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue, expectedToken.symbol, {noSymbol: true}))) compare(payPanel.selectedHoldingId.toLowerCase(), expectedToken.symbol.toLowerCase()) compare(payPanel.valueValid, valueToExchange <= maxPossibleValue) - compare(payPanel.value, valueToExchange) - compare(payPanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString()) + tryCompare(payPanel, "rawValue", SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString()) compare(errorTag.visible, valueToExchange > maxPossibleValue) if(errorTag.visible) compare(errorTag.text, qsTr("Insufficient funds for swap")) @@ -1793,9 +1791,8 @@ Item { {input: "1.00015", locale: Qt.locale("en_US")}, {input: "0.001", locale: Qt.locale("pl_PL")}, {input: "1.90015", locale: Qt.locale("pl_PL")}, - /* TODO uncomment after https://discord.com/channels/@me/927512790296563712/1260937239140241408 - {input: "100.000000000000151001"}, - {input: "1.0200000000000151001"} */ + {input: "100.000000000000151001", locale: Qt.locale("en_US")}, + {input: "1.020000000000015101", locale: Qt.locale("en_US")} ] } @@ -1807,20 +1804,18 @@ Item { const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") verify(!!amountToSendInput) - amountToSendInput.input.locale = data.locale + amountToSendInput.locale = data.locale // Launch popup launchAndVerfyModal() - + mouseClick(amountToSendInput) waitForRendering(amountToSendInput) - //TODO: should not be needed after https://github.com/status-im/status-desktop/issues/15417 - amountToSendInput.input.input.cursorPosition = data.input.length - let amountToTestInLocale = data.input.replace('.', amountToSendInput.input.locale.decimalPoint) + let amountToTestInLocale = data.input.replace('.', amountToSendInput.locale.decimalPoint) for(let i =0; i< data.input.length; i++) { keyClick(Qt.Key_Backspace) let expectedAmount = amountToTestInLocale.substring(0, data.input.length - (i+1)) - compare(amountToSendInput.input.text, expectedAmount) + tryCompare(amountToSendInput, "text", expectedAmount) } } diff --git a/ui/app/AppLayouts/Wallet/panels/SwapInputPanel.qml b/ui/app/AppLayouts/Wallet/panels/SwapInputPanel.qml index ad9dbdbe75..6ffbdb6f24 100644 --- a/ui/app/AppLayouts/Wallet/panels/SwapInputPanel.qml +++ b/ui/app/AppLayouts/Wallet/panels/SwapInputPanel.qml @@ -39,7 +39,7 @@ Control { onTokenKeyChanged: Qt.callLater(reevaluateSelectedId) property string tokenAmount - onTokenAmountChanged: Qt.callLater(d.updateInputText) + onTokenAmountChanged: Qt.callLater(d.updateInputText) // FIXME remove the callLater(), shouldn't be needed now property int swapSide: SwapInputPanel.SwapSide.Pay property bool fiatInputInteractive @@ -47,6 +47,7 @@ Control { property bool bottomTextLoading property bool interactive: true + // FIXME drop after using ModelEntry, shouldn't be needed function reevaluateSelectedId() { holdingSelector.selectToken(tokenKey) d.selectedHolding = SQUtils.ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey) @@ -54,18 +55,24 @@ Control { // output API readonly property string selectedHoldingId: holdingSelector.currentTokensKey - readonly property double value: amountToSendInput.cryptoValueToSendFloat - readonly property string rawValue: amountToSendInput.cryptoValueToSend + readonly property double value: amountToSendInput.asNumber + readonly property string rawValue: { + if (!d.isSelectedHoldingValidAsset || !d.selectedHolding.marketDetails || !d.selectedHolding.marketDetails.currencyPrice) { + return "0" + } + return amountToSendInput.amount + } readonly property int rawValueMultiplierIndex: amountToSendInput.multiplierIndex - readonly property bool valueValid: amountToSendInput.inputNumberValid - readonly property bool amountEnteredGreaterThanBalance: value > maxSendButton.maxSafeValue + readonly property bool valueValid: value > 0 && amountToSendInput.valid && + (swapSide === SwapInputPanel.SwapSide.Pay ? !amountEnteredGreaterThanBalance : true) + readonly property bool amountEnteredGreaterThanBalance: amountToSendInput.balanceExceeded // visual properties property int swapExchangeButtonWidth: 44 property string caption: swapSide === SwapInputPanel.SwapSide.Pay ? qsTr("Pay") : qsTr("Receive") function forceActiveFocus() { - amountToSendInput.input.forceActiveFocus() + amountToSendInput.forceActiveFocus() } enum SwapSide { @@ -82,14 +89,15 @@ Control { QtObject { id: d + // FIXME use ModelEntry property var selectedHolding: SQUtils.ModelUtils.getByKey(holdingSelector.model, "tokensKey", holdingSelector.currentTokensKey) readonly property bool isSelectedHoldingValidAsset: !!selectedHolding readonly property double maxFiatBalance: isSelectedHoldingValidAsset && !!selectedHolding.currencyBalance ? selectedHolding.currencyBalance : 0 readonly property double maxCryptoBalance: isSelectedHoldingValidAsset && !!selectedHolding.currentBalance ? selectedHolding.currentBalance : 0 - readonly property double maxInputBalance: amountToSendInput.inputIsFiat ? maxFiatBalance : maxCryptoBalance - readonly property string inputSymbol: amountToSendInput.inputIsFiat ? root.currencyStore.currentCurrency - : (!!selectedHolding ? selectedHolding.symbol : "") + readonly property double maxInputBalance: amountToSendInput.fiatMode ? maxFiatBalance : maxCryptoBalance + readonly property string inputSymbol: amountToSendInput.fiatMode ? root.currencyStore.currentCurrency + : (!!selectedHolding ? selectedHolding.symbol : "") readonly property var adaptor: TokenSelectorViewAdaptor { assetsModel: root.processedAssetsModel @@ -105,7 +113,7 @@ Control { function updateInputText() { if (!tokenAmount) { - amountToSendInput.input.input.edit.clear() + amountToSendInput.clear() return } let amountToSet = SQUtils.AmountsArithmetic.fromString(tokenAmount).toFixed() @@ -114,10 +122,10 @@ Control { and thats why we compare with toFixed() also when deleting a numbers last digit, we should not update the text to 0 instead it should remain empty as entered by the user */ - let currentInputTextAmount = SQUtils.AmountsArithmetic.fromString(amountToSendInput.input.text.replace(amountToSendInput.input.locale.decimalPoint,'.')).toFixed() + let currentInputTextAmount = SQUtils.AmountsArithmetic.fromString(amountToSendInput.text.replace(amountToSendInput.locale.decimalPoint,'.')).toFixed() if (currentInputTextAmount !== amountToSet && - !(amountToSet === "0" && !amountToSendInput.input.text)) { - amountToSendInput.input.text = amountToSet.replace('.', amountToSendInput.input.locale.decimalPoint) + !(amountToSet === "0" && !amountToSendInput.text)) { + amountToSendInput.setValue(tokenAmount) } } } @@ -138,7 +146,7 @@ Control { ShapePath { id: path fillColor: Theme.palette.indirectColor3 - strokeColor: amountToSendInput.input.input.edit.activeFocus ? Theme.palette.directColor7 : Theme.palette.directColor8 + strokeColor: amountToSendInput.cursorVisible ? Theme.palette.directColor7 : Theme.palette.directColor8 strokeWidth: 1 capStyle: ShapePath.RoundCap @@ -205,24 +213,30 @@ Control { Layout.preferredWidth: parent.width*.66 Layout.fillHeight: true - AmountToSend { + AmountToSendNew { + readonly property bool balanceExceeded: + SQUtils.AmountsArithmetic.fromNumber(maxSendButton.maxSafeCryptoValue, multiplierIndex).cmp(amount) === -1 + + readonly property double asNumber: { + if (!valid) + return 0 + + return parseFloat(text.replace(LocaleUtils.userInputLocale.decimalPoint, ".")) + } + Layout.fillWidth: true id: amountToSendInput objectName: "amountToSendInput" caption: root.caption interactive: root.interactive - selectedHolding: d.selectedHolding // FIXME shouldn't be necesary to pass the whole object - + markAsInvalid: (root.swapSide === SwapInputPanel.SwapSide.Pay && (balanceExceeded || d.maxInputBalance === 0)) || (!!text && !valid) fiatInputInteractive: root.fiatInputInteractive - input.input.edit.color: !input.valid ? Theme.palette.dangerColor1 : maxSendButton.hovered ? Theme.palette.baseColor1 - : Theme.palette.directColor1 + multiplierIndex: d.isSelectedHoldingValidAsset && !!d.selectedHolding && !!d.selectedHolding.decimals ? d.selectedHolding.decimals : 18 + price: d.isSelectedHoldingValidAsset ? (!!d.selectedHolding && !!d.selectedHolding.marketDetails ? d.selectedHolding.marketDetails.currencyPrice.amount : 1) + : 1 + formatFiat: amount => root.currencyStore.formatCurrencyAmount(amount, root.currencyStore.currentCurrency) + formatBalance: amount => root.currencyStore.formatCurrencyAmount(amount, d.inputSymbol) - multiplierIndex: d.selectedHolding && d.selectedHolding.decimals ? d.selectedHolding.decimals : 0 - - maxInputBalance: (root.swapSide === SwapInputPanel.SwapSide.Receive || !d.isSelectedHoldingValidAsset) ? Number.POSITIVE_INFINITY - : maxSendButton.maxSafeValue - currentCurrency: root.currencyStore.currentCurrency - formatCurrencyAmount: root.currencyStore.formatCurrencyAmount mainInputLoading: root.mainInputLoading bottomTextLoading: root.bottomTextLoading } @@ -239,7 +253,7 @@ Control { Layout.alignment: Qt.AlignRight model: d.adaptor.outputAssetsModel nonInteractiveDelegateKey: root.nonInteractiveTokensKey - onActivated: if (root.interactive) amountToSendInput.input.forceActiveFocus() + onActivated: if (root.interactive) root.forceActiveFocus() } Item { Layout.fillHeight: !maxSendButton.visible } @@ -251,19 +265,15 @@ Control { Layout.maximumWidth: parent.width objectName: "maxTagButton" - readonly property double maxSafeValue: WalletUtils.calculateMaxSafeSendAmount( - d.maxInputBalance, d.inputSymbol) - readonly property string maxSafeValueAsString: maxSafeValue.toLocaleString( - amountToSendInput.input.locale, 'f', -128) + readonly property double maxSafeValue: WalletUtils.calculateMaxSafeSendAmount(d.maxInputBalance, d.inputSymbol) + readonly property double maxSafeCryptoValue: WalletUtils.calculateMaxSafeSendAmount(d.maxCryptoBalance, d.inputSymbol) - markAsInvalid: (!amountToSendInput.input.valid && !!amountToSendInput.input.text) - || d.maxInputBalance === 0 + markAsInvalid: amountToSendInput.markAsInvalid - formattedValue: - d.maxInputBalance === 0 ? amountToSendInput.input.locale.zeroDigit - : root.currencyStore.formatCurrencyAmount( - maxSafeValue, d.inputSymbol, - { noSymbol: !amountToSendInput.inputIsFiat }) + formattedValue: d.maxInputBalance === 0 ? LocaleUtils.userInputLocale.zeroDigit + : root.currencyStore.formatCurrencyAmount( + maxSafeValue, d.inputSymbol, + { noSymbol: !amountToSendInput.fiatMode }) visible: d.isSelectedHoldingValidAsset && root.swapSide === SwapInputPanel.SwapSide.Pay // FIXME: This should be enabled after #15709 is resolved @@ -271,10 +281,10 @@ Control { onClicked: { if (maxSafeValue) - amountToSendInput.input.text = maxSafeValueAsString + amountToSendInput.setValue(SQUtils.AmountsArithmetic.fromNumber(maxSafeValue).toString()) else - amountToSendInput.input.input.edit.clear() - amountToSendInput.input.forceActiveFocus() + amountToSendInput.clear() + root.forceActiveFocus() } } } diff --git a/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml b/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml index c820905dc8..6e9d5ccb16 100644 --- a/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml +++ b/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml @@ -75,6 +75,8 @@ StatusDialog { function onFormValuesChanged() { d.fetchSuggestedRoutes() } + + // FIXME drop after SwapInputPanel uses ModelEntry to track the currently selected token // refresh the selected asset in payPanel when account/network changes function onSelectedAccountAddressChanged() { payPanel.reevaluateSelectedId() diff --git a/ui/imports/shared/popups/send/SendModal.qml b/ui/imports/shared/popups/send/SendModal.qml index f169059e9c..7944481dff 100644 --- a/ui/imports/shared/popups/send/SendModal.qml +++ b/ui/imports/shared/popups/send/SendModal.qml @@ -488,9 +488,7 @@ StatusDialog { interactive: popup.interactive readonly property bool balanceExceeded: - SQUtils.AmountsArithmetic.cmp( - SQUtils.AmountsArithmetic.fromNumber(maxButton.maxSafeCryptoValue, multiplierIndex), - SQUtils.AmountsArithmetic.fromString(amount)) === -1 + SQUtils.AmountsArithmetic.fromNumber(maxButton.maxSafeCryptoValue, multiplierIndex).cmp(amount) === -1 readonly property bool ready: valid && !empty && !balanceExceeded @@ -517,7 +515,6 @@ StatusDialog { fiatMode ? minSendFiatDecimals + 1 : 0 // End of to-be-removed part - decimalPoint: LocaleUtils.userInputLocale.decimalPoint markAsInvalid: balanceExceeded // Collectibles do not have decimals diff --git a/ui/imports/shared/popups/send/views/AmountToSendNew.qml b/ui/imports/shared/popups/send/views/AmountToSendNew.qml index f0c6c9dcb5..596fb71d0a 100644 --- a/ui/imports/shared/popups/send/views/AmountToSendNew.qml +++ b/ui/imports/shared/popups/send/views/AmountToSendNew.qml @@ -140,9 +140,9 @@ Control { return SQUtils.AmountsArithmetic.times( SQUtils.AmountsArithmetic.fromString(inputDelocalized), SQUtils.AmountsArithmetic.fromNumber( - price * (10 ** root.fiatDecimalPlaces))).round().toFixed() + price * (10 ** root.fiatDecimalPlaces))).toFixed() - if (!price) + if (!price) // prevent div by zero below return 0 const multiplier = SQUtils.AmountsArithmetic.fromExponent( @@ -152,7 +152,7 @@ Control { SQUtils.AmountsArithmetic.times( SQUtils.AmountsArithmetic.fromString(inputDelocalized), multiplier), - SQUtils.AmountsArithmetic.fromNumber(price)).round().toFixed() + SQUtils.AmountsArithmetic.fromNumber(price)).toFixed() } }