From 6a9f0a51337a4a3c7e0eac7d435f7151b038168b Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Thu, 26 Oct 2023 13:14:29 -0700 Subject: [PATCH] `Paywalls`: ignore URL deserialization errors Note that this is only for the optional URLs, `assetBaseURL` is still required, but I'll handle errors there in a separate PR. --- .../purchases/paywalls/PaywallData.kt | 8 ++++-- .../purchases/paywalls/URLSerializer.kt | 27 ++++++++++++++++++- .../purchases/paywalls/PaywallDataTest.kt | 8 ++++++ .../resources/paywalldata-empty-images.json | 2 ++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/PaywallData.kt b/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/PaywallData.kt index 5ef82a4094..df640b64ac 100644 --- a/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/PaywallData.kt +++ b/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/PaywallData.kt @@ -116,12 +116,16 @@ data class PaywallData( /** * If set, the paywall will display a terms of service link. */ - @SerialName("tos_url") @Serializable(with = URLSerializer::class) val termsOfServiceURL: URL? = null, + @SerialName("tos_url") + @Serializable(with = OptionalURLSerializer::class) + val termsOfServiceURL: URL? = null, /** * If set, the paywall will display a privacy policy link. */ - @SerialName("privacy_url") @Serializable(with = URLSerializer::class) val privacyURL: URL? = null, + @SerialName("privacy_url") + @Serializable(with = OptionalURLSerializer::class) + val privacyURL: URL? = null, /** * The set of colors used. diff --git a/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/URLSerializer.kt b/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/URLSerializer.kt index bfce093ec1..e5d31cfda1 100644 --- a/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/URLSerializer.kt +++ b/purchases/src/main/kotlin/com/revenuecat/purchases/paywalls/URLSerializer.kt @@ -1,13 +1,15 @@ package com.revenuecat.purchases.paywalls import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.nullable import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import java.net.MalformedURLException import java.net.URL -object URLSerializer : KSerializer { +internal object URLSerializer : KSerializer { override val descriptor = PrimitiveSerialDescriptor("URL", PrimitiveKind.STRING) override fun deserialize(decoder: Decoder): URL { @@ -18,3 +20,26 @@ object URLSerializer : KSerializer { encoder.encodeString(value.toString()) } } + +/** + * Equivalent to URLSerializer but allows empty or invalid URLs. + */ +internal object OptionalURLSerializer : KSerializer { + private val delegate = URLSerializer.nullable + override val descriptor = PrimitiveSerialDescriptor("URL?", PrimitiveKind.STRING) + + override fun deserialize(decoder: Decoder): URL? { + return try { + delegate.deserialize(decoder) + } catch (e: MalformedURLException) { + null + } + } + + override fun serialize(encoder: Encoder, value: URL?) { + when (value) { + null -> encoder.encodeString("") + else -> delegate.serialize(encoder, value) + } + } +} diff --git a/purchases/src/test/java/com/revenuecat/purchases/paywalls/PaywallDataTest.kt b/purchases/src/test/java/com/revenuecat/purchases/paywalls/PaywallDataTest.kt index 10bedac4ad..e484c4a8a4 100644 --- a/purchases/src/test/java/com/revenuecat/purchases/paywalls/PaywallDataTest.kt +++ b/purchases/src/test/java/com/revenuecat/purchases/paywalls/PaywallDataTest.kt @@ -112,6 +112,14 @@ class PaywallDataTest { assertThat(images.icon).isNull() } + @Test + fun `does not fail to decode invalid URLs`() { + val paywall: PaywallData = decode(PAYWALLDATA_EMPTY_IMAGES) + + assertThat(paywall.config.privacyURL).isNull() + assertThat(paywall.config.termsOfServiceURL).isNull() + } + @Test fun `paywall color can be created from a ColorInt`() { val colorInt = Color.parseColor("#FFAABB") diff --git a/purchases/src/test/resources/paywalldata-empty-images.json b/purchases/src/test/resources/paywalldata-empty-images.json index 36bc8a37d4..1bf578c1b3 100644 --- a/purchases/src/test/resources/paywalldata-empty-images.json +++ b/purchases/src/test/resources/paywalldata-empty-images.json @@ -17,6 +17,8 @@ "background": " ", "icon": null }, + "privacy_url": "invalid url", + "tos_url": "unrecognized:?/2 URL", "colors": { "light": { "background": "#FFFFFF",