-
Notifications
You must be signed in to change notification settings - Fork 50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PaywallData validation tests #1310
Changes from 8 commits
0ed3970
0fa14da
a6507bc
a5e05af
66f1a22
b2850fe
68a535b
6054cce
5875da0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
package com.revenuecat.purchases.ui.revenuecatui | ||
|
||
import androidx.test.ext.junit.runners.AndroidJUnit4 | ||
import com.revenuecat.purchases.Offering | ||
import com.revenuecat.purchases.paywalls.PaywallColor | ||
import com.revenuecat.purchases.paywalls.PaywallData | ||
import com.revenuecat.purchases.ui.revenuecatui.data.testdata.TestData | ||
import com.revenuecat.purchases.ui.revenuecatui.data.testdata.offerings.offeringWithMultiPackagePaywall | ||
import com.revenuecat.purchases.ui.revenuecatui.errors.PaywallValidationError | ||
import com.revenuecat.purchases.ui.revenuecatui.helpers.validatedPaywall | ||
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 | ||
import java.io.File | ||
import java.net.URL | ||
|
||
@RunWith(AndroidJUnit4::class) | ||
class PaywallDataValidationTest { | ||
|
||
@Test | ||
fun `Validate an offering without paywall`() { | ||
val offering = TestData.offeringWithNoPaywall | ||
val paywallValidationResult = getPaywallValidationResult(offering) | ||
assertThat(paywallValidationResult.error).isEqualTo(PaywallValidationError.MissingPaywall) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Awesome |
||
} | ||
|
||
@Test | ||
fun `Validate a valid paywall`() { | ||
val offering = TestData.template1Offering | ||
val paywallValidationResult = getPaywallValidationResult(offering) | ||
assertThat(paywallValidationResult.error).isNull() | ||
} | ||
|
||
@Test | ||
fun `Unrecognized template name generates default paywall`() { | ||
val templateName = "unrecognized_template" | ||
val originalOffering = TestData.template2Offering | ||
val offering = originalOffering.copy(paywall = originalOffering.paywall!!.copy(templateName = templateName)) | ||
|
||
val paywallValidationResult = getPaywallValidationResult(offering) | ||
|
||
verifyPackages(paywallValidationResult.displayablePaywall, originalOffering.paywall!!) | ||
compareWithDefaultTemplate(paywallValidationResult.displayablePaywall) | ||
assertThat(paywallValidationResult.error).isEqualTo(PaywallValidationError.InvalidTemplate(templateName)) | ||
} | ||
|
||
@Test | ||
fun `Unrecognized variable generates default paywall`() { | ||
val originalOffering = TestData.template2Offering | ||
|
||
val paywall = originalOffering.paywall!!.let { originalPaywall -> | ||
val (locale, originalLocalizedConfiguration) = originalPaywall.localizedConfiguration | ||
val localizedConfiguration = originalLocalizedConfiguration.copy( | ||
title = "Title with {{ unrecognized_variable }}", | ||
callToAction = "{{ future_variable }}", | ||
) | ||
originalPaywall.copy(localization = mapOf(locale.toString() to localizedConfiguration)) | ||
} | ||
|
||
val offering = originalOffering.copy(paywall = paywall) | ||
val paywallValidationResult = getPaywallValidationResult(offering) | ||
verifyPackages(paywallValidationResult.displayablePaywall, originalOffering.paywall!!) | ||
compareWithDefaultTemplate(paywallValidationResult.displayablePaywall) | ||
assertThat(paywallValidationResult.error).isEqualTo( | ||
PaywallValidationError.InvalidVariables(setOf("unrecognized_variable", "future_variable")) | ||
) | ||
} | ||
|
||
@Test | ||
fun `Unrecognized variables in features generate default paywall`() { | ||
val originalOffering = TestData.template2Offering | ||
|
||
val paywall = originalOffering.paywall!!.let { originalPaywall -> | ||
val (locale, originalLocalizedConfiguration) = originalPaywall.localizedConfiguration | ||
val localizedConfiguration = originalLocalizedConfiguration.copy( | ||
features = listOf( | ||
PaywallData.LocalizedConfiguration.Feature( | ||
title = "{{ future_variable }}", | ||
content = "{{ new_variable }}" | ||
), | ||
PaywallData.LocalizedConfiguration.Feature( | ||
title = "{{ another_one }}" | ||
) | ||
) | ||
) | ||
originalPaywall.copy(localization = mapOf(locale.toString() to localizedConfiguration)) | ||
} | ||
|
||
val offering = originalOffering.copy(paywall = paywall) | ||
val paywallValidationResult = getPaywallValidationResult(offering) | ||
verifyPackages(paywallValidationResult.displayablePaywall, originalOffering.paywall!!) | ||
compareWithDefaultTemplate(paywallValidationResult.displayablePaywall) | ||
assertThat(paywallValidationResult.error).isEqualTo( | ||
PaywallValidationError.InvalidVariables(setOf("future_variable", "new_variable", "another_one")) | ||
) | ||
} | ||
|
||
@Test | ||
fun `Unrecognized icons generate default paywall`() { | ||
val originalOffering = TestData.template2Offering | ||
|
||
val paywall = originalOffering.paywall!!.let { originalPaywall -> | ||
val (locale, originalLocalizedConfiguration) = originalPaywall.localizedConfiguration | ||
val localizedConfiguration = originalLocalizedConfiguration.copy( | ||
features = listOf( | ||
PaywallData.LocalizedConfiguration.Feature( | ||
title = "Feature Title", | ||
iconID = "an_unrecognized_icon", | ||
), | ||
) | ||
) | ||
originalPaywall.copy(localization = mapOf(locale.toString() to localizedConfiguration)) | ||
} | ||
|
||
val offering = originalOffering.copy(paywall = paywall) | ||
val paywallValidationResult = getPaywallValidationResult(offering) | ||
verifyPackages(paywallValidationResult.displayablePaywall, originalOffering.paywall!!) | ||
compareWithDefaultTemplate(paywallValidationResult.displayablePaywall) | ||
assertThat(paywallValidationResult.error).isEqualTo( | ||
PaywallValidationError.InvalidIcons(setOf("an_unrecognized_icon")) | ||
) | ||
} | ||
|
||
private fun getPaywallValidationResult(offering: Offering) = offering.validatedPaywall( | ||
currentColorScheme = TestData.Constants.currentColorScheme, | ||
) | ||
|
||
private fun verifyPackages(actual: PaywallData, expectation: PaywallData) { | ||
assertThat(actual.config.packages).isEqualTo(expectation.config.packages) | ||
} | ||
|
||
private fun compareWithDefaultTemplate(displayablePaywall: PaywallData) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice!! This is a great idea There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes... the only issue I am seeing wiht this approach is that it's very hard to see what fails in tests... It will just say that both paywall datas are different and print them both, without printing the actual difference. I might replace it with asserting all properties to be honest |
||
val json = File(javaClass.classLoader!!.getResource("default_template.json").file).readText() | ||
val defaultPaywall: PaywallData = Json.decodeFromString(json) | ||
|
||
assertThat(displayablePaywall.assetBaseURL).isEqualTo(defaultPaywall.assetBaseURL) | ||
assertThat(displayablePaywall.templateName).isEqualTo(defaultPaywall.templateName) | ||
assertThat(displayablePaywall.revision).isEqualTo(defaultPaywall.revision) | ||
|
||
(displayablePaywall.config to defaultPaywall.config).let { (config, defaultConfig) -> | ||
assertThat(config.blurredBackgroundImage).isEqualTo(defaultConfig.blurredBackgroundImage) | ||
assertColors(config.colors.light, defaultConfig.colors.light) | ||
assertColors(config.colors.dark!!, defaultConfig.colors.dark!!) | ||
assertThat(config.displayRestorePurchases).isEqualTo(defaultConfig.displayRestorePurchases) | ||
assertThat(config.images.background).isEqualTo(defaultConfig.images.background) | ||
assertThat(config.images.header).isEqualTo(defaultConfig.images.header) | ||
assertThat(config.images.icon).isEqualTo(defaultConfig.images.icon) | ||
assertThat(config.packages).containsExactly(*defaultConfig.packages.toTypedArray()) | ||
assertThat(config.defaultPackage).isEqualTo(defaultConfig.defaultPackage) | ||
assertThat(config.termsOfServiceURL).isEqualTo(defaultConfig.termsOfServiceURL) | ||
assertThat(config.privacyURL).isEqualTo(defaultConfig.privacyURL) | ||
} | ||
|
||
assertThat(displayablePaywall.localizedConfiguration).isEqualTo(defaultPaywall.localizedConfiguration) | ||
} | ||
|
||
private fun assertColors( | ||
actualColors: PaywallData.Configuration.Colors, | ||
defaultColors: PaywallData.Configuration.Colors, | ||
) { | ||
assertThat(actualColors.accent1).isEqualTo(defaultColors.accent1) | ||
assertThat(actualColors.accent2).isEqualTo(defaultColors.accent2) | ||
assertThat(actualColors.background).isEqualTo(defaultColors.background) | ||
assertThat(actualColors.callToActionBackground).isEqualTo(defaultColors.callToActionBackground) | ||
assertThat(actualColors.callToActionForeground).isEqualTo(defaultColors.callToActionForeground) | ||
assertThat(actualColors.text1).isEqualTo(defaultColors.text1) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👏🏻 |
||
"asset_base_url" : "https:", | ||
"config" : { | ||
"blurred_background_image" : true, | ||
"colors" : { | ||
"light" : { | ||
"accent_1" : "#000000", | ||
"accent_2" : "#FFFFFF", | ||
"background" : "#FFFFFF", | ||
"call_to_action_background" : "#000000", | ||
"call_to_action_foreground" : "#FFFFFF", | ||
"text_1" : "#FFFFFF" | ||
}, | ||
"dark" : { | ||
"accent_1" : "#000000", | ||
"accent_2" : "#FFFFFF", | ||
"background" : "#000000", | ||
"call_to_action_background" : "#000000", | ||
"call_to_action_foreground" : "#000000", | ||
"text_1" : "#FFFFFF" | ||
} | ||
}, | ||
"display_restore_purchases" : true, | ||
"images" : { | ||
"background" : "default_background", | ||
"header" : null, | ||
"icon" : "revenuecatui_default_paywall_app_icon" | ||
}, | ||
"packages" : [ | ||
"$rc_annual", | ||
"$rc_monthly" | ||
], | ||
"privacy_url" : null, | ||
"tos_url" : null | ||
}, | ||
"localized_strings" : { | ||
"en_US" : { | ||
"call_to_action" : "Continue", | ||
"call_to_action_with_intro_offer" : null, | ||
"features" : [ | ||
|
||
], | ||
"offer_details" : "{{ total_price_and_per_month }}", | ||
"offer_details_with_intro_offer" : "Start your {{ sub_offer_duration }} trial, then {{ total_price_and_per_month }}.", | ||
"offer_name" : null, | ||
"subtitle" : null, | ||
"title" : "{{ app_name }}" | ||
} | ||
}, | ||
"revision" : -1, | ||
"template_name" : "2" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