[408] Reduce dependency on TCA in the dependencies (#413)
Following dependencies refactored to await/async - RecoveryPhraseValidationFlowReducer - RecoveryPhraseDisplayStore - AppStore - UserPreferencesStorage - WrappedUserDefaults which allowed to reduce imports of Combine/TCA
This commit is contained in:
parent
4c36aa39a2
commit
558675aced
|
@ -6,7 +6,6 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import ComposableArchitecture
|
||||
|
||||
/// Live implementation of the `UserPreferences` using User Defaults
|
||||
/// according to https://developer.apple.com/documentation/foundation/userdefaults
|
||||
|
@ -50,8 +49,8 @@ struct UserPreferencesStorage {
|
|||
getValue(forKey: Constants.zcashActiveAppSessionFrom.rawValue, default: appSessionFrom)
|
||||
}
|
||||
|
||||
func setActiveAppSessionFrom(_ timeInterval: TimeInterval) -> Effect<Never, Never> {
|
||||
setValue(timeInterval, forKey: Constants.zcashActiveAppSessionFrom.rawValue)
|
||||
func setActiveAppSessionFrom(_ timeInterval: TimeInterval) async {
|
||||
await setValue(timeInterval, forKey: Constants.zcashActiveAppSessionFrom.rawValue)
|
||||
}
|
||||
|
||||
/// What is the set up currency
|
||||
|
@ -59,8 +58,8 @@ struct UserPreferencesStorage {
|
|||
getValue(forKey: Constants.zcashCurrency.rawValue, default: convertedCurrency)
|
||||
}
|
||||
|
||||
func setCurrency(_ string: String) -> Effect<Never, Never> {
|
||||
setValue(string, forKey: Constants.zcashCurrency.rawValue)
|
||||
func setCurrency(_ string: String) async {
|
||||
await setValue(string, forKey: Constants.zcashCurrency.rawValue)
|
||||
}
|
||||
|
||||
/// Whether the fiat conversion is on/off
|
||||
|
@ -68,8 +67,8 @@ struct UserPreferencesStorage {
|
|||
getValue(forKey: Constants.zcashFiatConverted.rawValue, default: fiatConvertion)
|
||||
}
|
||||
|
||||
func setIsFiatConverted(_ bool: Bool) -> Effect<Never, Never> {
|
||||
setValue(bool, forKey: Constants.zcashFiatConverted.rawValue)
|
||||
func setIsFiatConverted(_ bool: Bool) async {
|
||||
await setValue(bool, forKey: Constants.zcashFiatConverted.rawValue)
|
||||
}
|
||||
|
||||
/// Whether user finished recovery phrase backup test
|
||||
|
@ -77,8 +76,8 @@ struct UserPreferencesStorage {
|
|||
getValue(forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue, default: recoveryPhraseTestCompleted)
|
||||
}
|
||||
|
||||
func setIsRecoveryPhraseTestCompleted(_ bool: Bool) -> Effect<Never, Never> {
|
||||
setValue(bool, forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue)
|
||||
func setIsRecoveryPhraseTestCompleted(_ bool: Bool) async {
|
||||
await setValue(bool, forKey: Constants.zcashRecoveryPhraseTestCompleted.rawValue)
|
||||
}
|
||||
|
||||
/// Whether the user has been autoshielded in the running session
|
||||
|
@ -86,17 +85,15 @@ struct UserPreferencesStorage {
|
|||
getValue(forKey: Constants.zcashSessionAutoshielded.rawValue, default: sessionAutoshielded)
|
||||
}
|
||||
|
||||
func setIsSessionAutoshielded(_ bool: Bool) -> Effect<Never, Never> {
|
||||
setValue(bool, forKey: Constants.zcashSessionAutoshielded.rawValue)
|
||||
func setIsSessionAutoshielded(_ bool: Bool) async {
|
||||
await setValue(bool, forKey: Constants.zcashSessionAutoshielded.rawValue)
|
||||
}
|
||||
|
||||
/// Use carefully: Deletes all user preferences from the User Defaults
|
||||
func removeAll() -> Effect<Never, Never> {
|
||||
var removals: [Effect<Never, Never>] = []
|
||||
|
||||
Constants.allCases.forEach { removals.append(userDefaults.remove($0.rawValue)) }
|
||||
|
||||
return Effect.concatenate(removals)
|
||||
func removeAll() async {
|
||||
for key in Constants.allCases {
|
||||
await userDefaults.remove(key.rawValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,11 +102,9 @@ private extension UserPreferencesStorage {
|
|||
userDefaults.objectForKey(forKey) as? Value ?? defaultIfNil
|
||||
}
|
||||
|
||||
func setValue<Value>(_ value: Value, forKey: String) -> Effect<Never, Never> {
|
||||
let effect = userDefaults.setValue(value, forKey)
|
||||
_ = userDefaults.synchronize()
|
||||
|
||||
return effect
|
||||
func setValue<Value>(_ value: Value, forKey: String) async {
|
||||
await userDefaults.setValue(value, forKey)
|
||||
_ = await userDefaults.synchronize()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -322,11 +322,12 @@ extension AppReducer {
|
|||
// (https://github.com/zcash/secant-ios-wallet/issues/370)
|
||||
return .none
|
||||
}
|
||||
do {
|
||||
return try process(url: url, with: environment)
|
||||
} catch {
|
||||
// TODO: error we need to handle, issue #221 (https://github.com/zcash/secant-ios-wallet/issues/221)
|
||||
return .none
|
||||
return .run { send in
|
||||
do {
|
||||
await send(try await process(url: url, with: environment))
|
||||
} catch {
|
||||
// TODO: error we need to handle, issue #221 (https://github.com/zcash/secant-ios-wallet/issues/221)
|
||||
}
|
||||
}
|
||||
|
||||
case .deeplinkHome:
|
||||
|
@ -391,7 +392,6 @@ extension AppReducer {
|
|||
environment: { environment in
|
||||
RecoveryPhraseValidationFlowEnvironment(
|
||||
scheduler: environment.scheduler,
|
||||
newPhrase: { Effect(value: .init(words: RecoveryPhrase.placeholder.words)) },
|
||||
pasteboard: .test,
|
||||
feedbackGenerator: .silent,
|
||||
recoveryPhraseRandomizer: environment.recoveryPhraseRandomizer
|
||||
|
@ -405,7 +405,7 @@ extension AppReducer {
|
|||
environment: { environment in
|
||||
RecoveryPhraseDisplayEnvironment(
|
||||
scheduler: environment.scheduler,
|
||||
newPhrase: { Effect(value: .init(words: RecoveryPhrase.placeholder.words)) },
|
||||
newPhrase: { .init(words: RecoveryPhrase.placeholder.words) },
|
||||
pasteboard: .live,
|
||||
feedbackGenerator: environment.feedbackGenerator
|
||||
)
|
||||
|
@ -493,15 +493,15 @@ extension AppReducer {
|
|||
throw SDKInitializationError.failed
|
||||
}
|
||||
}
|
||||
|
||||
static func process(url: URL, with environment: AppEnvironment) throws -> Effect<AppAction, Never> {
|
||||
|
||||
static func process(url: URL, with environment: AppEnvironment) async throws -> AppAction {
|
||||
let deeplink = try environment.deeplinkHandler.resolveDeeplinkURL(url, environment.derivationTool)
|
||||
|
||||
switch deeplink {
|
||||
case .home:
|
||||
return Effect(value: .deeplinkHome)
|
||||
return .deeplinkHome
|
||||
case let .send(amount, address, memo):
|
||||
return Effect(value: .deeplinkSend(Zatoshi(amount), address, memo))
|
||||
return .deeplinkSend(Zatoshi(amount), address, memo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,14 @@ enum RecoveryPhraseDisplayAction: Equatable {
|
|||
case createPhrase
|
||||
case copyToBufferPressed
|
||||
case finishedPressed
|
||||
case phraseResponse(Result<RecoveryPhrase, RecoveryPhraseError>)
|
||||
case phraseResponse(RecoveryPhrase)
|
||||
}
|
||||
|
||||
// MARK: - Environment
|
||||
|
||||
struct RecoveryPhraseDisplayEnvironment {
|
||||
let scheduler: AnySchedulerOf<DispatchQueue>
|
||||
let newPhrase: () -> Effect<RecoveryPhrase, RecoveryPhraseError>
|
||||
let newPhrase: () async throws -> RecoveryPhrase
|
||||
let pasteboard: WrappedPasteboard
|
||||
let feedbackGenerator: WrappedFeedbackGenerator
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ struct RecoveryPhraseDisplayEnvironment {
|
|||
extension RecoveryPhraseDisplayEnvironment {
|
||||
static let demo = Self(
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
newPhrase: { Effect(value: .init(words: RecoveryPhrase.placeholder.words)) },
|
||||
newPhrase: { .init(words: RecoveryPhrase.placeholder.words) },
|
||||
pasteboard: .test,
|
||||
feedbackGenerator: .silent
|
||||
)
|
||||
|
@ -52,23 +52,27 @@ extension RecoveryPhraseDisplayReducer {
|
|||
static let `default` = RecoveryPhraseDisplayReducer { state, action, environment in
|
||||
switch action {
|
||||
case .createPhrase:
|
||||
return environment.newPhrase()
|
||||
.receive(on: environment.scheduler)
|
||||
.catchToEffect(RecoveryPhraseDisplayAction.phraseResponse)
|
||||
return .run { send in
|
||||
do {
|
||||
await send(.phraseResponse(try await environment.newPhrase()))
|
||||
} catch {
|
||||
// TODO: remove this when feature is implemented in https://github.com/zcash/secant-ios-wallet/issues/129
|
||||
}
|
||||
}
|
||||
|
||||
case .copyToBufferPressed:
|
||||
guard let phrase = state.phrase?.toString() else { return .none }
|
||||
environment.pasteboard.setString(phrase)
|
||||
state.showCopyToBufferAlert = true
|
||||
return .none
|
||||
|
||||
case .finishedPressed:
|
||||
// TODO: remove this when feature is implemented in https://github.com/zcash/secant-ios-wallet/issues/47
|
||||
return .none
|
||||
case let .phraseResponse(.success(phrase)):
|
||||
|
||||
case let .phraseResponse(phrase):
|
||||
state.phrase = phrase
|
||||
return .none
|
||||
case .phraseResponse(.failure):
|
||||
// TODO: remove this when feature is implemented in https://github.com/zcash/secant-ios-wallet/issues/129
|
||||
return .none
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,7 +112,6 @@ enum RecoveryPhraseValidationFlowAction: Equatable {
|
|||
|
||||
struct RecoveryPhraseValidationFlowEnvironment {
|
||||
let scheduler: AnySchedulerOf<DispatchQueue>
|
||||
let newPhrase: () -> Effect<RecoveryPhrase, RecoveryPhraseError>
|
||||
let pasteboard: WrappedPasteboard
|
||||
let feedbackGenerator: WrappedFeedbackGenerator
|
||||
let recoveryPhraseRandomizer: WrappedRecoveryPhraseRandomizer
|
||||
|
@ -121,7 +120,6 @@ struct RecoveryPhraseValidationFlowEnvironment {
|
|||
extension RecoveryPhraseValidationFlowEnvironment {
|
||||
static let demo = Self(
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
newPhrase: { Effect(value: .init(words: RecoveryPhrase.placeholder.words)) },
|
||||
pasteboard: .test,
|
||||
feedbackGenerator: .silent,
|
||||
recoveryPhraseRandomizer: .live
|
||||
|
@ -129,7 +127,6 @@ extension RecoveryPhraseValidationFlowEnvironment {
|
|||
|
||||
static let live = Self(
|
||||
scheduler: DispatchQueue.main.eraseToAnyScheduler(),
|
||||
newPhrase: { Effect(value: .init(words: RecoveryPhrase.placeholder.words)) },
|
||||
pasteboard: .live,
|
||||
feedbackGenerator: .haptic,
|
||||
recoveryPhraseRandomizer: .live
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
//
|
||||
|
||||
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
|
||||
let objectForKey: @Sendable (String) -> Any?
|
||||
let remove: @Sendable (String) async -> Void
|
||||
let setValue: @Sendable (Any?, String) async -> Void
|
||||
let synchronize: @Sendable () async -> Bool
|
||||
}
|
||||
|
||||
extension WrappedUserDefaults {
|
||||
|
@ -20,25 +19,17 @@ extension WrappedUserDefaults {
|
|||
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
|
||||
objectForKey: { userDefaults.object(forKey: $0) },
|
||||
remove: { userDefaults.removeObject(forKey: $0) },
|
||||
setValue: { userDefaults.set($0, forKey: $1) },
|
||||
synchronize: { userDefaults.synchronize() }
|
||||
)
|
||||
}
|
||||
|
||||
static let mock = WrappedUserDefaults(
|
||||
objectForKey: { _ in },
|
||||
remove: { _ in .none },
|
||||
setValue: { _, _ in .none },
|
||||
remove: { _ in },
|
||||
setValue: { _, _ in },
|
||||
synchronize: { true }
|
||||
)
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class RecoveryPhraseDisplayReducerTests: XCTestCase {
|
|||
environment: .demo
|
||||
)
|
||||
|
||||
store.send(.phraseResponse(.success(.placeholder))) {
|
||||
store.send(.phraseResponse(.placeholder)) {
|
||||
$0.phrase = .placeholder
|
||||
$0.showCopyToBufferAlert = false
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ import XCTest
|
|||
@testable import secant_testnet
|
||||
import ComposableArchitecture
|
||||
import ZcashLightClientKit
|
||||
import Combine
|
||||
|
||||
@MainActor
|
||||
class DeeplinkTests: XCTestCase {
|
||||
func testActionDeeplinkHome_SameRouteLevel() throws {
|
||||
let testEnvironment = AppEnvironment.mock
|
||||
|
@ -73,7 +73,7 @@ class DeeplinkTests: XCTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
func testDeeplinkRequest_homeURL() throws {
|
||||
func testDeeplinkRequest_homeURL() async throws {
|
||||
let synchronizer = TestWrappedSDKSynchronizer()
|
||||
synchronizer.updateStateChanged(.synced)
|
||||
|
||||
|
@ -107,14 +107,16 @@ class DeeplinkTests: XCTestCase {
|
|||
return XCTFail("Deeplink: 'testDeeplinkRequest_homeURL' URL is expected to be valid.")
|
||||
}
|
||||
|
||||
store.send(.deeplink(url))
|
||||
await store.send(.deeplink(url))
|
||||
|
||||
store.receive(.deeplinkHome) { state in
|
||||
await store.receive(.deeplinkHome) { state in
|
||||
state.route = .home
|
||||
}
|
||||
|
||||
await store.finish()
|
||||
}
|
||||
|
||||
func testDeeplinkRequest_sendURL_amount() throws {
|
||||
func testDeeplinkRequest_sendURL_amount() async throws {
|
||||
let synchronizer = TestWrappedSDKSynchronizer()
|
||||
synchronizer.updateStateChanged(.synced)
|
||||
|
||||
|
@ -148,22 +150,24 @@ class DeeplinkTests: XCTestCase {
|
|||
return XCTFail("Deeplink: 'testDeeplinkRequest_sendURL_amount' URL is expected to be valid.")
|
||||
}
|
||||
|
||||
store.send(.deeplink(url))
|
||||
await store.send(.deeplink(url))
|
||||
|
||||
let amount = Zatoshi(123_000_000)
|
||||
let address = ""
|
||||
let memo = ""
|
||||
|
||||
store.receive(.deeplinkSend(amount, address, memo)) { state in
|
||||
await store.receive(.deeplinkSend(amount, address, memo)) { state in
|
||||
state.route = .home
|
||||
state.homeState.route = .send
|
||||
state.homeState.sendState.amount = amount
|
||||
state.homeState.sendState.address = address
|
||||
state.homeState.sendState.memoState.text = memo
|
||||
}
|
||||
|
||||
await store.finish()
|
||||
}
|
||||
|
||||
func testDeeplinkRequest_sendURL_allFields() throws {
|
||||
func testDeeplinkRequest_sendURL_allFields() async throws {
|
||||
let synchronizer = TestWrappedSDKSynchronizer()
|
||||
synchronizer.updateStateChanged(.synced)
|
||||
|
||||
|
@ -197,18 +201,20 @@ class DeeplinkTests: XCTestCase {
|
|||
return XCTFail("Deeplink: 'testDeeplinkRequest_sendURL_amount' URL is expected to be valid.")
|
||||
}
|
||||
|
||||
store.send(.deeplink(url))
|
||||
await store.send(.deeplink(url))
|
||||
|
||||
let amount = Zatoshi(123_000_000)
|
||||
let address = "address"
|
||||
let memo = "some text"
|
||||
|
||||
store.receive(.deeplinkSend(amount, address, memo)) { state in
|
||||
await store.receive(.deeplinkSend(amount, address, memo)) { state in
|
||||
state.route = .home
|
||||
state.homeState.route = .send
|
||||
state.homeState.sendState.amount = amount
|
||||
state.homeState.sendState.address = address
|
||||
state.homeState.sendState.memoState.text = memo
|
||||
}
|
||||
|
||||
await store.finish()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ class RecoveryPhraseValidationTests: XCTestCase {
|
|||
|
||||
let testEnvironment = RecoveryPhraseValidationFlowEnvironment(
|
||||
scheduler: testScheduler.eraseToAnyScheduler(),
|
||||
newPhrase: { Effect(value: .init(words: RecoveryPhrase.placeholder.words)) },
|
||||
pasteboard: .test,
|
||||
feedbackGenerator: .silent,
|
||||
recoveryPhraseRandomizer: .live
|
||||
|
|
|
@ -7,16 +7,13 @@
|
|||
|
||||
import XCTest
|
||||
@testable import secant_testnet
|
||||
import Combine
|
||||
|
||||
class UserPreferencesStorageTests: XCTestCase {
|
||||
private var cancellables: [AnyCancellable] = []
|
||||
|
||||
// swiftlint:disable:next implicitly_unwrapped_optional
|
||||
var storage: UserPreferencesStorage!
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
override func setUp() async throws {
|
||||
try await super.setUp()
|
||||
|
||||
guard let userDefaults = UserDefaults.init(suiteName: "test") else {
|
||||
XCTFail("UserPreferencesStorageTests: UserDefaults.init(suiteName: \"test\") failed to initialize")
|
||||
|
@ -31,16 +28,12 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
sessionAutoshielded: false,
|
||||
userDefaults: .live(userDefaults: userDefaults)
|
||||
)
|
||||
storage.removeAll()
|
||||
.sink(receiveValue: { _ in })
|
||||
.store(in: &cancellables)
|
||||
await storage.removeAll()
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
super.tearDown()
|
||||
storage.removeAll()
|
||||
.sink(receiveValue: { _ in })
|
||||
.store(in: &cancellables)
|
||||
override func tearDown() async throws {
|
||||
try await super.tearDown()
|
||||
await storage.removeAll()
|
||||
storage = nil
|
||||
}
|
||||
|
||||
|
@ -68,42 +61,32 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
|
||||
// MARK: - Set new values in the live UserDefaults environment
|
||||
|
||||
func testAppSessionFrom_setNewValue() throws {
|
||||
storage.setActiveAppSessionFrom(87654321.0)
|
||||
.sink(receiveValue: { _ in })
|
||||
.store(in: &cancellables)
|
||||
func testAppSessionFrom_setNewValue() async throws {
|
||||
await storage.setActiveAppSessionFrom(87654321.0)
|
||||
|
||||
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)
|
||||
func testConvertedCurrency_setNewValue() async throws {
|
||||
await storage.setCurrency("CZK")
|
||||
|
||||
XCTAssertEqual("CZK", storage.currency, "User Preferences: `currency` default doesn't match.")
|
||||
}
|
||||
|
||||
func testFiatConvertion_setNewValue() throws {
|
||||
storage.setIsFiatConverted(false)
|
||||
.sink(receiveValue: { _ in })
|
||||
.store(in: &cancellables)
|
||||
func testFiatConvertion_setNewValue() async throws {
|
||||
await storage.setIsFiatConverted(false)
|
||||
|
||||
XCTAssertEqual(false, storage.isFiatConverted, "User Preferences: `isFiatConverted` default doesn't match.")
|
||||
}
|
||||
|
||||
func testRecoveryPhraseTestCompleted_setNewValue() throws {
|
||||
storage.setIsRecoveryPhraseTestCompleted(false)
|
||||
.sink(receiveValue: { _ in })
|
||||
.store(in: &cancellables)
|
||||
func testRecoveryPhraseTestCompleted_setNewValue() async throws {
|
||||
await storage.setIsRecoveryPhraseTestCompleted(false)
|
||||
|
||||
XCTAssertEqual(false, storage.isRecoveryPhraseTestCompleted, "User Preferences: `isRecoveryPhraseTestCompleted` default doesn't match.")
|
||||
}
|
||||
|
||||
func testSessionAutoshielded_setNewValue() throws {
|
||||
storage.setIsSessionAutoshielded(true)
|
||||
.sink(receiveValue: { _ in })
|
||||
.store(in: &cancellables)
|
||||
func testSessionAutoshielded_setNewValue() async throws {
|
||||
await storage.setIsSessionAutoshielded(true)
|
||||
|
||||
XCTAssertEqual(true, storage.isSessionAutoshielded, "User Preferences: `isSessionAutoshielded` default doesn't match.")
|
||||
}
|
||||
|
@ -113,8 +96,8 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
func testAppSessionFrom_mocked() throws {
|
||||
let mockedUD = WrappedUserDefaults(
|
||||
objectForKey: { _ in 87654321.0 },
|
||||
remove: { _ in .none },
|
||||
setValue: { _, _ in .none },
|
||||
remove: { _ in },
|
||||
setValue: { _, _ in },
|
||||
synchronize: { true }
|
||||
)
|
||||
|
||||
|
@ -133,8 +116,8 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
func testConvertedCurrency_mocked() throws {
|
||||
let mockedUD = WrappedUserDefaults(
|
||||
objectForKey: { _ in "CZK" },
|
||||
remove: { _ in .none },
|
||||
setValue: { _, _ in .none },
|
||||
remove: { _ in },
|
||||
setValue: { _, _ in },
|
||||
synchronize: { true }
|
||||
)
|
||||
|
||||
|
@ -153,8 +136,8 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
func testFiatConvertion_mocked() throws {
|
||||
let mockedUD = WrappedUserDefaults(
|
||||
objectForKey: { _ in false },
|
||||
remove: { _ in .none },
|
||||
setValue: { _, _ in .none },
|
||||
remove: { _ in },
|
||||
setValue: { _, _ in },
|
||||
synchronize: { true }
|
||||
)
|
||||
|
||||
|
@ -173,8 +156,8 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
func testRecoveryPhraseTestCompleted_mocked() throws {
|
||||
let mockedUD = WrappedUserDefaults(
|
||||
objectForKey: { _ in false },
|
||||
remove: { _ in .none },
|
||||
setValue: { _, _ in .none },
|
||||
remove: { _ in },
|
||||
setValue: { _, _ in },
|
||||
synchronize: { true }
|
||||
)
|
||||
|
||||
|
@ -193,8 +176,8 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
func testSessionAutoshielded_mocked() throws {
|
||||
let mockedUD = WrappedUserDefaults(
|
||||
objectForKey: { _ in true },
|
||||
remove: { _ in .none },
|
||||
setValue: { _, _ in .none },
|
||||
remove: { _ in },
|
||||
setValue: { _, _ in },
|
||||
synchronize: { true }
|
||||
)
|
||||
|
||||
|
@ -212,7 +195,7 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
|
||||
// MARK: - Remove all keys from the live UD environment
|
||||
|
||||
func testRemoveAll() throws {
|
||||
func testRemoveAll() async throws {
|
||||
guard let userDefaults = UserDefaults.init(suiteName: "test") else {
|
||||
XCTFail("User Preferences: UserDefaults.init(suiteName: \"test\") failed to initialize")
|
||||
return
|
||||
|
@ -224,9 +207,7 @@ class UserPreferencesStorageTests: XCTestCase {
|
|||
}
|
||||
|
||||
// remove it
|
||||
storage?.removeAll()
|
||||
.sink(receiveValue: { _ in })
|
||||
.store(in: &cancellables)
|
||||
await storage?.removeAll()
|
||||
|
||||
// check the presence
|
||||
UserPreferencesStorage.Constants.allCases.forEach {
|
||||
|
|
Loading…
Reference in New Issue