Updated on 2026-08-14
This commit is contained in:
commit
14a7ac4f5e
431 changed files with 23077 additions and 3701 deletions
|
|
@ -139,10 +139,10 @@ abstract class BaseTestCase : TestCase(
|
|||
return ApplicationInjectionExecutionRule(
|
||||
toggleStates = mapOf(
|
||||
"NEW_TOKEN_RECEIVE_ENABLED" to true,
|
||||
"WALLET_BALANCE_FETCHER_ENABLED" to true,
|
||||
"SWAP_REDESIGN_ENABLED" to true,
|
||||
"SWAP_REDESIGN_ENABLED" to false,
|
||||
"NEW_ONRAMP_MAIN_ENABLED" to true,
|
||||
"HOT_WALLET_ENABLED" to true
|
||||
"HOT_WALLET_ENABLED" to true,
|
||||
"YIELD_SUPPLY_FEATURE_ENABLED" to true
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ object TestConstants {
|
|||
const val ETHEREUM_RECIPIENT_ADDRESS = "0x5aa711F440Eb6d4361148bBD89d03464628ace84"
|
||||
const val ETHEREUM_RECIPIENT_SHORTENED_ADDRESS = "0x5aa711F440Eb6d43...89d03464628ace84"
|
||||
const val BITCOIN_ADDRESS = "bc1qtg9aa6jcpqtvun0pe0uct7sxm8nq2nsxfmfxm3"
|
||||
const val BITCOIN_RECIPIENT_ADDRESS = "bc1qt90qc0na7z05nh63kyd78tujfc8vqv6sl7e4a9"
|
||||
const val CARDANO_ADDRESS =
|
||||
"addr1q8f9499e58k4hhfd9vhawprxt3xd94x7rmlyp33ee4xkatakcl2zgkrg0p6ceqkndtkw4cumfe9enhdph8yhuswn785srksm9p"
|
||||
const val SOLANA_RECIPIENT_ADDRESS = "5fcy9woa8Di1QHcce65CsV3XKrxdB2pD4HJx5xx82ipM"
|
||||
|
|
@ -30,6 +31,7 @@ object TestConstants {
|
|||
const val XRP_ACTIVATED_RECIPIENT_ADDRESS = "rN7n7otQDd6FczFgLdSqtcsAUxDkw6fzRH"
|
||||
const val DOGECOIN_RECIPIENT_ADDRESS = "DJQR3bdhBKcFGMHX2BkMCkrMFApNWNzr6V"
|
||||
const val DOGECOIN_ADDRESS = "DJ2TaZ5vvp3mBLugUpKjVM3pRBLi4uYaqz"
|
||||
const val TERRA_RECIPIENT_ADDRESS = "terra148dmp5ccazcwdmrcpvqz5rprnn886kemqen3tj"
|
||||
|
||||
const val WAIT_UNTIL_TIMEOUT = 20_000L
|
||||
const val WAIT_UNTIL_TIMEOUT_LONG = 30_000L
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ fun BaseTestCase.checkNetworkFeeBlock(currentFeeAmount: String, withFeeSelector:
|
|||
step("Assert select fee icon is displayed") {
|
||||
onSendConfirmScreen { selectFeeIcon.assertIsDisplayed() }
|
||||
}
|
||||
} else {
|
||||
step("Assert select fee icon is not displayed") {
|
||||
onSendConfirmScreen { selectFeeIcon.assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,4 +142,29 @@ fun BaseTestCase.checkRecentAddressItem(address: String, description: String?) {
|
|||
recentAddressItem(recipientAddress = address, description = description).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun BaseTestCase.checkCustomFeeTooltip(title: String, tooltip: String) {
|
||||
step("Click on tooltip icon for '$title'") {
|
||||
waitForIdle()
|
||||
onSendSelectNetworkFeeBottomSheet { tooltipIcon(title).performClick() }
|
||||
}
|
||||
step("Check '$title' tooltip text") {
|
||||
onSendSelectNetworkFeeBottomSheet { tooltipText(tooltip).assertIsDisplayed() }
|
||||
}
|
||||
step("Click on tooltip icon again to close tooltip") {
|
||||
onSendSelectNetworkFeeBottomSheet { tooltipIcon(title).performClick() }
|
||||
}
|
||||
}
|
||||
|
||||
fun BaseTestCase.checkChangesInInputTextField(title: String, newValue: String, addition: String = "") {
|
||||
step("Click on '$title' input text field") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(title).performClick() }
|
||||
}
|
||||
step("Type '$newValue' in '$title' input text field") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(title).performTextReplacement(newValue) }
|
||||
}
|
||||
step("Assert '$title' value: '$newValue + $addition'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(title).assertTextContains(newValue + addition) }
|
||||
}
|
||||
}
|
||||
|
|
@ -95,10 +95,8 @@ class SendAddressPageObject(semanticsProvider: SemanticsNodeInteractionsProvider
|
|||
hasAnyDescendant(withText(description, substring = true))
|
||||
}
|
||||
if (isMyWallet) {
|
||||
hasAnySibling(withText(getResourceString(CoreUiR.string.send_recipient_wallets_title)))
|
||||
hasAnyDescendant(withText(getResourceString(CoreUiR.string.manage_tokens_network_selector_wallet)))
|
||||
} else {
|
||||
hasAnySibling(withText(getResourceString(CoreUiR.string.send_recent_transactions)))
|
||||
hasAnyDescendant(withTestTag(SendAddressScreenTestTags.RECENT_ADDRESS_TRANSACTION_ICON))
|
||||
}
|
||||
}
|
||||
|
|
@ -119,8 +117,7 @@ class SendAddressPageObject(semanticsProvider: SemanticsNodeInteractionsProvider
|
|||
}
|
||||
|
||||
val destinationTagTextFieldHint: KNode = child {
|
||||
hasParent(withTestTag(SendAddressScreenTestTags.DESTINATION_TAG_TEXT_FIELD))
|
||||
useUnmergedTree = true
|
||||
hasTestTag(SendAddressScreenTestTags.DESTINATION_TAG_TEXT_FIELD)
|
||||
}
|
||||
|
||||
val destinationTagBlockText: KNode = child {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,102 @@
|
|||
package com.tangem.screens
|
||||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.BaseBottomSheetTestTags
|
||||
import com.tangem.core.ui.test.BaseButtonTestTags
|
||||
import com.tangem.core.ui.test.SendSelectNetworkFeeBottomSheetTestTags
|
||||
import com.tangem.wallet.R
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen.Companion.onComposeScreen
|
||||
import io.github.kakaocup.compose.node.element.KNode
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
import androidx.compose.ui.test.hasTestTag as withTestTag
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
|
||||
class SendSelectNetworkFeeBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<SendSelectNetworkFeeBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val title: KNode = child {
|
||||
hasTestTag(BaseBottomSheetTestTags.TITLE)
|
||||
hasText(getResourceString(R.string.common_network_fee_title))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun regularFeeSelectorItem(title: String): KNode = child {
|
||||
hasTestTag(SendSelectNetworkFeeBottomSheetTestTags.REGULAR_FEE_ITEM)
|
||||
hasAnyDescendant(withText(title))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.REGULAR_ITEM_ICON))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.REGULAR_ITEM_TITLE))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.TOKEN_AMOUNT))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.FIAT_AMOUNT))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.DOT_SIGN))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val customSelectorItem: KNode = child {
|
||||
hasTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_FEE_ITEM)
|
||||
hasAnyDescendant(withText(getResourceString(R.string.common_custom)))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_ITEM_ICON))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_ITEM_TITLE))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun customInputItem(title: String, hasFiatAmount: Boolean = false): KNode = child {
|
||||
hasTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM)
|
||||
hasAnyDescendant(withText(title))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM_TITLE))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM_TOOLTIP_ICON))
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM_INPUT_TEXT_FIELD))
|
||||
useUnmergedTree = true
|
||||
if (hasFiatAmount) {
|
||||
hasAnyDescendant(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM_FIAT_AMOUNT))
|
||||
}
|
||||
}
|
||||
|
||||
val nonceInputItem: KNode = child {
|
||||
hasTestTag(SendSelectNetworkFeeBottomSheetTestTags.NONCE_INPUT_ITEM)
|
||||
hasAnyDescendant(withText(getResourceString(R.string.send_nonce)))
|
||||
hasAnyDescendant(withText(getResourceString(R.string.send_nonce_hint)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun tooltipIcon(title: String): KNode = child {
|
||||
hasAnySibling(withText(title))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun tooltipText(text: String): KNode = child {
|
||||
hasText(text)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
private fun inputTextField(title: String): KNode = child {
|
||||
hasTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM_INPUT_TEXT_FIELD)
|
||||
hasAnySibling(withText(title))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
fun inputTextFieldValue(title: String): KNode = inputTextField(title).child {
|
||||
hasParent(withTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM_INPUT_TEXT_FIELD))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val nonceInputTextField: KNode = child {
|
||||
hasTestTag(SendSelectNetworkFeeBottomSheetTestTags.NONCE_INPUT_TEXT_FIELD)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val customInputItemFiatAmount: KNode = child {
|
||||
hasTestTag(SendSelectNetworkFeeBottomSheetTestTags.CUSTOM_INPUT_ITEM_FIAT_AMOUNT)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val doneButton: KNode = child {
|
||||
hasTestTag(BaseButtonTestTags.TEXT)
|
||||
hasText(getResourceString(R.string.common_done))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onSendSelectNetworkFeeBottomSheet(function: SendSelectNetworkFeeBottomSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -2,7 +2,7 @@ package com.tangem.screens
|
|||
|
||||
import androidx.compose.ui.test.SemanticsNodeInteractionsProvider
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.core.ui.test.SelectNetworkFeeBottomSheetTestTags
|
||||
import com.tangem.core.ui.test.SwapSelectNetworkFeeBottomSheetTestTags
|
||||
import com.tangem.core.ui.test.TopAppBarTestTags
|
||||
import com.tangem.wallet.R
|
||||
import io.github.kakaocup.compose.node.element.ComposeScreen
|
||||
|
|
@ -11,8 +11,8 @@ import io.github.kakaocup.compose.node.element.KNode
|
|||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
import androidx.compose.ui.test.hasText as withText
|
||||
|
||||
class SelectNetworkFeePageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<SelectNetworkFeePageObject>(semanticsProvider = semanticsProvider) {
|
||||
class SwapSelectNetworkFeeBottomSheetPageObject(semanticsProvider: SemanticsNodeInteractionsProvider) :
|
||||
ComposeScreen<SwapSelectNetworkFeeBottomSheetPageObject>(semanticsProvider = semanticsProvider) {
|
||||
|
||||
val title: KNode = child {
|
||||
hasTestTag(TopAppBarTestTags.TITLE)
|
||||
|
|
@ -21,22 +21,22 @@ class SelectNetworkFeePageObject(semanticsProvider: SemanticsNodeInteractionsPro
|
|||
}
|
||||
|
||||
val marketSelectorItem: KNode = child {
|
||||
hasTestTag(SelectNetworkFeeBottomSheetTestTags.SELECTOR_ITEM)
|
||||
hasTestTag(SwapSelectNetworkFeeBottomSheetTestTags.SELECTOR_ITEM)
|
||||
hasAnyChild(withText(getResourceString(R.string.common_fee_selector_option_market)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val fastSelectorItem: KNode = child {
|
||||
hasTestTag(SelectNetworkFeeBottomSheetTestTags.SELECTOR_ITEM)
|
||||
hasTestTag(SwapSelectNetworkFeeBottomSheetTestTags.SELECTOR_ITEM)
|
||||
hasAnyChild(withText(getResourceString(R.string.common_fee_selector_option_fast)))
|
||||
useUnmergedTree = true
|
||||
}
|
||||
|
||||
val readMoreTextBlock: KNode = child {
|
||||
hasTestTag(SelectNetworkFeeBottomSheetTestTags.READ_MORE_TEXT)
|
||||
hasTestTag(SwapSelectNetworkFeeBottomSheetTestTags.READ_MORE_TEXT)
|
||||
useUnmergedTree = true
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseTestCase.onSelectNetworkFeeBottomSheet(function: SelectNetworkFeePageObject.() -> Unit) =
|
||||
internal fun BaseTestCase.onSwapSelectNetworkFeeBottomSheet(function: SwapSelectNetworkFeeBottomSheetPageObject.() -> Unit) =
|
||||
onComposeScreen(composeTestRule, function)
|
||||
|
|
@ -215,19 +215,19 @@ class SwapTokenTest : BaseTestCase() {
|
|||
}
|
||||
}
|
||||
step("Assert 'Select fee' bottom sheet title is displayed") {
|
||||
onSelectNetworkFeeBottomSheet { title.assertIsDisplayed() }
|
||||
onSwapSelectNetworkFeeBottomSheet { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Market' item is displayed") {
|
||||
onSelectNetworkFeeBottomSheet { marketSelectorItem.assertIsDisplayed() }
|
||||
onSwapSelectNetworkFeeBottomSheet { marketSelectorItem.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Fast' item is displayed") {
|
||||
onSelectNetworkFeeBottomSheet { fastSelectorItem.assertIsDisplayed() }
|
||||
onSwapSelectNetworkFeeBottomSheet { fastSelectorItem.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Read more' text block is displayed") {
|
||||
onSelectNetworkFeeBottomSheet { readMoreTextBlock.assertIsDisplayed() }
|
||||
onSwapSelectNetworkFeeBottomSheet { readMoreTextBlock.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Fast' item") {
|
||||
onSelectNetworkFeeBottomSheet { fastSelectorItem.assertIsDisplayed() }
|
||||
onSwapSelectNetworkFeeBottomSheet { fastSelectorItem.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Network fee' block is displayed") {
|
||||
onSwapTokenScreen {
|
||||
|
|
|
|||
|
|
@ -84,8 +84,8 @@ class TokenDetailsScreenActionButtonsTest : BaseTestCase() {
|
|||
step("Assert 'Buy' button is not dimmed") {
|
||||
onTokenDetailsScreen { buyButton().assertContentDescriptionEquals(actionButtonIsNotDimmed) }
|
||||
}
|
||||
step("Assert 'Send' button is dimmed") {
|
||||
onTokenDetailsScreen { sendButton().assertContentDescriptionEquals(actionButtonIsDimmed) }
|
||||
step("Assert 'Send' button is not dimmed") {
|
||||
onTokenDetailsScreen { sendButton().assertContentDescriptionEquals(actionButtonIsNotDimmed) }
|
||||
}
|
||||
step("Assert 'Swap' button is dimmed") {
|
||||
onTokenDetailsScreen { swapButton().assertContentDescriptionEquals(actionButtonIsDimmed) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,438 @@
|
|||
package com.tangem.tests.send.feeScreen
|
||||
|
||||
import com.tangem.common.BaseTestCase
|
||||
import com.tangem.common.constants.TestConstants.BITCOIN_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.ETHEREUM_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.POLKADOT_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.QUOTES_API_SCENARIO
|
||||
import com.tangem.common.constants.TestConstants.TERRA_RECIPIENT_ADDRESS
|
||||
import com.tangem.common.constants.TestConstants.USER_TOKENS_API_SCENARIO
|
||||
import com.tangem.common.extensions.SwipeDirection
|
||||
import com.tangem.common.extensions.clickWithAssertion
|
||||
import com.tangem.common.extensions.swipeVertical
|
||||
import com.tangem.common.utils.resetWireMockScenarioState
|
||||
import com.tangem.common.utils.setWireMockScenarioState
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.scenarios.*
|
||||
import com.tangem.screens.*
|
||||
import dagger.hilt.android.testing.HiltAndroidTest
|
||||
import io.github.kakaocup.kakao.common.utilities.getResourceString
|
||||
import io.qameta.allure.kotlin.AllureId
|
||||
import io.qameta.allure.kotlin.junit4.DisplayName
|
||||
import org.junit.Test
|
||||
|
||||
@HiltAndroidTest
|
||||
class SendFeeScreenTest : BaseTestCase() {
|
||||
|
||||
@AllureId("4906")
|
||||
@DisplayName("Send (Fee screen): check fee block for fee in token")
|
||||
@Test
|
||||
fun checkFeeBlockForFeeInTokenTest() {
|
||||
val tokenName = "TerraClassicUSD"
|
||||
val scenarioName = "Terra"
|
||||
val tokenAmount = "1"
|
||||
val feeAmount = "<$0.01"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName, scenarioName)
|
||||
}
|
||||
step("Type '$tokenAmount' in input text field") {
|
||||
onSendScreen {
|
||||
amountInputTextField.performClick()
|
||||
amountInputTextField.performTextReplacement(tokenAmount)
|
||||
}
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type recipient address") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(TERRA_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert fee block is displayed without fee selector") {
|
||||
checkNetworkFeeBlock(currentFeeAmount = feeAmount, withFeeSelector = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("4868")
|
||||
@DisplayName("Send (Fee screen): check fee block for fixed fee")
|
||||
@Test
|
||||
fun checkFeeBlockForFixedFeeTest() {
|
||||
val tokenName = "Polkadot"
|
||||
val tokenAmount = "1"
|
||||
val feeAmount = "$0.05"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
}
|
||||
step("Type '$tokenAmount' in input text field") {
|
||||
onSendScreen {
|
||||
amountInputTextField.performClick()
|
||||
amountInputTextField.performTextReplacement(tokenAmount)
|
||||
}
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type recipient address") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(POLKADOT_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert fee block is displayed without fee selector") {
|
||||
checkNetworkFeeBlock(currentFeeAmount = feeAmount, withFeeSelector = false)
|
||||
}
|
||||
step("Click on 'Fee selector' block") {
|
||||
onSendConfirmScreen { feeSelectorBlock.performClick() }
|
||||
}
|
||||
step("Assert 'Fee selector' bottom sheet is not displayed") {
|
||||
onSwapSelectNetworkFeeBottomSheet { title.assertIsNotDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("4869")
|
||||
@DisplayName("Send (Fee screen): check network fee bottom sheet for EVM networks")
|
||||
@Test
|
||||
fun checkNetworkFeeBottomSheetForEvmTest() {
|
||||
val tokenName = "Ethereum"
|
||||
val tokenAmount = "0.1"
|
||||
val feeAmount = "~$1.06"
|
||||
val fiatFeeAmount = "$1.09"
|
||||
val newFeeAmount = "~$1.09"
|
||||
val marketSelectorItem = getResourceString(R.string.common_fee_selector_option_market)
|
||||
val fastSelectorItem = getResourceString(R.string.common_fee_selector_option_fast)
|
||||
val slowSelectorItem = getResourceString(R.string.common_fee_selector_option_slow)
|
||||
val feeUpTo = getResourceString(R.string.send_max_fee)
|
||||
val feeUpToTooltip = getResourceString(R.string.send_custom_amount_fee_footer)
|
||||
val feeUpToValue = "0.00042 ETH"
|
||||
val newFeeUpToValue = "0.00043"
|
||||
val maxFee = getResourceString(R.string.send_custom_evm_max_fee)
|
||||
val maxFeeTooltip = getResourceString(R.string.send_custom_evm_max_fee_footer)
|
||||
val maxFeeValue = "20 GWEI"
|
||||
val newMaxFeeValue = "21"
|
||||
val priorityFee = getResourceString(R.string.send_custom_evm_priority_fee)
|
||||
val priorityFeeTooltip = getResourceString(R.string.send_custom_evm_priority_fee_footer)
|
||||
val priorityFeeValue = "2 GWEI"
|
||||
val newPriorityFeeValue = "3"
|
||||
val gasLimit = getResourceString(R.string.send_gas_limit)
|
||||
val gasLimitTooltip = getResourceString(R.string.send_gas_limit_footer)
|
||||
val gasLimitValue = "21,000 "
|
||||
val newGasLimitValue = "22"
|
||||
val nonce = getResourceString(R.string.send_nonce)
|
||||
val nonceTooltip = getResourceString(R.string.send_nonce_footer)
|
||||
val nonceValue = "1"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName)
|
||||
}
|
||||
step("Type '$tokenAmount' in input text field") {
|
||||
onSendScreen {
|
||||
amountInputTextField.performClick()
|
||||
amountInputTextField.performTextReplacement(tokenAmount)
|
||||
}
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type recipient address") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(ETHEREUM_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert fee block is displayed with fee selector") {
|
||||
checkNetworkFeeBlock(currentFeeAmount = feeAmount, withFeeSelector = true)
|
||||
}
|
||||
step("Click on fee selector icon") {
|
||||
onSendConfirmScreen { feeSelectorIcon.performClick() }
|
||||
}
|
||||
step("Assert 'Fee selector' bottom sheet title is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$fastSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(fastSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$slowSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(slowSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$marketSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(marketSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Custom' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { customSelectorItem.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Custom' selector item") {
|
||||
onSendSelectNetworkFeeBottomSheet { customSelectorItem.performClick() }
|
||||
}
|
||||
step("Assert '$feeUpTo' input item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet {
|
||||
customInputItem(title = feeUpTo, hasFiatAmount = true).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
step("Assert '$maxFee' input item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { customInputItem(maxFee).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$priorityFee' input item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { customInputItem(priorityFee).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$gasLimit' input item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { customInputItem(gasLimit).assertIsDisplayed() }
|
||||
}
|
||||
step("Swipe up") {
|
||||
swipeVertical(SwipeDirection.UP)
|
||||
}
|
||||
step("Assert '$nonce' input item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { nonceInputItem.assertIsDisplayed() }
|
||||
}
|
||||
step("Check '$feeUpTo' tooltip") {
|
||||
checkCustomFeeTooltip(title = feeUpTo, tooltip = feeUpToTooltip)
|
||||
}
|
||||
step("Check '$maxFee' tooltip") {
|
||||
checkCustomFeeTooltip(title = maxFee, tooltip = maxFeeTooltip)
|
||||
}
|
||||
step("Check '$priorityFee' tooltip") {
|
||||
checkCustomFeeTooltip(title = priorityFee, tooltip = priorityFeeTooltip)
|
||||
}
|
||||
step("Check '$gasLimit' tooltip") {
|
||||
checkCustomFeeTooltip(title = gasLimit, tooltip = gasLimitTooltip)
|
||||
}
|
||||
step("Check '$nonce' tooltip") {
|
||||
checkCustomFeeTooltip(title = nonce, tooltip = nonceTooltip)
|
||||
}
|
||||
step("Assert '$feeUpTo' value: '$feeUpToValue'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(feeUpTo).assertTextContains(feeUpToValue) }
|
||||
}
|
||||
step("Assert '$maxFee' value: '$maxFeeValue'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(maxFee).assertTextContains(maxFeeValue) }
|
||||
}
|
||||
step("Assert '$priorityFee' value: '$priorityFeeValue'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(priorityFee).assertTextContains(priorityFeeValue) }
|
||||
}
|
||||
step("Assert '$gasLimit' value: '$gasLimitValue'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(gasLimit).assertTextContains(gasLimitValue) }
|
||||
}
|
||||
step("Check changes in '$maxFee' input text field") {
|
||||
checkChangesInInputTextField(title = maxFee, newValue = newMaxFeeValue, addition = " GWEI")
|
||||
}
|
||||
step("Check changes in '$priorityFee' input text field") {
|
||||
checkChangesInInputTextField(title = priorityFee, newValue = newPriorityFeeValue, addition = " GWEI")
|
||||
}
|
||||
step("Check changes in '$gasLimit' input text field") {
|
||||
checkChangesInInputTextField(title = gasLimit, newValue = newGasLimitValue, addition = " ")
|
||||
}
|
||||
step("Type '$nonceValue' in '$nonce' text field") {
|
||||
onSendSelectNetworkFeeBottomSheet {
|
||||
nonceInputTextField.performClick()
|
||||
nonceInputTextField.performTextReplacement(nonceValue)
|
||||
}
|
||||
}
|
||||
step("Assert '$nonce' value: '$nonceValue'") {
|
||||
onSendSelectNetworkFeeBottomSheet { nonceInputTextField.assertTextContains(nonceValue) }
|
||||
}
|
||||
step("Check changes in '$feeUpTo' input text field") {
|
||||
checkChangesInInputTextField(title = feeUpTo, newValue = newFeeUpToValue, addition = " ETH")
|
||||
}
|
||||
step("Assert new fiat fee amount: '$fiatFeeAmount'") {
|
||||
onSendSelectNetworkFeeBottomSheet { customInputItemFiatAmount.assertTextContains(fiatFeeAmount) }
|
||||
}
|
||||
step("Click on 'Done' button") {
|
||||
onSendSelectNetworkFeeBottomSheet { doneButton.performClick() }
|
||||
}
|
||||
step("Assert fee block is displayed with new fee amount: '$newFeeAmount'") {
|
||||
checkNetworkFeeBlock(currentFeeAmount = newFeeAmount, withFeeSelector = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("4870")
|
||||
@DisplayName("Send (Fee screen): check network fee bottom sheet for Bitcoin")
|
||||
@Test
|
||||
fun checkNetworkFeeBottomSheetForBitcoinTest() {
|
||||
val tokenName = "Bitcoin"
|
||||
val tokenAmount = "0.00000001"
|
||||
val feeAmount = "$2.86"
|
||||
val fiatFeeAmount = "$0.24"
|
||||
val marketSelectorItem = getResourceString(R.string.common_fee_selector_option_market)
|
||||
val fastSelectorItem = getResourceString(R.string.common_fee_selector_option_fast)
|
||||
val slowSelectorItem = getResourceString(R.string.common_fee_selector_option_slow)
|
||||
val feeUpTo = getResourceString(R.string.send_max_fee)
|
||||
val feeUpToValue = "0.0000264 BTC"
|
||||
val newFeeUpToValue = "0.0000022 BTC"
|
||||
val satoshi = getResourceString(R.string.send_satoshi_per_byte_title)
|
||||
val satoshiValue = "2"
|
||||
val decimalNumber = "2.11"
|
||||
val newSatoshiValue = "1"
|
||||
val bitcoinUtxoScenarioName = "bitcoin_utxo"
|
||||
val bitcoinUtxoScenarioState = "Balance"
|
||||
val feeScenarioName = "bitcoin_estimate_smart_fee"
|
||||
val feeScenarioState = "Started"
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(bitcoinUtxoScenarioName)
|
||||
}
|
||||
).run {
|
||||
step("Set WireMock scenario: '$bitcoinUtxoScenarioName' to state: '$bitcoinUtxoScenarioState'") {
|
||||
setWireMockScenarioState(bitcoinUtxoScenarioName, bitcoinUtxoScenarioState)
|
||||
}
|
||||
step("Set WireMock scenario: '$feeScenarioName' to state: '$feeScenarioState'") {
|
||||
setWireMockScenarioState(feeScenarioName, feeScenarioState)
|
||||
}
|
||||
step("Open 'Main' screen") {
|
||||
openMainScreen()
|
||||
}
|
||||
step("Synchronize addresses") {
|
||||
synchronizeAddresses()
|
||||
}
|
||||
step("Open 'Send address' screen") {
|
||||
openSendAddressScreen(tokenName, tokenAmount)
|
||||
}
|
||||
step("Type recipient address") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(BITCOIN_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert fee block is displayed with fee selector") {
|
||||
checkNetworkFeeBlock(currentFeeAmount = feeAmount, withFeeSelector = true)
|
||||
}
|
||||
step("Click on fee selector icon") {
|
||||
onSendConfirmScreen { feeSelectorIcon.performClick() }
|
||||
}
|
||||
step("Assert 'Fee selector' bottom sheet title is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$fastSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(fastSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$slowSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(slowSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$marketSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(marketSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert 'Custom' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { customSelectorItem.assertIsDisplayed() }
|
||||
}
|
||||
step("Click on 'Custom' selector item") {
|
||||
onSendSelectNetworkFeeBottomSheet { customSelectorItem.performClick() }
|
||||
}
|
||||
step("Assert '$feeUpTo' input item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet {
|
||||
customInputItem(title = feeUpTo, hasFiatAmount = true).assertIsDisplayed()
|
||||
}
|
||||
}
|
||||
step("Assert '$feeUpTo' value: '$feeUpToValue'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(feeUpTo).assertTextContains(feeUpToValue) }
|
||||
}
|
||||
step("Assert '$satoshi' input item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { customInputItem(satoshi).assertIsDisplayed() }
|
||||
}
|
||||
step("Click on '$satoshi' input text field") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(satoshi).performClick() }
|
||||
}
|
||||
step("Type '$decimalNumber' in '$satoshi' input text field") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(satoshi).performTextReplacement(decimalNumber) }
|
||||
}
|
||||
step("Assert '$satoshi' value: '$satoshiValue + '") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(satoshi).assertTextContains("$satoshiValue ") }
|
||||
}
|
||||
step("Check changes in '$satoshi' input text field") {
|
||||
checkChangesInInputTextField(title = satoshi, newValue = newSatoshiValue, addition = " ")
|
||||
}
|
||||
step("Assert new fiat fee amount: '$fiatFeeAmount'") {
|
||||
onSendSelectNetworkFeeBottomSheet { customInputItemFiatAmount.assertTextContains(fiatFeeAmount) }
|
||||
}
|
||||
step("Assert '$feeUpTo' value: '$newFeeUpToValue'") {
|
||||
onSendSelectNetworkFeeBottomSheet { inputTextFieldValue(feeUpTo).assertTextContains(newFeeUpToValue) }
|
||||
}
|
||||
step("Click on 'Done' button") {
|
||||
onSendSelectNetworkFeeBottomSheet { doneButton.performClick() }
|
||||
}
|
||||
step("Assert fee block is displayed with new fee amount: '$fiatFeeAmount'") {
|
||||
checkNetworkFeeBlock(currentFeeAmount = fiatFeeAmount, withFeeSelector = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@AllureId("4871")
|
||||
@DisplayName("Send (Fee screen): check network fee bottom sheet networks with fee in token")
|
||||
@Test
|
||||
fun checkNetworkFeeBottomSheetForVeThorTest() {
|
||||
val tokenName = "VeThor"
|
||||
val mockState = "Vechain"
|
||||
val tokenAmount = "0.1"
|
||||
val feeAmount = "<$0.01"
|
||||
val marketSelectorItem = getResourceString(R.string.common_fee_selector_option_market)
|
||||
val fastSelectorItem = getResourceString(R.string.common_fee_selector_option_fast)
|
||||
val slowSelectorItem = getResourceString(R.string.common_fee_selector_option_slow)
|
||||
|
||||
setupHooks(
|
||||
additionalAfterSection = {
|
||||
resetWireMockScenarioState(USER_TOKENS_API_SCENARIO)
|
||||
resetWireMockScenarioState(QUOTES_API_SCENARIO)
|
||||
}
|
||||
).run {
|
||||
step("Open 'Send' screen") {
|
||||
openSendScreen(tokenName = tokenName, mockState = mockState)
|
||||
}
|
||||
step("Type '$tokenAmount' in input text field") {
|
||||
onSendScreen {
|
||||
amountInputTextField.performClick()
|
||||
amountInputTextField.performTextReplacement(tokenAmount)
|
||||
}
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendAddressScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Type recipient address") {
|
||||
onSendAddressScreen { addressTextField.performTextReplacement(ETHEREUM_RECIPIENT_ADDRESS) }
|
||||
}
|
||||
step("Click on 'Next' button") {
|
||||
onSendScreen { nextButton.clickWithAssertion() }
|
||||
}
|
||||
step("Assert fee block is displayed with fee selector") {
|
||||
checkNetworkFeeBlock(currentFeeAmount = feeAmount, withFeeSelector = true)
|
||||
}
|
||||
step("Click on fee selector icon") {
|
||||
onSendConfirmScreen { feeSelectorIcon.performClick() }
|
||||
}
|
||||
step("Assert 'Fee selector' bottom sheet title is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { title.assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$fastSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(fastSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$slowSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(slowSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
step("Assert '$marketSelectorItem' selector item is displayed") {
|
||||
onSendSelectNetworkFeeBottomSheet { regularFeeSelectorItem(marketSelectorItem).assertIsDisplayed() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -290,6 +290,17 @@
|
|||
android:host="tangem.com"
|
||||
android:path="/pay-app" />
|
||||
</intent-filter>
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="tangem.com"
|
||||
android:pathPrefix="/news" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Disable android.startup completely. Used for Worker according doc -->
|
||||
|
|
|
|||
|
|
@ -6,39 +6,43 @@ import dagger.Module
|
|||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object NewsDomainModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetNewsCategoriesUseCase(repository: NewsRepository): GetNewsCategoriesUseCase {
|
||||
return GetNewsCategoriesUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideObserveNewsDetailsUseCase(repository: NewsRepository): ObserveNewsDetailsUseCase {
|
||||
return ObserveNewsDetailsUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideObserveTrendingNewsUseCase(repository: NewsRepository): ManageTrendingNewsUseCase {
|
||||
return ManageTrendingNewsUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGetNewsListBatchFlowUseCase(repository: NewsRepository): GetNewsListBatchFlowUseCase {
|
||||
return GetNewsListBatchFlowUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideFetchTrendingNewsUseCase(repository: NewsRepository): FetchTrendingNewsUseCase {
|
||||
return FetchTrendingNewsUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideMarkArticleAsViewedUseCase(repository: NewsRepository): MarkArticleAsViewedUseCase {
|
||||
return MarkArticleAsViewedUseCase(repository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideGetNewsUseCase(repository: NewsRepository): GetNewsUseCase {
|
||||
return GetNewsUseCase(repository)
|
||||
}
|
||||
}
|
||||
|
|
@ -94,12 +94,12 @@ internal object StakingDomainModule {
|
|||
@Singleton
|
||||
fun provideFetchStakingOptionsUseCase(
|
||||
stakeKitRepository: StakeKitRepository,
|
||||
p2pRepository: P2PEthPoolRepository,
|
||||
p2pEthPoolRepository: P2PEthPoolRepository,
|
||||
stakingErrorResolver: StakingErrorResolver,
|
||||
): FetchStakingOptionsUseCase {
|
||||
return FetchStakingOptionsUseCase(
|
||||
stakeKitRepository = stakeKitRepository,
|
||||
p2pRepository = p2pRepository,
|
||||
p2pEthPoolRepository = p2pEthPoolRepository,
|
||||
stakingErrorResolver = stakingErrorResolver,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,14 @@ object WalletMockContent : MockContent {
|
|||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
),
|
||||
DerivationPath("m/44'/330'/0'/0/0") to ExtendedPublicKey(
|
||||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
),
|
||||
DerivationPath("m/44'/818'/0'/0/0") to ExtendedPublicKey(
|
||||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
),
|
||||
),
|
||||
extendedPublicKey = ExtendedPublicKey(
|
||||
publicKey = byteArrayOf(2, -109, 28, -27, -124, -58, -97, -61, 43, -84, 90, -9, -5, 4, 90, 17, 112, -125, -108, 44, 19, -79, -60, -23, 34, -20, -20, 61, 84, 113, 120, -90, -5),
|
||||
|
|
@ -261,6 +269,20 @@ object WalletMockContent : MockContent {
|
|||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/44'/330'/0'/0/0") to ExtendedPublicKey( // Terra
|
||||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
depth = 0,
|
||||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/44'/818'/0'/0/0") to ExtendedPublicKey( // Vechain
|
||||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
depth = 0,
|
||||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
ByteArrayKey(
|
||||
|
|
@ -318,6 +340,20 @@ object WalletMockContent : MockContent {
|
|||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/44'/330'/0'/0/0") to ExtendedPublicKey( // Terra
|
||||
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82),
|
||||
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
|
||||
depth = 0,
|
||||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/44'/818'/0'/0/0") to ExtendedPublicKey( // Vechain
|
||||
publicKey = byteArrayOf(2, 34, 6, 119, -106, 5, -119, 111, -22, 8, 23, -108, -72, -56, 6, 77, -17, -61, -101, -85, 16, 28, 18, 3, -3, -89, -81, -108, 48, -7, -86, -82),
|
||||
chainCode = byteArrayOf(-75, 55, 107, -106, -37, -81, -15, 72, -102, 94, 55, -39, 9, -112, 1, 90, -50, 103, 53, 120, -92, -36, -85, -39, -65, 1, 88, 46, 92, 104, -13, -109),
|
||||
depth = 0,
|
||||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
|
|
@ -371,6 +407,13 @@ object WalletMockContent : MockContent {
|
|||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
DerivationPath("m/44'/818'/0'/0/0") to ExtendedPublicKey( // Vechain
|
||||
publicKey = byteArrayOf(2, -40, 115, -15, 80, 104, 100, -29, 80, 29, 112, -35, -54, 64, -98, 45, 115, 108, 93, 113, -71, 89, 17, 72, 98, 21, 126, 82, -50, 50, -12, -87, -62),
|
||||
chainCode = byteArrayOf(-27, 56, 57, 54, 27, -40, 65, 109, 119, -54, -94, 88, -29, -115, -45, -112, -31, 57, 53, 56, 118, 87, 34, -16, -64, -45, 105, 77, 91, -106, -92, 41),
|
||||
depth = 0,
|
||||
parentFingerprint = byteArrayOf(0, 0, 0, 0),
|
||||
childNumber = 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
ByteArrayKey(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.tangem.tap.network.auth
|
||||
|
||||
import com.tangem.datasource.local.config.environment.EnvironmentConfigStorage
|
||||
import com.tangem.domain.staking.model.ethpool.P2PStakingConfig
|
||||
import com.tangem.domain.staking.model.ethpool.P2PEthPoolStakingConfig
|
||||
import com.tangem.lib.auth.P2PEthPoolAuthProvider
|
||||
|
||||
internal class DefaultP2PEthPoolAuthProvider(
|
||||
|
|
@ -12,6 +12,6 @@ internal class DefaultP2PEthPoolAuthProvider(
|
|||
val keys = environmentConfigStorage.getConfigSync().p2pApiKey
|
||||
?: error("No P2P api keys provided")
|
||||
|
||||
return if (P2PStakingConfig.USE_TESTNET) keys.hoodi else keys.mainnet
|
||||
return if (P2PEthPoolStakingConfig.USE_TESTNET) keys.hoodi else keys.mainnet
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,9 @@ import com.tangem.features.createwalletselection.CreateWalletSelectionComponent
|
|||
import com.tangem.features.createwalletstart.CreateWalletStartComponent
|
||||
import com.tangem.features.details.component.DetailsComponent
|
||||
import com.tangem.features.disclaimer.api.components.DisclaimerComponent
|
||||
import com.tangem.features.feed.entry.components.FeedEntryComponent
|
||||
import com.tangem.features.feed.entry.components.FeedEntryRoute
|
||||
import com.tangem.features.feed.entry.featuretoggle.FeedFeatureToggle
|
||||
import com.tangem.features.home.api.HomeComponent
|
||||
import com.tangem.features.hotwallet.*
|
||||
import com.tangem.features.kyc.KycComponent
|
||||
|
|
@ -38,10 +41,7 @@ import com.tangem.features.staking.api.StakingComponent
|
|||
import com.tangem.features.swap.SwapComponent
|
||||
import com.tangem.features.tangempay.components.TangemPayDetailsContainerComponent
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent.Params.ContinueOnboarding
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent.Params.Deeplink
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent.Params.FromBannerOnMain
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent.Params.FromBannerInSettings
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent.Params.*
|
||||
import com.tangem.features.tokendetails.TokenDetailsComponent
|
||||
import com.tangem.features.wallet.WalletEntryComponent
|
||||
import com.tangem.features.walletconnect.components.WalletConnectEntryComponent
|
||||
|
|
@ -121,6 +121,8 @@ internal class ChildFactory @Inject constructor(
|
|||
private val yieldSupplyPromoComponentFactory: YieldSupplyPromoComponent.Factory,
|
||||
private val yieldSupplyActiveComponentFactory: YieldSupplyActiveComponent.Factory,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
private val feedEntryComponentFactory: FeedEntryComponent.Factory,
|
||||
private val feedFeatureToggle: FeedFeatureToggle,
|
||||
) {
|
||||
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod")
|
||||
|
|
@ -204,21 +206,39 @@ internal class ChildFactory @Inject constructor(
|
|||
)
|
||||
}
|
||||
is AppRoute.MarketsTokenDetails -> {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = MarketsTokenDetailsComponent.Params(
|
||||
token = route.token,
|
||||
appCurrency = route.appCurrency,
|
||||
shouldShowPortfolio = route.shouldShowPortfolio,
|
||||
analyticsParams = route.analyticsParams?.let { params ->
|
||||
MarketsTokenDetailsComponent.AnalyticsParams(
|
||||
blockchain = params.blockchain,
|
||||
source = params.source,
|
||||
)
|
||||
},
|
||||
),
|
||||
componentFactory = marketsTokenDetailsComponentFactory,
|
||||
)
|
||||
if (feedFeatureToggle.isFeedEnabled) {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = FeedEntryRoute.MarketTokenDetails(
|
||||
token = route.token,
|
||||
appCurrency = route.appCurrency,
|
||||
shouldShowPortfolio = route.shouldShowPortfolio,
|
||||
analyticsParams = route.analyticsParams?.let { params ->
|
||||
FeedEntryRoute.MarketTokenDetails.AnalyticsParams(
|
||||
blockchain = params.blockchain,
|
||||
source = params.source,
|
||||
)
|
||||
},
|
||||
),
|
||||
componentFactory = feedEntryComponentFactory,
|
||||
)
|
||||
} else {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = MarketsTokenDetailsComponent.Params(
|
||||
token = route.token,
|
||||
appCurrency = route.appCurrency,
|
||||
shouldShowPortfolio = route.shouldShowPortfolio,
|
||||
analyticsParams = route.analyticsParams?.let { params ->
|
||||
MarketsTokenDetailsComponent.AnalyticsParams(
|
||||
blockchain = params.blockchain,
|
||||
source = params.source,
|
||||
)
|
||||
},
|
||||
),
|
||||
componentFactory = marketsTokenDetailsComponentFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
is AppRoute.Onramp -> {
|
||||
createComponentChild(
|
||||
|
|
@ -311,7 +331,7 @@ internal class ChildFactory @Inject constructor(
|
|||
params = StakingComponent.Params(
|
||||
userWalletId = route.userWalletId,
|
||||
cryptoCurrency = route.cryptoCurrency,
|
||||
yieldId = route.yieldId,
|
||||
integrationId = route.integrationId,
|
||||
),
|
||||
componentFactory = stakingComponentFactory,
|
||||
)
|
||||
|
|
@ -707,6 +727,16 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = yieldSupplyActiveComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.NewsDetails -> {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = FeedEntryRoute.NewsDetail(
|
||||
articleId = route.newsId,
|
||||
preselectedArticlesId = listOf(route.newsId),
|
||||
),
|
||||
componentFactory = feedEntryComponentFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ import com.tangem.common.routing.DeepLinkRoute
|
|||
import com.tangem.common.routing.DeepLinkScheme
|
||||
import com.tangem.data.card.sdk.CardSdkProvider
|
||||
import com.tangem.feature.referral.api.deeplink.ReferralDeepLinkHandler
|
||||
import com.tangem.features.feed.entry.deeplink.NewsDetailsDeepLinkHandler
|
||||
import com.tangem.features.feed.entry.featuretoggle.FeedFeatureToggle
|
||||
import com.tangem.features.markets.deeplink.MarketsDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsTokenDetailDeepLinkHandler
|
||||
import com.tangem.features.onramp.deeplink.BuyDeepLinkHandler
|
||||
|
|
@ -50,6 +52,8 @@ internal class DeepLinkFactory @Inject constructor(
|
|||
private val swapDeepLink: SwapDeepLinkHandler.Factory,
|
||||
private val promoDeepLink: PromoDeeplinkHandler.Factory,
|
||||
private val onboardVisaDeepLink: OnboardVisaDeepLinkHandler.Factory,
|
||||
private val newsDetailsDeepLink: NewsDetailsDeepLinkHandler.Factory,
|
||||
private val feedFeatureToggle: FeedFeatureToggle,
|
||||
) {
|
||||
private val permittedAppRoute = MutableStateFlow(false)
|
||||
|
||||
|
|
@ -102,7 +106,7 @@ internal class DeepLinkFactory @Inject constructor(
|
|||
|
||||
private fun launchDeepLink(deeplinkUri: Uri, coroutineScope: CoroutineScope, isFromOnNewIntent: Boolean) {
|
||||
when (deeplinkUri.scheme) {
|
||||
DeepLinkScheme.Https.scheme -> handleHttpDeepLinks(deeplinkUri)
|
||||
DeepLinkScheme.Https.scheme -> handleHttpDeepLinks(deeplinkUri, coroutineScope)
|
||||
DeepLinkScheme.Tangem.scheme -> handleTangemDeepLinks(deeplinkUri, coroutineScope, isFromOnNewIntent)
|
||||
DeepLinkScheme.WalletConnect.scheme -> walletConnectDeepLink.create(deeplinkUri)
|
||||
else -> {
|
||||
|
|
@ -116,10 +120,18 @@ internal class DeepLinkFactory @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleHttpDeepLinks(deeplinkUri: Uri) {
|
||||
if (deeplinkUri.host == DeepLinkRoute.PayApp.host && deeplinkUri.path?.startsWith("/pay-app") == true) {
|
||||
onboardVisaDeepLink.create(deeplinkUri)
|
||||
return
|
||||
private fun handleHttpDeepLinks(deeplinkUri: Uri, coroutineScope: CoroutineScope) {
|
||||
if (deeplinkUri.host == DeepLinkRoute.PayApp.host) {
|
||||
when {
|
||||
deeplinkUri.path?.startsWith("/pay-app") == true -> {
|
||||
onboardVisaDeepLink.create(deeplinkUri)
|
||||
return
|
||||
}
|
||||
deeplinkUri.path?.startsWith("/news") == true && feedFeatureToggle.isFeedEnabled -> {
|
||||
newsDetailsDeepLink.create(coroutineScope, deeplinkUri)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import android.net.Uri
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.data.card.sdk.CardSdkProvider
|
||||
import com.tangem.feature.referral.api.deeplink.ReferralDeepLinkHandler
|
||||
import com.tangem.features.feed.entry.deeplink.NewsDetailsDeepLinkHandler
|
||||
import com.tangem.features.feed.entry.featuretoggle.FeedFeatureToggle
|
||||
import com.tangem.features.markets.deeplink.MarketsDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsTokenDetailDeepLinkHandler
|
||||
import com.tangem.features.onramp.deeplink.BuyDeepLinkHandler
|
||||
|
|
@ -81,6 +83,12 @@ class DeepLinkFactoryTest {
|
|||
private val cardSdkProvider = mockk<CardSdkProvider>(relaxed = true) {
|
||||
every { sdk.uiVisibility() } returns MutableStateFlow(false)
|
||||
}
|
||||
|
||||
private val newsDeeplink = mockk<NewsDetailsDeepLinkHandler.Factory>(relaxed = true) {
|
||||
every { create(any(), any()) } returns mockk()
|
||||
}
|
||||
private val feedFeatureToggle = mockk<FeedFeatureToggle>()
|
||||
|
||||
private val mockedUri = mockk<Uri>(relaxed = true)
|
||||
private val isFromOnNewIntent: Boolean = false
|
||||
|
||||
|
|
@ -103,6 +111,8 @@ class DeepLinkFactoryTest {
|
|||
swapDeepLink = swapDeepLinkFactory,
|
||||
promoDeepLink = promoDeepLinkFactory,
|
||||
onboardVisaDeepLink = onboardVisaDeepLink,
|
||||
newsDetailsDeepLink = newsDeeplink,
|
||||
feedFeatureToggle = feedFeatureToggle,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue