fix(@desktop/wallet): solving the issues with SwapInputPanel list in the issue

fixes  #15162
This commit is contained in:
Khushboo Mehta 2024-06-14 13:34:20 +02:00 committed by Khushboo-dev-cpp
parent d700a1ad53
commit 0645ed4712
9 changed files with 288 additions and 123 deletions

View File

@ -27,6 +27,7 @@ SplitView {
anchors.centerIn: parent anchors.centerIn: parent
text: ctrlText.text text: ctrlText.text
buttonText: ctrlButtonText.text buttonText: ctrlButtonText.text
buttonVisible: buttonVisible.checked
asset.name: ctrlAssetName.text asset.name: ctrlAssetName.text
loading: ctrlLoading.checked loading: ctrlLoading.checked
onButtonClicked: logs.logEvent("ErrorTag::onButtonClicked", [], arguments) onButtonClicked: logs.logEvent("ErrorTag::onButtonClicked", [], arguments)
@ -85,6 +86,10 @@ SplitView {
id: ctrlLoading id: ctrlLoading
text: "Loading" text: "Loading"
} }
Switch {
id: buttonVisible
text: "Button Visible"
}
Item { Layout.fillHeight: true } Item { Layout.fillHeight: true }
} }
} }

View File

@ -86,7 +86,8 @@ SplitView {
swapSide: SwapInputPanel.SwapSide.Pay swapSide: SwapInputPanel.SwapSide.Pay
fiatInputInteractive: ctrlFiatInputInteractive.checked fiatInputInteractive: ctrlFiatInputInteractive.checked
swapExchangeButtonWidth: swapButton.width swapExchangeButtonWidth: swapButton.width
loading: ctrlLoading.checked mainInputLoading: ctrlMainInputLoading.checked
bottomTextLoading: ctrlBottomTextLoading.checked
} }
SwapInputPanel { SwapInputPanel {
@ -107,7 +108,8 @@ SplitView {
swapSide: SwapInputPanel.SwapSide.Receive swapSide: SwapInputPanel.SwapSide.Receive
fiatInputInteractive: ctrlFiatInputInteractive.checked fiatInputInteractive: ctrlFiatInputInteractive.checked
swapExchangeButtonWidth: swapButton.width swapExchangeButtonWidth: swapButton.width
loading: ctrlLoading.checked mainInputLoading: ctrlMainInputLoading.checked
bottomTextLoading: ctrlBottomTextLoading.checked
} }
SwapExchangeButton { SwapExchangeButton {
@ -191,8 +193,12 @@ SplitView {
checked: false checked: false
} }
Switch { Switch {
id: ctrlLoading id: ctrlMainInputLoading
text: "Loading" text: "mainInputLoading"
}
Switch {
id: ctrlBottomTextLoading
text: "bottomTextLoading"
} }
Label { Label {
@ -200,16 +206,16 @@ SplitView {
font.weight: Font.Medium font.weight: Font.Medium
text: "<b>Pay:</b><ul><li>Symbol: %1<li>Amount: %2<li>Valid: %3" text: "<b>Pay:</b><ul><li>Symbol: %1<li>Amount: %2<li>Valid: %3"
.arg(payPanel.selectedHoldingId || "N/A") .arg(payPanel.selectedHoldingId || "N/A")
.arg(payPanel.cryptoValue.toString()) .arg(payPanel.value.toString())
.arg(payPanel.cryptoValueValid ? "true" : "false") .arg(payPanel.valueValid ? "true" : "false")
} }
Label { Label {
Layout.fillWidth: true Layout.fillWidth: true
font.weight: Font.Medium font.weight: Font.Medium
text: "<b>Receive:</b><ul><li>Symbol: %1<li>Amount: %2<li>Valid: %3" text: "<b>Receive:</b><ul><li>Symbol: %1<li>Amount: %2<li>Valid: %3"
.arg(receivePanel.selectedHoldingId || "N/A") .arg(receivePanel.selectedHoldingId || "N/A")
.arg(receivePanel.cryptoValue.toString()) .arg(receivePanel.value.toString())
.arg(receivePanel.cryptoValueValid ? "true" : "false") .arg(receivePanel.valueValid ? "true" : "false")
} }
Item { Layout.fillHeight: true } Item { Layout.fillHeight: true }

View File

@ -48,6 +48,7 @@ Item {
function test_buttonClick() { function test_buttonClick() {
verify(!!controlUnderTest) verify(!!controlUnderTest)
controlUnderTest.buttonText = "Buy crypto" controlUnderTest.buttonText = "Buy crypto"
controlUnderTest.buttonVisible = true
const button = findChild(controlUnderTest, "rightComponentButton") const button = findChild(controlUnderTest, "rightComponentButton")
verify(!!button) verify(!!button)
tryCompare(button, "visible", true) tryCompare(button, "visible", true)

View File

@ -2,6 +2,8 @@ import QtQuick 2.15
import QtTest 1.15 import QtTest 1.15
import StatusQ 0.1 import StatusQ 0.1
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import StatusQ.Core.Utils 0.1 import StatusQ.Core.Utils 0.1
import AppLayouts.Wallet.stores 1.0 import AppLayouts.Wallet.stores 1.0
@ -71,8 +73,8 @@ Item {
tryCompare(controlUnderTest, "swapSide", SwapInputPanel.SwapSide.Pay) tryCompare(controlUnderTest, "swapSide", SwapInputPanel.SwapSide.Pay)
tryCompare(controlUnderTest, "caption", qsTr("Pay")) tryCompare(controlUnderTest, "caption", qsTr("Pay"))
tryCompare(controlUnderTest, "selectedHoldingId", "") tryCompare(controlUnderTest, "selectedHoldingId", "")
tryCompare(controlUnderTest, "cryptoValue", 0) tryCompare(controlUnderTest, "value", 0)
tryCompare(controlUnderTest, "cryptoValueRaw", "0") tryCompare(controlUnderTest, "rawValue", "0")
} }
function test_basicSetupReceiveSide() { function test_basicSetupReceiveSide() {
@ -85,8 +87,8 @@ Item {
tryCompare(controlUnderTest, "swapSide", SwapInputPanel.SwapSide.Receive) tryCompare(controlUnderTest, "swapSide", SwapInputPanel.SwapSide.Receive)
tryCompare(controlUnderTest, "caption", qsTr("Receive")) tryCompare(controlUnderTest, "caption", qsTr("Receive"))
tryCompare(controlUnderTest, "selectedHoldingId", "") tryCompare(controlUnderTest, "selectedHoldingId", "")
tryCompare(controlUnderTest, "cryptoValue", 0) tryCompare(controlUnderTest, "value", 0)
tryCompare(controlUnderTest, "cryptoValueRaw", "0") tryCompare(controlUnderTest, "rawValue", "0")
} }
function test_basicSetupWithInitialProperties() { function test_basicSetupWithInitialProperties() {
@ -101,8 +103,8 @@ Item {
tryCompare(controlUnderTest, "swapSide", SwapInputPanel.SwapSide.Pay) tryCompare(controlUnderTest, "swapSide", SwapInputPanel.SwapSide.Pay)
tryCompare(controlUnderTest, "selectedHoldingId", "STT") tryCompare(controlUnderTest, "selectedHoldingId", "STT")
tryCompare(controlUnderTest, "cryptoValue", 10000000.0000001) tryCompare(controlUnderTest, "value", 10000000.0000001)
verify(controlUnderTest.cryptoValueValid) verify(controlUnderTest.valueValid)
} }
function test_setTokenKeyAndAmounts_data() { function test_setTokenKeyAndAmounts_data() {
@ -129,8 +131,8 @@ Item {
tryCompare(controlUnderTest, "selectedHoldingId", tokenSymbol) tryCompare(controlUnderTest, "selectedHoldingId", tokenSymbol)
if (!valid) if (!valid)
expectFail(data.tag, "Invalid data expected to fail: %1".arg(tokenAmount)) expectFail(data.tag, "Invalid data expected to fail: %1".arg(tokenAmount))
tryCompare(controlUnderTest, "cryptoValue", parseFloat(tokenAmount)) tryCompare(controlUnderTest, "value", parseFloat(tokenAmount))
tryCompare(controlUnderTest, "cryptoValueValid", true) tryCompare(controlUnderTest, "valueValid", true)
const holdingSelector = findChild(controlUnderTest, "holdingSelector") const holdingSelector = findChild(controlUnderTest, "holdingSelector")
verify(!!holdingSelector) verify(!!holdingSelector)
@ -167,8 +169,8 @@ Item {
keyClick(Qt.Key_2) keyClick(Qt.Key_2)
tryCompare(amountToSendInput.input, "text", "1000000,00000042") tryCompare(amountToSendInput.input, "text", "1000000,00000042")
tryCompare(controlUnderTest, "cryptoValue", 1000000.00000042) tryCompare(controlUnderTest, "value", 1000000.00000042)
verify(controlUnderTest.cryptoValueValid) verify(controlUnderTest.valueValid)
} }
function test_selectSTTHoldingAndTypeAmount() { function test_selectSTTHoldingAndTypeAmount() {
@ -201,8 +203,8 @@ Item {
keyClick(Qt.Key_4) keyClick(Qt.Key_4)
keyClick(Qt.Key_2) keyClick(Qt.Key_2)
tryCompare(controlUnderTest, "cryptoValue", 1.42) tryCompare(controlUnderTest, "value", 1.42)
verify(controlUnderTest.cryptoValueValid) verify(controlUnderTest.valueValid)
} }
// verify that when "fiatInputInteractive" mode is on, the Max send button text shows fiat currency symbol (e.g. "1.2 USD") // verify that when "fiatInputInteractive" mode is on, the Max send button text shows fiat currency symbol (e.g. "1.2 USD")
@ -217,6 +219,7 @@ Item {
waitForRendering(maxTagButton) waitForRendering(maxTagButton)
verify(maxTagButton.visible) verify(maxTagButton.visible)
verify(!maxTagButton.text.endsWith("ETH")) verify(!maxTagButton.text.endsWith("ETH"))
compare(maxTagButton.type, StatusBaseButton.Type.Normal)
mouseClick(maxTagButton) mouseClick(maxTagButton)
const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") const amountToSendInput = findChild(controlUnderTest, "amountToSendInput")
@ -242,6 +245,7 @@ Item {
verify(!!maxTagButton) verify(!!maxTagButton)
waitForRendering(maxTagButton) waitForRendering(maxTagButton)
verify(maxTagButton.visible) verify(maxTagButton.visible)
compare(maxTagButton.type, StatusBaseButton.Type.Normal)
verify(!maxTagButton.text.endsWith("ETH")) verify(!maxTagButton.text.endsWith("ETH"))
} }
@ -255,6 +259,7 @@ Item {
verify(!!maxTagButton) verify(!!maxTagButton)
waitForRendering(maxTagButton) waitForRendering(maxTagButton)
verify(maxTagButton.visible) verify(maxTagButton.visible)
compare(maxTagButton.type, StatusBaseButton.Type.Normal)
mouseClick(maxTagButton) mouseClick(maxTagButton)
const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") const amountToSendInput = findChild(controlUnderTest, "amountToSendInput")
@ -263,15 +268,16 @@ Item {
const maxValue = amountToSendInput.maxInputBalance const maxValue = amountToSendInput.maxInputBalance
tryCompare(amountToSendInput.input, "text", maxValue.toLocaleString(Qt.locale(), 'f', -128)) tryCompare(amountToSendInput.input, "text", maxValue.toLocaleString(Qt.locale(), 'f', -128))
tryCompare(controlUnderTest, "cryptoValue", maxValue) tryCompare(controlUnderTest, "value", maxValue)
verify(controlUnderTest.cryptoValueValid) verify(controlUnderTest.valueValid)
} }
function test_loadingState() { function test_loadingState() {
controlUnderTest = createTemporaryObject(componentUnderTest, root) controlUnderTest = createTemporaryObject(componentUnderTest, root)
verify(!!controlUnderTest) verify(!!controlUnderTest)
controlUnderTest.loading = true controlUnderTest.mainInputLoading = true
controlUnderTest.bottomTextLoading = true
const amountToSendInput = findChild(controlUnderTest, "amountToSendInput") const amountToSendInput = findChild(controlUnderTest, "amountToSendInput")
verify(!!amountToSendInput) verify(!!amountToSendInput)
@ -292,5 +298,160 @@ Item {
verify(!!bottomItemTextLoadingComponent) verify(!!bottomItemTextLoadingComponent)
verify(bottomItemTextLoadingComponent.visible) verify(bottomItemTextLoadingComponent.visible)
} }
function test_max_button_when_different_tokens_clicked() {
controlUnderTest = createTemporaryObject(componentUnderTest, root)
verify(!!controlUnderTest)
controlUnderTest.mainInputLoading = true
controlUnderTest.bottomTextLoading = true
const maxTagButton = findChild(controlUnderTest, "maxTagButton")
verify(!!maxTagButton)
verify(!maxTagButton.visible)
const holdingSelector = findChild(controlUnderTest, "holdingSelector")
verify(!!holdingSelector)
const assetSelectorList = findChild(holdingSelector, "assetSelectorList")
verify(!!assetSelectorList)
const assetSelectorButton = findChild(controlUnderTest, "assetSelectorButton")
verify(!!assetSelectorButton)
const amountToSendInput = findChild(controlUnderTest, "amountToSendInput")
verify(!!amountToSendInput)
const bottomItemText = findChild(amountToSendInput, "bottomItemText")
verify(!!bottomItemText)
for (let i= 0; i < d.adaptor.processedAssetsModel.count; i++) {
let modelItemToTest = ModelUtils.get(d.adaptor.processedAssetsModel, i)
mouseClick(assetSelectorButton)
waitForRendering(assetSelectorList)
let delToTest = assetSelectorList.itemAtIndex(i)
verify(!!delToTest)
mouseClick(delToTest, 40, 40) // center might be covered by tags
waitForRendering(maxTagButton)
verify(maxTagButton.visible)
verify(!maxTagButton.text.endsWith(modelItemToTest.symbol))
compare(maxTagButton.type, modelItemToTest.currentBalance === 0 ? StatusBaseButton.Type.Danger : StatusBaseButton.Type.Normal)
// check input value and state
mouseClick(maxTagButton)
waitForRendering(amountToSendInput)
compare(amountToSendInput.input.text, modelItemToTest.currentBalance === 0 ? "" : maxTagButton.maxSafeValueAsString)
compare(controlUnderTest.value, maxTagButton.maxSafeValue)
verify(modelItemToTest.currentBalance === 0 ? !controlUnderTest.valueValid : controlUnderTest.valueValid)
compare(bottomItemText.text, d.adaptor.formatCurrencyAmount(
maxTagButton.maxSafeValue * amountToSendInput.selectedHolding.marketDetails.currencyPrice.amount,
d.adaptor.currencyStore.currentCurrency))
}
}
function test_input_greater_than_max_balance() {
controlUnderTest = createTemporaryObject(componentUnderTest, root)
verify(!!controlUnderTest)
controlUnderTest.mainInputLoading = true
controlUnderTest.bottomTextLoading = true
const maxTagButton = findChild(controlUnderTest, "maxTagButton")
verify(!!maxTagButton)
verify(!maxTagButton.visible)
const holdingSelector = findChild(controlUnderTest, "holdingSelector")
verify(!!holdingSelector)
const assetSelectorList = findChild(holdingSelector, "assetSelectorList")
verify(!!assetSelectorList)
const assetSelectorButton = findChild(controlUnderTest, "assetSelectorButton")
verify(!!assetSelectorButton)
const amountToSendInput = findChild(controlUnderTest, "amountToSendInput")
verify(!!amountToSendInput)
const bottomItemText = findChild(amountToSendInput, "bottomItemText")
verify(!!bottomItemText)
// 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")
for (let i= 0; i < d.adaptor.processedAssetsModel.count; i++) {
let modelItemToTest = ModelUtils.get(d.adaptor.processedAssetsModel, i)
mouseClick(assetSelectorButton)
waitForRendering(assetSelectorList)
let delToTest = assetSelectorList.itemAtIndex(i)
verify(!!delToTest)
mouseClick(delToTest, 40, 40) // center might be covered by tags
// check input value and state
waitForRendering(amountToSendInput)
compare(amountToSendInput.input.text, "5.42")
compare(bottomItemText.text, d.adaptor.formatCurrencyAmount(
numberTested * amountToSendInput.selectedHolding.marketDetails.currencyPrice.amount,
d.adaptor.currencyStore.currentCurrency))
compare(controlUnderTest.value, numberTested)
compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.input.text, modelItemToTest.decimals).toString())
compare(controlUnderTest.valueValid, numberTested <= maxTagButton.maxSafeValue)
compare(controlUnderTest.selectedHoldingId, modelItemToTest.tokensKey)
compare(controlUnderTest.amountEnteredGreaterThanBalance, numberTested > maxTagButton.maxSafeValue)
}
}
function test_if_values_are_reset_after_setting_tokenAmount_as_empty() {
const tokenKeyToTest = "ETH"
let numberTestedString = "1.0001"
let modelItemToTest = ModelUtils.getByKey(d.adaptor.processedAssetsModel, "tokensKey", tokenKeyToTest)
controlUnderTest = createTemporaryObject(componentUnderTest, root, {
swapSide: SwapInputPanel.SwapSide.Pay,
tokenKey: tokenKeyToTest,
tokenAmount: numberTestedString
})
verify(!!controlUnderTest)
waitForRendering(controlUnderTest)
const amountToSendInput = findChild(controlUnderTest, "amountToSendInput")
verify(!!amountToSendInput)
const bottomItemText = findChild(amountToSendInput, "bottomItemText")
verify(!!bottomItemText)
let numberTested = LocaleUtils.numberFromLocaleString(numberTestedString, amountToSendInput.input.locale)
compare(amountToSendInput.input.text, numberTestedString)
compare(controlUnderTest.value, numberTested)
compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(amountToSendInput.input.text, modelItemToTest.decimals).toString())
compare(controlUnderTest.valueValid, true)
compare(controlUnderTest.selectedHoldingId, tokenKeyToTest)
compare(controlUnderTest.amountEnteredGreaterThanBalance, false)
numberTestedString = ""
numberTested = 0
mouseClick(amountToSendInput)
controlUnderTest.tokenAmount = numberTestedString
waitForRendering(amountToSendInput)
compare(amountToSendInput.input.text, numberTestedString)
compare(controlUnderTest.value, numberTested)
compare(controlUnderTest.rawValue, AmountsArithmetic.fromNumber(numberTested, modelItemToTest.decimals).toString())
compare(controlUnderTest.valueValid, false)
compare(controlUnderTest.selectedHoldingId, tokenKeyToTest)
compare(controlUnderTest.amountEnteredGreaterThanBalance, false)
}
} }
} }

View File

@ -120,19 +120,18 @@ Item {
compare(root.swapAdaptor.swapOutputData.hasError, false) compare(root.swapAdaptor.swapOutputData.hasError, false)
// verfy input and output panels // verfy input and output panels
verify(!payPanel.loading) verify(!payPanel.mainInputLoading)
verify(!payPanel.bottomTextLoading)
compare(payPanel.selectedHoldingId, root.swapFormData.fromTokensKey) compare(payPanel.selectedHoldingId, root.swapFormData.fromTokensKey)
compare(payPanel.cryptoValue, Number(root.swapFormData.fromTokenAmount)) compare(payPanel.value, Number(root.swapFormData.fromTokenAmount))
compare(payPanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber(root.swapFormData.fromTokenAmount, root.swapAdaptor.fromToken.decimals).toString()) compare(payPanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(root.swapFormData.fromTokenAmount, root.swapAdaptor.fromToken.decimals).toString())
verify(payPanel.cryptoValueValid) verify(payPanel.valueValid)
verify(receivePanel.loading) verify(receivePanel.mainInputLoading)
verify(receivePanel.bottomTextLoading)
verify(!receivePanel.interactive) verify(!receivePanel.interactive)
compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey) compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey)
/* TODO: there is bug which prevents us from testing this right now compare(receivePanel.value, 0)
The value is not updated after setting tokenAmount to empty string in the receive input panel compare(receivePanel.rawValue, "0")
https://github.com/status-im/status-desktop/issues/15162
compare(receivePanel.cryptoValue, 0)
compare(receivePanel.cryptoValueRaw, "0") */
} }
// end helper functions ------------------------------------------------------------- // end helper functions -------------------------------------------------------------
@ -554,12 +553,14 @@ Item {
compare(signButton.text, qsTr("Swap")) compare(signButton.text, qsTr("Swap"))
// verfy input and output panels // verfy input and output panels
verify(!payPanel.loading) verify(!payPanel.mainInputLoading)
verify(!receivePanel.loading) verify(!payPanel.bottomTextLoading)
verify(!receivePanel.mainInputLoading)
verify(!receivePanel.bottomTextLoading)
verify(!receivePanel.interactive) verify(!receivePanel.interactive)
compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey) compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey)
compare(receivePanel.cryptoValue, 0) compare(receivePanel.value, 0)
compare(receivePanel.cryptoValueRaw, "0") compare(receivePanel.rawValue, "0")
// edit some params to retry swap // edit some params to retry swap
root.swapFormData.fromTokenAmount = "0.00011" root.swapFormData.fromTokenAmount = "0.00011"
@ -596,12 +597,13 @@ Item {
// verfy input and output panels // verfy input and output panels
waitForRendering(receivePanel) waitForRendering(receivePanel)
verify(payPanel.cryptoValueValid) verify(payPanel.valueValid)
verify(!receivePanel.loading) verify(!receivePanel.mainInputLoading)
verify(!receivePanel.bottomTextLoading)
verify(!receivePanel.interactive) verify(!receivePanel.interactive)
compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey) compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey)
compare(receivePanel.cryptoValue, root.swapStore.getWei2Eth(txRoutes.amountToReceive, root.swapAdaptor.toToken.decimals)) compare(receivePanel.value, root.swapStore.getWei2Eth(txRoutes.amountToReceive, root.swapAdaptor.toToken.decimals))
compare(receivePanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber(root.swapAdaptor.swapOutputData.toTokenAmount, root.swapAdaptor.toToken.decimals).toString()) compare(receivePanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(root.swapAdaptor.swapOutputData.toTokenAmount, root.swapAdaptor.toToken.decimals).toString())
// edit some params to retry swap // edit some params to retry swap
root.swapFormData.fromTokenAmount = "0.012" root.swapFormData.fromTokenAmount = "0.012"
@ -638,12 +640,13 @@ Item {
// verfy input and output panels // verfy input and output panels
waitForRendering(receivePanel) waitForRendering(receivePanel)
verify(payPanel.cryptoValueValid) verify(payPanel.valueValid)
verify(!receivePanel.loading) verify(!receivePanel.mainInputLoading)
verify(!receivePanel.bottomTextLoading)
verify(!receivePanel.interactive) verify(!receivePanel.interactive)
compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey) compare(receivePanel.selectedHoldingId, root.swapFormData.toTokenKey)
compare(receivePanel.cryptoValue, root.swapStore.getWei2Eth(txRoutes.amountToReceive, root.swapAdaptor.toToken.decimals)) compare(receivePanel.value, root.swapStore.getWei2Eth(txRoutes.amountToReceive, root.swapAdaptor.toToken.decimals))
compare(receivePanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber(root.swapAdaptor.swapOutputData.toTokenAmount, root.swapAdaptor.toToken.decimals).toString()) compare(receivePanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(root.swapAdaptor.swapOutputData.toTokenAmount, root.swapAdaptor.toToken.decimals).toString())
} }
function test_modal_pay_input_default() { function test_modal_pay_input_default() {
@ -680,9 +683,9 @@ Item {
verify(!holdingSelectorsTokenIcon.visible) verify(!holdingSelectorsTokenIcon.visible)
verify(!maxTagButton.visible) verify(!maxTagButton.visible)
compare(payPanel.selectedHoldingId, "") compare(payPanel.selectedHoldingId, "")
compare(payPanel.cryptoValue, 0) compare(payPanel.value, 0)
compare(payPanel.cryptoValueRaw, "0") compare(payPanel.rawValue, "0")
verify(!payPanel.cryptoValueValid) verify(!payPanel.valueValid)
closeAndVerfyModal() closeAndVerfyModal()
} }
@ -731,9 +734,9 @@ Item {
verify(maxTagButton.visible) verify(maxTagButton.visible)
compare(maxTagButton.text, qsTr("Max. %1").arg(root.swapAdaptor.currencyStore.formatCurrencyAmount(Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100, expectedToken.symbol, {noSymbol: true}))) compare(maxTagButton.text, qsTr("Max. %1").arg(root.swapAdaptor.currencyStore.formatCurrencyAmount(Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100, expectedToken.symbol, {noSymbol: true})))
compare(payPanel.selectedHoldingId, expectedToken.symbol) compare(payPanel.selectedHoldingId, expectedToken.symbol)
compare(payPanel.cryptoValue, valueToExchange) compare(payPanel.value, valueToExchange)
compare(payPanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString()) compare(payPanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString())
verify(payPanel.cryptoValueValid) verify(payPanel.valueValid)
closeAndVerfyModal() closeAndVerfyModal()
} }
@ -778,9 +781,9 @@ Item {
verify(!holdingSelectorsTokenIcon.visible) verify(!holdingSelectorsTokenIcon.visible)
verify(!maxTagButton.visible) verify(!maxTagButton.visible)
compare(payPanel.selectedHoldingId, invalidValue) compare(payPanel.selectedHoldingId, invalidValue)
compare(payPanel.cryptoValue, 0) compare(payPanel.value, 0)
compare(payPanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber("0", 0).toString()) compare(payPanel.rawValue, SQUtils.AmountsArithmetic.fromNumber("0", 0).toString())
verify(!payPanel.cryptoValueValid) verify(!payPanel.valueValid)
closeAndVerfyModal() closeAndVerfyModal()
} }
@ -822,7 +825,7 @@ Item {
compare(amountToSendInput.input.text, valueToExchangeString) compare(amountToSendInput.input.text, valueToExchangeString)
compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0)) compare(amountToSendInput.input.placeholderText, LocaleUtils.numberToLocaleString(0))
verify(amountToSendInput.input.input.edit.cursorVisible) verify(amountToSendInput.input.input.edit.cursorVisible)
compare(bottomItemText.text, root.swapAdaptor.currencyStore.formatCurrencyAmount(0 * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency)) compare(bottomItemText.text, root.swapAdaptor.currencyStore.formatCurrencyAmount(valueToExchange * expectedToken.marketDetails.currencyPrice.amount, root.swapAdaptor.currencyStore.currentCurrency))
compare(holdingSelector.selectedItem, expectedToken) compare(holdingSelector.selectedItem, expectedToken)
compare(holdingSelectorsContentItemText.text, expectedToken.symbol) compare(holdingSelectorsContentItemText.text, expectedToken.symbol)
compare(holdingSelectorsTokenIcon.image.source, Constants.tokenIcon(expectedToken.symbol)) compare(holdingSelectorsTokenIcon.image.source, Constants.tokenIcon(expectedToken.symbol))
@ -830,9 +833,9 @@ Item {
verify(maxTagButton.visible) verify(maxTagButton.visible)
compare(maxTagButton.text, qsTr("Max. %1").arg(root.swapAdaptor.currencyStore.formatCurrencyAmount(Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100, expectedToken.symbol, {noSymbol: true}))) compare(maxTagButton.text, qsTr("Max. %1").arg(root.swapAdaptor.currencyStore.formatCurrencyAmount(Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100, expectedToken.symbol, {noSymbol: true})))
compare(payPanel.selectedHoldingId, expectedToken.symbol) compare(payPanel.selectedHoldingId, expectedToken.symbol)
compare(payPanel.cryptoValue, 0) compare(payPanel.value, valueToExchange)
compare(payPanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber("0", expectedToken.decimals).toString()) compare(payPanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString())
verify(!payPanel.cryptoValueValid) verify(!payPanel.valueValid)
closeAndVerfyModal() closeAndVerfyModal()
} }
@ -864,12 +867,9 @@ Item {
let maxPossibleValue = Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100 let maxPossibleValue = Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100
compare(maxTagButton.text, qsTr("Max. %1").arg(root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue, expectedToken.symbol, {noSymbol: true}))) compare(maxTagButton.text, qsTr("Max. %1").arg(root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue, expectedToken.symbol, {noSymbol: true})))
compare(payPanel.selectedHoldingId, expectedToken.symbol) compare(payPanel.selectedHoldingId, expectedToken.symbol)
compare(payPanel.cryptoValueValid, valueToExchange <= maxPossibleValue) compare(payPanel.valueValid, valueToExchange <= maxPossibleValue)
/* TODO: there is bug which prevents us from testing this right now compare(payPanel.value, valueToExchange)
When value entered is greater than balance then fiat and crytpo values are not calculated compare(payPanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString())
https://github.com/status-im/status-desktop/issues/15162
compare(payPanel.cryptoValue, valueToExchange)
compare(payPanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString()) */
} }
closeAndVerfyModal() closeAndVerfyModal()
@ -904,9 +904,9 @@ Item {
compare(holdingSelectorsContentItemText.text, qsTr("Select asset")) compare(holdingSelectorsContentItemText.text, qsTr("Select asset"))
verify(!maxTagButton.visible) verify(!maxTagButton.visible)
compare(receivePanel.selectedHoldingId, "") compare(receivePanel.selectedHoldingId, "")
compare(receivePanel.cryptoValue, 0) compare(receivePanel.value, 0)
compare(receivePanel.cryptoValueRaw, "0") compare(receivePanel.rawValue, "0")
verify(!receivePanel.cryptoValueValid) verify(!receivePanel.valueValid)
closeAndVerfyModal() closeAndVerfyModal()
} }
@ -955,9 +955,9 @@ Item {
verify(holdingSelectorsTokenIcon.visible) verify(holdingSelectorsTokenIcon.visible)
verify(!maxTagButton.visible) verify(!maxTagButton.visible)
compare(receivePanel.selectedHoldingId, expectedToken.symbol) compare(receivePanel.selectedHoldingId, expectedToken.symbol)
compare(receivePanel.cryptoValue, valueToReceive) compare(receivePanel.value, valueToReceive)
compare(receivePanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber(valueToReceiveString, expectedToken.decimals).toString()) compare(receivePanel.rawValue, SQUtils.AmountsArithmetic.fromNumber(valueToReceiveString, expectedToken.decimals).toString())
verify(receivePanel.cryptoValueValid) verify(receivePanel.valueValid)
closeAndVerfyModal() closeAndVerfyModal()
} }
@ -1104,24 +1104,18 @@ Item {
let maxPossibleValue = Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100 let maxPossibleValue = Math.trunc(WalletUtils.calculateMaxSafeSendAmount(expectedToken.currentBalance, expectedToken.symbol)*100)/100
compare(maxTagButton.text, qsTr("Max. %1").arg(maxPossibleValue === 0 ? Qt.locale().zeroDigit : root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue, expectedToken.symbol, {noSymbol: true, minDecimals: 0}))) compare(maxTagButton.text, qsTr("Max. %1").arg(maxPossibleValue === 0 ? Qt.locale().zeroDigit : root.swapAdaptor.currencyStore.formatCurrencyAmount(maxPossibleValue, expectedToken.symbol, {noSymbol: true, minDecimals: 0})))
compare(payPanel.selectedHoldingId, expectedToken.symbol) compare(payPanel.selectedHoldingId, expectedToken.symbol)
/* TODO bug in max button not shown in red when max is 0 value and compare(payPanel.valueValid, !!root.swapFormData.fromTokenAmount && valueToExchange <= maxPossibleValue)
bug in swapInputModal that in case value entered is greater than maxPossibleValue then value is reset to 0, making the cryptoValueValid to false
https://github.com/status-im/status-desktop/issues/15162 */
compare(payPanel.cryptoValueValid, (valueToExchangeString === amountToSendInput.input.text) && !!root.swapFormData.fromTokenAmount && valueToExchange <= maxPossibleValue)
/* TODO: there is bug which prevents us from testing this right now compare(payPanel.value, valueToExchange)
The value is not updated after setting tokenAmount to empty string in the receive input panel compare(payPanel.rawValue, !!valueToExchangeString ? SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString(): "0")
https://github.com/status-im/status-desktop/issues/15162
compare(payPanel.cryptoValue, valueToExchange)
compare(payPanel.cryptoValueRaw, SQUtils.AmountsArithmetic.fromNumber(valueToExchangeString, expectedToken.decimals).toString())*/
/* TODO: check if tag is visible in case amount entered to exchange is greater than max balance to send // check if tag is visible in case amount entered to exchange is greater than max balance to send
https://github.com/status-im/status-desktop/issues/15162 */ let amountEnteredGreaterThanMaxBalance = valueToExchange > maxPossibleValue
let errortext = /*valueToExchange > maxPossibleValue ? qsTr("Insufficient funds for swap"): */qsTr("An error has occured, please try again") let errortext = amountEnteredGreaterThanMaxBalance ? qsTr("Insufficient funds for swap"): qsTr("An error has occured, please try again")
let buttonText = /*valueToExchange > maxPossibleValue ? qsTr("Buy crypto"):*/ "" compare(errorTag.visible, amountEnteredGreaterThanMaxBalance)
compare(errorTag.visible, false/*valueToExchange > maxPossibleValue*/)
compare(errorTag.text, errortext) compare(errorTag.text, errortext)
compare(errorTag.buttonText, buttonText) compare(errorTag.buttonText, qsTr("Buy crypto"))
compare(errorTag.buttonVisible, amountEnteredGreaterThanMaxBalance)
} }
closeAndVerfyModal() closeAndVerfyModal()

