### Description
This moves the offline backend integration tests to run on M1 machines
in CircleCI.
Since this causes tests to be much more flaky, this includes a
cherry-pick of the changes in the 5.0 branch that improves those:
https://github.com/RevenueCat/purchases-ios/pull/3902
---------
Co-authored-by: Josh Holtz <me@joshholtz.com>
Co-authored-by: Will Taylor <wtaylor151@gmail.com>
Co-authored-by: Andy Boedo <andresboedo@gmail.com>
Checking for the presence of `Xcode/DerivedData` in the receipt path was
failing for TestFlight builds or if the .app bundle generated by Xcode
was moved from the folder.
Additionally, checking for `MASReceipt/receipt` seems less robust than
simply using compiler directives.
Instead, for macOS apps, we check the environment embedded in the receipt and alternatively check the signature of the app bundle.
---------
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
- Added `RevenueCatUI` to `Package.json`
- Set up tests for `RevenueCatUI` using `snapshot-testing` (not in CI
during initial development)
- Added Schemes to allow easily building packages while working on the
`Package.swift`
- Updated `SimpleApp` to use new package
This test had a race condition because it was assuming that the prior
transactions had already been posted.
Otherwise the only post receipt that happens is detected as `.queue`.
The existing implementation was posting them in sequence, which meant
that it was always going to make N requests.
With this new implementation we can ensure that only one request is made
for all transactions.
`RevenueCat` took 16 seconds on Xcode 15, now it takes 8 seconds.
### Changes
-
`HTTPClient.testPerformSerialRequestWaitsUntilRequestsAreDoneBeforeStartingNext`
took almost ~1 second because of the artificial delays, now it takes
0.1s
- `FileHandlerTests.testRemoveMultipleLinesOnLineFile` was really slow
(~1 second) because it was appending one line at a time
` DebugViewSwiftUITests` are slow because of the nature of snapshotting
images. I moved them to `StoreKitUnitTests` because that's the slower
suite.

