Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Aug 3, 2023
1 parent 77253e5 commit a6777aa
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 15 deletions.
4 changes: 4 additions & 0 deletions RevenueCat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@
4FBBC5682A61E42F0077281F /* NonEmptyStringDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FBBC5672A61E42F0077281F /* NonEmptyStringDecodable.swift */; };
4FC083292A4A35FB00A97089 /* Integer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC083282A4A35FB00A97089 /* Integer+Extensions.swift */; };
4FC0832B2A4A361700A97089 /* IntegerExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC0832A2A4A361700A97089 /* IntegerExtensionsTests.swift */; };
4FC6F8892A73E445002139B2 /* PostedTransactionCacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC6F8882A73E445002139B2 /* PostedTransactionCacheTests.swift */; };
4FC972172A712DCC008593DE /* CachingProductsManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC972162A712DCC008593DE /* CachingProductsManagerTests.swift */; };
4FCBA84F2A15391B004134BD /* SnapshotTesting+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 576C8A9127D27DDD0058FA6E /* SnapshotTesting+Extensions.swift */; };
4FCBA8512A153940004134BD /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 4FCBA8502A153940004134BD /* SnapshotTesting */; };
Expand Down Expand Up @@ -981,6 +982,7 @@
4FBBC5672A61E42F0077281F /* NonEmptyStringDecodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NonEmptyStringDecodable.swift; sourceTree = "<group>"; };
4FC083282A4A35FB00A97089 /* Integer+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Integer+Extensions.swift"; sourceTree = "<group>"; };
4FC0832A2A4A361700A97089 /* IntegerExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntegerExtensionsTests.swift; sourceTree = "<group>"; };
4FC6F8882A73E445002139B2 /* PostedTransactionCacheTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostedTransactionCacheTests.swift; sourceTree = "<group>"; };
4FC972162A712DCC008593DE /* CachingProductsManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachingProductsManagerTests.swift; sourceTree = "<group>"; };
4FCBA8522A1539D0004134BD /* __Snapshots__ */ = {isa = PBXFileReference; lastKnownFileType = folder; path = __Snapshots__; sourceTree = "<group>"; };
4FCEEA5D2A379B80002C2112 /* DebugViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2145,6 +2147,7 @@
children = (
37E35D87B7E6F91E27E98F42 /* DeviceCacheTests.swift */,
37E35E3250FBBB03D92E06EC /* InMemoryCachedObjectTests.swift */,
4FC6F8882A73E445002139B2 /* PostedTransactionCacheTests.swift */,
);
path = Caching;
sourceTree = "<group>";
Expand Down Expand Up @@ -3454,6 +3457,7 @@
5766AA5A283D4CAB00FA6091 /* IgnoreHashableTests.swift in Sources */,
B36824BF268FBC8700957E4C /* SubscriberAttributeTests.swift in Sources */,
351B51BC26D450E800BD2BD7 /* OfferingsTests.swift in Sources */,
4FC6F8892A73E445002139B2 /* PostedTransactionCacheTests.swift in Sources */,
5796A38827D6B85900653165 /* BackendPostReceiptDataTests.swift in Sources */,
5752E8482892DC500069281E /* ErrorUtilsTests.swift in Sources */,
57488BF229CB84D40000EE7E /* BackendOfflineEntitlementsTests.swift in Sources */,
Expand Down
28 changes: 17 additions & 11 deletions Sources/Caching/DeviceCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class DeviceCache {
self.userDefaults.write {
var value: Value = $0.value(forKey: key) ?? defaultValue
updater(&value)
$0.set(value, forKey: key)
$0.set(codable: value, forKey: key)
}
}

