diff --git a/features/swap/domain/build.gradle.kts b/features/swap/domain/build.gradle.kts index 769a037ad0..95d56c4314 100644 --- a/features/swap/domain/build.gradle.kts +++ b/features/swap/domain/build.gradle.kts @@ -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) diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetSwapUiModeUseCase.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetSwapUiModeUseCase.kt index 68533c7a1f..61f2bbcb37 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetSwapUiModeUseCase.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/GetSwapUiModeUseCase.kt @@ -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" } } \ No newline at end of file diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt index 8a60dec354..36986b34c4 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/di/SwapDomainModule.kt @@ -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 diff --git a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapUIMode.kt b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapUIMode.kt index f865c32424..b81cb3fc36 100644 --- a/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapUIMode.kt +++ b/features/swap/domain/src/main/java/com/tangem/feature/swap/domain/models/domain/SwapUIMode.kt @@ -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"), } \ No newline at end of file diff --git a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/GetSwapUiModeUseCaseTest.kt b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/GetSwapUiModeUseCaseTest.kt index cc65da1b9b..4d3f65e317 100644 --- a/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/GetSwapUiModeUseCaseTest.kt +++ b/features/swap/domain/src/test/kotlin/com/tangem/feature/swap/domain/GetSwapUiModeUseCaseTest.kt @@ -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) + } } \ No newline at end of file