Skip to content

Commit

Permalink
SystemInfo: added ClockType (#3014)
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto authored and MarkVillacampa committed Sep 6, 2023
1 parent 976659c commit 4c790d3
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 30 deletions.
2 changes: 2 additions & 0 deletions RevenueCat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@
4F6BEE3B2A27B45300CD9322 /* StoreKitTestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 571E7AD3279F2D0C003B3606 /* StoreKitTestHelpers.swift */; };
4F6BEE3C2A27B45900CD9322 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE61A83264190830021CEA0 /* Constants.swift */; };
4F6BEE882A27E16B00CD9322 /* TestLogHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57057FF728B0048900995F21 /* TestLogHandler.swift */; };
4F6E81982A81BC30006EF181 /* TestClock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 578DAA492948EF4F001700FD /* TestClock.swift */; };
4F6E81E62A82AAE1006EF181 /* HTTPRequestPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F6E81E52A82AAE1006EF181 /* HTTPRequestPath.swift */; };
4F6EEBD92A38ED76007FD783 /* FakeSigning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F6EEBD82A38ED76007FD783 /* FakeSigning.swift */; };
4F7C37B22A27E2E8001E17D3 /* AsyncTestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 575A8EE02922C56300936709 /* AsyncTestHelpers.swift */; };
Expand Down Expand Up @@ -3144,6 +3145,7 @@
4FA4C9752A16D49E007D2803 /* MockOfflineEntitlementsManager.swift in Sources */,
F5E5E2EE28479BD000216ECD /* ProductsFetcherSK2Tests.swift in Sources */,
3543913626F90D6A00E669DF /* TrialOrIntroPriceEligibilityCheckerSK1Tests.swift in Sources */,
4F6E81982A81BC30006EF181 /* TestClock.swift in Sources */,
2D34D9D227481D9B00C05DB6 /* TrialOrIntroPriceEligibilityCheckerSK2Tests.swift in Sources */,
2D90F8C726FD221D009B9142 /* MockASN1ContainerBuilder.swift in Sources */,
F535515F286B5BE5009CA47A /* MockOfferingsManager.swift in Sources */,
Expand Down
12 changes: 12 additions & 0 deletions Sources/Misc/DateAndTime/Clock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,15 @@ final class Clock: ClockType {
static let `default`: Clock = .init()

}

extension ClockType {

func durationSince(_ startTime: DispatchTime) -> TimeInterval {
if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *) {
return startTime.distance(to: self.currentTime).seconds
} else {
return TimeInterval(self.currentTime.uptimeNanoseconds - startTime.uptimeNanoseconds) / 1_000_000_000
}
}

}
12 changes: 0 additions & 12 deletions Sources/Misc/DateAndTime/TimingUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,3 @@ private extension TimingUtil {
}

}

private extension ClockType {

func durationSince(_ startTime: DispatchTime) -> TimingUtil.Duration {
if #available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.2, *) {
return startTime.distance(to: self.currentTime).seconds
} else {
return TimingUtil.Duration(self.currentTime.uptimeNanoseconds - startTime.uptimeNanoseconds) / 1_000_000_000
}
}

}
5 changes: 4 additions & 1 deletion Sources/Misc/SystemInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class SystemInfo {
let platformFlavorVersion: String?
let responseVerificationMode: Signing.ResponseVerificationMode
let dangerousSettings: DangerousSettings
let clock: ClockType

var finishTransactions: Bool {
get { return self._finishTransactions.value }
Expand Down Expand Up @@ -107,7 +108,8 @@ class SystemInfo {
sandboxEnvironmentDetector: SandboxEnvironmentDetector = BundleSandboxEnvironmentDetector.default,
storeKit2Setting: StoreKit2Setting = .default,
responseVerificationMode: Signing.ResponseVerificationMode = .default,
dangerousSettings: DangerousSettings? = nil) {
dangerousSettings: DangerousSettings? = nil,
clock: ClockType = Clock.default) {
self.platformFlavor = platformInfo?.flavor ?? "native"
self.platformFlavorVersion = platformInfo?.version
self._bundle = .init(bundle)
Expand All @@ -118,6 +120,7 @@ class SystemInfo {
self.sandboxEnvironmentDetector = sandboxEnvironmentDetector
self.responseVerificationMode = responseVerificationMode
self.dangerousSettings = dangerousSettings ?? DangerousSettings()
self.clock = clock
}

/// Asynchronous API if caller can't ensure that it's invoked in the `@MainActor`
Expand Down
2 changes: 1 addition & 1 deletion Sources/Networking/Backend.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Backend {
let httpClient = HTTPClient(apiKey: apiKey,
systemInfo: systemInfo,
eTagManager: eTagManager,
signing: Signing(apiKey: apiKey),
signing: Signing(apiKey: apiKey, clock: systemInfo.clock),
requestTimeout: httpClientTimeout)
let config = BackendConfiguration(httpClient: httpClient,
operationDispatcher: operationDispatcher,
Expand Down
9 changes: 3 additions & 6 deletions Sources/Purchasing/ReceiptFetcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class ReceiptFetcher {
private let requestFetcher: StoreKitRequestFetcher
private let receiptParser: PurchasesReceiptParser
private let fileReader: FileReader
private let clock: ClockType

private let lastReceiptRefreshRequest: Atomic<Date?> = nil

Expand All @@ -29,14 +28,12 @@ class ReceiptFetcher {
requestFetcher: StoreKitRequestFetcher,
systemInfo: SystemInfo,
receiptParser: PurchasesReceiptParser = .default,
fileReader: FileReader = DefaultFileReader(),
clock: ClockType = Clock.default
fileReader: FileReader = DefaultFileReader()
) {
self.requestFetcher = requestFetcher
self.systemInfo = systemInfo
self.receiptParser = receiptParser
self.fileReader = fileReader
self.clock = clock
}

func receiptData(refreshPolicy: ReceiptRefreshPolicy, completion: @escaping (Data?, URL?) -> Void) {
Expand Down Expand Up @@ -97,7 +94,7 @@ class ReceiptFetcher {
return false
}

let timeSinceLastRequest = DispatchTimeInterval(self.clock.now.timeIntervalSince(lastRefresh))
let timeSinceLastRequest = DispatchTimeInterval(self.systemInfo.clock.now.timeIntervalSince(lastRefresh))
return timeSinceLastRequest < ReceiptRefreshPolicy.alwaysRefreshThrottleDuration
}

Expand Down Expand Up @@ -155,7 +152,7 @@ private extension ReceiptFetcher {
}

func refreshReceipt(_ completion: @escaping (Data, URL?) -> Void) {
self.lastReceiptRefreshRequest.value = self.clock.now
self.lastReceiptRefreshRequest.value = self.systemInfo.clock.now

self.requestFetcher.fetchReceiptData {
completion(self.receiptData() ?? Data(), self.receiptURL)
Expand Down
6 changes: 4 additions & 2 deletions Tests/UnitTests/Mocks/MockSystemInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ class MockSystemInfo: SystemInfo {

convenience init(finishTransactions: Bool,
storeKit2Setting: StoreKit2Setting = .default,
customEntitlementsComputation: Bool = false) {
customEntitlementsComputation: Bool = false,
clock: ClockType = TestClock()) {
let dangerousSettings = DangerousSettings(customEntitlementComputation: customEntitlementsComputation)
self.init(platformInfo: nil,
finishTransactions: finishTransactions,
storeKit2Setting: storeKit2Setting,
dangerousSettings: dangerousSettings)
dangerousSettings: dangerousSettings,
clock: clock)
}

override func isApplicationBackgrounded(completion: @escaping (Bool) -> Void) {
Expand Down
9 changes: 7 additions & 2 deletions Tests/UnitTests/Purchasing/Purchases/BasePurchasesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ class BasePurchasesTests: TestCase {
self.mockPaymentQueueWrapper = MockPaymentQueueWrapper()

self.userDefaults = UserDefaults(suiteName: Self.userDefaultsSuiteName)
self.systemInfo = MockSystemInfo(finishTransactions: true, storeKit2Setting: self.storeKit2Setting)
self.clock = TestClock()
self.systemInfo = MockSystemInfo(finishTransactions: true,
storeKit2Setting: self.storeKit2Setting,
clock: self.clock)
self.deviceCache = MockDeviceCache(sandboxEnvironmentDetector: self.systemInfo,
userDefaults: self.userDefaults)
self.requestFetcher = MockRequestFetcher()
Expand Down Expand Up @@ -144,6 +147,7 @@ class BasePurchasesTests: TestCase {
var subscriberAttributesManager: MockSubscriberAttributesManager!
var attribution: Attribution!
var identityManager: MockIdentityManager!
var clock: TestClock!
var systemInfo: MockSystemInfo!
var mockOperationDispatcher: MockOperationDispatcher!
var mockIntroEligibilityCalculator: MockIntroEligibilityCalculator!
Expand Down Expand Up @@ -206,7 +210,8 @@ class BasePurchasesTests: TestCase {
func setUpPurchasesObserverModeOn() {
self.systemInfo = MockSystemInfo(platformInfo: nil,
finishTransactions: false,
storeKit2Setting: self.storeKit2Setting)
storeKit2Setting: self.storeKit2Setting,
clock: self.clock)
self.initializePurchasesInstance(appUserId: nil)
}

Expand Down
9 changes: 5 additions & 4 deletions Tests/UnitTests/Purchasing/ReceiptFetcherTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,17 @@ class BaseReceiptFetcherTests: TestCase {
self.mockBundle = MockBundle()
self.mockRequestFetcher = MockRequestFetcher()
self.mockReceiptParser = MockReceiptParser()
self.clock = TestClock()

self.mockSystemInfo = MockSystemInfo(platformInfo: nil,
finishTransactions: false,
bundle: self.mockBundle)
self.clock = TestClock()
bundle: self.mockBundle,
clock: self.clock)

self.receiptFetcher = ReceiptFetcher(requestFetcher: self.mockRequestFetcher,
systemInfo: self.mockSystemInfo,
receiptParser: self.mockReceiptParser,
fileReader: self.createFileReader(),
clock: self.clock)
fileReader: self.createFileReader())
}

func createFileReader() -> FileReader {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class PurchasesSubscriberAttributesTests: TestCase {
var subscriberAttributeHeight: SubscriberAttribute!
var subscriberAttributeWeight: SubscriberAttribute!
var mockAttributes: [String: SubscriberAttribute]!
let systemInfo: SystemInfo = MockSystemInfo(finishTransactions: true)
var systemInfo: MockSystemInfo!
var clock: TestClock!
var mockReceiptParser: MockReceiptParser!
var mockAttributionFetcher: MockAttributionFetcher!
var mockAttributionPoster: AttributionPoster!
Expand Down Expand Up @@ -67,7 +68,10 @@ class PurchasesSubscriberAttributesTests: TestCase {
override func setUpWithError() throws {
try super.setUpWithError()

userDefaults = UserDefaults(suiteName: "TestDefaults")
self.userDefaults = UserDefaults(suiteName: "TestDefaults")
self.clock = TestClock()
self.systemInfo = MockSystemInfo(finishTransactions: true, clock: self.clock)

self.mockDeviceCache = MockDeviceCache(sandboxEnvironmentDetector: self.systemInfo,
userDefaults: self.userDefaults)

Expand Down

0 comments on commit 4c790d3

Please sign in to comment.