feat(@desktop/wallet): Integrate recurring onramp providers in Recurrent tab
fixes #14820
This commit is contained in:
parent
3f77a16317
commit
aa03edf17c
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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: "",
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue