mirror of
https://github.com/RevenueCat/purchases-ios
synced 2026-11-11 22:55:55 +05:45
See #3599. This is listed in the [release notes](https://developer.apple.com/documentation/xcode-release-notes/xcode-15_3-release-notes) as fixed.
135 lines
4.3 KiB
Swift
135 lines
4.3 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 let hasWaited: Atomic<Bool> = false
|
|
private static let waitTimeInSeconds: TimeInterval? = {
|
|
ProcessInfo.processInfo.environment["CIRCLECI_STOREKIT_TESTS_DELAY_SECONDS"]
|
|
.flatMap(TimeInterval.init)
|
|
}()
|
|
|
|
var testSession: SKTestSession!
|
|
var userDefaults: UserDefaults!
|
|
|
|
override func setUp() async throws {
|
|
try await super.setUp()
|
|
|
|
try AvailabilityChecks.iOS14APIAvailableOrSkipTest()
|
|
|
|
// Avoid continuing with potentially bad data after a failed assertion
|
|
self.continueAfterFailure = false
|
|
|
|
self.testSession = try SKTestSession(configurationFileNamed: "UnitTestsConfiguration")
|
|
self.testSession.resetToDefaultState()
|
|
self.testSession.disableDialogs = true
|
|
self.testSession.clearTransactions()
|
|
|
|
await self.waitForStoreKitTestIfNeeded()
|
|
|
|
if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) {
|
|
await self.deleteAllTransactions(session: self.testSession)
|
|
}
|
|
|
|
let suiteName = "StoreKitConfigTests"
|
|
self.userDefaults = UserDefaults(suiteName: suiteName)
|
|
self.userDefaults.removePersistentDomain(forName: suiteName)
|
|
}
|
|
|
|
override func tearDown() async throws {
|
|
self.clearReceiptIfExists()
|
|
|
|
// `SKTestSession` might have not been initialized if the test was skipped.
|
|
if let session = self.testSession {
|
|
if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) {
|
|
await self.deleteAllTransactions(session: session)
|
|
}
|
|
session.clearTransactions()
|
|
}
|
|
|
|
try await super.tearDown()
|
|
}
|
|
|
|
// MARK: - Transactions observation
|
|
|
|
private static var transactionsObservation: Task<Void, Never>?
|
|
|
|
override class func setUp() {
|
|
super.setUp()
|
|
|
|
if #available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *) {
|
|
Self.transactionsObservation?.cancel()
|
|
Self.transactionsObservation = Task {
|
|
await Self.listenToTransactionUpdates()
|
|
}
|
|
}
|
|
}
|
|
|
|
override class func tearDown() {
|
|
Self.transactionsObservation?.cancel()
|
|
Self.transactionsObservation = nil
|
|
|
|
super.tearDown()
|
|
}
|
|
|
|
@available(iOS 15.0, tvOS 15.0, macOS 12.0, watchOS 8.0, *)
|
|
private static func listenToTransactionUpdates() async {
|
|
// Silence warning in tests:
|
|
// "Making a purchase without listening for transaction updates risks missing successful purchases.
|
|
for await _ in Transaction.updates {}
|
|
}
|
|
|
|
}
|
|
|
|
@available(iOS 14.0, tvOS 14.0, macOS 11.0, watchOS 7.0, *)
|
|
private extension StoreKitConfigTestCase {
|
|
|
|
func waitForStoreKitTestIfNeeded() async {
|
|
// 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 }
|
|
guard !Self.hasWaited.getAndSet(true) else { return }
|
|
|
|
Logger.warn(StoreKitTestMessage.delayingTest(waitTime))
|
|
|
|
try? await Task.sleep(nanoseconds: DispatchTimeInterval(waitTime).nanoseconds)
|
|
}
|
|
|
|
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(StoreKitTestMessage.errorRemovingReceipt(url, error))
|
|
}
|
|
}
|
|
|
|
}
|