mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-11 22:55:55 +05:45
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`
122 lines
3.7 KiB
Swift
122 lines
3.7 KiB
Swift
//
|
|
// Copyright RevenueCat Inc. All Rights Reserved.
|
|
//
|
|
// Licensed under the MIT License (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// https://opensource.org/licenses/MIT
|
|
//
|
|
// StoreKitConfigTestCase.swift
|
|
//
|
|
// Created by Andrés Boedo on 23/9/21.
|
|
|
|
import Foundation
|
|
import Nimble
|
|
@testable import RevenueCat
|
|
import StoreKitTest
|
|
import XCTest
|
|
|
|
/// Available from iOS 14.0 because that's when `SKTestSession` was introduced.
|
|
@available(iOS 14.0, tvOS 14.0, macOS 11.0, watchOS 7.0, *)
|
|
class StoreKitConfigTestCase: TestCase {
|
|
|
|
static var requestTimeout: TimeInterval = 60
|
|
static var requestDispatchTimeout: DispatchTimeInterval {
|
|
return .seconds(Int(Self.requestTimeout))
|
|
}
|
|
|
|
private static var hasWaited = false
|
|
private static let waitLock = Lock()
|
|
private static let waitTimeInSeconds: Double? = {
|
|
ProcessInfo.processInfo.environment["CIRCLECI_STOREKIT_TESTS_DELAY_SECONDS"]
|
|
.flatMap(Double.init)
|
|
}()
|
|
|
|
var testSession: SKTestSession!
|
|
var userDefaults: UserDefaults!
|
|
|
|
@MainActor
|
|
override func setUp() async throws {
|
|
try await super.setUp()
|
|
|
|
try AvailabilityChecks.iOS14APIAvailableOrSkipTest()
|
|
|
|
self.testSession = try SKTestSession(configurationFileNamed: "UnitTestsConfiguration")
|
|
self.testSession.resetToDefaultState()
|
|
self.testSession.disableDialogs = true
|
|
self.testSession.clearTransactions()
|
|
|
|
if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) {
|
|
await self.finishAllUnfinishedTransactions()
|
|
}
|
|
|
|
self.waitForStoreKitTestIfNeeded()
|
|
|
|
let suiteName = "StoreKitConfigTests"
|
|
self.userDefaults = UserDefaults(suiteName: suiteName)
|
|
self.userDefaults.removePersistentDomain(forName: suiteName)
|
|
}
|
|
|
|
override func tearDown() {
|
|
super.tearDown()
|
|
|
|
self.clearReceiptIfExists()
|
|
}
|
|
|
|
// MARK: - Transactions observation
|
|
|
|
private static var transactionsObservation: Task<Void, Never>?
|
|
|
|
override class func setUp() {
|
|
if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) {
|
|
Self.transactionsObservation?.cancel()
|
|
Self.transactionsObservation = Task {
|
|
// Silence warning in tests:
|
|
// "Making a purchase without listening for transaction updates risks missing successful purchases.
|
|
for await _ in Transaction.updates {}
|
|
}
|
|
}
|
|
}
|
|
|
|
override class func tearDown() {
|
|
Self.transactionsObservation?.cancel()
|
|
Self.transactionsObservation = nil
|
|
}
|
|
|
|
}
|
|
|
|
@available(iOS 14.0, tvOS 14.0, macOS 11.0, watchOS 7.0, *)
|
|
private extension StoreKitConfigTestCase {
|
|
|
|
func waitForStoreKitTestIfNeeded() {
|
|
// StoreKitTest seems to take a few seconds to initialize, and running tests before that
|
|
// might result in failure. So we give it a few seconds to load before testing.
|
|
|
|
guard let waitTime = Self.waitTimeInSeconds else { return }
|
|
|
|
Self.waitLock.perform {
|
|
if !Self.hasWaited {
|
|
Logger.warn("Delaying tests for \(waitTime) seconds for StoreKit initialization...")
|
|
|
|
Thread.sleep(forTimeInterval: waitTime)
|
|
|
|
Self.hasWaited = true
|
|
}
|
|
}
|
|
}
|
|
|
|
func clearReceiptIfExists() {
|
|
let manager = FileManager.default
|
|
|
|
guard let url = Bundle.main.appStoreReceiptURL, manager.fileExists(atPath: url.path) else { return }
|
|
|
|
do {
|
|
try manager.removeItem(at: url)
|
|
} catch {
|
|
Logger.appleWarning("Error attempting to remove receipt URL '\(url)': \(error)")
|
|
}
|
|
}
|
|
|
|
}
|