From 4807321b9a400f3762cd440cee04f587421325a9 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 8 Jun 2026 13:55:32 +0100 Subject: [PATCH] Updated on 2026-08-14 --- .../tangem/tap/routing/utils/ChildFactory.kt | 9 ++ .../com/tangem/common/routing/AppRoute.kt | 5 ++ .../addressbook/AddressBookComponent.kt | 11 +++ features/address-book/impl/build.gradle.kts | 12 +++ .../addressbook/component/AddressBookRoute.kt | 10 +++ .../component/DefaultAddressBookComponent.kt | 65 ++++++++++++++ .../di/AddressBookComponentModule.kt | 26 ++++++ .../addressbook/di/AddressBookModelModule.kt | 20 +++++ .../list/AddressBookListComponent.kt | 11 +++ .../list/DefaultAddressBookListComponent.kt | 42 +++++++++ .../list/contract/AddressBookListContract.kt | 16 ++++ .../list/model/AddressBookListModel.kt | 34 +++++++ .../list/ui/AddressBookEmptyScreen.kt | 88 +++++++++++++++++++ .../features/details/utils/ItemsBuilder.kt | 2 +- .../details/utils/ItemsBuilderTest.kt | 47 ++++++++++ 15 files changed, 397 insertions(+), 1 deletion(-) create mode 100644 features/address-book/api/src/main/kotlin/com/tangem/features/addressbook/AddressBookComponent.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/AddressBookRoute.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/DefaultAddressBookComponent.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookComponentModule.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookModelModule.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/AddressBookListComponent.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/DefaultAddressBookListComponent.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/contract/AddressBookListContract.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/model/AddressBookListModel.kt create mode 100644 features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index 1684f52754..816ba6c2eb 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -11,6 +11,7 @@ import com.tangem.feature.walletsettings.component.WalletSettingsComponent import com.tangem.features.account.AccountCreateEditComponent import com.tangem.features.account.AccountDetailsComponent import com.tangem.features.account.ArchivedAccountListComponent +import com.tangem.features.addressbook.AddressBookComponent import com.tangem.features.createwalletselection.CreateWalletSelectionComponent import com.tangem.features.createwalletstart.CreateWalletStartComponent import com.tangem.features.details.component.DetailsComponent @@ -115,6 +116,7 @@ internal class ChildFactory @Inject constructor( private val surveyComponentFactory: SurveyComponent.Factory, private val yieldSupplyEntryComponentFactory: YieldSupplyEntryComponent.Factory, private val feedEntryComponentFactory: FeedEntryComponent.Factory, + private val addressBookComponentFactory: AddressBookComponent.Factory, ) { @Suppress("LongMethod", "CyclomaticComplexMethod") @@ -744,6 +746,13 @@ internal class ChildFactory @Inject constructor( componentFactory = feedEntryComponentFactory, ) } + is AppRoute.AddressBook -> { + createComponentChild( + context = context, + params = AddressBookComponent.Params(route.predefinedAddress), + componentFactory = addressBookComponentFactory, + ) + } } } } diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt index 5cda954ac5..73d0e6bebb 100644 --- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt +++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt @@ -172,6 +172,11 @@ sealed class AppRoute(val path: String) : Route { @Serializable data class WalletConnectSessions(val userWalletId: UserWalletId) : AppRoute(path = "/wallet_connect_sessions") + @Serializable + data class AddressBook( + val predefinedAddress: String? = null, + ) : AppRoute(path = "/address_book/predefinedAddress/$predefinedAddress") + @Serializable data class QrScanning(val source: Source) : AppRoute(path = "/$source/qr_scanning${source.path}") { diff --git a/features/address-book/api/src/main/kotlin/com/tangem/features/addressbook/AddressBookComponent.kt b/features/address-book/api/src/main/kotlin/com/tangem/features/addressbook/AddressBookComponent.kt new file mode 100644 index 0000000000..e9fe9ddb22 --- /dev/null +++ b/features/address-book/api/src/main/kotlin/com/tangem/features/addressbook/AddressBookComponent.kt @@ -0,0 +1,11 @@ +package com.tangem.features.addressbook + +import com.tangem.core.decompose.factory.ComponentFactory +import com.tangem.core.ui.decompose.ComposableContentComponent + +interface AddressBookComponent : ComposableContentComponent { + + interface Factory : ComponentFactory + + data class Params(val predefinedAddress: String?) +} \ No newline at end of file diff --git a/features/address-book/impl/build.gradle.kts b/features/address-book/impl/build.gradle.kts index f91cde71b1..c36b2239ed 100644 --- a/features/address-book/impl/build.gradle.kts +++ b/features/address-book/impl/build.gradle.kts @@ -1,6 +1,7 @@ plugins { alias(deps.plugins.android.library) alias(deps.plugins.kotlin.android) + alias(deps.plugins.kotlin.serialization) alias(deps.plugins.kotlin.kapt) alias(deps.plugins.hilt.android) id("configuration") @@ -14,13 +15,24 @@ dependencies { /** Api */ implementation(projects.features.addressBook.api) + /** Domain */ + implementation(projects.domain.models) + /** Core modules */ implementation(projects.core.configToggles) implementation(projects.core.decompose) implementation(projects.core.ui) + implementation(projects.core.utils) /** Compose */ implementation(deps.compose.runtime) + implementation(deps.compose.foundation) + implementation(deps.compose.ui) + implementation(deps.compose.ui.tooling) + implementation(deps.compose.material3) + implementation(deps.androidx.activity.compose) + implementation(deps.lifecycle.compose) + implementation(deps.decompose.ext.compose) /** DI */ implementation(deps.hilt.android) diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/AddressBookRoute.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/AddressBookRoute.kt new file mode 100644 index 0000000000..baa9ee7021 --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/AddressBookRoute.kt @@ -0,0 +1,10 @@ +package com.tangem.features.addressbook.component + +import kotlinx.serialization.Serializable + +@Serializable +internal sealed class AddressBookRoute { + + @Serializable + data object List : AddressBookRoute() +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/DefaultAddressBookComponent.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/DefaultAddressBookComponent.kt new file mode 100644 index 0000000000..8a816cec10 --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/component/DefaultAddressBookComponent.kt @@ -0,0 +1,65 @@ +package com.tangem.features.addressbook.component + +import androidx.activity.compose.BackHandler +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import com.arkivanov.decompose.ComponentContext +import com.arkivanov.decompose.extensions.compose.stack.Children +import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation +import com.arkivanov.decompose.extensions.compose.subscribeAsState +import com.arkivanov.decompose.router.stack.StackNavigation +import com.arkivanov.decompose.router.stack.childStack +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.context.childByContext +import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.features.addressbook.AddressBookComponent +import com.tangem.features.addressbook.list.AddressBookListComponent +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +internal class DefaultAddressBookComponent @AssistedInject constructor( + @Assisted context: AppComponentContext, + @Assisted private val params: AddressBookComponent.Params, + private val addressBookListComponentFactory: AddressBookListComponent.Factory, +) : AddressBookComponent, AppComponentContext by context { + + private val navigation = StackNavigation() + + private val contentStack = childStack( + key = "address_book_stack", + source = navigation, + serializer = AddressBookRoute.serializer(), + initialConfiguration = AddressBookRoute.List, + handleBackButton = false, + childFactory = ::screenChild, + ) + + @Suppress("ReusedModifierInstance") + @Composable + override fun Content(modifier: Modifier) { + val childStack by contentStack.subscribeAsState() + + BackHandler(onBack = router::pop) + Children(stack = childStack, animation = stackAnimation()) { child -> + child.instance.Content(modifier = modifier) + } + } + + private fun screenChild(config: AddressBookRoute, componentContext: ComponentContext): ComposableContentComponent = + when (config) { + AddressBookRoute.List -> addressBookListComponentFactory.create( + context = childByContext(componentContext), + params = AddressBookListComponent.Params, + ) + } + + @AssistedFactory + interface Factory : AddressBookComponent.Factory { + override fun create( + context: AppComponentContext, + params: AddressBookComponent.Params, + ): DefaultAddressBookComponent + } +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookComponentModule.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookComponentModule.kt new file mode 100644 index 0000000000..00e407405f --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookComponentModule.kt @@ -0,0 +1,26 @@ +package com.tangem.features.addressbook.di + +import com.tangem.features.addressbook.AddressBookComponent +import com.tangem.features.addressbook.component.DefaultAddressBookComponent +import com.tangem.features.addressbook.list.AddressBookListComponent +import com.tangem.features.addressbook.list.DefaultAddressBookListComponent +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal interface AddressBookComponentModule { + + @Binds + @Singleton + fun bindAddressBookComponentFactory(factory: DefaultAddressBookComponent.Factory): AddressBookComponent.Factory + + @Binds + @Singleton + fun bindAddressBookListComponentFactory( + factory: DefaultAddressBookListComponent.Factory, + ): AddressBookListComponent.Factory +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookModelModule.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookModelModule.kt new file mode 100644 index 0000000000..7c666b0b6d --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/di/AddressBookModelModule.kt @@ -0,0 +1,20 @@ +package com.tangem.features.addressbook.di + +import com.tangem.core.decompose.di.ModelComponent +import com.tangem.core.decompose.model.Model +import com.tangem.features.addressbook.list.model.AddressBookListModel +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.multibindings.ClassKey +import dagger.multibindings.IntoMap + +@Module +@InstallIn(ModelComponent::class) +internal interface AddressBookModelModule { + + @Binds + @IntoMap + @ClassKey(AddressBookListModel::class) + fun bindAddressBookModel(model: AddressBookListModel): Model +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/AddressBookListComponent.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/AddressBookListComponent.kt new file mode 100644 index 0000000000..280b889082 --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/AddressBookListComponent.kt @@ -0,0 +1,11 @@ +package com.tangem.features.addressbook.list + +import com.tangem.core.decompose.factory.ComponentFactory +import com.tangem.core.ui.decompose.ComposableContentComponent + +internal interface AddressBookListComponent : ComposableContentComponent { + + interface Factory : ComponentFactory + + data object Params +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/DefaultAddressBookListComponent.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/DefaultAddressBookListComponent.kt new file mode 100644 index 0000000000..a5ce1d1ea3 --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/DefaultAddressBookListComponent.kt @@ -0,0 +1,42 @@ +package com.tangem.features.addressbook.list + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.model.getOrCreateModel +import com.tangem.features.addressbook.list.contract.AddressBookListEvent +import com.tangem.features.addressbook.list.contract.AddressBookListUM +import com.tangem.features.addressbook.list.model.AddressBookListModel +import com.tangem.features.addressbook.list.ui.AddressBookEmptyScreen +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +internal class DefaultAddressBookListComponent @AssistedInject constructor( + @Assisted context: AppComponentContext, + @Assisted params: AddressBookListComponent.Params, +) : AddressBookListComponent, AppComponentContext by context { + + private val model: AddressBookListModel = getOrCreateModel(params) + + @Composable + override fun Content(modifier: Modifier) { + val state by model.state.collectAsStateWithLifecycle() + when (state) { + AddressBookListUM.Empty -> AddressBookEmptyScreen( + onAddContactClick = { model.onAction(event = AddressBookListEvent.NewContactClick) }, + modifier = modifier, + ) + } + } + + @AssistedFactory + interface Factory : AddressBookListComponent.Factory { + override fun create( + context: AppComponentContext, + params: AddressBookListComponent.Params, + ): DefaultAddressBookListComponent + } +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/contract/AddressBookListContract.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/contract/AddressBookListContract.kt new file mode 100644 index 0000000000..95f4736361 --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/contract/AddressBookListContract.kt @@ -0,0 +1,16 @@ +package com.tangem.features.addressbook.list.contract + +import androidx.compose.runtime.Immutable + +@Immutable +internal sealed interface AddressBookListUM { + + data object Empty : AddressBookListUM +} + +internal sealed interface AddressBookListEvent { + data object NewContactClick : AddressBookListEvent + data class ContactClick(val contactId: String) : AddressBookListEvent + data class ChipClick(val walletId: String) : AddressBookListEvent + data class SearchInput(val query: String) : AddressBookListEvent +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/model/AddressBookListModel.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/model/AddressBookListModel.kt new file mode 100644 index 0000000000..966a3b9205 --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/model/AddressBookListModel.kt @@ -0,0 +1,34 @@ +package com.tangem.features.addressbook.list.model + +import com.tangem.core.decompose.di.ModelScoped +import com.tangem.core.decompose.model.Model +import com.tangem.core.decompose.model.ParamsContainer +import com.tangem.features.addressbook.list.AddressBookListComponent +import com.tangem.features.addressbook.list.contract.AddressBookListEvent +import com.tangem.features.addressbook.list.contract.AddressBookListUM +import com.tangem.utils.coroutines.CoroutineDispatcherProvider +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import javax.inject.Inject + +@ModelScoped +internal class AddressBookListModel @Inject constructor( + paramsContainer: ParamsContainer, + override val dispatchers: CoroutineDispatcherProvider, +) : Model() { + + private val params: AddressBookListComponent.Params = paramsContainer.require() + + val state: StateFlow = MutableStateFlow( + AddressBookListUM.Empty, + ) + + fun onAction(event: AddressBookListEvent) { + when (event) { + AddressBookListEvent.NewContactClick -> params + is AddressBookListEvent.ContactClick -> Unit + is AddressBookListEvent.ChipClick -> Unit + is AddressBookListEvent.SearchInput -> Unit + } + } +} \ No newline at end of file diff --git a/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt new file mode 100644 index 0000000000..5c39b70eee --- /dev/null +++ b/features/address-book/impl/src/main/kotlin/com/tangem/features/addressbook/list/ui/AddressBookEmptyScreen.kt @@ -0,0 +1,88 @@ +package com.tangem.features.addressbook.list.ui + +import android.content.res.Configuration +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.R +import com.tangem.core.ui.components.PrimaryButtonIconEnd +import com.tangem.core.ui.extensions.stringResourceSafe +import com.tangem.core.ui.res.TangemTheme + +@Composable +internal fun AddressBookEmptyScreen(onAddContactClick: () -> Unit, modifier: Modifier = Modifier) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + NoContactInfo() + PrimaryButtonIconEnd( + modifier = Modifier + .fillMaxWidth() + .navigationBarsPadding() + .padding(start = 16.dp, end = 16.dp, bottom = 12.dp), + text = stringResourceSafe(R.string.address_book_add_contact), + iconResId = R.drawable.ic_plus_24, + onClick = onAddContactClick, + ) + } +} + +@Composable +private fun ColumnScope.NoContactInfo() { + Column( + modifier = Modifier.weight(1f), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + ContactImage() + Text( + modifier = Modifier.padding(top = TangemTheme.dimens.spacing24), + text = stringResourceSafe(R.string.address_book_no_contacts), + color = TangemTheme.colors3.text.primary, + style = TangemTheme.typography3.heading.medium, + ) + Text( + modifier = Modifier.padding(top = TangemTheme.dimens.spacing8), + text = stringResourceSafe(R.string.address_book_no_contacts_description), + color = TangemTheme.colors3.text.secondary, + style = TangemTheme.typography3.body.medium, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +private fun ContactImage() { + Box( + modifier = Modifier + .size(80.dp) + .background( + color = TangemTheme.colors3.bg.status.infoSubtle, + shape = CircleShape, + ), + contentAlignment = Alignment.Center, + ) { + Image( + painter = painterResource(R.drawable.ic_contact_20), + contentDescription = stringResourceSafe(R.string.address_book_no_contacts), + modifier = Modifier.size(28.dp), + ) + } +} + +@Composable +@Preview(showBackground = true, widthDp = 360) +@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun Preview_AddressBookEmptyScreen() { + AddressBookEmptyScreen(onAddContactClick = {}) +} \ No newline at end of file diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt index c309485bf6..df2e653821 100644 --- a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt +++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt @@ -114,7 +114,7 @@ internal class ItemsBuilder @Inject constructor( private fun buildAddressBookButton(): DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook { return DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook( - onClick = { }, + onClick = { router.push(AppRoute.AddressBook()) }, ) } diff --git a/features/details/impl/src/test/kotlin/com/tangem/features/details/utils/ItemsBuilderTest.kt b/features/details/impl/src/test/kotlin/com/tangem/features/details/utils/ItemsBuilderTest.kt index 5aa6f04da9..d6962201eb 100644 --- a/features/details/impl/src/test/kotlin/com/tangem/features/details/utils/ItemsBuilderTest.kt +++ b/features/details/impl/src/test/kotlin/com/tangem/features/details/utils/ItemsBuilderTest.kt @@ -1,6 +1,7 @@ package com.tangem.features.details.utils import com.google.common.truth.Truth.assertThat +import com.tangem.common.routing.AppRoute import com.tangem.core.decompose.navigation.Router import com.tangem.core.ui.components.block.model.BlockUM import com.tangem.core.ui.extensions.resourceReference @@ -11,6 +12,7 @@ import com.tangem.features.details.impl.R import io.mockk.clearMocks import io.mockk.every import io.mockk.mockk +import io.mockk.verify import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList @@ -90,6 +92,51 @@ internal class ItemsBuilderTest { ) } + @Test + fun `GIVEN standalone walletConnect block WHEN item clicked THEN router pushes WalletConnectSessions`() { + // Arrange + val result = buildAll(isWalletConnectAvailable = true, isAddressBookAvailable = false) + val walletConnect = result.first() as DetailsItemUM.WalletConnect + + // Act + walletConnect.onClick() + + // Assert + verify(exactly = 1) { router.push(route = AppRoute.WalletConnectSessions(USER_WALLET_ID), onComplete = any()) } + } + + @Test + fun `GIVEN combined block walletConnect item WHEN clicked THEN router pushes WalletConnectSessions`() { + // Arrange + val result = buildAll(isWalletConnectAvailable = true, isAddressBookAvailable = true) + val block = result.first() as DetailsItemUM.WalletConnectAddressBookBlock + val walletConnect = block.items + .filterIsInstance() + .single() + + // Act + walletConnect.onClick() + + // Assert + verify(exactly = 1) { router.push(route = AppRoute.WalletConnectSessions(USER_WALLET_ID), onComplete = any()) } + } + + @Test + fun `GIVEN combined block addressBook item WHEN clicked THEN router pushes AddressBook`() { + // Arrange + val result = buildAll(isWalletConnectAvailable = true, isAddressBookAvailable = true) + val block = result.first() as DetailsItemUM.WalletConnectAddressBookBlock + val addressBook = block.items + .filterIsInstance() + .single() + + // Act + addressBook.onClick() + + // Assert + verify(exactly = 1) { router.push(route = AppRoute.AddressBook(), onComplete = any()) } + } + @Test fun `GIVEN walletConnect AND addressBook unavailable WHEN buildAll THEN no walletConnect block`() { // Act