Commit Graph
44 Commits
Author SHA1 Message Date
Will Taylor 6de169a23e support fetching eligible win-back offers for a product 2024-11-06 15:46:04 -06:00
NachoSoto 2bcd0ce328 5.0.0 changes: support SK2 by default 2024-07-01 14:37:21 -05:00
Toni Rico c23d61651a Bring back offline integration tests on M1 (#3976)
### Description
This was introduced in #3961 and reverted temporarily in #3974. This
brings the changes back.
2024-06-21 08:58:48 +02:00
Toni Rico b63332be0e Revert "Run offline backend integration tests on M1 machines (#3961)" (#3974)
### Description
This reverts #3961. This was causing some problems in our iOS 12 tests,
so we're leaving them out from this release:
https://app.circleci.com/pipelines/github/RevenueCat/purchases-ios/19858/workflows/c470dc5c-03a8-4893-badd-5ea9a961f1a2/jobs/223279
2024-06-19 19:57:24 +02:00
d8f172e6a6 Run offline backend integration tests on M1 machines (#3961)
### 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>
2024-06-19 17:26:29 +02:00
NachoSoto d0bb035b72 Xcode 15.3 beta 1: fix warnings on tests (#3600)
Depends on #3599.
2024-01-26 08:41:38 +01:00
NachoSoto 65028b86f8 SandboxEnvironmentDetector: more tests for macOS (#3568) 2024-01-10 13:37:16 -08:00
NachoSoto 589580c8fa Tests: running tests on macOS (#3533) 2024-01-09 18:07:05 -08:00
Mark VillacampaandNachoSoto 84806ad86e Improve sandbox detector for macOS apps (#3549)
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>
2024-01-09 19:12:47 +01:00
32c63cdb46 [SK2] Add support for StoreKit Config files in SK2 (#3365)
When using StoreKit Config file, we do not have access to the
transaction history or subscription status server-side.

To work around this, we introduce a new `StoreKit2Receipt` type that
closely resembles the structure of an SK1 receipt and contains all the
transaction history and subscription status for the customer. It can be
sent in a single request to `/receipt`

---------

Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>
Co-authored-by: Distiller <distiller@static.38.39.183.137.cyberlynk.net>
Co-authored-by: Distiller <distiller@static.38.23.40.89.cyberlynk.net>
Co-authored-by: Distiller <distiller@static.38.39.185.65.cyberlynk.net>
Co-authored-by: NachoSoto <NachoSoto@users.noreply.github.com>
2023-12-13 17:00:37 +01:00
235a7dcdc1 StoreKit 2: Optionally send JWS tokens instead of receipts to the backend (#3227)
- Added a new option `usesStoreKit2JWS` under `DangerousSettings`. If
enabled, the SDK will send a JWS token instead of a receipt to the
applicable backend endpoints.
- The option must be used in conjunction with `usesStoreKit2IfAvailable`
configuration option.

### ToDo

- [x] Send JWS token when making a purchase in SK2 mode
- [x] Send JWS token when calculating promo offer eligibility
- [x] Update `syncTransactions` to send the latest transaction JWS.
- [x] Add tests

---------

Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>
Co-authored-by: Distiller <distiller@static.38.39.183.118.cyberlynk.net>
Co-authored-by: Distiller <distiller@static.198.206.135.125.macminivault.com>
Co-authored-by: Distiller <distiller@static.38.23.39.112.cyberlynk.net>
Co-authored-by: Distiller <distiller@static.38.39.183.58.cyberlynk.net>
Co-authored-by: Distiller <distiller@static.38.39.185.87.cyberlynk.net>
2023-10-16 22:45:29 +02:00
NachoSoto 8bb5482ada Integration Tests: add coverage for Purchases.customerInfoStream (#3213)
I noticed we had no integration tests for this.
2023-09-15 12:12:58 -07:00
NachoSoto d07123f77d Paywalls: fixed iOS 12 build (#3104) 2023-09-14 18:28:11 -07:00
NachoSoto 69a18fa410 Paywalls: initial RevenueCatUI target setup (#2776)
- 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
2023-09-14 18:28:11 -07:00
NachoSoto 5972790838 Integration Tests: another flaky failure (#3165) 2023-09-08 07:28:12 -07:00
NachoSoto d4145e6fca Integration Tests: fixed race condition in flaky test (#3086)
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`.
2023-08-24 15:25:29 -07:00
NachoSoto 581a048308 CustomerInfoManager: post transactions in parallel to POST receipts only once (#2954)
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.
2023-08-11 15:39:44 -07:00
NachoSoto 73d914f866 iOS 17: added tests for simulating cancellations (#2597) 2023-07-18 06:08:58 -07:00
NachoSoto edd5a238da Tests: optimized several tests (#2754)
`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.

![Screenshot 2023-07-06 at 08 33
06](https://github.com/RevenueCat/purchases-ios/assets/685609/1ca64916-b9b0-4ab0-a3ee-dc50abaceeea)
2023-07-07 19:22:20 +02:00
NachoSoto 7f875ae212 Changed Logger to use os_log (#2608) 2023-06-15 15:13:48 -07:00
NachoSoto 551cb2d8d2 DebugView: added snapshot tests (#2630)
UI tests for #2567.
2023-06-13 08:54:36 -07:00
NachoSoto 89ef553ba2 verifyNoUnfinishedTransactions/verifyUnfinishedTransaction: added missing #file parameter (#2625) 2023-06-13 06:34:00 -07:00
NachoSoto 2a95520b98 StoreKitConfigTestCase/BaseStoreKitIntegrationTests: also clear transactions after every test (#2616)
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.
2023-06-12 08:52:09 -07:00
NachoSoto db17623197 Improved finishAllUnfinishedTransactions (#2615) 2023-06-12 07:07:13 -07:00
NachoSoto a18d3b4fca PostReceiptOperation: added ability to also post AdServices token (#2566)
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)
2023-05-31 10:03:55 -07:00
NachoSoto b8fba2e322 Created StoreKit2TransactionFetcher (#2539)
This extracts the logic from `PurchasedProductsFetcher` and adds tests.
It will be used in #2536.

Also exposed and combined the duplicated `underlyingTransaction`
implementations.
2023-05-25 10:18:39 -07:00
NachoSoto e9e6d887c2 Offline Entitlements: integration tests (#2501)
## Example tests:
```swift
func testOfferingsAreCachedInMemory() async throws {
    let onlineOfferings = try await Purchases.shared.offerings()
    expect(onlineOfferings.all).toNot(beEmpty())

    self.serverDown()

    let offlineOfferings = try await Purchases.shared.offerings()
    expect(offlineOfferings) === onlineOfferings
}

func testOfferingsAreCachedOnDisk() async throws {
    let onlineOfferings = try await Purchases.shared.offerings()
    expect(onlineOfferings.all).toNot(beEmpty())

    self.serverDown()
    await self.resetPurchases()

    let offlineOfferings = try await Purchases.shared.offerings()
    expect(offlineOfferings.response) == onlineOfferings.response

    let offering = try XCTUnwrap(offlineOfferings.current)
    expect(offering.availablePackages.count) == onlineOfferings.current?.availablePackages.count
    expect(offering.monthly?.storeProduct.productIdentifier) == "com.revenuecat.monthly_4.99.1_week_intro"
}
```
2023-05-19 10:54:42 -07:00
NachoSoto 7b3b03d2b3 Xcode 14.3: fixed compilation errors (#2399)
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
2023-04-11 08:55:21 -07:00
339e13d5f1 Offline Entitlements: create CustomerInfo from offline entitlements (#2358)
Based on #2352.
Depends on #2351 and #2365.

---------

Co-authored-by: Andy Boedo <andresboedo@gmail.com>
Co-authored-by: Toni Rico <antonio.rico.diez@revenuecat.com>
2023-03-24 10:41:10 -07:00
NachoSoto 2fff5b0b75 CI: also run tests on watchOS (#2340)
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`
2023-03-16 13:11:24 -07:00
NachoSoto 84eed758c1 Introduced Configuration.EntitlementVerificationMode and VerificationResult (#2277)
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
2023-02-17 16:49:21 -08:00
NachoSoto 9ccd002b3b StoreKitTestHelpers: cleaned up unnecessary log (#2177)
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.
2022-12-20 14:02:59 -08:00
NachoSoto c8ed10d9a0 Extracted asyncWait to poll async conditions in tests (#2134)
This is necessary because we can't use `Quick` v6.x yet.

Abstracting this out to use it in #2069.
2022-12-15 08:51:15 -08:00
NachoSoto cd4e33cfe8 SKTestSession: finish all unfinished transactions before starting each test (#2066)
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.
2022-11-25 16:20:15 -08:00
NachoSoto 72a9f57103 PaymentQueueWrapper: handle promotional purchase requests from App Store when SK1 is disabled (#1901)
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`
2022-09-21 12:03:05 -07:00
NachoSoto a9874f86a1 StoreKitUnitTests: compile on iOS 11.0+ (#1904)
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.
2022-09-15 10:08:49 -07:00
NachoSoto 348d8fadde Added StoreKit2Setting.shouldOnlyUseStoreKit2 (#1881)
A couple of helpers that can be useful, for #1882 for example.
2022-09-04 14:42:30 -07:00
NachoSoto 0bff3f65fe Sendable support (#1795)
Fixes [CSDK-379] and https://github.com/RevenueCat/purchases-ios/issues/1041#issuecomment-1206445939

[CSDK-379]: https://revenuecats.atlassian.net/browse/CSDK-379?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

### Main changes:
- `Sendable` conformances to all types that are thread-safe
- `@unchecked Sendable` for types that the compiler can't enforce, but with documentation as to why
- Made classes that aren't mocked `final` (note that this doesn't change the API, because none of these were `open` to begin with)
- Made some classes thread-safe that weren't (like `DeviceCache`)

For the non-`final` `class`es, I've actually managed to compile the SDK with all of them as `final` and `Sendable`, to make sure that making them `@unchecked Sendable` didn't hide any other issues.

### Future improvements:
- https://twitter.com/nachosoto/status/1557139992056500224?s=21&t=arWdvEzTIFANBvwqQ0vPiA
- https://twitter.com/nachosoto/status/1557141944777592832?s=21&t=arWdvEzTIFANBvwqQ0vPiA
- https://twitter.com/nachosoto/status/1557143374922059776?s=21&t=arWdvEzTIFANBvwqQ0vPiA

### Depends on:
- #1794
- #1804
- #1806
- #1807
- #1808
- #1813
- #1822
- #1823
- #1824
- #1825
- #1826
2022-08-31 13:30:38 -07:00
NachoSoto c3279a57fa StoreKitConfigTestCase.changeStorefront: re-enabled on iOS 16 (#1811)
See #1701.

Apple fixed this in beta 5!
2022-08-09 14:27:44 -07:00
NachoSoto cffd2a4a51 Disabled tests that rely on StoreKitConfigTestCase.changeStorefront on iOS 16.0 (#1701)
This is currently broken on iOS 16.
I filed [CSDK-261] to make sure we review this before the GM is out.

I filed a Radar:
![Screen Shot 2022-06-14 at 11 34 34](https://user-images.githubusercontent.com/685609/173663713-9f413017-5726-43df-b0af-6d48d09dde83.png)

We might have to wait for a future beta, or find a workaround.

[CSDK-261]: https://revenuecats.atlassian.net/browse/CSDK-261?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
2022-06-30 08:57:04 -07:00
NachoSoto f774692845 Added Storefront.currentStorefront (#1502)
Follow up to #1052
2022-04-13 17:30:48 -04:00
NachoSoto 16e3e64a52 Added XCTAsyncUnwrap to simplify XCTUnwrap usage with async (#1501)
Because Swift (still?) doesn't have support for "`reasync`", this currently required 2 lines.
2022-04-13 17:29:07 -04:00
Juanpe Catalán 27e49f9470 Optimize price formatter (#1374)
* 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
2022-03-24 16:41:15 -03:00
aboedo d1ddd6bf9c Clean up tests folders (#1402)
* moved test suites to Tests folder

* fixed outdated path

* fixed more outdated paths

* moved TestsPlans to Tests folder

* update path to Constants.swift
2022-03-21 10:26:00 -03:00