Skip to content

fix: align PurchasesConfiguration.Builder defaults with the inspector - #1018

Draft
vegaro wants to merge 4 commits into
mainfrom
cesar/unity-builder-defaults
Draft

fix: align PurchasesConfiguration.Builder defaults with the inspector#1018
vegaro wants to merge 4 commits into
mainfrom
cesar/unity-builder-defaults

Conversation

@vegaro

@vegaro vegaro commented Jul 28, 2026

Copy link
Copy Markdown
Member

Stacked on #1014, which is where these divergences surfaced. Follow-up to review comments from @rickvdl and Bugbot on that PR.

PurchasesConfiguration.Builder left three of its fields at C# zero values, so apps that configure through runtime setup and don't call the setter got different behavior than apps configured through the inspector. Build() hands these to Configure, which forwards them to the native SDKs verbatim, so the divergence reached users.

Field Inspector (Purchases.cs) Builder, before this PR
StoreKitVersion StoreKitVersion.Default StoreKit1
ShouldShowInAppMessagesAutomatically true false
EntitlementVerificationMode Informational Disabled

Each looks like an oversight rather than a decision:

  • StoreKit versionAdd support new native majors #485 replaced bool UsesStoreKit2IfAvailable with the StoreKitVersion enum. Under the bool, false coherently meant "don't use SK2"; after the migration the zero value came to mean "always use StoreKit 1". The inspector field was updated to .Default, the builder field wasn't. Pinning SK1 makes the win-back offer APIs fail on iOS 18+, since those require StoreKit 2 — with no indication the app ever opted into SK1.
  • In-app messages — the inspector field and the builder field landed in the same commit (Add support for configuring in-app messages #338), one with = true and one without an initializer. The inspector tooltip has always documented that "by default, those messages will be shown automatically". Runtime-setup apps got the opposite: billing-issue messages suppressed, and since the developer never chose to take over presentation, nothing calls ShowInAppMessages() either. Users with a failed renewal are never prompted to fix their payment method.
  • Trusted entitlementsChange default TrustedEntitlements mode to Informational #748 (Change default TrustedEntitlements mode to Informational) touched one line in one file, Purchases.cs. That default has therefore only ever applied to inspector users.

Behavior change

Only for apps using runtime setup that leave these unset — anyone calling the setters is unaffected, as is the whole inspector path.

Informational reports verification results but still grants entitlements when verification fails, so no user loses access; VerificationResult moves from NOT_REQUESTED to VERIFIED/FAILED. StoreKit version moves from forced SK1 to RevenueCat's choice, which is the documented default. In-app messages start showing, which is what the docs already promise.

Tests

BuildUsesDocumentedDefaults in #1014 now asserts the documented values, and goes back to earning its name (that PR had to rename it BuildUsesBuilderDefaults and annotate each divergence). Verified by running the Edit Mode suite locally against a rebuilt Purchases.unitypackage — 9/9 pass, and the same assertions pinned the old values on the parent commit, so both directions are covered.

Follow-up worth checking

The hybrid SDKs share this builder shape via purchases-hybrid-common, so RN / Flutter / Capacitor / Cordova may have inherited the same drift. Not checked in this PR.

vegaro and others added 2 commits July 27, 2026 14:19
Adds baseline tests exercising the harness end to end: Configure
forwarding through the wrapper spy, configuration builder defaults,
presented-offering-context resolution, and baseline JSON model
parsing.
BuildUsesDocumentedDefaults asserted default(...) for StoreKitVersion,
ShouldShowInAppMessagesAutomatically and EntitlementVerificationMode,
which read as an endorsement of values that diverge from the inspector
defaults on Purchases: the builder leaves these at their C# zero values,
so the runtime-setup path gets StoreKit 1, in-app messages disabled and
verification disabled.

Assert the explicit current values and name each divergence, so the test
guards today's behavior without claiming it is correct. Renamed to
BuildUsesBuilderDefaults to match. Fixing the defaults is a runtime
behavior change and is handled separately.

Co-Authored-By: Claude <noreply@anthropic.com>
vegaro and others added 2 commits July 28, 2026 11:06
- Assert the serialized UseWorkflows flag alongside AutoSyncPurchases, and
  build DangerousSettings with differing values so the two keys can't be
  confused for each other.
- Read the spy's only invocation instead of its last, matching what the
  Has.Count.EqualTo(1) guard already asserts.
- Add a SUBSCRIPTION case for productCategory. The UNKNOWN fallback test
  alone would still pass if Enum.TryParse stopped matching anything.

Co-Authored-By: Claude <noreply@anthropic.com>
The builder left three fields at their C# zero values, so apps configuring
through runtime setup silently got StoreKit 1, store in-app messages
disabled, and entitlement verification disabled -- while the inspector
fields on Purchases default to StoreKitVersion.Default, in-app messages
enabled, and Informational. Build() passes these straight to the native
SDKs, so the divergence was user visible:

- StoreKit 1 is pinned rather than letting RevenueCat pick, which makes
  the win-back offer APIs fail on iOS 18+ (they require StoreKit 2).
  Broken since #485 replaced UsesStoreKit2IfAvailable with the enum.
- Store in-app messages are suppressed, so users with billing issues are
  never prompted to fix their payment method. The inspector tooltip has
  always documented the opposite. Broken since #338 added the setting.
- Trusted entitlements stayed Disabled, so #748's change of the default
  to Informational only ever reached inspector users.

Give the three fields explicit initializers matching the inspector, and
assert the documented values in BuildUsesDocumentedDefaults.

Co-Authored-By: Claude <noreply@anthropic.com>
@vegaro
vegaro force-pushed the cesar/unity-builder-defaults branch from 4f1f683 to f7f5321 Compare July 28, 2026 09:18
Base automatically changed from cesar/unity-configuration-smoke-tests to main July 28, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant