diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index da1a8d484c..b40fb7272c 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -274,6 +274,10 @@
- day
- days
+
+ - %d day ago
+ - %d days ago
+
Delete
Disable
Disabled
@@ -308,6 +312,10 @@
Hide
Hold to %s
hour
+
+ - %dh ago
+ - %dh ago
+
Import
In progress
Insufficient balance
@@ -318,6 +326,10 @@
Locked
Locked Wallets
Main network
+
+ - %d minute ago
+ - %d minutes ago
+
month
Network fee
Amount sent will be reduced by %1$s (%2$s) to cover the selected fee level
@@ -487,7 +499,6 @@
Disable dynamic addresses
Dynamic addresses disabled
Dynamic addresses enabled
- Dynamic address
Use a new address for each transaction to reduce traceability and improve on-chain privacy.
Enhanced Privacy
Easily receive funds in UTXO-based networks with automatic address generation — no manual address management required.
@@ -498,6 +509,9 @@
Dynamic Addresses Unavailable
We can’t connect to the provider right now. Please try again later.
Service unavailable. Please try again.
+ Funds were found on additional addresses. Enable Dynamic Addresses to access them.
+ Funds found on additional addresses
+ Dynamic address
Best opportunities
Clear filter
The list is temporarily empty as it’s being refreshed. Check back in a moment.
@@ -569,6 +583,7 @@
Provider
Best rate
FCA Warning List
+ Fixed rate is unavailable
Competitive rate
Provider in FCA warning list
Available up to %s
@@ -781,6 +796,7 @@
No data
**Add to your portfolio** to start buying, exchanging or receiving this asset
In your portfolio
+ Your portfolio
Market Pulse
Quick actions
Clear all
@@ -1020,7 +1036,9 @@
Getting started
Another wallet has already been created on the card you\'re trying to add. If you have funds in this wallet, please withdraw it and then reset this card and add it as a backup.
Save your wallet
+ Use biometrics
Creating a backup
+ Last step
Biometrics
Read more about seed phrase
@@ -1516,13 +1534,21 @@
Feel confident with round-the-clock support to help with any issues
Always Here
Multiple trusted providers in one place—swap any asset effortlessly in your wallet
+ Exchange crypto directly in Tangem\nNo additional transfers
\nNo moving funds to exchanges
Swap With Us
+ Swap Inside Your Wallet
No fumbles, no turnovers, no blind spots—your transaction is always protected
+ Swaps are executed through trusted providers. Your keys remain in your Tangem wallet at all times.
Clear. Transparent. Self-custodial.
Impenetrable Defense
+ You Stay in Control
Maximize your value with rates sourced from a wide network of trusted providers, always choosing the best one
+ Tangem compares multiple providers, both DEX and CEX. The best rate is selected automatically. Prefer another provider? You can choose it manually.
Unbeatable Rates
+ Best Available Rate
Hassle-free and intuitive, allowing you to swap tokens in just a few taps
+ Swap across major networks
and thousands of tokens 0% fee on stablecoin-to-stablecoin swaps
Simply Convenient
+ 90+ Blockchains
\n16,000+ Assets
Swap via provider
Your assets
The amount includes:\n• service provider\'s fee\n• network fee for sending %s from the exchange back to the user\'s address.
@@ -1557,17 +1583,6 @@
Explore transaction
Service fees
Fee
- Replace card
- Replace your card?
- This generates a new set of card details. Your old details will stop working. You can\'t undo this.
- Replacement fee
- Replace card
- Replacing your digital card
- Usually takes up to 5 minutes. In rare cases, up to 48 hours.
- Insufficient funds to replace the card
- Unable to cover fee
- Deposit USDC to payment account to cover the issuing fee
- Replacement fee info unreachable
Keep your money safe. You can unfreeze anytime.
Freeze your card?
Failed to freeze the card. Try again later.
@@ -1629,6 +1644,7 @@
Share your address or show QR-code
Technical issues detected. Please try again later or contact support.
Receive unavailable now
+ Replace card
Only letters and numbers are allowed.
Invalid characters
Reveal
@@ -1643,14 +1659,18 @@
Withdraw unavailable now
You can\'t initiate swap or new withdrawal till the current one is finished
Withdrawal in progress
- Card settings
- Daily limit
- Current limit
Change
- Daily limit unavailable
+ Current limit
We couldn\'t load your daily limit. Please try again.
+ Daily limit unavailable
+ You can change it again anytime you like
+ Daily limit is set
+ Daily limit
+ Card settings
Change PIN-code
Come back to the app if you forget it.
+ Set a limit from %s to %s
+ Set limits
Digital card
I understand that I will completely lose access to my Tangem Pay Card and all funds on it without the possibility of recovery
Failed to issue card
@@ -1693,12 +1713,22 @@
Payment account
Payment account is not synced
Invalid PIN: avoid sequences or repeats
+ Replace card
+ This generates a new set of card details. Your old details will stop working. You can\'t undo this.
+ Replacement fee
+ Replacement fee info unreachable
+ Replacing your digital card
+ Usually takes up to 5 minutes. In rare cases, up to 48 hours.
+ Insufficient funds to replace the card
+ Deposit USDC to payment account to cover the issuing fee
+ Unable to cover fee
+ Replace your card?
We’re fixing a technical issue. Please try again later.
Service temporarily unavailable
Unable to display details. However, card payments are still working.
Set \nPIN code
Session expired
- Restore access
+ Renew session
Use USDC for everyday payments
Tangem Pay is temporarily unreachable
Tangem Pay
@@ -1786,7 +1816,7 @@
Use %s or scan a card/ring to have access to your wallet
Connection failed: This dApp uses Wallet Connect version 1.0, which is not supported. Please ensure the dApp supports Wallet Connect version 2.0 to connect successfully.
Previous permission will be revoked and a new one will be issued. Network will charge token approval fee for each of theses actions. You will see a zero-amount transaction in the history as a revoke evidence.
- Transaction exceeds previously granted permission amount.\nUpdate permission to proceed
+ Transaction exceeds previously granted permission amount.\nUpdate permission to proceed
Update permission
Upgrade to hardware wallet
Stay up to date with the latest features and news
@@ -2157,8 +2187,6 @@
At least one network is required for dApp connection
Specify selected networks
Successfully signed
- Share Addresses
- Addresses to share
WalletConnect
To
Transaction request
@@ -2268,7 +2296,7 @@
All your future incoming %1$s deposits will be automatically supplied to Aave.
Active
Paused
- Disabling Yield Mode
+ Disable Yield Mode
Turning this off will withdraw your assets from Aave, convert them back to %s in your wallet, and stop yield accrual.
A network fee is charged by the blockchain when you exit Yield Mode.
Disable Yield Mode
diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt
index 255027abc8..f5999ae461 100644
--- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt
+++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/DefaultAddressSyncComponent.kt
@@ -1,6 +1,5 @@
package com.tangem.features.onboarding.v2.addresssync
-import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.DelicateDecomposeApi
@@ -18,6 +17,7 @@ import com.tangem.features.onboarding.v2.addresssync.model.AddressSyncIntent
import com.tangem.features.onboarding.v2.addresssync.model.AddressSyncModel
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
import com.tangem.features.onboarding.v2.addresssync.ui.AddressSyncContent
+import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.pushnotifications.api.PushNotificationsComponent
import com.tangem.features.pushnotifications.api.PushNotificationsModelCallbacks
import com.tangem.features.pushnotifications.api.PushNotificationsParams
@@ -25,11 +25,12 @@ import com.tangem.features.pushnotifications.api.PushNotificationsParams
@OptIn(DelicateDecomposeApi::class)
internal class DefaultAddressSyncComponent(
appComponentContext: AppComponentContext,
+ params: MultiWalletChildParams,
private val askBiometryComponentFactory: AskBiometryComponent.Factory,
private val pushNotificationsComponentFactory: PushNotificationsComponent.Factory,
) : AppComponentContext by appComponentContext, AddressSyncComponent {
- private val model: AddressSyncModel = getOrCreateModel()
+ private val model: AddressSyncModel = getOrCreateModel(params)
private val childStack: Value> =
childStack(
@@ -58,10 +59,6 @@ internal class DefaultAddressSyncComponent(
}
},
)
-
- BackHandler {
- model.onIntent(AddressSyncIntent.Back)
- }
}
private fun createChild(step: AddressSyncStep, childContext: AppComponentContext): ComposableContentComponent {
@@ -82,7 +79,6 @@ internal class DefaultAddressSyncComponent(
model.onIntent(
AddressSyncIntent.Next(
step = AddressSyncStep.ASK_NOTIFICATIONS,
- shouldReplace = true,
),
)
}
@@ -91,7 +87,6 @@ internal class DefaultAddressSyncComponent(
model.onIntent(
AddressSyncIntent.Next(
step = AddressSyncStep.ASK_NOTIFICATIONS,
- shouldReplace = false,
),
)
}
@@ -109,7 +104,6 @@ internal class DefaultAddressSyncComponent(
model.onIntent(
AddressSyncIntent.Next(
step = AddressSyncStep.ADDRESS_SYNC,
- shouldReplace = true,
),
)
}
@@ -118,7 +112,6 @@ internal class DefaultAddressSyncComponent(
model.onIntent(
AddressSyncIntent.Next(
step = AddressSyncStep.ADDRESS_SYNC,
- shouldReplace = false,
),
)
}
@@ -127,7 +120,6 @@ internal class DefaultAddressSyncComponent(
model.onIntent(
AddressSyncIntent.Next(
step = AddressSyncStep.ADDRESS_SYNC,
- shouldReplace = false,
),
)
}
diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt
index 1293c244d5..0776ea3cc7 100644
--- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt
+++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncIntent.kt
@@ -3,6 +3,6 @@ package com.tangem.features.onboarding.v2.addresssync.model
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
sealed interface AddressSyncIntent {
- data class Next(val step: AddressSyncStep, val shouldReplace: Boolean) : AddressSyncIntent
+ data class Next(val step: AddressSyncStep) : AddressSyncIntent
data object Back : AddressSyncIntent
}
\ No newline at end of file
diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt
index b06e54736c..a73fa83fae 100644
--- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt
+++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModel.kt
@@ -3,16 +3,19 @@ package com.tangem.features.onboarding.v2.addresssync.model
import com.arkivanov.decompose.DelicateDecomposeApi
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.pop
-import com.arkivanov.decompose.router.stack.push
import com.arkivanov.decompose.router.stack.replaceCurrent
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
+import com.tangem.core.decompose.model.ParamsContainer
+import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.settings.CanUseBiometryUseCase
import com.tangem.domain.settings.ShouldAskPermissionUseCase
import com.tangem.domain.settings.ShouldShowAskBiometryUseCase
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
+import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
+import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -23,10 +26,24 @@ internal class AddressSyncModel @Inject constructor(
private val shouldShowAskBiometryUseCase: ShouldShowAskBiometryUseCase,
private val canUseBiometryUseCase: CanUseBiometryUseCase,
private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase,
+ paramsContainer: ParamsContainer,
) : Model() {
+ private val params = paramsContainer.require()
val stackNavigation = StackNavigation()
+ init {
+ params.innerNavigation.update { innerNavigationState ->
+ innerNavigationState.copy(
+ stackSize = AddressSyncStep.ASK_BIOMETRY.pageNumber,
+ stackMaxSize = ADDRESS_SYNC_MAX_STEPS,
+ )
+ }
+ modelScope.launch {
+ trySkippingScreen(AddressSyncStep.ASK_BIOMETRY)
+ }
+ }
+
fun onIntent(intent: AddressSyncIntent) {
when (intent) {
is AddressSyncIntent.Next -> nextScreen(intent)
@@ -35,27 +52,24 @@ internal class AddressSyncModel @Inject constructor(
}
private fun nextScreen(next: AddressSyncIntent.Next) {
- val (nextStep, replace) = next
- if (replace) {
- stackNavigation.replaceCurrent(configuration = nextStep)
- } else {
- stackNavigation.push(configuration = nextStep)
- }
- modelScope.launch { trySkippingScreen(next) }
+ stackNavigation.replaceCurrent(configuration = next.step)
+ updateStepperPage(next)
+ updateTitle(next)
+ modelScope.launch { trySkippingScreen(next.step) }
}
- private suspend fun trySkippingScreen(next: AddressSyncIntent.Next) {
- when (next.step) {
+ private suspend fun trySkippingScreen(step: AddressSyncStep) {
+ when (step) {
AddressSyncStep.ASK_BIOMETRY -> {
val shouldShowAskBiometry = canUseBiometryUseCase.strict() && shouldShowAskBiometryUseCase()
if (shouldShowAskBiometry.not()) {
- nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = true))
+ nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS))
}
}
AddressSyncStep.ASK_NOTIFICATIONS -> {
val shouldShowAskNotification = shouldAskPermissionUseCase(PUSH_PERMISSION)
if (shouldShowAskNotification.not()) {
- nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ADDRESS_SYNC, shouldReplace = true))
+ nextScreen(AddressSyncIntent.Next(step = AddressSyncStep.ADDRESS_SYNC))
}
}
AddressSyncStep.ADDRESS_SYNC -> Unit
@@ -65,4 +79,22 @@ internal class AddressSyncModel @Inject constructor(
private fun goBack() {
stackNavigation.pop()
}
+
+ private fun updateStepperPage(next: AddressSyncIntent.Next) {
+ params.innerNavigation.update { innerNavigationState ->
+ innerNavigationState.copy(
+ stackSize = next.step.pageNumber,
+ )
+ }
+ }
+
+ private fun updateTitle(next: AddressSyncIntent.Next) {
+ params.parentParams.titleProvider.changeTitle(
+ text = resourceReference(next.step.stringId),
+ )
+ }
+
+ private companion object {
+ const val ADDRESS_SYNC_MAX_STEPS = 3
+ }
}
\ No newline at end of file
diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt
index edd056ce90..c03a4fc662 100644
--- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt
+++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/addresssync/navigation/AddressSyncStep.kt
@@ -1,7 +1,10 @@
package com.tangem.features.onboarding.v2.addresssync.navigation
-enum class AddressSyncStep {
- ASK_BIOMETRY,
- ASK_NOTIFICATIONS,
- ADDRESS_SYNC,
+import androidx.annotation.StringRes
+import com.tangem.features.onboarding.v2.impl.R
+
+enum class AddressSyncStep(val pageNumber: Int, @StringRes val stringId: Int) {
+ ASK_BIOMETRY(pageNumber = 1, stringId = R.string.onboarding_navbar_title_biometrics),
+ ASK_NOTIFICATIONS(pageNumber = 2, stringId = R.string.onboarding_title_notifications),
+ ADDRESS_SYNC(pageNumber = 3, stringId = R.string.onboarding_navbar_title_last_step),
}
\ No newline at end of file
diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt
index 4fe733a371..4f7588e705 100644
--- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt
+++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/DefaultOnboardingMultiWalletComponent.kt
@@ -194,6 +194,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
)
AddressSync -> DefaultAddressSyncComponent(
appComponentContext = childContext,
+ params = childParams,
askBiometryComponentFactory = askBiometryComponentFactory,
pushNotificationsComponentFactory = pushNotificationsComponentFactory,
)
diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt
index cb903802ce..050a14f74e 100644
--- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt
+++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/OnboardingMultiWalletModel.kt
@@ -1,5 +1,6 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.model
+import com.tangem.common.routing.AppRoute
import com.tangem.common.ui.userwallet.converter.ArtworkUMConverter
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ModelScoped
@@ -70,7 +71,11 @@ internal class OnboardingMultiWalletModel @Inject constructor(
onConfirm = {
modelScope.launch {
onboardingRepository.clearUnfinishedFinalizeOnboarding()
- router.pop()
+ if (params.mode == OnboardingMultiWalletComponent.Mode.AddressSync) {
+ router.replaceAll(AppRoute.Wallet)
+ } else {
+ router.pop()
+ }
}
},
),
diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt
index aff07ca039..5e4f6a5152 100644
--- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt
+++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/multiwallet/impl/model/Utils.kt
@@ -15,5 +15,5 @@ fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = wh
OnboardingMultiWalletState.Step.Finalize -> resourceReference(R.string.onboarding_button_finalize_backup)
OnboardingMultiWalletState.Step.Done -> resourceReference(R.string.common_done)
OnboardingMultiWalletState.Step.UpgradeWallet -> resourceReference(R.string.common_tangem)
- OnboardingMultiWalletState.Step.AddressSync -> TODO("Will be implemented during [REDACTED_TASK_KEY]")
+ OnboardingMultiWalletState.Step.AddressSync -> resourceReference(R.string.onboarding_navbar_title_biometrics)
}
\ No newline at end of file
diff --git a/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt b/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt
index 0e4a8acc7d..f784c38c74 100644
--- a/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt
+++ b/features/onboarding-v2/impl/src/test/kotlin/com/tangem/features/onboarding/v2/addresssync/model/AddressSyncModelTest.kt
@@ -1,15 +1,23 @@
package com.tangem.features.onboarding.v2.addresssync.model
import com.arkivanov.decompose.router.stack.StackNavigation
+import com.tangem.core.decompose.model.ParamsContainer
+import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.settings.CanUseBiometryUseCase
import com.tangem.domain.settings.ShouldAskPermissionUseCase
import com.tangem.domain.settings.ShouldShowAskBiometryUseCase
+import com.tangem.features.onboarding.v2.TitleProvider
import com.tangem.features.onboarding.v2.addresssync.navigation.AddressSyncStep
+import com.tangem.features.onboarding.v2.multiwallet.impl.MultiWalletInnerNavigationState
+import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
import com.tangem.utils.coroutines.TestingCoroutineDispatcherProvider
import io.mockk.coEvery
+import io.mockk.every
import io.mockk.mockk
+import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.advanceUntilIdle
@@ -23,12 +31,36 @@ internal class AddressSyncModelTest {
private val shouldShowAskBiometryUseCase: ShouldShowAskBiometryUseCase = mockk()
private val canUseBiometryUseCase: CanUseBiometryUseCase = mockk()
private val shouldAskPermissionUseCase: ShouldAskPermissionUseCase = mockk()
+ private val paramsContainer: ParamsContainer = mockk()
+ private val testInnerNavigation = MutableStateFlow(
+ value = MultiWalletInnerNavigationState(
+ stackSize = 0,
+ stackMaxSize = 0,
+ )
+ )
+ private val titleProvider: TitleProvider = mockk(relaxUnitFun = true)
+ private val params: MultiWalletChildParams = mockk {
+ every { innerNavigation } returns testInnerNavigation
+ every { parentParams } returns mockk {
+ every { titleProvider } returns this@AddressSyncModelTest.titleProvider
+ }
+ }
@BeforeEach
fun setUp() {
coEvery { canUseBiometryUseCase.strict() } returns false
coEvery { shouldShowAskBiometryUseCase() } returns false
coEvery { shouldAskPermissionUseCase(PUSH_PERMISSION) } returns false
+ every { paramsContainer.require() } returns params
+ }
+
+ @Test
+ fun `WHEN model is created THEN inner navigation stack size and max size are set`() = runTest {
+ createModel(this)
+
+ val state = testInnerNavigation.value
+ assert(state.stackSize == AddressSyncStep.ASK_BIOMETRY.pageNumber)
+ assert(state.stackMaxSize == AddressSyncStep.entries.size)
}
@Test
@@ -39,10 +71,11 @@ internal class AddressSyncModelTest {
val model = createModel(this)
val stack = model.stackNavigation.trackStack()
- model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false))
+ model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY))
advanceUntilIdle()
assert(stack == listOf(AddressSyncStep.ASK_BIOMETRY))
+ assertStepperAndTitleFor(AddressSyncStep.ASK_BIOMETRY)
}
@Test
@@ -55,10 +88,11 @@ internal class AddressSyncModelTest {
val model = createModel(this)
val stack = model.stackNavigation.trackStack()
- model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false))
+ model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY))
advanceUntilIdle()
assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS))
+ assertStepperAndTitleFor(AddressSyncStep.ASK_NOTIFICATIONS)
}
@Test
@@ -70,10 +104,11 @@ internal class AddressSyncModelTest {
val model = createModel(this)
val stack = model.stackNavigation.trackStack()
- model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY, shouldReplace = false))
+ model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_BIOMETRY))
advanceUntilIdle()
assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC))
+ assertStepperAndTitleFor(AddressSyncStep.ADDRESS_SYNC)
}
@Test
@@ -83,10 +118,11 @@ internal class AddressSyncModelTest {
val model = createModel(this)
val stack = model.stackNavigation.trackStack()
- model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = false))
+ model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS))
advanceUntilIdle()
assert(stack == listOf(AddressSyncStep.ASK_NOTIFICATIONS))
+ assertStepperAndTitleFor(AddressSyncStep.ASK_NOTIFICATIONS)
}
@Test
@@ -96,10 +132,16 @@ internal class AddressSyncModelTest {
val model = createModel(this)
val stack = model.stackNavigation.trackStack()
- model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS, shouldReplace = false))
+ model.onIntent(AddressSyncIntent.Next(step = AddressSyncStep.ASK_NOTIFICATIONS))
advanceUntilIdle()
assert(stack == listOf(AddressSyncStep.ADDRESS_SYNC))
+ assertStepperAndTitleFor(AddressSyncStep.ADDRESS_SYNC)
+ }
+
+ private fun assertStepperAndTitleFor(step: AddressSyncStep) {
+ assert(testInnerNavigation.value.stackSize == step.pageNumber)
+ verify { titleProvider.changeTitle(resourceReference(step.stringId)) }
}
private fun StackNavigation.trackStack(): List {
@@ -118,6 +160,7 @@ internal class AddressSyncModelTest {
shouldShowAskBiometryUseCase = shouldShowAskBiometryUseCase,
canUseBiometryUseCase = canUseBiometryUseCase,
shouldAskPermissionUseCase = shouldAskPermissionUseCase,
+ paramsContainer = paramsContainer,
)
}