Trying to work around `FB11799675`, this was suggested by @joshdholtz
and it seems to be working really well. This now calls
`deleteAllTransactions` and `SKTestSession.clearTransactions` _after_
every test, not only before.
The problem is that `clearTransactions` only seems to delete stuff from
`SKTestSession.allTransactions`, but not from
`StoreKit.Transaction.unfinished`. Doing this at the end of every test
seems to do a much better job at ensuring that each test invocation has
no leftover transaction, hopefully leading to fewer flaky failures.
Cherry-picked #2549 post refactors (#2540 and #2542). This becomes a lot
simpler since #2542, thanks to the fact that we can put this new
parameter in `PurchasedTransactionData`.
### Changes:
- Added `aadAttributionToken` to `PurchasedTransactionData`
- Exposed `AttributionPoster.adServicesTokenToPostIfNeeded`
- Added snapshot test to verify it's sent
- Added `PurchasesOrchestrator` tests (SK1/SK2) for sending the
attribution token
- Added missing `PurchasesOrchestrator` tests for sending attributes
- Added log when marking `AdServices` token as synced
- Exposed `Purchases.attribution` for custom entitlement computation
framework (and added to API tester)
- Exposed `Purchases.enableAdServicesAttributionTokenCollection` for
custom entitlement computation framework (and added to API tester)
This extracts the logic from `PurchasedProductsFetcher` and adds tests.
It will be used in #2536.
Also exposed and combined the duplicated `underlyingTransaction`
implementations.
See also #2397.
Xcode 14.3 introduced the following error:
> Heterogeneous collection literal could only be inferred to '[String :
Any]'; add explicit type annotation if this is intentional
### Changes:
- Added explicit types to fix this new error
- Removed unnecessary `@preconcurrency` imports
- Added new `CustomerInfo.emptyInfo` to reduce duplication of same fake
`CustomerInfo` creation
This is a follow up to #717.
In order to be able to reproduce #2338, which seems to be an issue only
on `watchOS`, it's important that we now run tests on `watchOS` as well.
We probably won't be able to fully replicate that issue since we don't
run tests on actual devices, so they'll still run on 64 bits. But this
way we might be able to prevent issues that are only reproducible on
`watchOS` in the future.
## Changes:
- Added CircleCI job
- Added lane
- Simplified `UnitTestsHostApp` definition using `SwiftUI`
- Increased _test only_ `watchOS` deployment target to 7.0 (this was
necessary to be able to have a common `@main` for the host app)
- Increased _test only_ `tvOS` deployment target to `14.0` (same as
above, plus we only run tvOS tests on the latest version anyway. We test
backwards compatibility through iOS already)
- Fixed test compilation on `watchOS`
- Disabled `HTTPClient` tests on `watchOS` (see
https://github.com/AliSoftware/OHHTTPStubs/issues/287)
- `StoreKitConfigTestCase` is only available from `watchOS 7.0` since
that's when `SKTestSession` was introduced
- Added `watchOS` support to `UnitTests` target
- Added `watchOS` support to `ReceiptParserTests` target
- Fixed `isFamilySharable` `watchOS` version checks for version 8.0
- Created new `CI-RevenueCat` Test Plan to only run unit tests and not
StoreKit tests on `watchOS`
Fixes [CSDK-629].
Depends on #2274 and #2267.
Entitlement verification is accomplished by preventing MiTM attacks
between the SDK and the RevenueCat server.
With verification enabled, the SDK ensures that the response created by
the server was not modified by a third-party, and the entitlements
received are exactly what was sent.
Entitlements are only verified if enabled using
`Configuration.Builder.with(entitlementVerificationMode:)`, which is
disabled by default.
### Changes:
- Added new `VerificationResult`, which replaces
`HTTPResponseVerificationResult`
- Renamed `Configuration.EntitlementVerificationLevel` to
`Configuration.EntitlementVerificationMode`
- `Configuration.with(entitlementVerificationMode:)` is now `public`
- Added `CustomerInfo.entitlementVerification`
- Added `EntitlementInfos.verification` and
`EntitlementInfo.verification`
- Added tests to cover serialization of these new values
- `CustomerInfoResponseHandler` copies the `ValidationResult` to
`CustomerInfo` (all operations that fetch `CustomerInfo` use this)
- Renamed "validation" to "verification" everywhere for consistency
- Finalized documentation
### TODO:
- [x] Figure out whether to use a separate type from
`HTTPResponseValidationResult` or rename that one
- [x] Figure out final API type and property names
- [x] Add tests for `CustomerInfo.copy(with:)`
- [x] Ensure validation result is encoded and decoded (for caching)
- [x] Add missing snapshots
[CSDK-629]:
https://revenuecats.atlassian.net/browse/CSDK-629?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
See #2066.
I saw a bunch of these messages:
> DEBUG: ℹ️ Finishing 0 transactions before running tests
Which doesn't add anything if there aren't any leftover transactions.
Filed this as `FB11799675`. I noticed some tests began with prior
transactions (despite using `SKTestSession.clearTransactions`), so this
workaround ensures each test begins in a clean state.
Follow up to #1882. After that PR, `StoreKit1Wrapper` was no longer
listening to
`SKPaymentQueueDelegate.paymentQueue(:shouldAddStorePayment:for:)`,
which means that purchases initiated from the App Store were being
ignored by the SDK if SK2 is enabled.
To fix this, `PaymentQueueWrapper` now becomes the
`SKPaymentQueueDelegate` only when `StoreKit1Wrapper` is not
initialized, and `PurchasesOrchestrator` initiates an SK2 purchase
instead.
## Other changes:
- `PurchasesOrchestrator` purchase methods no longer need the whole
`PromotionalOffer`, only the `SignedData`. This allows the new
implementation to create that data from only the `SKPaymentDiscount`
provided from the `SKPayment`.
- Added tests for `PromotionalOffer.SignedData`
The entire target had a deployment target of iOS 14.0 because
`SKTestSession` requires it. However, not all tests in that target use
`StoreKitConfigTestCase`, and those weren't running before iOS 14.0.
To fix this, I've removed the deployment target overrides from all
targets (expect for integration tests, those have a higher one for
simplicity), and instead defined them only once at the *project level*,
so all targets inherit that automatically.
`StoreKitConfigTestCase` will skip the test automatically if the iOS is
below 14.0, but the other tests will now run on iOS 12 and 13.
* Created PriceFormatterProvider
* Used provider to get the cached price formatter
* Created tests for PriceFormatterProvider
* Create a new test case to cover Storefront changes
* Changes after CR comments
* Update logic of how store and return price formatters
* Create a new price formatter if the currency code or locale is different
* moved test suites to Tests folder
* fixed outdated path
* fixed more outdated paths
* moved TestsPlans to Tests folder
* update path to Constants.swift