Skip to content

Commit

Permalink
Paywalls: add test coverage for locales with different region (#1600)
Browse files Browse the repository at this point in the history
Test coverage to ensure that Android isn't affected by
RevenueCat/purchases-ios#3633.

I've also extracted `getDefaultLocales` and
`localizedConfiguration(List<Locale>)` so we can test those.
  • Loading branch information
NachoSoto committed Feb 6, 2024
1 parent 202ac70 commit bad03da
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package com.revenuecat.purchases.paywalls

import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.os.LocaleListCompat
import androidx.annotation.VisibleForTesting
import com.revenuecat.purchases.utils.convertToCorrectlyFormattedLocale
import com.revenuecat.purchases.utils.getDefaultLocales
import com.revenuecat.purchases.utils.serializers.OptionalURLSerializer
import com.revenuecat.purchases.utils.serializers.URLSerializer
import com.revenuecat.purchases.utils.sharedLanguageCodeWith
Expand Down Expand Up @@ -50,20 +51,22 @@ data class PaywallData(
val localizedConfiguration: Pair<Locale, LocalizedConfiguration>
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
get() {
val preferredLocales = LocaleListCompat.getDefault()

for (i in 0 until preferredLocales.size()) {
preferredLocales.get(i)?.let { locale: Locale ->
val localeToCheck = locale.convertToCorrectlyFormattedLocale()
configForLocale(localeToCheck)?.let { localizedConfiguration ->
return (localeToCheck to localizedConfiguration)
}
}
}
return localizedConfiguration(locales = getDefaultLocales())
}

return fallbackLocalizedConfiguration
@VisibleForTesting
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun localizedConfiguration(locales: List<Locale>): Pair<Locale, LocalizedConfiguration> {
for (locale in locales) {
val localeToCheck = locale.convertToCorrectlyFormattedLocale()
configForLocale(localeToCheck)?.let { localizedConfiguration ->
return (localeToCheck to localizedConfiguration)
}
}

return fallbackLocalizedConfiguration
}

private val fallbackLocalizedConfiguration: Pair<Locale, LocalizedConfiguration>
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
get() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.revenuecat.purchases.utils

import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.os.LocaleListCompat
import com.revenuecat.purchases.common.errorLog
import java.util.Locale
import java.util.MissingResourceException
Expand Down Expand Up @@ -38,6 +39,13 @@ internal fun Locale.sharedLanguageCodeWith(locale: Locale): Boolean {
}
}

/**
* @return list of Locales from LocaleListCompat.getDefault()
*/
fun getDefaultLocales(): List<Locale> {
return LocaleListCompat.getDefault().toList()
}

@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private fun Locale.inferScript(): String {
if (!script.isNullOrEmpty()) {
Expand All @@ -54,3 +62,9 @@ private fun Locale.inferScript(): String {
else -> ""
}
}

private fun LocaleListCompat.toList(): List<Locale> {
return Array(size()) {
this.get(it)
}.filterNotNull()
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,19 @@ class PaywallDataTest {
assertThat(localization.title).isEqualTo("Tienda")
}

@Test
fun `localized configuration finds locale with different region`() {
val paywall: PaywallData = decode(PAYWALLDATA_SAMPLE1)

val configuration = paywall.localizedConfiguration(
locales = listOf(
Locale("en", "IN")
)
)
assertThat(configuration).isNotNull
assertThat(configuration.second.title).isEqualTo("Paywall")
}

@Test
fun `decodes empty images as null`() {
val paywall: PaywallData = decode(PAYWALLDATA_EMPTY_IMAGES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ class LocaleExtensionsTest {
assertThat(locale.sharedLanguageCodeWith(otherLocale)).isTrue
}

@Test
fun `sharedLanguageCodeWith - returns true without region`() {
val locale = Locale("en")
val otherLocale = Locale("en", "IN")
assertThat(locale.sharedLanguageCodeWith(otherLocale)).isTrue
assertThat(otherLocale.sharedLanguageCodeWith(locale)).isTrue
}

@Test
fun `sharedLanguageCodeWith - returns false when locales don't share language code`() {
val locale = Locale("es", "ES")
Expand All @@ -70,4 +78,14 @@ class LocaleExtensionsTest {
val otherLocale = Locale("zh-Hans")
assertThat(locale.sharedLanguageCodeWith(otherLocale)).isFalse
}

@Test
fun `getDefaultLocales returns the correct list`() {
// Note: this is primarily to test that we use LocaleListCompat correctly.
// It might fail locally, but it's meant to be checked on CI where we know this will be the locale.
// Fix-me: only run this on CI.
assertThat(
getDefaultLocales().map { it.toString() }
).isEqualTo(listOf("en_US"))
}
}

0 comments on commit bad03da

Please sign in to comment.