Skip to content

Add regression tests for merged bridge fixes and make the runtime test suite runnable - #18

Open
bilck wants to merge 7 commits into
superwall:mainfrom
bilck:test/bridge-regression-specs
Open

bilck wants to merge 7 commits into
superwall:mainfrom
bilck:test/bridge-regression-specs

Conversation

@bilck

@bilck bilck commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Why

Several bridge fixes merged without a test (#5, #7, #8, #9, #11), so nothing stops them from coming back. 0.3.0 already regressed one earlier fix in the Android serializer (#13). These tests pin each fix to the payload the native bridges send today, so a test both documents the contract and catches a regression.

Stacked on #13. This branch contains #13's two fix commits and its harness commit (the ci~/android-harness/bridge-tests source set and the native.yml step). Review or merge #13 first; this PR then reduces to the last commit.

Changes

C# (Tests/Runtime/BridgeRegressionTests.cs):

Kotlin (ci~/android-harness/bridge-tests, run by native.yml):

Runtime test assembly made runnable. Superwall.Tests.asmdef was restricted to the Editor platform, so its [UnityTest]s ran in EditMode, where BridgeCallbackHandler.Initialize calls DontDestroyOnLoad and throws. All 33 tests failed in EditMode, and PlayMode found none. The assembly now targets all platforms and runs in PlayMode. It is still compiled only with UNITY_INCLUDE_TESTS, so player builds are unaffected. Two existing tests asserted DoesNotThrow on payloads that the handler reports with an error log. They now expect that log, because Unity fails a test on any unexpected error.

Verification

  • C#, PlayMode, Unity 6000.5, in a throwaway project that loads this checkout as a local package with "testables": ["com.superwall.sdk"]: 33/33 pass.
  • The tests catch the regressions they guard. With the culture-dependent price parse and the setter that drops entitlements restored, the price test and the setter test fail (2 failures, all others pass).
  • Kotlin, AGP 8.5.2: 7/7 pass (4 new plus Preserve entitlements in Android subscription status #13's 3). The AGP 9.0.1 job has only run in CI.
  • unity.yml is still parked, so CI does not run the C# tests yet. The local recipe above is what this PR used.

Not covered (no harness exists for it)

The Swift halves of #3 (event-param sanitizer), #6 (onDismiss product id), #7, #8 and #9. Proposal: add an XCTest target to ci~/ios-harness/Package.swift and an xcodebuild test step with an iOS Simulator destination in native.yml; the bridge's serializers would need internal visibility for @testable import. I have no macOS machine to build and run it on, so it is not part of this PR.

bilck added 7 commits October 23, 2026 01:19
The Android harness gains a test source set (ci~/android-harness/bridge-tests, nothing test-only ships in
the package) and the native workflow runs it on both AGP versions. The first test pins what
getSubscriptionStatus() hands to C#: an active status carries every entitlement in the full entitlement
shape, and inactive/unknown carry no entitlements key. Removing the entitlements from the serializer fails
two of the three tests.

The harness also keeps the androidlib's build outputs under ci~/android-harness/build instead of inside
Plugins/Android/SuperwallSDK.androidlib, and accepts -PbuildToolsVersion for machines without AGP's default
build-tools.
…nd make the runtime suite runnable

C# (Tests/Runtime/BridgeRegressionTests.cs), each test feeding what the native bridges send today:
- SubscriptionStatus keeps its entitlements read from native (subscriptionStatusDidChange) and written
  to native (the setter's payload), the fix in superwall#5.
- SuperwallEventInfo.EventType parses Android snake_case, iOS camelCase and the two remapped names (superwall#7).
- Delegate events carry product, transaction and paywall info, and leave them null when absent (superwall#9).
- Product prices parse the same under pt-BR whether they arrive as strings (Android) or numbers (iOS) (superwall#11).
- Entitlements deserialize every field in the shared vocabulary, and an Android-only offer type stays
  null (superwall#8, C# side).

Kotlin (ci~/android-harness/bridge-tests): the Android serializer emits every entitlement field in the
C# vocabulary, maps GRACE_PERIOD / BILLING_RETRY to the C# names, omits absent optionals and drops
UNKNOWN (superwall#8, Android side).

The runtime test assembly was restricted to the Editor platform, so its UnityTests ran in EditMode, where
BridgeCallbackHandler.Initialize's DontDestroyOnLoad throws: all 33 tests failed there and none were found
in PlayMode. It now targets all platforms and runs in PlayMode: 33/33 pass locally (Unity 6000.5). Two
existing tests asserted DoesNotThrow on payloads the handler reports with an error log; they now expect
that log, as Unity fails a test on an unexpected error.

Each new C# test was checked against the bug it guards: restoring the culture-dependent price parse and
the entitlement-less setter fails the price and setter tests.
AGP 9 creates unit-test tasks only for the tested build type (debug) by default, so testReleaseUnitTest did not exist on the AGP 9.0.1 job.
… no test ran

On AGP 9 the srcDirs reassignment was ignored and testDebugUnitTest went NO-SOURCE, a green job that ran nothing. srcDir() (plus the Kotlin source set where the DSL has one) works on AGP 8.5.2 and 9.0.1 (7 tests each, checked locally). The CI step now also requires the JUnit result files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant