Skip to content

Commit

Permalink
Paywalls: decode empty images as null
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Oct 26, 2023
1 parent 26d5832 commit ea90b14
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.revenuecat.purchases.paywalls

import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.nullable
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

/**
* Decodes empty or blank strings as null
*/
internal object EmptyStringToNullSerializer : KSerializer<String?> {
private val delegate = String.serializer().nullable

override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
"EmptyStringToNullSerializer",
PrimitiveKind.STRING
)

override fun deserialize(decoder: Decoder): String? {
return delegate.deserialize(decoder)?.takeIf(String::isNotBlank)
}

override fun serialize(encoder: Encoder, value: String?) {
when (value) {
null -> encoder.encodeString("")
else -> encoder.encodeString(value)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,19 @@ data class PaywallData(
/**
* Image displayed as a header in a template.
*/
@Serializable(with = EmptyStringToNullSerializer::class)
val header: String? = null,

/**
* Image displayed as a background in a template.
*/
@Serializable(with = EmptyStringToNullSerializer::class)
val background: String? = null,

/**
* Image displayed as an app icon in a template.
*/
@Serializable(with = EmptyStringToNullSerializer::class)
val icon: String? = null,
) {
internal val all: List<String>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package com.revenuecat.purchases.paywalls

import android.graphics.Color
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.revenuecat.purchases.common.OfferingParser
import com.revenuecat.purchases.utils.toLocale
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -15,16 +15,14 @@ import java.util.*

private const val PAYWALLDATA_SAMPLE1 = "paywalldata-sample1.json"
private const val PAYWALLDATA_MISSING_CURRENT_LOCALE = "paywalldata-missing_current_locale.json"
private const val PAYWALLDATA_EMPTY_IMAGES = "paywalldata-empty-images.json"

@RunWith(AndroidJUnit4::class)
@Config(manifest = Config.NONE)
class PaywallDataTest {

@Test
fun `test PaywallData properties`() {
val json = loadJSON(PAYWALLDATA_SAMPLE1)

val paywall: PaywallData = Json.decodeFromString(json)
val paywall: PaywallData = decode(PAYWALLDATA_SAMPLE1)

assertThat(paywall.templateName).isEqualTo("1")
assertThat(paywall.assetBaseURL).isEqualTo(URL("https://rc-paywalls.s3.amazonaws.com"))
Expand Down Expand Up @@ -78,9 +76,7 @@ class PaywallDataTest {

@Test
fun `finds locale if it only has language`() {
val json = loadJSON(PAYWALLDATA_SAMPLE1)

val paywall: PaywallData = Json.decodeFromString(json)
val paywall: PaywallData = decode(PAYWALLDATA_SAMPLE1)

val enConfig = paywall.configForLocale(Locale("en"))
assertThat(enConfig?.title).isEqualTo("Paywall")
Expand All @@ -91,25 +87,31 @@ class PaywallDataTest {

@Test
fun `does not return a locale if no matching language`() {
val json = loadJSON(PAYWALLDATA_SAMPLE1)

val paywall: PaywallData = Json.decodeFromString(json)
val paywall: PaywallData = decode(PAYWALLDATA_SAMPLE1)

val enConfig = paywall.configForLocale(Locale("fr"))
assertThat(enConfig).isNull()
}

@Test
fun `if current locale is missing it loads available locale`() {
val json = loadJSON(PAYWALLDATA_MISSING_CURRENT_LOCALE)

val paywall: PaywallData = Json.decodeFromString(json)
val paywall: PaywallData = decode(PAYWALLDATA_MISSING_CURRENT_LOCALE)

val localization = paywall.localizedConfiguration.second
assertThat(localization.callToAction).isEqualTo("Comprar")
assertThat(localization.title).isEqualTo("Tienda")
}

@Test
fun `decodes empty images as null`() {
val paywall: PaywallData = decode(PAYWALLDATA_EMPTY_IMAGES)

val images = paywall.config.images
assertThat(images.background).isNull()
assertThat(images.header).isNull()
assertThat(images.icon).isNull()
}

@Test
fun `paywall color can be created from a ColorInt`() {
val colorInt = Color.parseColor("#FFAABB")
Expand All @@ -121,5 +123,6 @@ class PaywallDataTest {
}

private fun loadJSON(jsonFileName: String) = File(javaClass.classLoader!!.getResource(jsonFileName).file).readText()

private fun decode(file: String): PaywallData =
OfferingParser.json.decodeFromString(loadJSON(file))
}
32 changes: 32 additions & 0 deletions purchases/src/test/resources/paywalldata-empty-images.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"template_name": "1",
"localized_strings": {
"en_US": {
"title": "Paywall",
"subtitle": "Description",
"call_to_action": "Purchase now",
"call_to_action_with_intro_offer": "Purchase now",
"offer_details": "{{ sub_price_per_month }} per month",
"offer_details_with_intro_offer": "Start your {{ sub_offer_duration }} trial, then {{ sub_price_per_month }} per month"
}
},
"config": {
"packages": ["$rc_monthly", "$rc_annual"],
"images": {
"header": "",
"background": " ",
"icon": null
},
"colors": {
"light": {
"background": "#FFFFFF",
"text_1": "#FFFFFF",
"call_to_action_background": "#FFFFFF",
"call_to_action_foreground": "#FFFFFF",
"accent_1": "#FFFFFF"
},
"dark": null
}
},
"asset_base_url": "https://rc-paywalls.s3.amazonaws.com"
}

0 comments on commit ea90b14

Please sign in to comment.