Skip to content
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

[Paywalls V2] New overrides structure #2120

Merged
merged 7 commits into from
Feb 7, 2025
Merged

[Paywalls V2] New overrides structure #2120

merged 7 commits into from
Feb 7, 2025

Conversation

tonidero
Copy link
Contributor

@tonidero tonidero commented Feb 6, 2025

Motivation

Migrating overrides from a structured object to an array of override objects

Description

Previously

Overrides were a very structure object that had all of the different types of states/conditions that allowed base properties of a component to be overridden. However, this was not flexible when it came to multiple being activated as it was missing for cases when multiples types of conditions were being evaluated.

Now

Overrides is an array that has an array of conditions and properties. It will get applied in order from first to last IF all of the conditions are true.

This allows the FE/BE to determine the orders of overrides from lowest to higher priority so all of the SDKs/renderers don't need to duplicate that logic.

Android equivalent of RevenueCat/purchases-ios#4705

UNSUPPORTED,
}

private object ConditionSerializer : KSerializer<Condition> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit confused with this one... The backend right now returns an object with a type property but in iOS, we deserialize that directly to the Condition enum so I followed the same pattern... I'm not sure if we add more properties to that object, if we would be able to expose it with this API though...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could automatically deserialize an object with only a type property if we make Condition sealed, and make its cases (Kotlin) objects instead of an enum. However, we would still need a custom serializer to handle the UNSUPPORTED case, so we wouldn't really gain anything in that respect haha.

As an example, TabControlComponent is a Kotlin object, because it's JSON is:

{ "type": "tab_control" }

Making Condition sealed now would maybe make it slightly easier to "migrate" (big word) if we ever add more properties to it. But we can also cross that bridge when we get there, as this is not public. I'd say whatever you prefer!


@RunWith(Enclosed::class)
internal class ComponentOverridesTests {

// This tests deserialization of ComponentOverrides containing PartialTextComponent and PartialImageComponent, just
// to make sure deserialization of generics works as expected.

@RunWith(Parameterized::class)
@RunWith(ParameterizedRobolectricTestRunner::class)
Copy link
Contributor Author

@tonidero tonidero Feb 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding a test where a log gets called (when a condition is unknown). It was failing with the junit runner since it doesn't know the Log android class.

Copy link

codecov bot commented Feb 6, 2025

Codecov Report

Attention: Patch coverage is 80.64516% with 6 lines in your changes missing coverage. Please review.

Project coverage is 80.62%. Comparing base (424d477) to head (45d7416).
Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
...es/paywalls/components/common/ComponentOverride.kt 86.20% 2 Missing and 2 partials ⚠️
...at/purchases/paywalls/components/ImageComponent.kt 0.00% 1 Missing ⚠️
...cat/purchases/paywalls/components/TextComponent.kt 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2120      +/-   ##
==========================================
+ Coverage   80.60%   80.62%   +0.01%     
==========================================
  Files         273      273              
  Lines        9143     9166      +23     
  Branches     1287     1289       +2     
==========================================
+ Hits         7370     7390      +20     
- Misses       1232     1236       +4     
+ Partials      541      540       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tonidero tonidero marked this pull request as ready for review February 6, 2025 18:24
@tonidero tonidero requested review from JayShortway and a team February 6, 2025 18:24
Copy link
Member

@JayShortway JayShortway left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice job! 💪 Just a comment on ignoring unknown JSON keys in condition, and some suggestions for tests.

UNSUPPORTED,
}

private object ConditionSerializer : KSerializer<Condition> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could automatically deserialize an object with only a type property if we make Condition sealed, and make its cases (Kotlin) objects instead of an enum. However, we would still need a custom serializer to handle the UNSUPPORTED case, so we wouldn't really gain anything in that respect haha.

As an example, TabControlComponent is a Kotlin object, because it's JSON is:

{ "type": "tab_control" }

Making Condition sealed now would maybe make it slightly easier to "migrate" (big word) if we ever add more properties to it. But we can also cross that bridge when we get there, as this is not public. I'd say whatever you prefer!

@@ -58,6 +56,33 @@ internal class ToPresentedOverridesTests(@Suppress("UNUSED_PARAMETER") name: Str
medium to FontSpec.System("medium"),
expanded to FontSpec.System("expanded"),
)

private val defaultAvailableOverrides = listOf(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea haha!

@tonidero tonidero force-pushed the new-overrides-system branch from 3e53119 to 8862d9a Compare February 7, 2025 12:05
@tonidero tonidero force-pushed the new-overrides-system branch from 8862d9a to a6ae83d Compare February 7, 2025 12:12
@tonidero tonidero merged commit a07303d into main Feb 7, 2025
10 checks passed
@tonidero tonidero deleted the new-overrides-system branch February 7, 2025 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants