Option picking refactor and tests #349
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Changes in this pull request
Checklist
CHANGELOG.mdfor any breaking changes, enhancements, or bug fixes.ktlintin the main directory and fixed any issues.Greptile Overview
Greptile Summary
Refactored product option selection from string-based to type-safe sealed classes (
BasePlanTypeandOfferType), introducing support forsw-autoandsw-nonespecial values.Key changes:
BasePlanTypesealed class (Auto, Specific) to replace nullable stringbasePlanIdOfferTypesealed class (Auto, None, Specific) withtoOffer()conversion methodDecomposedProductIdsto parse and use these type-safe representationsDecomposedProductIdsTest, 135 inOfferTypeTest, 246 inPaywallProductIdsTest)StoreManagerusing the newtoOffer()methodPaywall.productIdsto fallback toproducts_v3whenproducts_v2is emptyAdditional changes:
AutomaticPurchaseController.syncSubscriptionStatusAndWait()andqueryPurchasesOfType()Confidence Score: 4/5
AutomaticPurchaseControllerwarrant verification to ensure they don't inadvertently consume purchases that should persist (e.g., non-consumable in-app purchases or purchases that need to be validated server-side first).superwall/src/main/java/com/superwall/sdk/store/AutomaticPurchaseController.kt- verify the in-app purchase consumption behavior is intentional and won't affect non-consumable productsImportant Files Changed
Sequence Diagram
sequenceDiagram participant Client as SDK Client participant QueryUseCase as QueryProductDetailsUseCase participant Decomposer as DecomposedProductIds participant RawProduct as RawStoreProduct participant OfferSelection as Offer Selection Logic participant BillingClient as Google BillingClient Client->>QueryUseCase: Query products (productId:basePlan:offer) QueryUseCase->>Decomposer: Parse product ID Decomposer->>Decomposer: Split by ":" Decomposer->>Decomposer: Parse basePlan (sw-auto → Auto, specific ID → Specific) Decomposer->>Decomposer: Parse offer (sw-auto → Auto, sw-none → None, specific ID → Specific) Decomposer-->>QueryUseCase: DecomposedProductIds(basePlanType, offerType) QueryUseCase->>BillingClient: Query product details from Google Play BillingClient-->>QueryUseCase: ProductDetails QueryUseCase->>RawProduct: Create RawStoreProduct(details, basePlanType, offerType) RawProduct->>OfferSelection: getSelectedOfferDetails() alt One-Time Purchase Product OfferSelection->>OfferSelection: Check offerType alt offerType is None (sw-none) OfferSelection->>OfferSelection: Filter purchase options without offers OfferSelection->>OfferSelection: Select cheapest option else offerType is Specific OfferSelection->>OfferSelection: Filter by specific offer ID else offerType is Auto OfferSelection->>OfferSelection: Select option with lowest price end OfferSelection-->>RawProduct: SelectedOfferDetails.OneTime else Subscription Product OfferSelection->>OfferSelection: Check basePlanType alt basePlanType is Specific OfferSelection->>OfferSelection: Filter offers by base plan ID else basePlanType is Auto OfferSelection->>OfferSelection: Use first base plan end OfferSelection->>OfferSelection: Check offerType alt offerType is Auto OfferSelection->>OfferSelection: Find longest free trial OfferSelection->>OfferSelection: Or find cheapest offer else offerType is None OfferSelection->>OfferSelection: Use base plan only else offerType is Specific OfferSelection->>OfferSelection: Find offer by ID end OfferSelection-->>RawProduct: SelectedOfferDetails.Subscription end RawProduct-->>QueryUseCase: StoreProduct with selected offer QueryUseCase-->>Client: List<StoreProduct>