* feat(remote-config): wire manager behind feature flag
* fix(remote-config): only mark refresh fresh after cache write
* feat(remote-config): source API base host from remote-config sources
Resolve the API base host from the shared RemoteConfigSourceProvider (with
the embedded defaults as a floor) instead of the hardcoded apiBaseURL, so
requests can fail over across API hosts. proxyURL and an overridden
apiBaseURL still pin the host and bypass API sources, and per-endpoint
fallback URLs are unchanged.
The provider is created once in the composition root (gated on
remoteConfigEnabled) and injected explicitly into Backend/HTTPClient; nil
preserves the existing SystemInfo.apiBaseURL behavior.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): derive nullable API source provider and manager from remoteConfigEnabled
Create the RemoteConfigSourceProvider (and its shared on-disk cache) up front,
gated on remoteConfigEnabled, and build the RemoteConfigManager from the
provider's nullability after Backend exists so it can reuse backend.remoteConfigAPI.
Keeps a single shared source provider + disk cache across the networking layer
and the manager, and avoids touching the disk cache directory when remote config
is disabled.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): drop redundant remote-config wiring comment
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): drop redundant remote-config manager comment
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): simplify APISourceProviding doc comment
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): always wire API source provider, gate only disk cache
Create the RemoteConfigSourceProvider unconditionally and inject it into
Backend/HTTPClient so main-API host resolution runs even when remote config
is disabled (embedded default sources as the floor). Only the on-disk cache
and the real RemoteConfigManager stay gated on remoteConfigEnabled; the
provider's topic store is now optional (nil means defaults-only).
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): rename APISourceProviding to APISourceProviderType
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(remote-config): resolve web billing host from API sources
The web billing paths are hosted on the same api.revenuecat.com host as the
main API, so they should resolve their base host from the API source provider
too (with failover) instead of the static serverHostURL.
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): drop redundant web billing API-sources comments
The comments restated what the code and surrounding context already convey.
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(remote-config): assert ETag retry stays on the API source host
Co-authored-by: Cursor <cursoragent@cursor.com>
* refactor(remote-config): drop APISourceProviderType, use RemoteConfigSourceProviderType directly
The networking layer depended on the narrow APISourceProviderType protocol, an extra
abstraction over RemoteConfigSourceProviderType that added little. Fold currentAPISource()
into RemoteConfigSourceProviderType and have HTTPClient/Backend depend on it directly.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(remote-config): wire apiSourceProvider into dedicated remote-config lane
The main-into-branch merge left `HTTPClient.dedicatedRemoteConfig` (and its
call site) without the new `apiSourceProvider` argument, breaking compilation.
Thread the provider through so the dedicated `/config` lane also resolves its
base host from remote-config API sources, matching the main lane.
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: gate remote-config API sources behind usesRemoteConfigAPISources
Resolve main-API request hosts from the remote-config API sources only when
the `usesRemoteConfigAPISources` dangerous setting is enabled. When disabled
(the default), requests keep targeting the static `SystemInfo.apiBaseURL`.
Enable the setting in the API-source `HTTPClient` tests and add a test
asserting an injected provider is ignored while the setting is off.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(test): pass apiSourceProvider in BackendRemoteConfigLaneTests HTTPClient init
The lane test constructed HTTPClient without the now-required apiSourceProvider
argument, breaking compilation of the unit test target after merging main.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Rick van der Linden <rick.vanderlinden@revenuecat.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* Add validation logic for Test Store API keys under the TEST_STORE compiler flag
* add unit test for test store api key validation
* Move API key validation to `configure` and store validation result in `SystemInfo`
* start new flow for purchase of `TestStoreProduct`s
* WIP: implement alert for purchase of a Test Store product
* Add file to Xcode workspace
* WIP: implement fake purchase alert in all platforms and OSs
* Enforce only one test purchases at once. Use constants for test purchase alert strings
* Place new test store purchase APIs under the TEST_STORE compiler flag
* fix lint
* fix unit tests after change of internal APIs
* PR comments
* temporarily return hardcoded `CustomerInfo` on confirmed test purchase
* tests: adapt unit tests to new `TestStorePurchaseHandler` dependency of `PurchasesOrchestrator`
* fix lint
* Fix backend integration tests compilation
* Remove deprecation warning
* remove unnecessary OSs checks
Since the minimum supported versions of the SDK are iOS 13 and tvOS 13
* add `GetWebProductsOperation`
* avoid duplicating decoding objects from WebOfferingProductsResponse and WebProductsResponse
* add missing tests snapshots
* Add `WebProductsResponse.ProductType` enum
* Fix tests
* add web products decoding tests
* Rename WebProducts to WebBillingProducts
* (more) rename WebProducts to WebBillingProducts
* (even more) rename WebProducts to WebBillingProducts
* Move `getWebBillingProducts` outside of `OfferingsAPI` into a new `WebBillingAPI` object
* improve test
* remove unnecessary `sorted()` of `Set`
* fix lint
* fix tests
Since the GetWebBilling request path contains an unordered set of productIds, which the tests do not support, we're only doing snapshot tests with 1 product ID
* fix more tests
* Change to use new endpoint to fetch web product info
* [skip ci] Generating new test snapshots (#5142)
* [skip ci] Generating new test snapshots (#5141)
* [skip ci] Generating new test snapshots (#5140)
* [skip ci] Generating new test snapshots (#5139)
* [skip ci] Generating new test snapshots (#5138)
* [skip ci] Generating new test snapshots (#5137)
* [skip ci] Generating new test snapshots (#5136)
* Add small utility function to know if offerings has any web biling offering available
---------
Co-authored-by: RevenueCat Git Bot <72824662+RCGitBot@users.noreply.github.com>
* Add support for fetching web billing products
* Some fixes
* Escape product ids
* Fixes from review
* Support etags
* Change to Int64
* Add method to MockOfferingsAPI