diff --git a/src/app/modules/main/wallet_section/buy_sell_crypto/item.nim b/src/app/modules/main/wallet_section/buy_sell_crypto/item.nim index 22c40f4179..b4db2cc3d2 100644 --- a/src/app/modules/main/wallet_section/buy_sell_crypto/item.nim +++ b/src/app/modules/main/wallet_section/buy_sell_crypto/item.nim @@ -7,15 +7,17 @@ type Item* = object logoUrl: string siteUrl: string hostname: string + recurrentSiteUrl: string proc initItem*(name, description, fees, logoUrl, siteUrl, - hostname: string): Item = + hostname, recurrentSiteUrl,: string): Item = result.name = name result.description = description result.fees = fees result.logoUrl = logoUrl result.siteUrl = siteUrl result.hostname = hostname + result.recurrentSiteUrl = recurrentSiteUrl proc `$`*(self: Item): string = result = "Item(" @@ -25,6 +27,7 @@ proc `$`*(self: Item): string = result &= fmt"logoUrl:{self.logoUrl}, " result &= fmt"siteUrl:{self.siteUrl}" result &= fmt"hostname:{self.hostname}" + result &= fmt"recurrentSiteUrl:{self.recurrentSiteUrl}" result &= ")" method getName*(self: Item): string {.base.} = @@ -44,3 +47,6 @@ method getSiteUrl*(self: Item): string {.base.} = method getHostname*(self: Item): string {.base.} = return self.hostname + +method getRecurrentSiteUrl*(self: Item): string {.base.} = + return self.recurrentSiteUrl diff --git a/src/app/modules/main/wallet_section/buy_sell_crypto/model.nim b/src/app/modules/main/wallet_section/buy_sell_crypto/model.nim index 479b0638e3..eab88511d3 100644 --- a/src/app/modules/main/wallet_section/buy_sell_crypto/model.nim +++ b/src/app/modules/main/wallet_section/buy_sell_crypto/model.nim @@ -10,6 +10,7 @@ type LogoUrl SiteUrl Hostname + RecurrentSiteUrl QtObject: type @@ -36,7 +37,8 @@ QtObject: ModelRole.Fees.int:"fees", ModelRole.LogoUrl.int:"logoUrl", ModelRole.SiteUrl.int:"siteUrl", - ModelRole.Hostname.int:"hostname" + ModelRole.Hostname.int:"hostname", + ModelRole.RecurrentSiteUrl.int:"recurrentSiteUrl" }.toTable method data(self: Model, index: QModelIndex, role: int): QVariant = @@ -62,6 +64,8 @@ QtObject: result = newQVariant(item.getSiteUrl) of ModelRole.Hostname: result = newQVariant(item.getHostname) + of ModelRole.RecurrentSiteUrl: + result = newQVariant(item.getRecurrentSiteUrl) proc setItems*(self: Model, items: seq[Item]) = self.beginResetModel() diff --git a/src/app/modules/main/wallet_section/buy_sell_crypto/module.nim b/src/app/modules/main/wallet_section/buy_sell_crypto/module.nim index 5d9751774e..b141828479 100644 --- a/src/app/modules/main/wallet_section/buy_sell_crypto/module.nim +++ b/src/app/modules/main/wallet_section/buy_sell_crypto/module.nim @@ -40,7 +40,8 @@ method updateCryptoServices*(self: Module, cryptoServices: seq[CryptoRampDto]) = w.fees, w.logoUrl, w.siteUrl, - w.hostname + w.hostname, + w.recurrentSiteUrl, )) self.view.setItems(items) diff --git a/src/app_service/service/transaction/cryptoRampDto.nim b/src/app_service/service/transaction/cryptoRampDto.nim index 823a565bbd..caa52159ca 100644 --- a/src/app_service/service/transaction/cryptoRampDto.nim +++ b/src/app_service/service/transaction/cryptoRampDto.nim @@ -10,6 +10,7 @@ type logoUrl*: string siteUrl*: string hostname*: string + recurrentSiteUrl*: string proc newDto*( name: string, @@ -17,7 +18,8 @@ proc newDto*( fees: string, logoUrl: string, siteUrl: string, - hostname: string + hostname: string, + recurrentSiteUrl: string ): CryptoRampDto = return CryptoRampDto( name: name, @@ -25,7 +27,8 @@ proc newDto*( fees: fees, logoUrl: logoUrl, siteUrl: siteUrl, - hostname: hostname + hostname: hostname, + recurrentSiteUrl: recurrentSiteUrl ) proc `$`*(self: CryptoRampDto): string = @@ -36,6 +39,7 @@ proc `$`*(self: CryptoRampDto): string = result &= fmt"logoUrl:{self.logoUrl}, " result &= fmt"siteUrl:{self.siteUrl}, " result &= fmt"hostname:{self.hostname}" + result &= fmt"recurrentSiteUrl:{self.recurrentSiteUrl}" result &= ")" proc toCryptoRampDto*(jsonObj: JsonNode): CryptoRampDto = @@ -46,3 +50,4 @@ proc toCryptoRampDto*(jsonObj: JsonNode): CryptoRampDto = discard jsonObj.getProp("logoUrl", result.logoUrl) discard jsonObj.getProp("siteUrl", result.siteUrl) discard jsonObj.getProp("hostname", result.hostname) + discard jsonObj.getProp("recurrentSiteUrl", result.recurrentSiteUrl) diff --git a/storybook/qmlTests/tests/tst_BuyCryptoModal.qml b/storybook/qmlTests/tests/tst_BuyCryptoModal.qml index 4408d47152..a67295c8a0 100644 --- a/storybook/qmlTests/tests/tst_BuyCryptoModal.qml +++ b/storybook/qmlTests/tests/tst_BuyCryptoModal.qml @@ -1,7 +1,10 @@ import QtQuick 2.15 import QtTest 1.15 +import SortFilterProxyModel 0.2 + import StatusQ.Core.Theme 0.1 +import StatusQ.Core.Utils 0.1 as SQUtils import Models 1.0 import utils 1.0 @@ -14,13 +17,23 @@ Item { height: 800 OnRampProvidersModel{ - id: onRampProvidersModal + id: _onRampProvidersModel + } + + SortFilterProxyModel { + id: recurrentOnRampProvidersModel + sourceModel: _onRampProvidersModel + filters: ValueFilter { + roleName: "recurrentSiteUrl" + value: "" + inverted: true + } } Component { id: componentUnderTest BuyCryptoModal { - onRampProvidersModel: onRampProvidersModal + onRampProvidersModel: _onRampProvidersModel onClosed: destroy() } } @@ -47,6 +60,32 @@ Item { verify(!!controlUnderTest.opened) } + function testDelegateItems(providersList, modelToCompareAgainst) { + for(let i =0; i< providersList.count; i++) { + let delegateUnderTest = providersList.itemAtIndex(i) + verify(!!delegateUnderTest) + + compare(delegateUnderTest.title, modelToCompareAgainst.get(i).name) + compare(delegateUnderTest.subTitle, modelToCompareAgainst.get(i).description) + compare(delegateUnderTest.asset.name, modelToCompareAgainst.get(i).logoUrl) + + const feesText = findChild(delegateUnderTest, "feesText") + verify(!!feesText) + compare(feesText.text, modelToCompareAgainst.get(i).fees) + + const externalLinkIcon = findChild(delegateUnderTest, "externalLinkIcon") + verify(!!externalLinkIcon) + compare(externalLinkIcon.icon, "tiny/external") + compare(externalLinkIcon.color, Theme.palette.baseColor1) + + // Hover over the item and check hovered state + mouseMove(delegateUnderTest, delegateUnderTest.width/2, delegateUnderTest.height/2) + verify(delegateUnderTest.sensor.containsMouse) + compare(externalLinkIcon.color, Theme.palette.directColor1) + verify(delegateUnderTest.color, Theme.palette.baseColor2) + } + } + function test_launchAndCloseModal() { launchPopup() @@ -64,7 +103,7 @@ Item { verify(!!footer) compare(footer.rightButtons.count, 1) compare(footer.rightButtons.get(0).text, qsTr("Done")) - mouseClick(footer.rightButtons.get(0), Qt.LeftButton) + mouseClick(footer.rightButtons.get(0)) // popup should be closed verify(!controlUnderTest.opened) @@ -78,6 +117,11 @@ Item { const tabBar = findChild(controlUnderTest, "tabBar") verify(!!tabBar) + // find providers list + const providersList = findChild(controlUnderTest, "providersList") + waitForRendering(providersList) + verify(!!providersList) + // should have 2 items compare(tabBar.count, 2) @@ -90,57 +134,88 @@ Item { // item 1 should have text "Recurrent" compare(tabBar.itemAt(1).text, qsTr("Recurrent")) - // TODO: this will be implemnted under https://github.com/status-im/status-desktop/issues/14820 - // until then this list will be empty - mouseClick(tabBar.itemAt(1), Qt.LeftButton) - compare(tabBar.currentIndex, 1) + // close popup + controlUnderTest.close() + verify(!controlUnderTest.opened) + } + function test_modalContent_OneTime_tab() { + // Launch modal + launchPopup() + + // find tab bar + const tabBar = findChild(controlUnderTest, "tabBar") + verify(!!tabBar) + + // find providers list const providersList = findChild(controlUnderTest, "providersList") waitForRendering(providersList) verify(!!providersList) - compare(providersList.count, 0) - // check data on 1st tab -------------------------------------------------------- - mouseClick(tabBar.itemAt(0), Qt.LeftButton) + mouseClick(tabBar.itemAt(0)) compare(tabBar.currentIndex, 0) - waitForRendering(providersList) - verify(!!providersList) - // verify that 3 items are listed compare(providersList.count, 3) // check if delegate contents are as expected - for(let i =0; i< providersList.count; i++) { - let delegateUnderTest = providersList.itemAtIndex(i) - verify(!!delegateUnderTest) + testDelegateItems(providersList, _onRampProvidersModel) - compare(delegateUnderTest.title, onRampProvidersModal.get(i).name) - compare(delegateUnderTest.subTitle, onRampProvidersModal.get(i).description) - compare(delegateUnderTest.asset.name, onRampProvidersModal.get(i).logoUrl) - - const feesText = findChild(delegateUnderTest, "feesText") - verify(!!feesText) - compare(feesText.text, onRampProvidersModal.get(i).fees) - - const externalLinkIcon = findChild(delegateUnderTest, "externalLinkIcon") - verify(!!externalLinkIcon) - compare(externalLinkIcon.icon, "tiny/external") - compare(externalLinkIcon.color, Theme.palette.baseColor1) - - // Hover over the item and check hovered state - mouseMove(delegateUnderTest, delegateUnderTest.width/2, delegateUnderTest.height/2) - verify(delegateUnderTest.sensor.containsMouse) - compare(externalLinkIcon.color, Theme.palette.directColor1) - verify(delegateUnderTest.color, Theme.palette.baseColor2) - } + let delegateUnderTest = providersList.itemAtIndex(0) + verify(!!delegateUnderTest) // test mouse click tryCompare(notificationSpy, "count", 0) - mouseClick(providersList.itemAtIndex(0)) + mouseClick(delegateUnderTest) tryCompare(notificationSpy, "count", 1) - compare(notificationSpy.signalArguments[0][0],onRampProvidersModal.get(0).siteUrl) - compare(notificationSpy.signalArguments[0][1],onRampProvidersModal.get(0).hostname) + compare(notificationSpy.signalArguments[0][0], _onRampProvidersModel.get(0).siteUrl) + compare(notificationSpy.signalArguments[0][1], _onRampProvidersModel.get(0).hostname) + notificationSpy.clear() + + // popup should be closed + verify(!controlUnderTest.opened) + } + + function test_modalContent_recurrent_tab() { + // Launch modal + launchPopup() + + // find tab bar + const tabBar = findChild(controlUnderTest, "tabBar") + verify(!!tabBar) + + // find providers list + const providersList = findChild(controlUnderTest, "providersList") + waitForRendering(providersList) + verify(!!providersList) + + + // check data in "Recurrent" tab -------------------------------------------------------- + mouseClick(tabBar.itemAt(1)) + compare(tabBar.currentIndex, 1) + waitForRendering(providersList) + verify(!!providersList) + + // verify that 1 item is listed + compare(providersList.count, 1) + + // check if delegate contents are as expected + testDelegateItems(providersList, recurrentOnRampProvidersModel) + + let delegateUnderTest = providersList.itemAtIndex(0) + verify(!!delegateUnderTest) + + // test mouse click + tryCompare(notificationSpy, "count", 0) + verify(controlUnderTest.opened) + mouseClick(delegateUnderTest) + tryCompare(notificationSpy, "count", 1) + compare(notificationSpy.signalArguments[0][0], recurrentOnRampProvidersModel.get(0).recurrentSiteUrl) + compare(notificationSpy.signalArguments[0][1], recurrentOnRampProvidersModel.get(0).hostname) + notificationSpy.clear() + + // popup should be closed + verify(!controlUnderTest.opened) } } } diff --git a/storybook/src/Models/OnRampProvidersModel.qml b/storybook/src/Models/OnRampProvidersModel.qml index 5404f0a533..5d877ed041 100644 --- a/storybook/src/Models/OnRampProvidersModel.qml +++ b/storybook/src/Models/OnRampProvidersModel.qml @@ -9,7 +9,7 @@ ListModel { logoUrl: ModelsData.onRampProviderImages.ramp, siteUrl: "https://ramp.network/buy?hostApiKey=zrtf9u2uqebeyzcs37fu5857tktr3eg9w5tffove&swapAsset=DAI,ETH,USDC,USDT", hostname: "ramp.network", - recurrentSiteURL: "" + recurrentSiteUrl: "" }, { name: "MoonPay", @@ -18,7 +18,7 @@ ListModel { logoUrl: ModelsData.onRampProviderImages.moonPay, siteUrl: "https://buy.moonpay.com/?apiKey=pk_live_YQC6CQPA5qqDu0unEwHJyAYQyeIqFGR", hostname: "moonpay.com", - recurrentSiteURL: "https://buy.moonpay.com/?apiKey=pk_live_YQC6CQPA5qqDu0unEwHJyAYQyeIqFGR", + recurrentSiteUrl: "https://buy.moonpay.com/?apiKey=pk_live_ABCCQPA5qqDu0unEwHJyAYQyeIqFGR", }, { name: "Latamex", @@ -27,7 +27,7 @@ ListModel { logoUrl: ModelsData.onRampProviderImages.latamex, siteUrl: "https://latamex.com/", hostname: "latamex.com", - recurrentSiteURL: "", + recurrentSiteUrl: "", } ] diff --git a/ui/app/AppLayouts/Wallet/popups/BuyCryptoModal.qml b/ui/app/AppLayouts/Wallet/popups/BuyCryptoModal.qml index 18eb113f41..0fd9c6c23b 100644 --- a/ui/app/AppLayouts/Wallet/popups/BuyCryptoModal.qml +++ b/ui/app/AppLayouts/Wallet/popups/BuyCryptoModal.qml @@ -46,12 +46,11 @@ StatusDialog { Layout.fillHeight: true model: SortFilterProxyModel { sourceModel: !!root.onRampProvidersModel ? root.onRampProvidersModel : null - // TODO: this temporary and changed under https://github.com/status-im/status-desktop/issues/14820 - // when recurrentSiteURL is available filters: ValueFilter { enabled: tabBar.currentIndex - roleName: "name" + roleName: "recurrentSiteUrl" value: "" + inverted: true } } delegate: StatusListItem { @@ -78,7 +77,7 @@ StatusDialog { } ] onClicked: { - let url = tabBar.currentIndex ? recurrentSiteURL : siteUrl + let url = tabBar.currentIndex ? recurrentSiteUrl : siteUrl Global.openLinkWithConfirmation(url, hostname) root.close() }