Expand Down Expand Up @@ -163,11 +163,8 @@ class DeviceCache {

func cache(offerings: Offerings, appUserID: String) {
self.cacheInMemory(offerings: offerings)

if let jsonData = try? JSONEncoder.default.encode(value: offerings.response, logErrors: true) {
self.userDefaults.write {
$0.set(jsonData, forKey: CacheKey.offerings(appUserID))
}
self.userDefaults.write {
$0.set(codable: offerings.response, forKey: CacheKey.offerings(appUserID))
}
}

Expand Down Expand Up @@ -572,18 +569,27 @@ private extension DeviceCache {
_ userDefaults: UserDefaults,
productEntitlementMapping mapping: ProductEntitlementMapping
) {
guard let data = try? JSONEncoder.default.encode(value: mapping, logErrors: true) else {
return
if userDefaults.set(codable: mapping,
forKey: CacheKeys.productEntitlementMapping) {
userDefaults.set(Date(), forKey: CacheKeys.productEntitlementMappingLastUpdated)
}

userDefaults.set(data, forKey: CacheKeys.productEntitlementMapping)
userDefaults.set(Date(), forKey: CacheKeys.productEntitlementMappingLastUpdated)
}

}

fileprivate extension UserDefaults {

/// - Returns: whether the value could be saved
@discardableResult
func set<T: Codable>(codable: T, forKey key: DeviceCacheKeyType) -> Bool {
guard let data = try? JSONEncoder.default.encode(value: codable, logErrors: true) else {
return false

Check warning on line 586 in Sources/Caching/DeviceCache.swift

View check run for this annotation

Codecov / codecov/patch

Sources/Caching/DeviceCache.swift#L586

Added line #L586 was not covered by tests
}

self.set(data, forKey: key)
return true
}

func value<T: Decodable>(forKey key: DeviceCacheKeyType) -> T? {
guard let data = self.data(forKey: key) else {
return nil
Expand Down
6 changes: 2 additions & 4 deletions Sources/Caching/PostedTransactionCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@

import Foundation

protocol PostedTransactionCacheType {
/// A type that can keep track of which transactions have been posted to the backend.
protocol PostedTransactionCacheType: Sendable {

func savePostedTransaction(_ transaction: StoreTransactionType)
func hasPostedTransaction(_ transaction: StoreTransactionType) -> Bool

}

// TODO: tests
// TODO: integrate

final class PostedTransactionCache: PostedTransactionCacheType {

private typealias StoredTransactions = Set<String>
Expand Down
57 changes: 57 additions & 0 deletions Tests/UnitTests/Caching/PostedTransactionCacheTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// 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
//
// PostedTransactionCacheTests.swift
//
// Created by Nacho Soto on 7/28/23.

import Foundation
import Nimble
import XCTest

@testable import RevenueCat

class PostedTransactionCacheTests: TestCase {

private var userDefaults: UserDefaults!
private var deviceCache: DeviceCache!
private var cache: PostedTransactionCache!

override func setUpWithError() throws {
try super.setUpWithError()

self.userDefaults = try XCTUnwrap(.init(suiteName: UUID().uuidString))
self.deviceCache = .init(sandboxEnvironmentDetector: MockSandboxEnvironmentDetector(isSandbox: true),
userDefaults: self.userDefaults)
self.cache = .init(deviceCache: self.deviceCache)
}

func testNoPostedTransactions() {
expect(self.cache.hasPostedTransaction(MockStoreTransaction())) == false
}

func testSavesFirstTransaction() {
let transaction = MockStoreTransaction()

self.cache.savePostedTransaction(transaction)
expect(self.cache.hasPostedTransaction(transaction)) == true
}

func testSaveMultipleTransactions() {
let transaction1 = MockStoreTransaction()
let transaction2 = MockStoreTransaction()

self.cache.savePostedTransaction(transaction1)
self.cache.savePostedTransaction(transaction2)

expect(self.cache.hasPostedTransaction(transaction1)) == true
expect(self.cache.hasPostedTransaction(transaction2)) == true
}

}
31 changes: 31 additions & 0 deletions Tests/UnitTests/Mocks/MockDeviceCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,37 @@ class MockDeviceCache: DeviceCache {
userDefaults: MockUserDefaults())
}

// MARK: - generic methods

var stubbedUpdateValues: [Any] = []
var invokedUpdateKey: Bool = false
var invokedUpdateKeyParameters: [(key: String, newValue: Any)] = []

override func update<Key: DeviceCacheKeyType, Value: Codable>(
key: Key,
default defaultValue: Value,
updater: @Sendable (inout Value) -> Void
) {
// swiftlint:disable:next force_cast
var value = (self.stubbedUpdateValues.popFirst() as! Value?) ?? defaultValue
updater(&value)

self.invokedUpdateKey = true
self.invokedUpdateKeyParameters.append((key: key.rawValue, newValue: value))
}

var stubbedValueForKey: [Any] = []
var invokedValueForKey: Bool = false
var invokedValueForKeyParameters: [String] = []

override func value<Key: DeviceCacheKeyType, Value: Codable>(for key: Key) -> Value? {
self.invokedValueForKey = true
self.invokedValueForKeyParameters.append(key.rawValue)

// swiftlint:disable:next force_cast
return self.stubbedValueForKey.popFirst() as! Value?
}

// MARK: appUserID

var stubbedAppUserID: String?
Expand Down

0 comments on commit a6777aa

Please sign in to comment.