Skip to content

Commit

Permalink
Rename and document some of the experiments code, incidental
Browse files Browse the repository at this point in the history
  • Loading branch information
aitorvs committed Oct 11, 2024
1 parent 74e9bea commit 6f578d9
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ import javax.inject.Inject
import kotlinx.coroutines.runBlocking

interface ExperimentFiltersManager {
fun addFilters(entity: VariantConfig): (AppBuildConfig) -> Boolean
/**
* This method computes the result of the filters
* @return returns `true` if the filters match the client state, else `false`
*/
fun computeFilters(entity: VariantConfig): (AppBuildConfig) -> Boolean
}

@ContributesBinding(AppScope::class)
Expand All @@ -39,7 +43,7 @@ class ExperimentFiltersManagerImpl @Inject constructor(
private val subscriptions: Subscriptions,
private val dispatcherProvider: DispatcherProvider,
) : ExperimentFiltersManager {
override fun addFilters(entity: VariantConfig): (AppBuildConfig) -> Boolean {
override fun computeFilters(entity: VariantConfig): (AppBuildConfig) -> Boolean {
if (entity.variantKey == "sc" || entity.variantKey == "se") {
return { isSerpRegionToggleCountry() }
}
Expand All @@ -51,7 +55,7 @@ class ExperimentFiltersManagerImpl @Inject constructor(
)

if (!entity.filters?.locale.isNullOrEmpty()) {
val userLocale = Locale.getDefault()
val userLocale = appBuildConfig.deviceLocale
filters[LOCALE] = entity.filters!!.locale.contains(userLocale.toString())
}
if (!entity.filters?.androidVersion.isNullOrEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ class VariantManagerImpl @Inject constructor(
experimentVariantRepository.updateAppReferrerVariant(variant)
}

override fun updateVariants(variantConfig: List<VariantConfig>) {
val activeVariants = variantConfig.toVariants()
Timber.d("Variants update $variantConfig")
override fun updateVariants(variants: List<VariantConfig>) {
val activeVariants = variants.toVariants()
Timber.d("Variants update $variants")
val currentVariantKey = experimentVariantRepository.getUserVariant()

updateUserVariant(activeVariants, currentVariantKey)
Expand Down Expand Up @@ -84,14 +84,14 @@ class VariantManagerImpl @Inject constructor(
Timber.i("Variant $currentVariantKey is still in use, no need to update")
}

fun List<VariantConfig>.toVariants(): List<Variant> {
private fun List<VariantConfig>.toVariants(): List<Variant> {
val activeVariants: MutableList<Variant> = mutableListOf()
this.map { entity ->
activeVariants.add(
Variant(
key = entity.variantKey,
weight = entity.weight ?: 0.0,
filterBy = experimentFiltersManager.addFilters(entity),
filterBy = experimentFiltersManager.computeFilters(entity),
),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,59 +51,59 @@ class ExperimentFiltersManagerImplTest {
}

@Test
fun whenVariantComplyWithLocaleFilterThenAddFiltersReturnsTrue() {
fun whenVariantComplyWithLocaleFilterThenComputeFiltersReturnsTrue() {
val locale = Locale("en", "US")
Locale.setDefault(locale)
whenever(mockAppBuildConfig.deviceLocale).thenReturn(locale)
val testEntity = addActiveVariant(localeFilter = listOf("en_US"))

assertTrue(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertTrue(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantDoesNotComplyWithLocaleFilterThenAddFiltersReturnsFalse() {
fun whenVariantDoesNotComplyWithLocaleFilterThenComputeFiltersReturnsFalse() {
val locale = Locale("en", "US")
Locale.setDefault(locale)
whenever(mockAppBuildConfig.deviceLocale).thenReturn(locale)
val testEntity = addActiveVariant(localeFilter = listOf("de_DE"))

assertFalse(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertFalse(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantComplyWithAndroidVersionFilterThenAddFiltersReturnsTrue() {
fun whenVariantComplyWithAndroidVersionFilterThenComputeFiltersReturnsTrue() {
whenever(mockAppBuildConfig.sdkInt).thenReturn(33)
val testEntity = addActiveVariant(androidVersionFilter = listOf("33", "34"))

assertTrue(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertTrue(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantDoesNotComplyWithAndroidVersionFilterThenAddFiltersReturnsFalse() {
fun whenVariantDoesNotComplyWithAndroidVersionFilterThenComputeFiltersReturnsFalse() {
whenever(mockAppBuildConfig.sdkInt).thenReturn(32)
val testEntity = addActiveVariant(androidVersionFilter = listOf("33", "34"))

assertFalse(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertFalse(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantComplyWithPrivacyProEligibleFilterThenAddFiltersReturnsTrue() = runTest {
fun whenVariantComplyWithPrivacyProEligibleFilterThenComputeFiltersReturnsTrue() = runTest {
whenever(mockSubscriptions.isEligible()).thenReturn(true)
val testEntity = addActiveVariant(privacyProEligible = true)

assertTrue(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertTrue(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantDoesNotComplyWithPrivacyProEligibleFilterThenAddFiltersReturnsFalse() = runTest {
fun whenVariantDoesNotComplyWithPrivacyProEligibleFilterThenComputeFiltersReturnsFalse() = runTest {
whenever(mockSubscriptions.isEligible()).thenReturn(false)
val testEntity = addActiveVariant(privacyProEligible = true)

assertFalse(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertFalse(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantComplyWithAllFiltersThenAddFiltersReturnsTrue() = runTest {
fun whenVariantComplyWithAllFiltersThenComputeFiltersReturnsTrue() = runTest {
val locale = Locale("en", "US")
Locale.setDefault(locale)
whenever(mockAppBuildConfig.deviceLocale).thenReturn(locale)
whenever(mockAppBuildConfig.sdkInt).thenReturn(33)
whenever(mockSubscriptions.isEligible()).thenReturn(false)
val testEntity = addActiveVariant(
Expand All @@ -112,33 +112,33 @@ class ExperimentFiltersManagerImplTest {
privacyProEligible = false,
)

assertTrue(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertTrue(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantComplyWithLocaleFiltersAndDoesNotComplyWithAndroidVersionFilterThenAddFiltersReturnsFalse() {
fun whenVariantComplyWithLocaleFiltersAndDoesNotComplyWithAndroidVersionFilterThenComputeFiltersReturnsFalse() {
val locale = Locale("en", "US")
Locale.setDefault(locale)
whenever(mockAppBuildConfig.deviceLocale).thenReturn(locale)
whenever(mockAppBuildConfig.sdkInt).thenReturn(32)
val testEntity = addActiveVariant(localeFilter = listOf("en_US"), androidVersionFilter = listOf("33", "34"))

assertFalse(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertFalse(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantComplyWithAndroidVersionFiltersAndDoesNotComplyWithLocaleFilterThenAddFiltersReturnsFalse() {
fun whenVariantComplyWithAndroidVersionFiltersAndDoesNotComplyWithLocaleFilterThenComputeFiltersReturnsFalse() {
val locale = Locale("en", "US")
Locale.setDefault(locale)
whenever(mockAppBuildConfig.deviceLocale).thenReturn(locale)
whenever(mockAppBuildConfig.sdkInt).thenReturn(33)
val testEntity = addActiveVariant(localeFilter = listOf("de_DE"), androidVersionFilter = listOf("33", "34"))

assertFalse(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertFalse(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

@Test
fun whenVariantComplyWithLocaleAndAndroidVersionFiltersAndDoesNotComplyWithPrivacyProEligibleThenAddFiltersReturnsFalse() = runTest {
fun whenVariantComplyWithLocaleAndAndroidVersionFiltersAndDoesNotComplyWithPrivacyProEligibleThenComputeFiltersReturnsFalse() = runTest {
val locale = Locale("en", "US")
Locale.setDefault(locale)
whenever(mockAppBuildConfig.deviceLocale).thenReturn(locale)
whenever(mockAppBuildConfig.sdkInt).thenReturn(33)
whenever(mockSubscriptions.isEligible()).thenReturn(true)
val testEntity = addActiveVariant(
Expand All @@ -147,7 +147,7 @@ class ExperimentFiltersManagerImplTest {
privacyProEligible = false,
)

assertFalse(testee.addFilters(testEntity).invoke(mockAppBuildConfig))
assertFalse(testee.computeFilters(testEntity).invoke(mockAppBuildConfig))
}

private fun addActiveVariant(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class VariantManagerImplTest {
fun setup() {
// mock randomizer always returns the first active variant
whenever(mockRandomizer.random(any())).thenReturn(0)
whenever(mockExperimentFiltersManager.addFilters(any())).thenReturn { true }
whenever(mockExperimentFiltersManager.computeFilters(any())).thenReturn { true }

testee = VariantManagerImpl(
mockRandomizer,
Expand Down

0 comments on commit 6f578d9

Please sign in to comment.