parent
e54ea3aa18
commit
f6e6f6991f
|
@ -105,6 +105,7 @@
|
||||||
9E5BF63F2819542C00BA3F17 /* TransactionHistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF63E2819542C00BA3F17 /* TransactionHistoryTests.swift */; };
|
9E5BF63F2819542C00BA3F17 /* TransactionHistoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF63E2819542C00BA3F17 /* TransactionHistoryTests.swift */; };
|
||||||
9E5BF641281FD7B600BA3F17 /* TransactionFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */; };
|
9E5BF641281FD7B600BA3F17 /* TransactionFailedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */; };
|
||||||
9E5BF644281FEC9900BA3F17 /* SendTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF643281FEC9900BA3F17 /* SendTests.swift */; };
|
9E5BF644281FEC9900BA3F17 /* SendTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF643281FEC9900BA3F17 /* SendTests.swift */; };
|
||||||
|
9E5BF6462821028C00BA3F17 /* WrappedUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E5BF6452821028C00BA3F17 /* WrappedUserDefaults.swift */; };
|
||||||
9E69A24D27FB002800A55317 /* Welcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* Welcome.swift */; };
|
9E69A24D27FB002800A55317 /* Welcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E69A24C27FB002800A55317 /* Welcome.swift */; };
|
||||||
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */; };
|
9E80B47227E4B34B008FF493 /* UserPreferencesStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */; };
|
||||||
9EAFEB822805793200199FC9 /* AppReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* AppReducerTests.swift */; };
|
9EAFEB822805793200199FC9 /* AppReducerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EAFEB812805793200199FC9 /* AppReducerTests.swift */; };
|
||||||
|
@ -272,6 +273,7 @@
|
||||||
9E5BF63E2819542C00BA3F17 /* TransactionHistoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionHistoryTests.swift; sourceTree = "<group>"; };
|
9E5BF63E2819542C00BA3F17 /* TransactionHistoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionHistoryTests.swift; sourceTree = "<group>"; };
|
||||||
9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionFailedView.swift; sourceTree = "<group>"; };
|
9E5BF640281FD7B600BA3F17 /* TransactionFailedView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionFailedView.swift; sourceTree = "<group>"; };
|
||||||
9E5BF643281FEC9900BA3F17 /* SendTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTests.swift; sourceTree = "<group>"; };
|
9E5BF643281FEC9900BA3F17 /* SendTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendTests.swift; sourceTree = "<group>"; };
|
||||||
|
9E5BF6452821028C00BA3F17 /* WrappedUserDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WrappedUserDefaults.swift; sourceTree = "<group>"; };
|
||||||
9E69A24C27FB002800A55317 /* Welcome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Welcome.swift; sourceTree = "<group>"; };
|
9E69A24C27FB002800A55317 /* Welcome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Welcome.swift; sourceTree = "<group>"; };
|
||||||
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorage.swift; sourceTree = "<group>"; };
|
9E80B47127E4B34B008FF493 /* UserPreferencesStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreferencesStorage.swift; sourceTree = "<group>"; };
|
||||||
9EAFEB812805793200199FC9 /* AppReducerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducerTests.swift; sourceTree = "<group>"; };
|
9EAFEB812805793200199FC9 /* AppReducerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducerTests.swift; sourceTree = "<group>"; };
|
||||||
|
@ -759,6 +761,7 @@
|
||||||
9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */,
|
9EAFEB83280597B700199FC9 /* WrappedSecItem.swift */,
|
||||||
9E02B5C2280458D2005B809B /* WrappedDerivationTool.swift */,
|
9E02B5C2280458D2005B809B /* WrappedDerivationTool.swift */,
|
||||||
9EAFEB872806E5AE00199FC9 /* WrappedSDKSynchronizer.swift */,
|
9EAFEB872806E5AE00199FC9 /* WrappedSDKSynchronizer.swift */,
|
||||||
|
9E5BF6452821028C00BA3F17 /* WrappedUserDefaults.swift */,
|
||||||
);
|
);
|
||||||
path = Wrappers;
|
path = Wrappers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1288,6 +1291,7 @@
|
||||||
9EAFEB84280597B700199FC9 /* WrappedSecItem.swift in Sources */,
|
9EAFEB84280597B700199FC9 /* WrappedSecItem.swift in Sources */,
|
||||||
9E2AC10327DA28200042AA47 /* WalletStorage.swift in Sources */,
|
9E2AC10327DA28200042AA47 /* WalletStorage.swift in Sources */,
|
||||||
9ECAE56827FC713C0089A0EF /* DatabaseFiles.swift in Sources */,
|
9ECAE56827FC713C0089A0EF /* DatabaseFiles.swift in Sources */,
|
||||||
|
9E5BF6462821028C00BA3F17 /* WrappedUserDefaults.swift in Sources */,
|
||||||
F9971A6B27680E1000A2DB75 /* WalletInfo.swift in Sources */,
|
F9971A6B27680E1000A2DB75 /* WalletInfo.swift in Sources */,
|
||||||
0D185819272723FF0046B928 /* ColoredChip.swift in Sources */,
|
0D185819272723FF0046B928 /* ColoredChip.swift in Sources */,
|
||||||
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */,
|
2EA11F5D27467F7700709571 /* OnboardingContentView.swift in Sources */,
|
||||||
|
|
|
@ -6,25 +6,12 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import ComposableArchitecture
|
||||||
/// Representation of the user preferences stored in the local persistent storage (non-encrypted, no security needed)
|
|
||||||
protocol UserPreferences {
|
|
||||||
/// From when the app is on and uninterrupted
|
|
||||||
var activeAppSessionFrom: TimeInterval { get set }
|
|
||||||
/// What is the set up currency
|
|
||||||
var currency: String { get set }
|
|
||||||
/// Whether the fiat conversion is on/off
|
|
||||||
var isFiatConverted: Bool { get set }
|
|
||||||
/// Whether user finished recovery phrase backup test
|
|
||||||
var isRecoveryPhraseTestCompleted: Bool { get set }
|
|
||||||
/// Whether the user has been autoshielded in the running session
|
|
||||||
var isSessionAutoshielded: Bool { get set }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Live implementation of the `UserPreferences` using User Defaults
|
/// Live implementation of the `UserPreferences` using User Defaults
|
||||||
/// according to https://developer.apple.com/documentation/foundation/userdefaults
|
/// according to https://developer.apple.com/documentation/foundation/userdefaults
|
||||||
/// the UserDefaults class is thread-safe.
|
/// the UserDefaults class is thread-safe.
|
||||||
struct UserPreferencesStorage: UserPreferences {
|
struct UserPreferencesStorage {
|
||||||
enum Constants: String, CaseIterable {
|
enum Constants: String, CaseIterable {
|
||||||
case zcashActiveAppSessionFrom
|
case zcashActiveAppSessionFrom
|
||||||
case zcashCurrency
|
case zcashCurrency
|
||||||
|
@ -33,15 +20,6 @@ struct UserPreferencesStorage: UserPreferences {
|
||||||
case zcashSessionAutoshielded
|
case zcashSessionAutoshielded
|
||||||
}
|
}
|
||||||
|
|
||||||
static let `default` = UserPreferencesStorage(
|
|
||||||
appSessionFrom: Date().timeIntervalSince1970,
|
|
||||||
convertedCurrency: "USD",
|
|
||||||
fiatConvertion: true,
|
|
||||||
recoveryPhraseTestCompleted: false,
|
|
||||||
sessionAutoshielded: true,
|
|
||||||
userDefaults: UserDefaults.standard
|
|
||||||
)
|
|
||||||
|
|
||||||
/// Default values for all preferences in case there is no value stored (counterparts to `Constants`)
|
/// Default values for all preferences in case there is no value stored (counterparts to `Constants`)
|
||||||
private let appSessionFrom: TimeInterval
|
private let appSessionFrom: TimeInterval
|
||||||
private let convertedCurrency: String
|
private let convertedCurrency: String
|
||||||
|
@ -49,7 +27,7 @@ struct UserPreferencesStorage: UserPreferences {
|
||||||
private let recoveryPhraseTestCompleted: Bool
|
private let recoveryPhraseTestCompleted: Bool
|
||||||
private let sessionAutoshielded: Bool
|
private let sessionAutoshielded: Bool
|
||||||
|
|
||||||
private let userDefaults: UserDefaults
|
private let userDefaults: WrappedUserDefaults
|
||||||
|
|
||||||
init(
|
init(
|
||||||
appSessionFrom: TimeInterval,
|
appSessionFrom: TimeInterval,
|
||||||
|
@ -57,7 +35,7 @@ struct UserPreferencesStorage: UserPreferences {
|
||||||
fiatConvertion: Bool,
|
fiatConvertion: Bool,
|
||||||
recoveryPhraseTestCompleted: Bool,
|
recoveryPhraseTestCompleted: Bool,
|
||||||
sessionAutoshielded: Bool,
|
sessionAutoshielded: Bool,
|
||||||
userDefaults: UserDefaults
|
userDefaults: WrappedUserDefaults
|
||||||
) {
|
) {
|
||||||
self.appSessionFrom = appSessionFrom
|
self.appSessionFrom = appSessionFrom
|
||||||
self.convertedCurrency = convertedCurrency
|
self.convertedCurrency = convertedCurrency
|
||||||
|
@ -69,47 +47,88 @@ struct UserPreferencesStorage: UserPreferences {
|
||||||
|
|
||||||
/// From when the app is on and uninterrupted
|
/// From when the app is on and uninterrupted
|
||||||
var activeAppSessionFrom: TimeInterval {
|
var activeAppSessionFrom: TimeInterval {
|
||||||
get { getValue(forKey: Constants.zcashActiveAppSessionFrom.rawValue, default: appSessionFrom) }
|
getValue(forKey: Constants.zcashActiveAppSessionFrom.rawValue, default: appSessionFrom)
|
||||||
set { setValue(newValue, forKey: Constants.zcashActiveAppSessionFrom.rawValue) }
|
}
|
||||||
|
|
||||||
|
func setActiveAppSessionFrom(_ timeInterval: TimeInterval) -> Effect<Never, Never> {
|
||||||
|
setValue(timeInterval, forKey: Constants.zcashActiveAppSessionFrom.rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What is the set up currency
|
/// What is the set up currency
|
||||||
var currency: String {
|
var currency: String {
|
||||||
get { getValue(forKey: Constants.zcashCurrency.rawValue, default: convertedCurrency) }
|
getValue(forKey: Constants.zcashCurrency.rawValue, default: convertedCurrency)
|
||||||
set { setValue(newValue, forKey: Constants.zcashCurrency.rawValue) }
|
}
|
||||||
|
|
||||||
|
func setCurrency(_ string: String) -> Effect<Never, Never> {
|
||||||
|
setValue(string, forKey: Constants.zcashCurrency.rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the fiat conversion is on/off
|
/// Whether the fiat conversion is on/off
|
||||||
var isFiatConverted: Bool {
|
var isFiatConverted: Bool {
|
||||||
get { getValue(forKey: Constants.zcashFiatConverted.rawValue, default: fiatConvertion) }
|
getValue(forKey: Constants.zcashFiatConverted.rawValue, default: fiatConvertion)
|
||||||
set { setValue(newValue, forKey: Constants.zcashFiatConverted.rawValue) }
|
}
|
||||||
|
|
||||||
|
func setIsFiatConverted(_ bool: Bool) -> Effect<Never, Never> {
|
||||||
|
setValue(bool, forKey: Constants.zcashFiatConverted.rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether user finished recovery phrase backup test
|
/// Whether user finished recovery phrase backup test
|
||||||
var isRecoveryPhraseTestCompleted: Bool {
|
var isRecoveryPhraseTestCompleted: Bool {
|
||||||
get { getValue(forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue, default: recoveryPhraseTestCompleted) }
|
getValue(forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue, default: recoveryPhraseTestCompleted)
|
||||||
set { setValue(newValue, forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue) }
|
}
|
||||||
|
|
||||||
|
func setIsRecoveryPhraseTestCompleted(_ bool: Bool) -> Effect<Never, Never> {
|
||||||
|
setValue(bool, forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the user has been autoshielded in the running session
|
/// Whether the user has been autoshielded in the running session
|
||||||
var isSessionAutoshielded: Bool {
|
var isSessionAutoshielded: Bool {
|
||||||
get { getValue(forKey: Constants.zcashSessionAutoshielded.rawValue, default: sessionAutoshielded) }
|
getValue(forKey: Constants.zcashSessionAutoshielded.rawValue, default: sessionAutoshielded)
|
||||||
set { setValue(newValue, forKey: Constants.zcashSessionAutoshielded.rawValue) }
|
}
|
||||||
|
|
||||||
|
func setIsSessionAutoshielded(_ bool: Bool) -> Effect<Never, Never> {
|
||||||
|
setValue(bool, forKey: Constants.zcashSessionAutoshielded.rawValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use carefully: Deletes all user preferences from the User Defaults
|
/// Use carefully: Deletes all user preferences from the User Defaults
|
||||||
func removeAll() {
|
func removeAll() -> Effect<Never, Never> {
|
||||||
Constants.allCases.forEach { userDefaults.removeObject(forKey: $0.rawValue) }
|
var removals: [Effect<Never, Never>] = []
|
||||||
|
|
||||||
|
Constants.allCases.forEach { removals.append(userDefaults.remove($0.rawValue)) }
|
||||||
|
|
||||||
|
return Effect.concatenate(removals)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension UserPreferencesStorage {
|
private extension UserPreferencesStorage {
|
||||||
func getValue<Value>(forKey: String, default defaultIfNil: Value) -> Value {
|
func getValue<Value>(forKey: String, default defaultIfNil: Value) -> Value {
|
||||||
userDefaults.object(forKey: forKey) as? Value ?? defaultIfNil
|
userDefaults.objectForKey(forKey) as? Value ?? defaultIfNil
|
||||||
}
|
}
|
||||||
|
|
||||||
func setValue<Value>(_ value: Value, forKey: String) {
|
func setValue<Value>(_ value: Value, forKey: String) -> Effect<Never, Never> {
|
||||||
userDefaults.set(value, forKey: forKey)
|
let effect = userDefaults.setValue(value, forKey)
|
||||||
userDefaults.synchronize()
|
_ = userDefaults.synchronize()
|
||||||
|
|
||||||
|
return effect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension UserPreferencesStorage {
|
||||||
|
static let live = UserPreferencesStorage(
|
||||||
|
appSessionFrom: Date().timeIntervalSince1970,
|
||||||
|
convertedCurrency: "USD",
|
||||||
|
fiatConvertion: true,
|
||||||
|
recoveryPhraseTestCompleted: false,
|
||||||
|
sessionAutoshielded: true,
|
||||||
|
userDefaults: .live()
|
||||||
|
)
|
||||||
|
|
||||||
|
static let mock = UserPreferencesStorage(
|
||||||
|
appSessionFrom: 1651039606.0,
|
||||||
|
convertedCurrency: "USD",
|
||||||
|
fiatConvertion: true,
|
||||||
|
recoveryPhraseTestCompleted: false,
|
||||||
|
sessionAutoshielded: true,
|
||||||
|
userDefaults: .mock
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
//
|
||||||
|
// WrappedUserDefaults.swift
|
||||||
|
// secant-testnet
|
||||||
|
//
|
||||||
|
// Created by Lukáš Korba on 03.05.2022.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import ComposableArchitecture
|
||||||
|
|
||||||
|
struct WrappedUserDefaults {
|
||||||
|
let objectForKey: (String) -> Any?
|
||||||
|
let remove: (String) -> Effect<Never, Never>
|
||||||
|
let setValue: (Any?, String) -> Effect<Never, Never>
|
||||||
|
let synchronize: () -> Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
extension WrappedUserDefaults {
|
||||||
|
static func live(
|
||||||
|
userDefaults: UserDefaults = .standard
|
||||||
|
) -> Self {
|
||||||
|
Self(
|
||||||
|
objectForKey: userDefaults.object(forKey:),
|
||||||
|
remove: { key in
|
||||||
|
.fireAndForget {
|
||||||
|
userDefaults.removeObject(forKey: key)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setValue: { value, key in
|
||||||
|
.fireAndForget {
|
||||||
|
userDefaults.set(value, forKey: key)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
synchronize: userDefaults.synchronize
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static let mock = WrappedUserDefaults(
|
||||||
|
objectForKey: { _ in },
|
||||||
|
remove: { _ in .none },
|
||||||
|
setValue: { _, _ in .none },
|
||||||
|
synchronize: { true }
|
||||||
|
)
|
||||||
|
}
|
|
@ -7,29 +7,45 @@
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
@testable import secant_testnet
|
@testable import secant_testnet
|
||||||
|
import Combine
|
||||||
|
|
||||||
class UserPreferencesStorageTests: XCTestCase {
|
class UserPreferencesStorageTests: XCTestCase {
|
||||||
|
private var cancellables: [AnyCancellable] = []
|
||||||
|
|
||||||
// swiftlint:disable:next implicitly_unwrapped_optional
|
// swiftlint:disable:next implicitly_unwrapped_optional
|
||||||
var storage: UserPreferencesStorage!
|
var storage: UserPreferencesStorage!
|
||||||
|
|
||||||
override func setUp() {
|
override func setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
|
|
||||||
|
guard let userDefaults = UserDefaults.init(suiteName: "test") else {
|
||||||
|
XCTFail("UserPreferencesStorageTests: UserDefaults.init(suiteName: "test") failed to initialize")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
storage = UserPreferencesStorage(
|
storage = UserPreferencesStorage(
|
||||||
appSessionFrom: 12345678.0,
|
appSessionFrom: 12345678.0,
|
||||||
convertedCurrency: "USD",
|
convertedCurrency: "USD",
|
||||||
fiatConvertion: true,
|
fiatConvertion: true,
|
||||||
recoveryPhraseTestCompleted: true,
|
recoveryPhraseTestCompleted: true,
|
||||||
sessionAutoshielded: false,
|
sessionAutoshielded: false,
|
||||||
userDefaults: .standard
|
userDefaults: .live(userDefaults: userDefaults)
|
||||||
)
|
)
|
||||||
storage.removeAll()
|
storage.removeAll()
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func tearDown() {
|
override func tearDown() {
|
||||||
super.tearDown()
|
super.tearDown()
|
||||||
|
storage.removeAll()
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
storage = nil
|
storage = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Default values in the live UserDefaults environment
|
||||||
|
|
||||||
func testAppSessionFrom_defaultValue() throws {
|
func testAppSessionFrom_defaultValue() throws {
|
||||||
XCTAssertEqual(12345678.0, storage.activeAppSessionFrom, "User Preferences: `activeAppSessionFrom` default doesn't match.")
|
XCTAssertEqual(12345678.0, storage.activeAppSessionFrom, "User Preferences: `activeAppSessionFrom` default doesn't match.")
|
||||||
}
|
}
|
||||||
|
@ -50,8 +66,157 @@ class UserPreferencesStorageTests: XCTestCase {
|
||||||
XCTAssertEqual(false, storage.isSessionAutoshielded, "User Preferences: `isSessionAutoshielded` default doesn't match.")
|
XCTAssertEqual(false, storage.isSessionAutoshielded, "User Preferences: `isSessionAutoshielded` default doesn't match.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Set new values in the live UserDefaults environment
|
||||||
|
|
||||||
|
func testAppSessionFrom_setNewValue() throws {
|
||||||
|
storage.setActiveAppSessionFrom(87654321.0)
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
XCTAssertEqual(87654321.0, storage.activeAppSessionFrom, "User Preferences: `activeAppSessionFrom` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testConvertedCurrency_setNewValue() throws {
|
||||||
|
storage.setCurrency("CZK")
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
XCTAssertEqual("CZK", storage.currency, "User Preferences: `currency` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFiatConvertion_setNewValue() throws {
|
||||||
|
storage.setIsFiatConverted(false)
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
XCTAssertEqual(false, storage.isFiatConverted, "User Preferences: `isFiatConverted` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRecoveryPhraseTestCompleted_setNewValue() throws {
|
||||||
|
storage.setIsRecoveryPhraseTestCompleted(false)
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
XCTAssertEqual(false, storage.isRecoveryPhraseTestCompleted, "User Preferences: `isRecoveryPhraseTestCompleted` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSessionAutoshielded_setNewValue() throws {
|
||||||
|
storage.setIsSessionAutoshielded(true)
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
XCTAssertEqual(true, storage.isSessionAutoshielded, "User Preferences: `isSessionAutoshielded` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Mocked user defaults vs. default values
|
||||||
|
|
||||||
|
func testAppSessionFrom_mocked() throws {
|
||||||
|
let mockedUD = WrappedUserDefaults(
|
||||||
|
objectForKey: { _ in 87654321.0 },
|
||||||
|
remove: { _ in .none },
|
||||||
|
setValue: { _, _ in .none },
|
||||||
|
synchronize: { true }
|
||||||
|
)
|
||||||
|
|
||||||
|
let mockedStorage = UserPreferencesStorage(
|
||||||
|
appSessionFrom: 12345678.0,
|
||||||
|
convertedCurrency: "USD",
|
||||||
|
fiatConvertion: true,
|
||||||
|
recoveryPhraseTestCompleted: true,
|
||||||
|
sessionAutoshielded: false,
|
||||||
|
userDefaults: mockedUD
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertEqual(87654321.0, mockedStorage.activeAppSessionFrom, "User Preferences: `activeAppSessionFrom` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testConvertedCurrency_mocked() throws {
|
||||||
|
let mockedUD = WrappedUserDefaults(
|
||||||
|
objectForKey: { _ in "CZK" },
|
||||||
|
remove: { _ in .none },
|
||||||
|
setValue: { _, _ in .none },
|
||||||
|
synchronize: { true }
|
||||||
|
)
|
||||||
|
|
||||||
|
let mockedStorage = UserPreferencesStorage(
|
||||||
|
appSessionFrom: 12345678.0,
|
||||||
|
convertedCurrency: "USD",
|
||||||
|
fiatConvertion: true,
|
||||||
|
recoveryPhraseTestCompleted: true,
|
||||||
|
sessionAutoshielded: false,
|
||||||
|
userDefaults: mockedUD
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertEqual("CZK", mockedStorage.currency, "User Preferences: `currency` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testFiatConvertion_mocked() throws {
|
||||||
|
let mockedUD = WrappedUserDefaults(
|
||||||
|
objectForKey: { _ in false },
|
||||||
|
remove: { _ in .none },
|
||||||
|
setValue: { _, _ in .none },
|
||||||
|
synchronize: { true }
|
||||||
|
)
|
||||||
|
|
||||||
|
let mockedStorage = UserPreferencesStorage(
|
||||||
|
appSessionFrom: 12345678.0,
|
||||||
|
convertedCurrency: "USD",
|
||||||
|
fiatConvertion: true,
|
||||||
|
recoveryPhraseTestCompleted: true,
|
||||||
|
sessionAutoshielded: false,
|
||||||
|
userDefaults: mockedUD
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertEqual(false, mockedStorage.isFiatConverted, "User Preferences: `isFiatConverted` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRecoveryPhraseTestCompleted_mocked() throws {
|
||||||
|
let mockedUD = WrappedUserDefaults(
|
||||||
|
objectForKey: { _ in false },
|
||||||
|
remove: { _ in .none },
|
||||||
|
setValue: { _, _ in .none },
|
||||||
|
synchronize: { true }
|
||||||
|
)
|
||||||
|
|
||||||
|
let mockedStorage = UserPreferencesStorage(
|
||||||
|
appSessionFrom: 12345678.0,
|
||||||
|
convertedCurrency: "USD",
|
||||||
|
fiatConvertion: true,
|
||||||
|
recoveryPhraseTestCompleted: true,
|
||||||
|
sessionAutoshielded: false,
|
||||||
|
userDefaults: mockedUD
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertEqual(false, mockedStorage.isRecoveryPhraseTestCompleted, "User Preferences: `isRecoveryPhraseTestCompleted` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSessionAutoshielded_mocked() throws {
|
||||||
|
let mockedUD = WrappedUserDefaults(
|
||||||
|
objectForKey: { _ in true },
|
||||||
|
remove: { _ in .none },
|
||||||
|
setValue: { _, _ in .none },
|
||||||
|
synchronize: { true }
|
||||||
|
)
|
||||||
|
|
||||||
|
let mockedStorage = UserPreferencesStorage(
|
||||||
|
appSessionFrom: 12345678.0,
|
||||||
|
convertedCurrency: "USD",
|
||||||
|
fiatConvertion: true,
|
||||||
|
recoveryPhraseTestCompleted: true,
|
||||||
|
sessionAutoshielded: false,
|
||||||
|
userDefaults: mockedUD
|
||||||
|
)
|
||||||
|
|
||||||
|
XCTAssertEqual(true, mockedStorage.isSessionAutoshielded, "User Preferences: `isSessionAutoshielded` default doesn't match.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Remove all keys from the live UD environment
|
||||||
|
|
||||||
func testRemoveAll() throws {
|
func testRemoveAll() throws {
|
||||||
let userDefaults = UserDefaults.standard
|
guard let userDefaults = UserDefaults.init(suiteName: "test") else {
|
||||||
|
XCTFail("User Preferences: UserDefaults.init(suiteName: "test") failed to initialize")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// fill in the data
|
// fill in the data
|
||||||
UserPreferencesStorage.Constants.allCases.forEach {
|
UserPreferencesStorage.Constants.allCases.forEach {
|
||||||
|
@ -60,6 +225,8 @@ class UserPreferencesStorageTests: XCTestCase {
|
||||||
|
|
||||||
// remove it
|
// remove it
|
||||||
storage?.removeAll()
|
storage?.removeAll()
|
||||||
|
.sink(receiveValue: { _ in })
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
// check the presence
|
// check the presence
|
||||||
UserPreferencesStorage.Constants.allCases.forEach {
|
UserPreferencesStorage.Constants.allCases.forEach {
|
||||||
|
|
Loading…
Reference in New Issue