Updated on 2026-08-14

This commit is contained in:
Tangem 2026-05-18 21:27:20 +04:00
parent b4552e4b5f
commit bebbef6127
5 changed files with 101 additions and 26 deletions

View file

@ -56,6 +56,7 @@ dependencies {
implementation(projects.core.utils)
implementation(projects.core.ui)
implementation(projects.core.datasource)
implementation(projects.core.abTests)
/** Feature Apis */
implementation(projects.features.wallet.api)

View file

@ -1,18 +1,27 @@
package com.tangem.feature.swap.domain
import com.tangem.core.abtests.manager.ABTestsManager
import com.tangem.feature.swap.domain.api.SwapRepository
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
import com.tangem.features.swap.SwapFeatureToggles
import com.tangem.utils.logging.TangemLogger
class GetSwapUiModeUseCase(
private val swapFeatureToggles: SwapFeatureToggles,
private val swapRepository: SwapRepository,
private val abTestsManager: ABTestsManager,
) {
suspend operator fun invoke(): SwapUIMode {
if (!swapFeatureToggles.isSwapAbEnabled) return SwapUIMode.Detailed
// TODO: take default from Amplitude (true -> Detailed, false -> Simple).
// Until then default is Detailed.
return swapRepository.getStoredSwapUiMode() ?: SwapUIMode.Detailed
swapRepository.getStoredSwapUiMode()?.let { return it }
val variant = abTestsManager.getValue(KEY_SWAP_FORM_VARIANT, SwapUIMode.Detailed.key)
TangemLogger.d("Get $variant Swap AB variant from Amplitude as default value")
return SwapUIMode.entries.firstOrNull { it.key.equals(variant, ignoreCase = true) }
?: SwapUIMode.Detailed
}
private companion object {
const val KEY_SWAP_FORM_VARIANT = "swap_form_variant"
}
}

View file

@ -1,5 +1,6 @@
package com.tangem.feature.swap.domain.di
import com.tangem.core.abtests.manager.ABTestsManager
import com.tangem.feature.swap.domain.AllowPermissionsHandler
import com.tangem.feature.swap.domain.AllowPermissionsHandlerImpl
import com.tangem.feature.swap.domain.GetSwapUiModeUseCase
@ -32,9 +33,11 @@ internal class SwapDomainModule {
fun provideGetSwapUiModeUseCase(
swapFeatureToggles: SwapFeatureToggles,
swapRepository: SwapRepository,
abTestsManager: ABTestsManager,
): GetSwapUiModeUseCase = GetSwapUiModeUseCase(
swapFeatureToggles = swapFeatureToggles,
swapRepository = swapRepository,
abTestsManager = abTestsManager,
)
@Provides

View file

@ -1,6 +1,6 @@
package com.tangem.feature.swap.domain.models.domain
enum class SwapUIMode {
Simple,
Detailed,
enum class SwapUIMode(val key: String) {
Simple(key = "simple"),
Detailed(key = "detailed"),
}

View file

@ -1,12 +1,15 @@
package com.tangem.feature.swap.domain
import com.google.common.truth.Truth.assertThat
import com.tangem.core.abtests.manager.ABTestsManager
import com.tangem.feature.swap.domain.api.SwapRepository
import com.tangem.feature.swap.domain.models.domain.SwapUIMode
import com.tangem.features.swap.SwapFeatureToggles
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Test
@ -14,49 +17,108 @@ internal class GetSwapUiModeUseCaseTest {
private val swapFeatureToggles: SwapFeatureToggles = mockk()
private val swapRepository: SwapRepository = mockk()
private val abTestsManager: ABTestsManager = mockk()
private val sut = GetSwapUiModeUseCase(
swapFeatureToggles = swapFeatureToggles,
swapRepository = swapRepository,
abTestsManager = abTestsManager,
)
@Test
fun `GIVEN feature toggle is disabled WHEN invoke THEN returns Detailed without reading repository`() = runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns false
fun `GIVEN feature toggle is disabled WHEN invoke THEN returns Detailed without reading repository or AB tests`() =
runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns false
val actual = sut.invoke()
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
coVerify(exactly = 0) { swapRepository.getStoredSwapUiMode() }
}
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
coVerify(exactly = 0) { swapRepository.getStoredSwapUiMode() }
verify(exactly = 0) { abTestsManager.getValue(any(), any()) }
}
@Test
fun `GIVEN toggle enabled and repository has Detailed WHEN invoke THEN returns Detailed`() = runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns SwapUIMode.Detailed
fun `GIVEN toggle enabled and repository has Detailed WHEN invoke THEN returns Detailed without reading AB tests`() =
runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns SwapUIMode.Detailed
val actual = sut.invoke()
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
}
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
verify(exactly = 0) { abTestsManager.getValue(any(), any()) }
}
@Test
fun `GIVEN toggle enabled and repository has Simple WHEN invoke THEN returns Simple`() = runTest {
fun `GIVEN toggle enabled and repository has Simple WHEN invoke THEN returns Simple without reading AB tests`() =
runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns SwapUIMode.Simple
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Simple)
verify(exactly = 0) { abTestsManager.getValue(any(), any()) }
}
@Test
fun `GIVEN toggle enabled and repository empty and AB returns detailed WHEN invoke THEN returns Detailed`() =
runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns null
every { abTestsManager.getValue("swap_form_variant", "detailed") } returns "detailed"
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
verify(exactly = 1) { abTestsManager.getValue("swap_form_variant", "detailed") }
}
@Test
fun `GIVEN toggle enabled and repository empty and AB returns simple WHEN invoke THEN returns Simple`() = runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns SwapUIMode.Simple
coEvery { swapRepository.getStoredSwapUiMode() } returns null
every { abTestsManager.getValue("swap_form_variant", "detailed") } returns "simple"
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Simple)
verify(exactly = 1) { abTestsManager.getValue("swap_form_variant", "detailed") }
}
@Test
fun `GIVEN toggle enabled and repository has no value WHEN invoke THEN returns Detailed`() = runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns null
fun `GIVEN toggle enabled and repository empty and AB returns SIMPLE uppercase WHEN invoke THEN returns Simple`() =
runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns null
every { abTestsManager.getValue("swap_form_variant", "detailed") } returns "SIMPLE"
val actual = sut.invoke()
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
}
assertThat(actual).isEqualTo(SwapUIMode.Simple)
}
@Test
fun `GIVEN toggle enabled and repository empty and AB returns unknown variant WHEN invoke THEN returns Detailed`() =
runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns null
every { abTestsManager.getValue("swap_form_variant", "detailed") } returns "something_else"
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
}
@Test
fun `GIVEN toggle enabled and repository empty and AB returns empty string WHEN invoke THEN returns Detailed`() =
runTest {
coEvery { swapFeatureToggles.isSwapAbEnabled } returns true
coEvery { swapRepository.getStoredSwapUiMode() } returns null
every { abTestsManager.getValue("swap_form_variant", "detailed") } returns ""
val actual = sut.invoke()
assertThat(actual).isEqualTo(SwapUIMode.Detailed)
}
}