View File

@ -32,23 +32,21 @@ Control {
onTokenKeyChanged: reevaluateSelectedId() onTokenKeyChanged: reevaluateSelectedId()
property string tokenAmount property string tokenAmount
onTokenAmountChanged: { onTokenAmountChanged: {
if (!!tokenAmount) Qt.callLater(() => amountToSendInput.input.text = !!tokenAmount ? SQUtils.AmountsArithmetic.fromString(tokenAmount).toLocaleString(locale, 'f', -128): "")
Qt.callLater(() => amountToSendInput.input.text = SQUtils.AmountsArithmetic.fromString(tokenAmount).toLocaleString(locale, 'f', -128))
} }
property int swapSide: SwapInputPanel.SwapSide.Pay property int swapSide: SwapInputPanel.SwapSide.Pay
property bool fiatInputInteractive property bool fiatInputInteractive
property bool loading property bool mainInputLoading
property bool bottomTextLoading
property bool interactive: true property bool interactive: true
// output API // output API
readonly property string selectedHoldingId: d.selectedHoldingId readonly property string selectedHoldingId: d.selectedHoldingId
readonly property double cryptoValue: amountToSendInput.cryptoValueToSendFloat readonly property double value: amountToSendInput.cryptoValueToSendFloat
readonly property string cryptoValueRaw: amountToSendInput.cryptoValueToSend readonly property string rawValue: amountToSendInput.cryptoValueToSend
readonly property bool cryptoValueValid: amountToSendInput.inputNumberValid readonly property bool valueValid: amountToSendInput.inputNumberValid
/* TODO: this does not work as expected because of bug - readonly property bool amountEnteredGreaterThanBalance: value > maxSendButton.maxSafeValue
https://github.com/status-im/status-desktop/issues/15162 */
readonly property bool amountEnteredGreaterThanBalance: cryptoValue > maxSendButton.maxSafeValue
function reevaluateSelectedId() { function reevaluateSelectedId() {
if (!!tokenKey) { if (!!tokenKey) {
Qt.callLater(d.setSelectedHoldingId, tokenKey, Constants.TokenType.ERC20) Qt.callLater(d.setSelectedHoldingId, tokenKey, Constants.TokenType.ERC20)
@ -205,7 +203,8 @@ Control {
: maxSendButton.maxSafeValue : maxSendButton.maxSafeValue
currentCurrency: root.currencyStore.currentCurrency currentCurrency: root.currencyStore.currentCurrency
formatCurrencyAmount: root.currencyStore.formatCurrencyAmount formatCurrencyAmount: root.currencyStore.formatCurrencyAmount
loading: root.loading mainInputLoading: root.mainInputLoading
bottomTextLoading: root.bottomTextLoading
} }
} }
ColumnLayout { ColumnLayout {
@ -256,7 +255,7 @@ Control {
value: d.maxInputBalance value: d.maxInputBalance
symbol: d.inputSymbol symbol: d.inputSymbol
valid: amountToSendInput.input.valid || !amountToSendInput.input.text valid: (amountToSendInput.input.valid || !amountToSendInput.input.text) && value > 0
formatCurrencyAmount: (amount, symbol) => root.currencyStore.formatCurrencyAmount(amount, symbol, {noSymbol: !amountToSendInput.inputIsFiat}) formatCurrencyAmount: (amount, symbol) => root.currencyStore.formatCurrencyAmount(amount, symbol, {noSymbol: !amountToSendInput.inputIsFiat})
visible: d.isSelectedHoldingValidAsset && root.swapSide === SwapInputPanel.SwapSide.Pay visible: d.isSelectedHoldingValidAsset && root.swapSide === SwapInputPanel.SwapSide.Pay

View File

@ -37,15 +37,17 @@ StatusDialog {
QtObject { QtObject {
id: d id: d
property var debounceFetchSuggestedRoutes: Backpressure.debounce(root, 1000, function() { property var debounceFetchSuggestedRoutes: Backpressure.debounce(root, 1000, function() {
root.swapAdaptor.fetchSuggestedRoutes(payPanel.cryptoValueRaw) root.swapAdaptor.fetchSuggestedRoutes(payPanel.rawValue)
}) })
function fetchSuggestedRoutes() { function fetchSuggestedRoutes() {
if (payPanel.valueValid) {
root.swapAdaptor.newFetchReset() root.swapAdaptor.newFetchReset()
root.swapAdaptor.swapProposalLoading = true root.swapAdaptor.swapProposalLoading = true
debounceFetchSuggestedRoutes() debounceFetchSuggestedRoutes()
} }
} }
}
Connections { Connections {
target: root.swapInputParamsForm target: root.swapInputParamsForm
@ -151,7 +153,7 @@ StatusDialog {
tokenAmount: { tokenAmount: {
// Only update if there is different in amount displayed // Only update if there is different in amount displayed
if (root.swapInputParamsForm.fromTokenAmount !== if (root.swapInputParamsForm.fromTokenAmount !==
SQUtils.AmountsArithmetic.fromString(cryptoValue).toLocaleString(locale, 'f', -128)){ SQUtils.AmountsArithmetic.fromString(value).toLocaleString(locale, 'f', -128)){
return root.swapInputParamsForm.fromTokenAmount return root.swapInputParamsForm.fromTokenAmount
} }
return payPanel.tokenAmount return payPanel.tokenAmount
@ -161,7 +163,8 @@ StatusDialog {
swapExchangeButtonWidth: swapButton.width swapExchangeButtonWidth: swapButton.width
onSelectedHoldingIdChanged: root.swapInputParamsForm.fromTokensKey = selectedHoldingId onSelectedHoldingIdChanged: root.swapInputParamsForm.fromTokensKey = selectedHoldingId
onCryptoValueChanged: root.swapInputParamsForm.fromTokenAmount = cryptoValue.toLocaleString(locale, 'f', -128) onValueChanged: root.swapInputParamsForm.fromTokenAmount = value.toLocaleString(locale, 'f', -128)
onValueValidChanged: d.fetchSuggestedRoutes()
} }
SwapInputPanel { SwapInputPanel {
@ -184,7 +187,8 @@ StatusDialog {
swapSide: SwapInputPanel.SwapSide.Receive swapSide: SwapInputPanel.SwapSide.Receive
swapExchangeButtonWidth: swapButton.width swapExchangeButtonWidth: swapButton.width
loading: root.swapAdaptor.swapProposalLoading mainInputLoading: root.swapAdaptor.swapProposalLoading
bottomTextLoading: root.swapAdaptor.swapProposalLoading
onSelectedHoldingIdChanged: root.swapInputParamsForm.toTokenKey = selectedHoldingId onSelectedHoldingIdChanged: root.swapInputParamsForm.toTokenKey = selectedHoldingId
@ -236,7 +240,8 @@ StatusDialog {
} }
return qsTr("An error has occured, please try again") return qsTr("An error has occured, please try again")
} }
buttonText: payPanel.amountEnteredGreaterThanBalance ? qsTr("Buy crypto"): "" buttonText: qsTr("Buy crypto")
buttonVisible: payPanel.amountEnteredGreaterThanBalance
onButtonClicked: Global.openBuyCryptoModalRequested() onButtonClicked: Global.openBuyCryptoModalRequested()
} }
} }

View File

@ -13,6 +13,7 @@ InformationTag {
property string text property string text
property string buttonText property string buttonText
property bool buttonVisible
signal buttonClicked() signal buttonClicked()
@ -54,7 +55,7 @@ InformationTag {
horizontalPadding: 8 horizontalPadding: 8
width: visible || root.loading ? implicitWidth : 0 width: visible || root.loading ? implicitWidth : 0
visible: !!text visible: root.buttonVisible
size: StatusBaseButton.Size.Tiny size: StatusBaseButton.Size.Tiny
font.pixelSize: priv.fontPixelSize font.pixelSize: priv.fontPixelSize

View File

@ -51,7 +51,8 @@ ColumnLayout {
property var formatCurrencyAmount: property var formatCurrencyAmount:
(amount, symbol, options = null, locale = null) => {} (amount, symbol, options = null, locale = null) => {}
property bool loading property bool mainInputLoading
property bool bottomTextLoading
signal reCalculateSuggestedRoute() signal reCalculateSuggestedRoute()
@ -88,9 +89,6 @@ ColumnLayout {
readonly property string selectedSymbol: !!root.selectedHolding && !!root.selectedHolding.symbol ? root.selectedHolding.symbol: "" readonly property string selectedSymbol: !!root.selectedHolding && !!root.selectedHolding.symbol ? root.selectedHolding.symbol: ""
readonly property string cryptoValueRawToSend: { readonly property string cryptoValueRawToSend: {
if (!root.inputNumberValid)
return "0"
return SQUtils.AmountsArithmetic.fromNumber( return SQUtils.AmountsArithmetic.fromNumber(
d.cryptoValueToSend, root.multiplierIndex).toString() d.cryptoValueToSend, root.multiplierIndex).toString()
} }
@ -106,7 +104,8 @@ ColumnLayout {
topAmountToSendInput.locale) topAmountToSendInput.locale)
readonly property double inputNumber: readonly property double inputNumber:
root.inputNumberValid ? d.parsedInput : 0 // we should still calculate if value entered is greater than max safe value
!!input.text && !isNaN(d.parsedInput) && d.parsedInput >= 0 ? d.parsedInput : 0
readonly property Timer waitTimer: Timer { readonly property Timer waitTimer: Timer {
interval: 1000 interval: 1000
@ -146,15 +145,9 @@ ColumnLayout {
errorMessage: "" errorMessage: ""
validate: (text) => { validate: (text) => {
var num = 0 var num = LocaleUtils.numberFromLocaleString(topAmountToSendInput.text,
try { topAmountToSendInput.locale)
num = Number.fromLocaleString(topAmountToSendInput.locale, text) return !isNaN(num) && num > 0 && num <= root.maxInputBalance
} catch (e) {
console.warn(e, "(Error parsing number from text: %1)".arg(text))
return false
}
return num > 0 && num <= root.maxInputBalance
} }
} }
] ]
@ -173,13 +166,13 @@ ColumnLayout {
d.waitTimer.restart() d.waitTimer.restart()
} }
visible: !root.loading visible: !root.mainInputLoading
} }
LoadingComponent { LoadingComponent {
objectName: "topAmountToSendInputLoadingComponent" objectName: "topAmountToSendInputLoadingComponent"
Layout.preferredWidth: topAmountToSendInput.width Layout.preferredWidth: topAmountToSendInput.width
Layout.preferredHeight: topAmountToSendInput.height Layout.preferredHeight: topAmountToSendInput.height
visible: root.loading visible: root.mainInputLoading
} }
} }
@ -215,13 +208,13 @@ ColumnLayout {
d.waitTimer.restart() d.waitTimer.restart()
} }
} }
visible: !root.loading visible: !root.bottomTextLoading
} }
LoadingComponent { LoadingComponent {
objectName: "bottomItemTextLoadingComponent" objectName: "bottomItemTextLoadingComponent"
Layout.preferredWidth: bottomItem.width Layout.preferredWidth: bottomItem.width
Layout.preferredHeight: bottomItem.height Layout.preferredHeight: bottomItem.height
visible: root.loading visible: root.bottomTextLoading
} }
} }